<commit_before>#include "graphics/font.h"
#include "graphics/graphics.h"
#include "graphics/texture.h"
#include "loaders/font.h"
#include "loaders/texture.h"
#include "util.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

Font* lovrFontCreate(FontData* fontData) {
  Font* font = lovrAlloc(sizeof(Font), lovrFontDestroy);
  if (!font) return NULL;

  font->fontData = fontData;
  font->texture = NULL;
  font->lineHeight = 1.f;
  vec_init(&font->vertices);
  map_init(&font->kerning);

  // Atlas
  int padding = 1;
  font->atlas.x = padding;
  font->atlas.y = padding;
  font->atlas.width = 128;
  font->atlas.height = 128;
  font->atlas.padding = padding;
  map_init(&font->atlas.glyphs);

  // Set initial atlas size
  while (font->atlas.height < 4 * fontData->size) {
    lovrFontExpandTexture(font);
  }

  // Texture
  TextureData* textureData = lovrTextureDataGetBlank(font->atlas.width, font->atlas.height, 0x0, FORMAT_RG);
  font->texture = lovrTextureCreate(textureData);
  lovrTextureSetWrap(font->texture, WRAP_CLAMP, WRAP_CLAMP);
  int swizzle[4] = { GL_RED, GL_RED, GL_RED, GL_GREEN };
  glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);

  return font;
}

void lovrFontDestroy(const Ref* ref) {
  Font* font = containerof(ref, Font);
  lovrFontDataDestroy(font->fontData);
  lovrRelease(&font->texture->ref);
  map_deinit(&font->atlas.glyphs);
  map_deinit(&font->kerning);
  vec_deinit(&font->vertices);
  free(font);
}

void lovrFontPrint(Font* font, const char* str, float x, float y, float z, float w, float h, float angle, float ax, float ay, float az) {
  FontAtlas* atlas = &font->atlas;

  float cx = 0;
  float cy = -font->fontData->height * font->lineHeight / 2;
  float u = atlas->width;
  float v = atlas->height;
  float scale = h / font->fontData->height;

  int len = strlen(str);
  const char* start = str;
  const char* end = str + len;
  unsigned int previous = '\0';
  unsigned int codepoint;
  size_t bytes;

  int linePtr = 0;

  vec_reserve(&font->vertices, len * 30);
  vec_clear(&font->vertices);

  while ((bytes = utf8_decode(str, end, &codepoint)) > 0) {

    // Newlines
    if (codepoint == '\n' || (w && cx > w / scale && codepoint == ' ')) {

      // Center the line
      while (linePtr < font->vertices.length) {
        font->vertices.data[linePtr] -= cx / 2;
        linePtr += 5;
      }

      cx = 0;
      cy -= font->fontData->size * font->lineHeight;
      previous = '\0';
      str += bytes;
      continue;
    }

    // Kerning
    cx += lovrFontGetKerning(font, previous, codepoint);
    previous = codepoint;

    // Get glyph
    Glyph* glyph = lovrFontGetGlyph(font, codepoint);

    // Start over if texture was repacked
    if (u != atlas->width || v != atlas->height) {
      lovrFontPrint(font, start, x, y, z, w, h, angle, ax, ay, az);
      return;
    }

    // Triangles
    if (glyph->w > 0 && glyph->h > 0) {
      float x1 = cx + glyph->dx;
      float y1 = cy + glyph->dy;
      float x2 = x1 + glyph->w;
      float y2 = y1 - glyph->h;
      float s1 = glyph->x / u;
      float t1 = glyph->y / v;
      float s2 = (glyph->x + glyph->w) / u;
      float t2 = (glyph->y + glyph->h) / v;

      float vertices[30] = {
        x1, y1, 0, s1, t1,
        x1, y2, 0, s1, t2,
        x2, y1, 0, s2, t1,
        x2, y1, 0, s2, t1,
        x1, y2, 0, s1, t2,
        x2, y2, 0, s2, t2
      };

      vec_pusharr(&font->vertices, vertices, 30);
    }

    // Advance cursor
    cx += glyph->advance;
    str += bytes;
  }

  // Center the last line
  while (linePtr < font->vertices.length) {
    font->vertices.data[linePtr] -= cx / 2;
    linePtr += 5;
  }

  // We override the depth test to LEQUAL to prevent blending issues with glyphs, not great
  CompareMode oldCompareMode = lovrGraphicsGetDepthTest();

  lovrGraphicsPush();
  lovrGraphicsTranslate(x, y, z);
  lovrGraphicsScale(scale, scale, scale);
  lovrGraphicsRotate(angle, ax, ay, az);
  lovrGraphicsTranslate(0, -cy / 2, 0);
  lovrGraphicsSetDepthTest(COMPARE_LEQUAL);
  lovrGraphicsBindTexture(NULL);<commit_msg>Use correct texture for fonts;<commit_after>#include "graphics/font.h"
#include "graphics/graphics.h"
#include "graphics/texture.h"
#include "loaders/font.h"
#include "loaders/texture.h"
#include "util.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

Font* lovrFontCreate(FontData* fontData) {
  Font* font = lovrAlloc(sizeof(Font), lovrFontDestroy);
  if (!font) return NULL;

  font->fontData = fontData;
  font->texture = NULL;
  font->lineHeight = 1.f;
  vec_init(&font->vertices);
  map_init(&font->kerning);

  // Atlas
  int padding = 1;
  font->atlas.x = padding;
  font->atlas.y = padding;
  font->atlas.width = 128;
  font->atlas.height = 128;
  font->atlas.padding = padding;
  map_init(&font->atlas.glyphs);

  // Set initial atlas size
  while (font->atlas.height < 4 * fontData->size) {
    lovrFontExpandTexture(font);
  }

  // Texture
  TextureData* textureData = lovrTextureDataGetBlank(font->atlas.width, font->atlas.height, 0x0, FORMAT_RG);
  font->texture = lovrTextureCreate(textureData);
  lovrTextureSetWrap(font->texture, WRAP_CLAMP, WRAP_CLAMP);
  int swizzle[4] = { GL_RED, GL_RED, GL_RED, GL_GREEN };
  glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);

  return font;
}

void lovrFontDestroy(const Ref* ref) {
  Font* font = containerof(ref, Font);
  lovrFontDataDestroy(font->fontData);
  lovrRelease(&font->texture->ref);
  map_deinit(&font->atlas.glyphs);
  map_deinit(&font->kerning);
  vec_deinit(&font->vertices);
  free(font);
}

void lovrFontPrint(Font* font, const char* str, float x, float y, float z, float w, float h, float angle, float ax, float ay, float az) {
  FontAtlas* atlas = &font->atlas;

  float cx = 0;
  float cy = -font->fontData->height * font->lineHeight / 2;
  float u = atlas->width;
  float v = atlas->height;
  float scale = h / font->fontData->height;

  int len = strlen(str);
  const char* start = str;
  const char* end = str + len;
  unsigned int previous = '\0';
  unsigned int codepoint;
  size_t bytes;

  int linePtr = 0;

  vec_reserve(&font->vertices, len * 30);
  vec_clear(&font->vertices);

  while ((bytes = utf8_decode(str, end, &codepoint)) > 0) {

    // Newlines
    if (codepoint == '\n' || (w && cx > w / scale && codepoint == ' ')) {

      // Center the line
      while (linePtr < font->vertices.length) {
        font->vertices.data[linePtr] -= cx / 2;
        linePtr += 5;
      }

      cx = 0;
      cy -= font->fontData->size * font->lineHeight;
      previous = '\0';
      str += bytes;
      continue;
    }

    // Kerning
    cx += lovrFontGetKerning(font, previous, codepoint);
    previous = codepoint;

    // Get glyph
    Glyph* glyph = lovrFontGetGlyph(font, codepoint);

    // Start over if texture was repacked
    if (u != atlas->width || v != atlas->height) {
      lovrFontPrint(font, start, x, y, z, w, h, angle, ax, ay, az);
      return;
    }

    // Triangles
    if (glyph->w > 0 && glyph->h > 0) {
      float x1 = cx + glyph->dx;
      float y1 = cy + glyph->dy;
      float x2 = x1 + glyph->w;
      float y2 = y1 - glyph->h;
      float s1 = glyph->x / u;
      float t1 = glyph->y / v;
      float s2 = (glyph->x + glyph->w) / u;
      float t2 = (glyph->y + glyph->h) / v;

      float vertices[30] = {
        x1, y1, 0, s1, t1,
        x1, y2, 0, s1, t2,
        x2, y1, 0, s2, t1,
        x2, y1, 0, s2, t1,
        x1, y2, 0, s1, t2,
        x2, y2, 0, s2, t2
      };

      vec_pusharr(&font->vertices, vertices, 30);
    }

    // Advance cursor
    cx += glyph->advance;
    str += bytes;
  }

  // Center the last line
  while (linePtr < font->vertices.length) {
    font->vertices.data[linePtr] -= cx / 2;
    linePtr += 5;
  }

  // We override the depth test to LEQUAL to prevent blending issues with glyphs, not great
  CompareMode oldCompareMode = lovrGraphicsGetDepthTest();

  lovrGraphicsPush();
  lovrGraphicsTranslate(x, y, z);
  lovrGraphicsScale(scale, scale, scale);
  lovrGraphicsRotate(angle, ax, ay, az);
  lovrGraphicsTranslate(0, -cy / 2, 0);
  lovrGraphicsSetDepthTest(COMPARE_LEQUAL);
  lovrGraphicsBindTexture(font->texture);
{'fraction_non_alphanumeric': 0.15184461275348154, 'fraction_numerical': 0.018568287319814317, 'mean_word_length': 2.9285028790786947, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 130, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '191664', 'n_tokens_mistral': 3147, 'n_tokens_neox': 2984, 'n_words': 745}