Freetype с C++ не загружает все глифы правильно

Я использую FreeType для загрузки текстур глифов, в основном используя FT_Load_Char для получения текстуры, а затем создаю экземпляр моего пользовательского класса Character, который содержит все метрики и текстуру для последующего рендеринга:

  for (unsigned int c = min; c < max; c++)
  {
    if (FT_Get_Char_Index(faces[faceIndex].second, c) == 0)
      continue;
    if (FT_Load_Char(faces[faceIndex].second, c, FT_LOAD_RENDER))
    {
      cout << "Error: Failed to load Glyph: " << c << endl;
      continue;
    }
    FT_GlyphSlot glyph = faces[faceIndex].second->glyph;
    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, glyph->bitmap.width, glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, glyph->bitmap.buffer);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    Character character;
    character.texture = texture;
    character.bearingX = glyph->bitmap_left;
    character.bearingY = glyph->bitmap_top;
    character.width = glyph->bitmap.width;
    character.height = glyph->bitmap.rows;
    character.advance = glyph->advance.x;

    characters[faceIndex][c] = character;
    count++;
  }

Это правильно работает для подавляющего большинства символов, но ввод чего-то вроде asd-=_+123 приведет к следующему:

введите здесь описание изображения

Таким образом, некоторые глифы, такие как +=-, загружаются неправильно, я использую NotoMono-Regular, поэтому он, очевидно, имеет эти основные глифы.

Дальнейшая отладка путем распечатки буфера растрового изображения глифа дает следующее для плохих символов: bitmap buffer of - gives: α α α α α α α α α α

В то время как для хороших персонажей это что-то вроде: bitmap buffer of 1 gives: 94

Так что я думаю, что проблема здесь, но не знаю, как это исправить


person Mudkip Hacker    schedule 17.02.2021    source источник


Ответы (2)


Вы уверены, что файл TTF, который потребляет ваша библиотека бесплатных типов, завершен? Попробуйте загрузить файл TTF на один из этих веб-сайтов и посмотрите, есть ли у него проблемы с анализом символов, с которыми у вас возникли проблемы.

http://mathew-kurian.github.io/CharacterMap/

http://www.glyphrstudio.com/online/

person halexh    schedule 18.02.2021
comment
Да, я уверен, я вижу в своей программе просмотра VSCode ttf, что =-+ существует - person Mudkip Hacker; 18.02.2021

Character character;
character.texture = texture;
character.bearingX = glyph->bitmap_left;
character.bearingY = glyph->bitmap_top;
character.width = glyph->bitmap.width;
character.height = glyph->bitmap.rows;
character.advance = glyph->advance.x;

Как оказалось, использование unsigned int вместо height и int вместо bearingY семантически корректно, однако есть арифметические действия, которые выглядят так:

transformation.translation().y() - (ch.height - ch.bearingY) * size * renderer->aspectRatio

где ch.height - ch.bearingY неявно повышается до unsigned int, а затем неявно преобразуется в float, как вы можете догадаться, если ожидаемый результат ch.height - ch.bearingY отрицательный, произойдут плохие вещи. Кто вообще решил, что unsigned int имеет более высокий рейтинг конверсии....

person Mudkip Hacker    schedule 20.02.2021