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.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/src/ui/text.c b/src/ui/text.c
index ab2af2b2..51531057 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -246,10 +246,22 @@ struct Impl_CacheRow {
246 iInt2 pos; 246 iInt2 pos;
247}; 247};
248 248
249iDeclareType(PrioMapItem)
250struct Impl_PrioMapItem {
251 int priority;
252 uint32_t fontIndex;
253};
254
255static int cmp_PrioMapItem_(const void *a, const void *b) {
256 const iPrioMapItem *i = a, *j = b;
257 return -iCmp(i->priority, j->priority);
258}
259
249struct Impl_Text { 260struct Impl_Text {
250 float contentFontSize; 261 float contentFontSize;
251 iArray fonts; /* fonts currently selected for use (incl. all styles/sizes) */ 262 iArray fonts; /* fonts currently selected for use (incl. all styles/sizes) */
252 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 */
264 iArray fontPriorityOrder;
253 SDL_Renderer * render; 265 SDL_Renderer * render;
254 SDL_Texture * cache; 266 SDL_Texture * cache;
255 iInt2 cacheSize; 267 iInt2 cacheSize;
@@ -283,8 +295,9 @@ static void setupFontVariants_Text_(iText *d, const iFontSpec *spec, int baseId)
283 /* This is the highest priority override font. */ 295 /* This is the highest priority override font. */
284 d->overrideFontId = baseId; 296 d->overrideFontId = baseId;
285 } 297 }
298 pushBack_Array(&d->fontPriorityOrder, &(iPrioMapItem){ spec->priority, baseId });
286 for (enum iFontStyle style = 0; style < max_FontStyle; style++) { 299 for (enum iFontStyle style = 0; style < max_FontStyle; style++) {
287 for (enum iFontSize sizeId = 0; sizeId < max_FontSize; sizeId++) { 300 for (enum iFontSize sizeId = 0; sizeId < max_FontSize; sizeId++) {
288 init_Font(font_Text_(FONT_ID(baseId, style, sizeId)), 301 init_Font(font_Text_(FONT_ID(baseId, style, sizeId)),
289 spec, 302 spec,
290 spec->styles[style], 303 spec->styles[style],
@@ -321,6 +334,7 @@ static void initFonts_Text_(iText *d) {
321 and styles for each available font. Indices to `fonts` act as font runtime IDs. */ 334 and styles for each available font. Indices to `fonts` act as font runtime IDs. */
322 /* First the mandatory fonts. */ 335 /* First the mandatory fonts. */
323 d->overrideFontId = -1; 336 d->overrideFontId = -1;
337 clear_Array(&d->fontPriorityOrder);
324 resize_Array(&d->fonts, auxiliary_FontId); /* room for the built-ins */ 338 resize_Array(&d->fonts, auxiliary_FontId); /* room for the built-ins */
325 setupFontVariants_Text_(d, tryFindSpec_(uiFont_PrefsString, "default"), default_FontId); 339 setupFontVariants_Text_(d, tryFindSpec_(uiFont_PrefsString, "default"), default_FontId);
326 setupFontVariants_Text_(d, tryFindSpec_(monospaceFont_PrefsString, "iosevka"), monospace_FontId); 340 setupFontVariants_Text_(d, tryFindSpec_(monospaceFont_PrefsString, "iosevka"), monospace_FontId);
@@ -330,12 +344,14 @@ static void initFonts_Text_(iText *d) {
330 /* Check if there are auxiliary fonts available and set those up, too. */ 344 /* Check if there are auxiliary fonts available and set those up, too. */
331 iConstForEach(PtrArray, s, listSpecsByPriority_Fonts()) { 345 iConstForEach(PtrArray, s, listSpecsByPriority_Fonts()) {
332 const iFontSpec *spec = s.ptr; 346 const iFontSpec *spec = s.ptr;
347// printf("spec '%s': prio=%d\n", cstr_String(&spec->name), spec->priority);
333 if (spec->flags & (auxiliary_FontSpecFlag | user_FontSpecFlag)) { 348 if (spec->flags & (auxiliary_FontSpecFlag | user_FontSpecFlag)) {
334 const int fontId = size_Array(&d->fonts); 349 const int fontId = size_Array(&d->fonts);
335 resize_Array(&d->fonts, fontId + maxVariants_Fonts); 350 resize_Array(&d->fonts, fontId + maxVariants_Fonts);
336 setupFontVariants_Text_(d, spec, fontId); 351 setupFontVariants_Text_(d, spec, fontId);
337 } 352 }
338 } 353 }
354 sort_Array(&d->fontPriorityOrder, cmp_PrioMapItem_);
339#if !defined (NDEBUG) 355#if !defined (NDEBUG)
340 printf("[Text] %zu font variants ready\n", size_Array(&d->fonts)); 356 printf("[Text] %zu font variants ready\n", size_Array(&d->fonts));
341#endif 357#endif
@@ -403,6 +419,7 @@ void init_Text(iText *d, SDL_Renderer *render) {
403 iText *oldActive = activeText_; 419 iText *oldActive = activeText_;
404 activeText_ = d; 420 activeText_ = d;
405 init_Array(&d->fonts, sizeof(iFont)); 421 init_Array(&d->fonts, sizeof(iFont));
422 init_Array(&d->fontPriorityOrder, sizeof(iPrioMapItem));
406 d->contentFontSize = contentScale_Text_; 423 d->contentFontSize = contentScale_Text_;
407 d->ansiEscape = makeAnsiEscapePattern_Text(iFalse /* no ESC */); 424 d->ansiEscape = makeAnsiEscapePattern_Text(iFalse /* no ESC */);
408 d->baseFontId = -1; 425 d->baseFontId = -1;
@@ -438,6 +455,7 @@ void deinit_Text(iText *d) {
438 deinitCache_Text_(d); 455 deinitCache_Text_(d);
439 d->render = NULL; 456 d->render = NULL;
440 iRelease(d->ansiEscape); 457 iRelease(d->ansiEscape);
458 deinit_Array(&d->fontPriorityOrder);
441 deinit_Array(&d->fonts); 459 deinit_Array(&d->fonts);
442} 460}
443 461
@@ -573,25 +591,24 @@ iLocalDef iFont *characterFont_Font_(iFont *d, iChar ch, uint32_t *glyphIndex) {
573 if ((*glyphIndex = glyphIndex_Font_(d, ch)) != 0) { 591 if ((*glyphIndex = glyphIndex_Font_(d, ch)) != 0) {
574 return d; 592 return d;
575 } 593 }
576 /* As a fallback, check all other available fonts of this size. */ 594 /* As a fallback, check all other available fonts of this size in priority order. */
577 for (int aux = 0; aux < 2; aux++) { 595 iConstForEach(Array, i, &activeText_->fontPriorityOrder) {
578 for (iFont *font = font_Text_(FONT_ID(0, styleId, sizeId)); 596 iFont *font = font_Text_(FONT_ID(((const iPrioMapItem *) i.value)->fontIndex,
579 font < (iFont *) end_Array(&activeText_->fonts); 597 styleId, sizeId));
580 font += maxVariants_Fonts) { 598 if (font == d || font == overrideFont) {
581 const iBool isAuxiliary = (font->fontSpec->flags & auxiliary_FontSpecFlag) ? 1 : 0; 599 continue; /* already checked this one */
582 if (aux == isAuxiliary) { 600 }
583 /* First try auxiliary fonts, then other remaining fonts. */ 601 if ((*glyphIndex = glyphIndex_Font_(font, ch)) != 0) {
584 continue; 602#if 0
585 } 603 printf("using '%s' (pr:%d) for %lc (%x) => %d [missing in '%s']\n",
586 if (font == d || font == overrideFont) { 604 cstr_String(&font->fontSpec->id),
587 continue; /* already checked this one */ 605 font->fontSpec->priority,
588 } 606 (int) ch,
589 if ((*glyphIndex = glyphIndex_Font_(font, ch)) != 0) { 607 ch,
590// printf("using %s[%f] for %lc (%x) => %d\n", 608 glyphIndex_Font_(font, ch),
591// cstr_String(&font->fontSpec->name), font->fontSpec->scaling, 609 cstr_String(&d->fontSpec->id));
592// (int) ch, ch, glyphIndex_Font_(font, ch)); 610#endif
593 return font; 611 return font;
594 }
595 } 612 }
596 } 613 }
597 if (!*glyphIndex) { 614 if (!*glyphIndex) {
@@ -1450,7 +1467,7 @@ static void evenMonospaceAdvances_GlyphBuffer_(iGlyphBuffer *d, iFont *baseFont)
1450 if (d->glyphPos[i].x_advance > 0 && d->font != baseFont) { 1467 if (d->glyphPos[i].x_advance > 0 && d->font != baseFont) {
1451 const iChar ch = d->logicalText[info->cluster]; 1468 const iChar ch = d->logicalText[info->cluster];
1452 if (isPictograph_Char(ch) || isEmoji_Char(ch)) { 1469 if (isPictograph_Char(ch) || isEmoji_Char(ch)) {
1453 const float dw = d->font->xScale * d->glyphPos[i].x_advance - monoAdvance; 1470 const float dw = d->font->xScale * d->glyphPos[i].x_advance - (isEmoji_Char(ch) ? 2 : 1) * monoAdvance;
1454 d->glyphPos[i].x_offset -= dw / 2 / d->font->xScale - 1; 1471 d->glyphPos[i].x_offset -= dw / 2 / d->font->xScale - 1;
1455 d->glyphPos[i].x_advance -= dw / d->font->xScale - 1; 1472 d->glyphPos[i].x_advance -= dw / d->font->xScale - 1;
1456 } 1473 }