Пытаюсь сделать самодельный рендеринг текста с помощью PF2 шрифтов и OpenGL. В качестве шрифта использую Droid Sans. Для начала рендерю его в «моноширинном» режиме (поддержку переменной ширины глифа добавлю потом) - просто создаю текстуру, где каждому глифу отводится область maxCharWidth * maxCharHeight, а при рендеринге соответственно на каждую плоскость соответствующую очередному символу натягиваю текстуру по нужным координатам. Проблема в том, что глифы в шрифте могут иметь размеры меньше максимальных и их в этом случае надо правильно позиционировать внутри их места, иначе получается вот так (строчные буквы ниже заглавных и попадают не туда):
https://freeimage.host/i/iI0Yxt
Алгоритм помещения очередного глифа в текстуру шрифта выглядит так:
struct PF2CharHeader {
uint16_t width;
uint16_t height;
int16_t xOffset;
int16_t yOffset;
int16_t deviceWidth;
};
...
class PF2FontLoader {
...
int m_pointSize;
int m_maxCharWidth;
int m_maxCharHeight;
int m_ascent;
int m_descent;
...
}
...
void PF2FontLoader::parseCharBitmap(int index, const PF2CharHeader &header) {
int x0 = (index % m_colCount) * m_maxCharWidth; //+ header.xOffset;
int y0 = (index / m_colCount) * m_maxCharHeight; //+ header.yOffset;
auto base = m_deserializer.adapter().currentReadPos();
for (int y = 0; y < header.height; y++) {
int j = (y0 + y) * m_textureWidth + x0;
for (int x = 0; x < header.width; x++) {
int i = y * header.width + x;
uint8_t byte = m_data[base + i / 8];
if ((byte & (1 << (7 - i % 8))) != 0) {
m_textureData[j + x] = {255, 255, 255, 255};
}
}
}
}
Также у меня есть параметры m_pointSize, m_ascent и m_descent извлеченные из заголовка шрифта (см. полное описание формата - http://grub.gibibit.com/New_font_format).
По идее ими надо как-то воспользоваться, чтобы вычислить baseline и разместить глиф, когда его размер меньше максимального, однако использовать xOffset и yOffset не помогает. Во-первых, у «e» и «H» одинаковый нулевой yOffset (хотя буквы имеют разную высоту глифа), во-вторых, тогда некоторые другие глифы выходят за границы своего места в текстуре.
Также вот параметры шрифта Droid Sans:
PF2 font "assets/fonts/DroidSans-32.pf2"
PF2 font name: Droid Sans Regular 32
PF2 font family: Droid Sans
PF2 font weight: normal
PF2 font slant: normal
PF2 font point size: 32
PF2 font max char width: 36
PF2 font max char height: 36
PF2 font ascent: 34
PF2 font descent: 9
PF2 font character index has 873 Unicode code point(s) (873 unique glyph(s))