diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2022-01-19 15:51:07 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2022-01-19 15:51:07 +0200 |
commit | a6146ac91c90a4003efd489ee3ada175203995cc (patch) | |
tree | 0ec4545734f49441c2638530ae0c5d617a763399 /src/ui | |
parent | ea1b72af1b43c846ada3380ba422fffd400ed5b4 (diff) |
Fontpack lookup via missing glyphs
IssueID #435
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/banner.c | 3 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 1 | ||||
-rw-r--r-- | src/ui/text.c | 40 | ||||
-rw-r--r-- | src/ui/text.h | 2 | ||||
-rw-r--r-- | src/ui/util.c | 48 | ||||
-rw-r--r-- | src/ui/util.h | 1 |
6 files changed, 89 insertions, 6 deletions
diff --git a/src/ui/banner.c b/src/ui/banner.c index 11ae1574..79d70039 100644 --- a/src/ui/banner.c +++ b/src/ui/banner.c | |||
@@ -327,7 +327,8 @@ iBool processEvent_Banner(iBanner *d, const SDL_Event *ev) { | |||
327 | else { | 327 | else { |
328 | switch (item->code) { | 328 | switch (item->code) { |
329 | case missingGlyphs_GmStatusCode: | 329 | case missingGlyphs_GmStatusCode: |
330 | postCommandf_App("open newtab:1 url:about:fonts"); | 330 | //postCommandf_App("open newtab:1 url:about:fonts"); |
331 | makeGlyphFinder_Widget(); | ||
331 | break; | 332 | break; |
332 | case ansiEscapes_GmStatusCode: | 333 | case ansiEscapes_GmStatusCode: |
333 | makeQuestion_Widget( | 334 | makeQuestion_Widget( |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 6a535882..fdb55232 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -2756,6 +2756,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, | |||
2756 | } | 2756 | } |
2757 | d->flags |= drawDownloadCounter_DocumentWidgetFlag; | 2757 | d->flags |= drawDownloadCounter_DocumentWidgetFlag; |
2758 | clear_PtrSet(d->view.invalidRuns); | 2758 | clear_PtrSet(d->view.invalidRuns); |
2759 | documentRunsInvalidated_DocumentWidget_(d); | ||
2759 | deinit_String(&str); | 2760 | deinit_String(&str); |
2760 | return; | 2761 | return; |
2761 | } | 2762 | } |
diff --git a/src/ui/text.c b/src/ui/text.c index 7bb418eb..86ac709b 100644 --- a/src/ui/text.c +++ b/src/ui/text.c | |||
@@ -247,8 +247,6 @@ struct Impl_CacheRow { | |||
247 | }; | 247 | }; |
248 | 248 | ||
249 | struct Impl_Text { | 249 | struct Impl_Text { |
250 | // enum iTextFont contentFont; | ||
251 | // enum iTextFont headingFont; | ||
252 | float contentFontSize; | 250 | float contentFontSize; |
253 | iArray fonts; /* fonts currently selected for use (incl. all styles/sizes) */ | 251 | iArray fonts; /* fonts currently selected for use (incl. all styles/sizes) */ |
254 | int overrideFontId; /* always checked for glyphs first, regardless of which font is used */ | 252 | int overrideFontId; /* always checked for glyphs first, regardless of which font is used */ |
@@ -264,7 +262,8 @@ struct Impl_Text { | |||
264 | int ansiFlags; | 262 | int ansiFlags; |
265 | int baseFontId; /* base attributes (for restoring via escapes) */ | 263 | int baseFontId; /* base attributes (for restoring via escapes) */ |
266 | int baseFgColorId; | 264 | int baseFgColorId; |
267 | iBool missingGlyphs; /* true if a glyph couldn't be found */ | 265 | iBool missingGlyphs; /* true if a glyph couldn't be found */ |
266 | iChar missingChars[20]; /* rotating buffer of the latest missing characters */ | ||
268 | }; | 267 | }; |
269 | 268 | ||
270 | iDefineTypeConstructionArgs(Text, (SDL_Renderer *render), render) | 269 | iDefineTypeConstructionArgs(Text, (SDL_Renderer *render), render) |
@@ -341,6 +340,8 @@ static void initFonts_Text_(iText *d) { | |||
341 | printf("[Text] %zu font variants ready\n", size_Array(&d->fonts)); | 340 | printf("[Text] %zu font variants ready\n", size_Array(&d->fonts)); |
342 | #endif | 341 | #endif |
343 | gap_Text = iRound(gap_UI * d->contentFontSize); | 342 | gap_Text = iRound(gap_UI * d->contentFontSize); |
343 | // d->missingGlyphs = iFalse; | ||
344 | // iZap(d->missingChars); | ||
344 | } | 345 | } |
345 | 346 | ||
346 | static void deinitFonts_Text_(iText *d) { | 347 | static void deinitFonts_Text_(iText *d) { |
@@ -403,6 +404,7 @@ void init_Text(iText *d, SDL_Renderer *render) { | |||
403 | d->baseFontId = -1; | 404 | d->baseFontId = -1; |
404 | d->baseFgColorId = -1; | 405 | d->baseFgColorId = -1; |
405 | d->missingGlyphs = iFalse; | 406 | d->missingGlyphs = iFalse; |
407 | iZap(d->missingChars); | ||
406 | d->render = render; | 408 | d->render = render; |
407 | /* A grayscale palette for rasterized glyphs. */ { | 409 | /* A grayscale palette for rasterized glyphs. */ { |
408 | SDL_Color colors[256]; | 410 | SDL_Color colors[256]; |
@@ -589,8 +591,23 @@ iLocalDef iFont *characterFont_Font_(iFont *d, iChar ch, uint32_t *glyphIndex) { | |||
589 | } | 591 | } |
590 | } | 592 | } |
591 | if (!*glyphIndex) { | 593 | if (!*glyphIndex) { |
592 | activeText_->missingGlyphs = iTrue; | 594 | fprintf(stderr, "failed to find %08x (%lc)\n", ch, (int) ch); fflush(stderr); |
593 | fprintf(stderr, "failed to find %08x (%lc)\n", ch, (int)ch); fflush(stderr); | 595 | iText *tx = activeText_; |
596 | tx->missingGlyphs = iTrue; | ||
597 | /* Remember a few of the latest missing characters. */ | ||
598 | iBool gotIt = iFalse; | ||
599 | for (size_t i = 0; i < iElemCount(tx->missingChars); i++) { | ||
600 | if (tx->missingChars[i] == ch) { | ||
601 | gotIt = iTrue; | ||
602 | break; | ||
603 | } | ||
604 | } | ||
605 | if (!gotIt) { | ||
606 | memmove(tx->missingChars + 1, | ||
607 | tx->missingChars, | ||
608 | sizeof(tx->missingChars) - sizeof(tx->missingChars[0])); | ||
609 | tx->missingChars[0] = ch; | ||
610 | } | ||
594 | } | 611 | } |
595 | return d; | 612 | return d; |
596 | } | 613 | } |
@@ -2199,6 +2216,19 @@ iBool checkMissing_Text(void) { | |||
2199 | return missing; | 2216 | return missing; |
2200 | } | 2217 | } |
2201 | 2218 | ||
2219 | iChar missing_Text(size_t index) { | ||
2220 | const iText *d = activeText_; | ||
2221 | if (index >= iElemCount(d->missingChars)) { | ||
2222 | return 0; | ||
2223 | } | ||
2224 | return d->missingChars[index]; | ||
2225 | } | ||
2226 | |||
2227 | void resetMissing_Text(iText *d) { | ||
2228 | d->missingGlyphs = iFalse; | ||
2229 | iZap(d->missingChars); | ||
2230 | } | ||
2231 | |||
2202 | SDL_Texture *glyphCache_Text(void) { | 2232 | SDL_Texture *glyphCache_Text(void) { |
2203 | return activeText_->cache; | 2233 | return activeText_->cache; |
2204 | } | 2234 | } |
diff --git a/src/ui/text.h b/src/ui/text.h index c8bb6f85..a34cc9bd 100644 --- a/src/ui/text.h +++ b/src/ui/text.h | |||
@@ -227,6 +227,8 @@ struct Impl_WrapText { | |||
227 | iTextMetrics measure_WrapText (iWrapText *, int fontId); | 227 | iTextMetrics measure_WrapText (iWrapText *, int fontId); |
228 | iTextMetrics draw_WrapText (iWrapText *, int fontId, iInt2 pos, int color); | 228 | iTextMetrics draw_WrapText (iWrapText *, int fontId, iInt2 pos, int color); |
229 | 229 | ||
230 | iChar missing_Text (size_t index); | ||
231 | void resetMissing_Text (iText *); | ||
230 | iBool checkMissing_Text (void); /* returns the flag, and clears it */ | 232 | iBool checkMissing_Text (void); /* returns the flag, and clears it */ |
231 | SDL_Texture * glyphCache_Text (void); | 233 | SDL_Texture * glyphCache_Text (void); |
232 | 234 | ||
diff --git a/src/ui/util.c b/src/ui/util.c index 31907721..8e71dcec 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -3451,6 +3451,54 @@ iWidget *makeTranslation_Widget(iWidget *parent) { | |||
3451 | return dlg; | 3451 | return dlg; |
3452 | } | 3452 | } |
3453 | 3453 | ||
3454 | iWidget *makeGlyphFinder_Widget(void) { | ||
3455 | iString msg; | ||
3456 | iString command; | ||
3457 | init_String(&msg); | ||
3458 | initCStr_String(&command, "!font.find chars:"); | ||
3459 | for (size_t i = 0; ; i++) { | ||
3460 | iChar ch = missing_Text(i); | ||
3461 | if (!ch) break; | ||
3462 | appendFormat_String(&msg, " U+%04X", ch); | ||
3463 | appendChar_String(&command, ch); | ||
3464 | } | ||
3465 | iArray items; | ||
3466 | init_Array(&items, sizeof(iMenuItem)); | ||
3467 | if (!isEmpty_String(&msg)) { | ||
3468 | prependCStr_String(&msg, "${dlg.glyphfinder.missing} "); | ||
3469 | appendCStr_String(&msg, "\n\n${dlg.glyphfinder.help}"); | ||
3470 | pushBackN_Array( | ||
3471 | &items, | ||
3472 | (iMenuItem[]){ | ||
3473 | { "${menu.fonts}", 0, 0, "!open newtab:1 url:about:fonts" }, | ||
3474 | { "${dlg.glyphfinder.disable}", 0, 0, "prefs.font.warnmissing.changed arg:0" }, | ||
3475 | { "---" }, | ||
3476 | { uiTextCaution_ColorEscape magnifyingGlass_Icon " ${dlg.glyphfinder.search}", | ||
3477 | 0, | ||
3478 | 0, | ||
3479 | cstr_String(&command) }, | ||
3480 | { "${close}", 0, 0, "cancel" } }, | ||
3481 | 5); | ||
3482 | } | ||
3483 | else { | ||
3484 | setCStr_String(&msg, "${dlg.glyphfinder.help.empty}"); | ||
3485 | pushBackN_Array(&items, | ||
3486 | (iMenuItem[]){ { "${menu.reload}", 0, 0, "navigate.reload" }, | ||
3487 | { "${close}", 0, 0, "cancel" } }, | ||
3488 | 2); | ||
3489 | } | ||
3490 | iWidget *dlg = makeQuestion_Widget("${heading.glyphfinder}", cstr_String(&msg), | ||
3491 | constData_Array(&items), | ||
3492 | size_Array(&items)); | ||
3493 | arrange_Widget(dlg); | ||
3494 | deinit_Array(&items); | ||
3495 | deinit_String(&command); | ||
3496 | deinit_String(&msg); | ||
3497 | return dlg; | ||
3498 | } | ||
3499 | |||
3500 | /*----------------------------------------------------------------------------------------------*/ | ||
3501 | |||
3454 | void init_PerfTimer(iPerfTimer *d) { | 3502 | void init_PerfTimer(iPerfTimer *d) { |
3455 | d->ticks = SDL_GetPerformanceCounter(); | 3503 | d->ticks = SDL_GetPerformanceCounter(); |
3456 | } | 3504 | } |
diff --git a/src/ui/util.h b/src/ui/util.h index 98ce784c..0289d579 100644 --- a/src/ui/util.h +++ b/src/ui/util.h | |||
@@ -342,6 +342,7 @@ iWidget * makeBookmarkCreation_Widget (const iString *url, const iString *titl | |||
342 | iWidget * makeIdentityCreation_Widget (void); | 342 | iWidget * makeIdentityCreation_Widget (void); |
343 | iWidget * makeFeedSettings_Widget (uint32_t bookmarkId); | 343 | iWidget * makeFeedSettings_Widget (uint32_t bookmarkId); |
344 | iWidget * makeTranslation_Widget (iWidget *parent); | 344 | iWidget * makeTranslation_Widget (iWidget *parent); |
345 | iWidget * makeGlyphFinder_Widget (void); | ||
345 | 346 | ||
346 | const char * languageId_String (const iString *menuItemLabel); | 347 | const char * languageId_String (const iString *menuItemLabel); |
347 | int languageIndex_CStr (const char *langId); | 348 | int languageIndex_CStr (const char *langId); |