fix glyph positions

This commit is contained in:
boolean-false 2026-09-27 17:33:55 +07:00
parent bac0d43fd7
commit 64ba1dad4e
3 changed files with 24 additions and 21 deletions

View file

@ -122,10 +122,16 @@ namespace {
std::vector<Glyph>& glyphs std::vector<Glyph>& glyphs
) { ) {
int size = canvas.getWidth() / 16; int size = canvas.getWidth() / 16;
const size_t end = (pageid + 1) * 256;
if (glyphs.size() < end) {
glyphs.resize(end);
}
for (int c = 0; c < 256; c++) { for (int c = 0; c < 256; c++) {
int codepoint = pageid << 8 | c; int codepoint = pageid << 8 | c;
if (!renderGlyph(codepoint, bitmapDst)) { if (!renderGlyph(codepoint, bitmapDst)) {
glyphs.push_back(Glyph {0, size / 2}); glyphs[codepoint] = Glyph {0, size / 2};
continue; continue;
} }
@ -133,13 +139,10 @@ namespace {
Glyph glyph { Glyph glyph {
face->glyph->bitmap_top - size, face->glyph->bitmap_top - size,
static_cast<int>(face->glyph->advance.x >> 6) static_cast<int>(face->glyph->advance.x >> 6),
face->glyph->bitmap_left
}; };
if (codepoint < glyphs.size()) { glyphs[codepoint] = glyph;
glyphs[codepoint] = std::move(glyph);
} else {
glyphs.push_back(std::move(glyph));
}
} }
canvas.flipY(); canvas.flipY();
} }

View file

@ -176,7 +176,7 @@ static inline void draw_text(
int y = 0; int y = 0;
bool hasLines = false; bool hasLines = false;
float baseAdvance = glm::length(right); const float cellAdvance = interval * font.getLineHeight();
do { do {
for (size_t i = 0; i < text.length(); i++) { for (size_t i = 0; i < text.length(); i++) {
@ -193,12 +193,12 @@ static inline void draw_text(
continue; continue;
} }
int yOffset = 0; int yOffset = 0;
float advance = baseAdvance; int xOffset = 0;
float advance = 1.0f;
if (auto glyph = font.getGlyph(c)) { if (auto glyph = font.getGlyph(c)) {
yOffset = glyph->yOffset; yOffset = glyph->yOffset;
advance = glyph->xAdvance / xOffset = glyph->xOffset;
static_cast<float>(font.getLineHeight()) * 2.0f * advance = glyph->xAdvance / cellAdvance;
baseAdvance;
} }
uint charpage = c >> 8; uint charpage = c >> 8;
if (charpage == page){ if (charpage == page){
@ -207,7 +207,7 @@ static inline void draw_text(
batch, batch,
pos, pos,
glm::vec2( glm::vec2(
x, x + xOffset / cellAdvance,
y - yOffset * (is3d ? -1 : 1) / y - yOffset * (is3d ? -1 : 1) /
static_cast<float>(font.getLineHeight()) static_cast<float>(font.getLineHeight())
), ),
@ -221,7 +221,7 @@ static inline void draw_text(
else if (charpage > page && charpage < next){ else if (charpage > page && charpage < next){
next = charpage; next = charpage;
} }
x += advance / baseAdvance; x += advance;
} }
page = next; page = next;
next = MAX_CODEPAGES; next = MAX_CODEPAGES;
@ -329,23 +329,22 @@ const Glyph* Font::getGlyph(int codepoint) {
if (codepoint < 0) { if (codepoint < 0) {
return nullptr; return nullptr;
} }
if (codepoint < glyphs.size()) { const int codepage = codepoint >> 8;
if (codepoint < glyphs.size() &&
(!fontFile.has_value() ||
(codepage < pages.size() && pages[codepage]))) {
return &glyphs.at(codepoint); return &glyphs.at(codepoint);
} }
if (!this->fontFile.has_value() || this->fontFile->expired()) { if (!this->fontFile.has_value() || this->fontFile->expired()) {
return nullptr; return nullptr;
} }
int codepage = codepoint >> 8;
if (codepage >= 1024) { if (codepage >= 1024) {
return nullptr; return nullptr;
} }
if (glyphs.size() < (codepage << 8)) {
glyphs.resize(codepage << 8);
}
auto fontFile = this->fontFile->lock(); auto fontFile = this->fontFile->lock();
if (pages.size() <= codepage) { if (pages.size() <= codepage) {
pages.resize(codepage); pages.resize(codepage + 1);
} }
pages.push_back(fontFile->renderPage(codepage, glyphs, lineHeight)); pages[codepage] = fontFile->renderPage(codepage, glyphs, lineHeight);
return &glyphs.at(codepoint); return &glyphs.at(codepoint);
} }

View file

@ -26,6 +26,7 @@ namespace vector_fonts {
struct Glyph { struct Glyph {
int yOffset; int yOffset;
int xAdvance; int xAdvance;
int xOffset = 0;
}; };
class Font { class Font {