summaryrefslogtreecommitdiff
path: root/src/ui/text.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/text.c')
-rw-r--r--src/ui/text.c60
1 files changed, 47 insertions, 13 deletions
diff --git a/src/ui/text.c b/src/ui/text.c
index c19aed2f..83e87d0c 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -258,8 +258,6 @@ static int cmp_PrioMapItem_(const void *a, const void *b) {
258} 258}
259 259
260struct Impl_Text { 260struct Impl_Text {
261// enum iTextFont contentFont;
262// enum iTextFont headingFont;
263 float contentFontSize; 261 float contentFontSize;
264 iArray fonts; /* fonts currently selected for use (incl. all styles/sizes) */ 262 iArray fonts; /* fonts currently selected for use (incl. all styles/sizes) */
265 int overrideFontId; /* always checked for glyphs first, regardless of which font is used */ 263 int overrideFontId; /* always checked for glyphs first, regardless of which font is used */
@@ -276,7 +274,8 @@ struct Impl_Text {
276 int ansiFlags; 274 int ansiFlags;
277 int baseFontId; /* base attributes (for restoring via escapes) */ 275 int baseFontId; /* base attributes (for restoring via escapes) */
278 int baseFgColorId; 276 int baseFgColorId;
279 iBool missingGlyphs; /* true if a glyph couldn't be found */ 277 iBool missingGlyphs; /* true if a glyph couldn't be found */
278 iChar missingChars[20]; /* rotating buffer of the latest missing characters */
280}; 279};
281 280
282iDefineTypeConstructionArgs(Text, (SDL_Renderer *render), render) 281iDefineTypeConstructionArgs(Text, (SDL_Renderer *render), render)
@@ -296,6 +295,7 @@ static void setupFontVariants_Text_(iText *d, const iFontSpec *spec, int baseId)
296 /* This is the highest priority override font. */ 295 /* This is the highest priority override font. */
297 d->overrideFontId = baseId; 296 d->overrideFontId = baseId;
298 } 297 }
298 iAssert(activeText_ == d);
299 pushBack_Array(&d->fontPriorityOrder, &(iPrioMapItem){ spec->priority, baseId }); 299 pushBack_Array(&d->fontPriorityOrder, &(iPrioMapItem){ spec->priority, baseId });
300 for (enum iFontStyle style = 0; style < max_FontStyle; style++) { 300 for (enum iFontStyle style = 0; style < max_FontStyle; style++) {
301 for (enum iFontSize sizeId = 0; sizeId < max_FontSize; sizeId++) { 301 for (enum iFontSize sizeId = 0; sizeId < max_FontSize; sizeId++) {
@@ -357,6 +357,8 @@ static void initFonts_Text_(iText *d) {
357 printf("[Text] %zu font variants ready\n", size_Array(&d->fonts)); 357 printf("[Text] %zu font variants ready\n", size_Array(&d->fonts));
358#endif 358#endif
359 gap_Text = iRound(gap_UI * d->contentFontSize); 359 gap_Text = iRound(gap_UI * d->contentFontSize);
360// d->missingGlyphs = iFalse;
361// iZap(d->missingChars);
360} 362}
361 363
362static void deinitFonts_Text_(iText *d) { 364static void deinitFonts_Text_(iText *d) {
@@ -424,6 +426,7 @@ void init_Text(iText *d, SDL_Renderer *render) {
424 d->baseFontId = -1; 426 d->baseFontId = -1;
425 d->baseFgColorId = -1; 427 d->baseFgColorId = -1;
426 d->missingGlyphs = iFalse; 428 d->missingGlyphs = iFalse;
429 iZap(d->missingChars);
427 d->render = render; 430 d->render = render;
428 /* A grayscale palette for rasterized glyphs. */ { 431 /* A grayscale palette for rasterized glyphs. */ {
429 SDL_Color colors[256]; 432 SDL_Color colors[256];
@@ -497,10 +500,13 @@ static void resetCache_Text_(iText *d) {
497} 500}
498 501
499void resetFonts_Text(iText *d) { 502void resetFonts_Text(iText *d) {
503 iText *oldActive = activeText_;
504 setCurrent_Text(d); /* some routines rely on the global `activeText_` pointer */
500 deinitFonts_Text_(d); 505 deinitFonts_Text_(d);
501 deinitCache_Text_(d); 506 deinitCache_Text_(d);
502 initCache_Text_(d); 507 initCache_Text_(d);
503 initFonts_Text_(d); 508 initFonts_Text_(d);
509 setCurrent_Text(oldActive);
504} 510}
505 511
506static SDL_Palette *glyphPalette_(void) { 512static SDL_Palette *glyphPalette_(void) {
@@ -610,8 +616,23 @@ iLocalDef iFont *characterFont_Font_(iFont *d, iChar ch, uint32_t *glyphIndex) {
610 } 616 }
611 } 617 }
612 if (!*glyphIndex) { 618 if (!*glyphIndex) {
613 activeText_->missingGlyphs = iTrue; 619 fprintf(stderr, "failed to find %08x (%lc)\n", ch, (int) ch); fflush(stderr);
614 fprintf(stderr, "failed to find %08x (%lc)\n", ch, (int)ch); fflush(stderr); 620 iText *tx = activeText_;
621 tx->missingGlyphs = iTrue;
622 /* Remember a few of the latest missing characters. */
623 iBool gotIt = iFalse;
624 for (size_t i = 0; i < iElemCount(tx->missingChars); i++) {
625 if (tx->missingChars[i] == ch) {
626 gotIt = iTrue;
627 break;
628 }
629 }
630 if (!gotIt) {
631 memmove(tx->missingChars + 1,
632 tx->missingChars,
633 sizeof(tx->missingChars) - sizeof(tx->missingChars[0]));
634 tx->missingChars[0] = ch;
635 }
615 } 636 }
616 return d; 637 return d;
617} 638}
@@ -1459,14 +1480,14 @@ static void evenMonospaceAdvances_GlyphBuffer_(iGlyphBuffer *d, iFont *baseFont)
1459} 1480}
1460 1481
1461static iRect run_Font_(iFont *d, const iRunArgs *args) { 1482static iRect run_Font_(iFont *d, const iRunArgs *args) {
1462 const int mode = args->mode; 1483 const int mode = args->mode;
1463 const iInt2 orig = args->pos; 1484 const iInt2 orig = args->pos;
1464 iRect bounds = { orig, init_I2(0, d->height) }; 1485 iRect bounds = { orig, init_I2(0, d->height) };
1465 float xCursor = 0.0f; 1486 float xCursor = 0.0f;
1466 float yCursor = 0.0f; 1487 float yCursor = 0.0f;
1467 float xCursorMax = 0.0f; 1488 float xCursorMax = 0.0f;
1468 const iBool isMonospaced = isMonospaced_Font(d); 1489 const iBool isMonospaced = isMonospaced_Font(d);
1469 iWrapText *wrap = args->wrap; 1490 iWrapText *wrap = args->wrap;
1470 iAssert(args->text.end >= args->text.start); 1491 iAssert(args->text.end >= args->text.start);
1471 /* Split the text into a number of attributed runs that specify exactly which 1492 /* Split the text into a number of attributed runs that specify exactly which
1472 font is used and other attributes such as color. (HarfBuzz shaping is done 1493 font is used and other attributes such as color. (HarfBuzz shaping is done
@@ -2250,6 +2271,19 @@ iBool checkMissing_Text(void) {
2250 return missing; 2271 return missing;
2251} 2272}
2252 2273
2274iChar missing_Text(size_t index) {
2275 const iText *d = activeText_;
2276 if (index >= iElemCount(d->missingChars)) {
2277 return 0;
2278 }
2279 return d->missingChars[index];
2280}
2281
2282void resetMissing_Text(iText *d) {
2283 d->missingGlyphs = iFalse;
2284 iZap(d->missingChars);
2285}
2286
2253SDL_Texture *glyphCache_Text(void) { 2287SDL_Texture *glyphCache_Text(void) {
2254 return activeText_->cache; 2288 return activeText_->cache;
2255} 2289}