Skip to content

Commit 744debc

Browse files
authored
Merge pull request #36 from zao/fix-glyph-overflow
Interpret invalid glyphs as zero-width placeholder
2 parents 308f249 + 7100ff6 commit 744debc

File tree

1 file changed

+28
-15
lines changed

1 file changed

+28
-15
lines changed

engine/render/r_font.cpp

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ struct f_fontHeight_s {
3232
int height;
3333
int numGlyph;
3434
f_glyph_s glyphs[128];
35+
f_glyph_s defGlyph{0.0, 0.0, 0.0, 0.0, 0, 0, 0};
36+
37+
f_glyph_s const& Glyph(char ch) const {
38+
if ((unsigned char)ch >= numGlyph) {
39+
return defGlyph;
40+
}
41+
return glyphs[(unsigned char)ch];
42+
}
3543
};
3644

3745
// ===========
@@ -126,11 +134,13 @@ int r_font_c::StringWidthInternal(f_fontHeight_s* fh, const char* str)
126134
if (escLen) {
127135
str+= escLen;
128136
} else if (*str == '\t') {
129-
int spWidth = fh->glyphs[' '].width + fh->glyphs[' '].spLeft + fh->glyphs[' '].spRight;
130-
width+= spWidth << 2;
137+
auto& glyph = fh->Glyph(' ');
138+
int spWidth = glyph.width + glyph.spLeft + glyph.spRight;
139+
width += spWidth << 2;
131140
str++;
132141
} else {
133-
width+= fh->glyphs[*str].width + fh->glyphs[*str].spLeft + fh->glyphs[*str].spRight;
142+
auto& glyph = fh->Glyph(*str);
143+
width+= glyph.width + glyph.spLeft + glyph.spRight;
134144
str++;
135145
}
136146
}
@@ -165,15 +175,17 @@ const char* r_font_c::StringCursorInternal(f_fontHeight_s* fh, const char* str,
165175
if (escLen) {
166176
str+= escLen;
167177
} else if (*str == '\t') {
168-
int spWidth = fh->glyphs[' '].width + fh->glyphs[' '].spLeft + fh->glyphs[' '].spRight;
178+
auto& glyph = fh->Glyph(' ');
179+
int spWidth = glyph.width + glyph.spLeft + glyph.spRight;
169180
x+= spWidth << 1;
170181
if (curX <= x) {
171182
break;
172183
}
173184
x+= spWidth << 1;
174185
str++;
175186
} else {
176-
x+= fh->glyphs[*str].width + fh->glyphs[*str].spLeft + fh->glyphs[*str].spRight;
187+
auto& glyph = fh->Glyph(*str);
188+
x+= glyph.width + glyph.spLeft + glyph.spRight;
177189
if (curX <= x) {
178190
break;
179191
}
@@ -274,28 +286,29 @@ void r_font_c::DrawTextLine(scp_t pos, int align, int height, col4_t col, const
274286

275287
// Handle tabs
276288
if (*str == '\t') {
277-
int spWidth = fh->glyphs[' '].width + fh->glyphs[' '].spLeft + fh->glyphs[' '].spRight;
289+
auto& glyph = fh->Glyph(' ');
290+
int spWidth = glyph.width + glyph.spLeft + glyph.spRight;
278291
x+= (spWidth << 2) * scale;
279292
str++;
280293
continue;
281294
}
282295

283296
// Draw glyph
284-
f_glyph_s* glyph = fh->glyphs + *(str++);
285-
x+= glyph->spLeft * scale;
286-
if (glyph->width) {
287-
double w = glyph->width * scale;
297+
auto& glyph = fh->Glyph(*str++);
298+
x+= glyph.spLeft * scale;
299+
if (glyph.width) {
300+
double w = glyph.width * scale;
288301
if (x + w >= 0 && x < renderer->VirtualScreenWidth()) {
289302
renderer->curLayer->Quad(
290-
glyph->tcLeft, glyph->tcTop, x, y,
291-
glyph->tcRight, glyph->tcTop, x + w, y,
292-
glyph->tcRight, glyph->tcBottom, x + w, y + height,
293-
glyph->tcLeft, glyph->tcBottom, x, y + height
303+
glyph.tcLeft, glyph.tcTop, x, y,
304+
glyph.tcRight, glyph.tcTop, x + w, y,
305+
glyph.tcRight, glyph.tcBottom, x + w, y + height,
306+
glyph.tcLeft, glyph.tcBottom, x, y + height
294307
);
295308
}
296309
x+= w;
297310
}
298-
x+= glyph->spRight * scale;
311+
x+= glyph.spRight * scale;
299312
}
300313
}
301314

0 commit comments

Comments
 (0)