summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.c16
-rw-r--r--src/app.h2
-rw-r--r--src/gmdocument.c42
-rw-r--r--src/gmdocument.h2
-rw-r--r--src/ui/color.h4
-rw-r--r--src/ui/documentwidget.c67
6 files changed, 117 insertions, 16 deletions
diff --git a/src/app.c b/src/app.c
index f909c251..4872799b 100644
--- a/src/app.c
+++ b/src/app.c
@@ -2109,6 +2109,7 @@ iBool handleCommand_App(const char *cmd) {
2109 iBool wasCurrent = (doc == (iWidget *) document_App()); 2109 iBool wasCurrent = (doc == (iWidget *) document_App());
2110 size_t index = tabPageIndex_Widget(tabs, doc); 2110 size_t index = tabPageIndex_Widget(tabs, doc);
2111 iBool wasClosed = iFalse; 2111 iBool wasClosed = iFalse;
2112 postCommand_App("document.openurls.changed");
2112 if (argLabel_Command(cmd, "toright")) { 2113 if (argLabel_Command(cmd, "toright")) {
2113 while (tabCount_Widget(tabs) > index + 1) { 2114 while (tabCount_Widget(tabs) > index + 1) {
2114 destroy_Widget(removeTabPage_Widget(tabs, index + 1)); 2115 destroy_Widget(removeTabPage_Widget(tabs, index + 1));
@@ -2314,6 +2315,11 @@ iBool handleCommand_App(const char *cmd) {
2314 save_Visited(d->visited, dataDir_App_()); 2315 save_Visited(d->visited, dataDir_App_());
2315 return iFalse; 2316 return iFalse;
2316 } 2317 }
2318 else if (equal_Command(cmd, "document.changed")) {
2319 /* Set of open tabs has changed. */
2320 postCommand_App("document.openurls.changed");
2321 return iFalse;
2322 }
2317 else if (equal_Command(cmd, "ident.new")) { 2323 else if (equal_Command(cmd, "ident.new")) {
2318 iWidget *dlg = makeIdentityCreation_Widget(); 2324 iWidget *dlg = makeIdentityCreation_Widget();
2319 setFocus_Widget(findChild_Widget(dlg, "ident.until")); 2325 setFocus_Widget(findChild_Widget(dlg, "ident.until"));
@@ -2472,3 +2478,13 @@ iObjectList *listDocuments_App(const iRoot *rootOrNull) {
2472 } 2478 }
2473 return docs; 2479 return docs;
2474} 2480}
2481
2482iStringSet *listOpenURLs_App(void) {
2483 iStringSet *set = new_StringSet();
2484 iObjectList *docs = listDocuments_App(NULL);
2485 iConstForEach(ObjectList, i, docs) {
2486 insert_StringSet(set, withSpacesEncoded_String(url_DocumentWidget(i.object)));
2487 }
2488 iRelease(docs);
2489 return set;
2490}
diff --git a/src/app.h b/src/app.h
index 952688a4..c8f0f1c2 100644
--- a/src/app.h
+++ b/src/app.h
@@ -26,6 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
26 26
27#include <the_Foundation/objectlist.h> 27#include <the_Foundation/objectlist.h>
28#include <the_Foundation/string.h> 28#include <the_Foundation/string.h>
29#include <the_Foundation/stringset.h>
29#include <the_Foundation/time.h> 30#include <the_Foundation/time.h>
30 31
31#include "prefs.h" 32#include "prefs.h"
@@ -90,6 +91,7 @@ iMimeHooks * mimeHooks_App (void);
90iPeriodic * periodic_App (void); 91iPeriodic * periodic_App (void);
91iDocumentWidget * document_App (void); 92iDocumentWidget * document_App (void);
92iObjectList * listDocuments_App (const iRoot *rootOrNull); /* NULL for all roots */ 93iObjectList * listDocuments_App (const iRoot *rootOrNull); /* NULL for all roots */
94iStringSet * listOpenURLs_App (void); /* all tabs */
93iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew); 95iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew);
94void trimCache_App (void); 96void trimCache_App (void);
95 97
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 47f629bd..b64e9ea7 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
33 33
34#include <the_Foundation/ptrarray.h> 34#include <the_Foundation/ptrarray.h>
35#include <the_Foundation/regexp.h> 35#include <the_Foundation/regexp.h>
36#include <the_Foundation/stringset.h>
36 37
37#include <ctype.h> 38#include <ctype.h>
38 39
@@ -87,6 +88,7 @@ struct Impl_GmDocument {
87 uint32_t themeSeed; 88 uint32_t themeSeed;
88 iChar siteIcon; 89 iChar siteIcon;
89 iMedia * media; 90 iMedia * media;
91 iStringSet *openURLs; /* currently open URLs for highlighting links */
90}; 92};
91 93
92iDefineObjectConstruction(GmDocument) 94iDefineObjectConstruction(GmDocument)
@@ -229,6 +231,9 @@ static iRangecc addLink_GmDocument_(iGmDocument *d, iRangecc line, iGmLinkId *li
229 if (isValid_Time(&link->when)) { 231 if (isValid_Time(&link->when)) {
230 link->flags |= visited_GmLinkFlag; 232 link->flags |= visited_GmLinkFlag;
231 } 233 }
234 if (contains_StringSet(d->openURLs, &link->url)) {
235 link->flags |= isOpen_GmLinkFlag;
236 }
232 } 237 }
233 } 238 }
234 pushBack_PtrArray(&d->links, link); 239 pushBack_PtrArray(&d->links, link);
@@ -340,6 +345,13 @@ static void alignDecoration_GmRun_(iGmRun *run, iBool isCentered) {
340 run->visBounds.size.x -= xAdjust; 345 run->visBounds.size.x -= xAdjust;
341} 346}
342 347
348static void updateOpenURLs_GmDocument_(iGmDocument *d) {
349 if (d->openURLs) {
350 iReleasePtr(&d->openURLs);
351 }
352 d->openURLs = listOpenURLs_App();
353}
354
343static void doLayout_GmDocument_(iGmDocument *d) { 355static void doLayout_GmDocument_(iGmDocument *d) {
344 const iPrefs *prefs = prefs_App(); 356 const iPrefs *prefs = prefs_App();
345 const iBool isMono = isForcedMonospace_GmDocument_(d); 357 const iBool isMono = isForcedMonospace_GmDocument_(d);
@@ -405,6 +417,7 @@ static void doLayout_GmDocument_(iGmDocument *d) {
405 if (d->size.x <= 0 || isEmpty_String(&d->source)) { 417 if (d->size.x <= 0 || isEmpty_String(&d->source)) {
406 return; 418 return;
407 } 419 }
420 updateOpenURLs_GmDocument_(d);
408 const iRangecc content = range_String(&d->source); 421 const iRangecc content = range_String(&d->source);
409 iRangecc contentLine = iNullRange; 422 iRangecc contentLine = iNullRange;
410 iInt2 pos = zero_I2(); 423 iInt2 pos = zero_I2();
@@ -861,9 +874,11 @@ void init_GmDocument(iGmDocument *d) {
861 d->themeSeed = 0; 874 d->themeSeed = 0;
862 d->siteIcon = 0; 875 d->siteIcon = 0;
863 d->media = new_Media(); 876 d->media = new_Media();
877 d->openURLs = NULL;
864} 878}
865 879
866void deinit_GmDocument(iGmDocument *d) { 880void deinit_GmDocument(iGmDocument *d) {
881 iReleasePtr(&d->openURLs);
867 delete_Media(d->media); 882 delete_Media(d->media);
868 deinit_String(&d->bannerText); 883 deinit_String(&d->bannerText);
869 deinit_String(&d->title); 884 deinit_String(&d->title);
@@ -900,10 +915,15 @@ static void setDerivedThemeColors_(enum iGmDocumentTheme theme) {
900 set_Color(tmQuoteIcon_ColorId, 915 set_Color(tmQuoteIcon_ColorId,
901 mix_Color(get_Color(tmQuote_ColorId), get_Color(tmBackground_ColorId), 0.55f)); 916 mix_Color(get_Color(tmQuote_ColorId), get_Color(tmBackground_ColorId), 0.55f));
902 set_Color(tmBannerSideTitle_ColorId, 917 set_Color(tmBannerSideTitle_ColorId,
903 mix_Color(get_Color(tmBannerTitle_ColorId), get_Color(tmBackground_ColorId), 918 mix_Color(get_Color(tmBannerTitle_ColorId),
919 get_Color(tmBackground_ColorId),
904 theme == colorfulDark_GmDocumentTheme ? 0.55f : 0)); 920 theme == colorfulDark_GmDocumentTheme ? 0.55f : 0));
905 set_Color(tmAltTextBackground_ColorId, mix_Color(get_Color(tmQuoteIcon_ColorId), 921 set_Color(tmBackgroundAltText_ColorId,
906 get_Color(tmBackground_ColorId), 0.85f)); 922 mix_Color(get_Color(tmQuoteIcon_ColorId), get_Color(tmBackground_ColorId), 0.85f));
923 set_Color(tmBackgroundOpenLink_ColorId,
924 mix_Color(get_Color(tmLinkText_ColorId), get_Color(tmBackground_ColorId), 0.92f));
925 set_Color(tmFrameOpenLink_ColorId,
926 mix_Color(get_Color(tmLinkText_ColorId), get_Color(tmBackground_ColorId), 0.78f));
907 if (theme == colorfulDark_GmDocumentTheme) { 927 if (theme == colorfulDark_GmDocumentTheme) {
908 /* Ensure paragraph text and link text aren't too similarly colored. */ 928 /* Ensure paragraph text and link text aren't too similarly colored. */
909 if (delta_Color(get_Color(tmLinkText_ColorId), get_Color(tmParagraph_ColorId)) < 100) { 929 if (delta_Color(get_Color(tmLinkText_ColorId), get_Color(tmParagraph_ColorId)) < 100) {
@@ -1381,6 +1401,22 @@ void redoLayout_GmDocument(iGmDocument *d) {
1381 doLayout_GmDocument_(d); 1401 doLayout_GmDocument_(d);
1382} 1402}
1383 1403
1404iBool updateOpenURLs_GmDocument(iGmDocument *d) {
1405 iBool wasChanged = iFalse;
1406 updateOpenURLs_GmDocument_(d);
1407 iForEach(PtrArray, i, &d->links) {
1408 iGmLink *link = i.ptr;
1409 if (!equal_String(&link->url, &d->url)) {
1410 const iBool isOpen = contains_StringSet(d->openURLs, &link->url);
1411 if (isOpen ^ ((link->flags & isOpen_GmLinkFlag) != 0)) {
1412 iChangeFlags(link->flags, isOpen_GmLinkFlag, isOpen);
1413 wasChanged = iTrue;
1414 }
1415 }
1416 }
1417 return wasChanged;
1418}
1419
1384iLocalDef iBool isNormalizableSpace_(char ch) { 1420iLocalDef iBool isNormalizableSpace_(char ch) {
1385 return ch == ' ' || ch == '\t'; 1421 return ch == ' ' || ch == '\t';
1386} 1422}
diff --git a/src/gmdocument.h b/src/gmdocument.h
index 5d34dbaf..574f0acf 100644
--- a/src/gmdocument.h
+++ b/src/gmdocument.h
@@ -83,6 +83,7 @@ enum iGmLinkFlags {
83 permanent_GmLinkFlag = iBit(15), /* content cannot be dismissed; media link */ 83 permanent_GmLinkFlag = iBit(15), /* content cannot be dismissed; media link */
84 query_GmLinkFlag = iBit(16), /* Gopher query link */ 84 query_GmLinkFlag = iBit(16), /* Gopher query link */
85 iconFromLabel_GmLinkFlag = iBit(17), /* use an Emoji/special character from label */ 85 iconFromLabel_GmLinkFlag = iBit(17), /* use an Emoji/special character from label */
86 isOpen_GmLinkFlag = iBit(18), /* currently open in a tab */
86}; 87};
87 88
88struct Impl_GmHeading { 89struct Impl_GmHeading {
@@ -164,6 +165,7 @@ void setFormat_GmDocument (iGmDocument *, enum iGmDocumentFormat format);
164void setBanner_GmDocument (iGmDocument *, enum iGmDocumentBanner type); 165void setBanner_GmDocument (iGmDocument *, enum iGmDocumentBanner type);
165void setWidth_GmDocument (iGmDocument *, int width); 166void setWidth_GmDocument (iGmDocument *, int width);
166void redoLayout_GmDocument (iGmDocument *); 167void redoLayout_GmDocument (iGmDocument *);
168iBool updateOpenURLs_GmDocument(iGmDocument *);
167void setUrl_GmDocument (iGmDocument *, const iString *url); 169void setUrl_GmDocument (iGmDocument *, const iString *url);
168void setSource_GmDocument (iGmDocument *, const iString *source, int width); 170void setSource_GmDocument (iGmDocument *, const iString *source, int width);
169void foldPre_GmDocument (iGmDocument *, uint16_t preId); 171void foldPre_GmDocument (iGmDocument *, uint16_t preId);
diff --git a/src/ui/color.h b/src/ui/color.h
index c0db4382..d2fa3c00 100644
--- a/src/ui/color.h
+++ b/src/ui/color.h
@@ -132,7 +132,9 @@ enum iColorId {
132 tmBannerIcon_ColorId, 132 tmBannerIcon_ColorId,
133 tmBannerSideTitle_ColorId, 133 tmBannerSideTitle_ColorId,
134 tmInlineContentMetadata_ColorId, 134 tmInlineContentMetadata_ColorId,
135 tmAltTextBackground_ColorId, /* derived from other theme colors */ 135 tmBackgroundAltText_ColorId, /* derived from other theme colors */
136 tmBackgroundOpenLink_ColorId, /* derived from other theme colors */
137 tmFrameOpenLink_ColorId, /* derived from other theme colors */
136 tmLinkCustomIconVisited_ColorId, /* derived from other theme colors */ 138 tmLinkCustomIconVisited_ColorId, /* derived from other theme colors */
137 tmBadLink_ColorId, 139 tmBadLink_ColorId,
138 140
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 16d2a84a..6a44fd5f 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -286,7 +286,7 @@ struct Impl_DocumentWidget {
286 iWidget * playerMenu; 286 iWidget * playerMenu;
287 iWidget * copyMenu; 287 iWidget * copyMenu;
288 iVisBuf * visBuf; 288 iVisBuf * visBuf;
289 iGmRunRange * visBufMeta; 289 iVisBufMeta * visBufMeta;
290 iPtrSet * invalidRuns; 290 iPtrSet * invalidRuns;
291 iDrawBufs * drawBufs; /* dynamic state for drawing */ 291 iDrawBufs * drawBufs; /* dynamic state for drawing */
292 iTranslation * translation; 292 iTranslation * translation;
@@ -1881,7 +1881,15 @@ static iBool handlePinch_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
1881 1881
1882static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { 1882static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
1883 iWidget *w = as_Widget(d); 1883 iWidget *w = as_Widget(d);
1884 if (equal_Command(cmd, "document.render")) /* Periodic makes direct dispatch to here */ { 1884 if (equal_Command(cmd, "document.openurls.changed")) {
1885 /* When any tab changes its document URL, update the open link indicators. */
1886 if (updateOpenURLs_GmDocument(d->doc)) {
1887 invalidate_DocumentWidget_(d);
1888 refresh_Widget(d);
1889 }
1890 return iFalse;
1891 }
1892 if (equal_Command(cmd, "document.render")) /* `Periodic` makes direct dispatch to here */ {
1885// printf("%u: document.render\n", SDL_GetTicks()); 1893// printf("%u: document.render\n", SDL_GetTicks());
1886 if (SDL_GetTicks() - d->drawBufs->lastRenderTime > 150) { 1894 if (SDL_GetTicks() - d->drawBufs->lastRenderTime > 150) {
1887 remove_Periodic(periodic_App(), d); 1895 remove_Periodic(periodic_App(), d);
@@ -3486,15 +3494,18 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3486 /* Media UIs are drawn afterwards as a dynamic overlay. */ 3494 /* Media UIs are drawn afterwards as a dynamic overlay. */
3487 return; 3495 return;
3488 } 3496 }
3489// printf(" drawRun: {%s}\n", cstr_Rangecc(run->text)); 3497 enum iColorId fg = run->color;
3490 enum iColorId fg = run->color; 3498 const iGmDocument *doc = d->widget->doc;
3491 const iGmDocument *doc = d->widget->doc; 3499 const int linkFlags = linkFlags_GmDocument(doc, run->linkId);
3492 iBool isHover = 3500 /* Hover state of a link. */
3501 iBool isHover =
3493 (run->linkId && d->widget->hoverLink && run->linkId == d->widget->hoverLink->linkId && 3502 (run->linkId && d->widget->hoverLink && run->linkId == d->widget->hoverLink->linkId &&
3494 ~run->flags & decoration_GmRunFlag); 3503 ~run->flags & decoration_GmRunFlag);
3504 /* Visible (scrolled) position of the run. */
3495 const iInt2 visPos = addX_I2(add_I2(run->visBounds.pos, origin), 3505 const iInt2 visPos = addX_I2(add_I2(run->visBounds.pos, origin),
3496 /* Preformatted runs can be scrolled. */ 3506 /* Preformatted runs can be scrolled. */
3497 runOffset_DocumentWidget_(d->widget, run)); 3507 runOffset_DocumentWidget_(d->widget, run));
3508 const iRect visRect = { visPos, run->visBounds.size };
3498 if (run->flags & footer_GmRunFlag) { 3509 if (run->flags & footer_GmRunFlag) {
3499 iRect footerBack = 3510 iRect footerBack =
3500 (iRect){ visPos, init_I2(width_Rect(d->widgetBounds), run->visBounds.size.y) }; 3511 (iRect){ visPos, init_I2(width_Rect(d->widgetBounds), run->visBounds.size.y) };
@@ -3502,16 +3513,48 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3502 fillRect_Paint(&d->paint, footerBack, tmBackground_ColorId); 3513 fillRect_Paint(&d->paint, footerBack, tmBackground_ColorId);
3503 return; 3514 return;
3504 } 3515 }
3505 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmBackground_ColorId); 3516 /* Fill the background. */ {
3517 if (run->linkId && linkFlags & isOpen_GmLinkFlag) {
3518 /* Open links get a highlighted background. */
3519 int bg = tmBackgroundOpenLink_ColorId;
3520 const int frame = tmFrameOpenLink_ColorId;
3521 iRect wideRect = { init_I2(left_Rect(d->widgetBounds), visPos.y),
3522 init_I2(width_Rect(d->widgetBounds) +
3523 width_Widget(d->widget->scroll),
3524 height_Rect(run->visBounds)) };
3525 /* The first line is composed of two runs that may be drawn in either order, so
3526 only draw half of the background. */
3527 if (run->flags & decoration_GmRunFlag) {
3528 wideRect.size.x = right_Rect(visRect) - left_Rect(wideRect);
3529 }
3530 else if (run->flags & startOfLine_GmRunFlag) {
3531 wideRect.size.x = right_Rect(wideRect) - left_Rect(visRect);
3532 wideRect.pos.x = left_Rect(visRect);
3533 }
3534 fillRect_Paint(&d->paint, wideRect, bg);
3535 if (run->flags & (startOfLine_GmRunFlag | decoration_GmRunFlag)) {
3536 drawHLine_Paint(&d->paint, topLeft_Rect(wideRect), width_Rect(wideRect), frame);
3537 }
3538 /* TODO: The decoration is not marked as endOfLine, so it lacks the bottom line. */
3539// if (run->flags & endOfLine_GmRunFlag) {
3540// drawHLine_Paint(
3541// &d->paint, addY_I2(bottomLeft_Rect(wideRect), -1), width_Rect(wideRect), frame);
3542// }
3543 }
3544 else {
3545 /* Normal background for other runs. */
3546 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmBackground_ColorId);
3547 }
3548 }
3506 if (run->linkId && ~run->flags & decoration_GmRunFlag) { 3549 if (run->linkId && ~run->flags & decoration_GmRunFlag) {
3507 fg = linkColor_GmDocument(doc, run->linkId, isHover ? textHover_GmLinkPart : text_GmLinkPart); 3550 fg = linkColor_GmDocument(doc, run->linkId, isHover ? textHover_GmLinkPart : text_GmLinkPart);
3508 if (linkFlags_GmDocument(doc, run->linkId) & content_GmLinkFlag) { 3551 if (linkFlags & content_GmLinkFlag) {
3509 fg = linkColor_GmDocument(doc, run->linkId, textHover_GmLinkPart); /* link is inactive */ 3552 fg = linkColor_GmDocument(doc, run->linkId, textHover_GmLinkPart); /* link is inactive */
3510 } 3553 }
3511 } 3554 }
3512 if (run->flags & altText_GmRunFlag) { 3555 if (run->flags & altText_GmRunFlag) {
3513 const iInt2 margin = preRunMargin_GmDocument(doc, run->preId); 3556 const iInt2 margin = preRunMargin_GmDocument(doc, run->preId);
3514 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmAltTextBackground_ColorId); 3557 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmBackgroundAltText_ColorId);
3515 drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmQuoteIcon_ColorId); 3558 drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmQuoteIcon_ColorId);
3516 drawWrapRange_Text(run->font, add_I2(visPos, margin), 3559 drawWrapRange_Text(run->font, add_I2(visPos, margin),
3517 run->visBounds.size.x - 2 * margin.x, run->color, run->text); 3560 run->visBounds.size.x - 2 * margin.x, run->color, run->text);
@@ -3552,7 +3595,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3552 if (run->linkId && ~run->flags & decoration_GmRunFlag) { 3595 if (run->linkId && ~run->flags & decoration_GmRunFlag) {
3553 const int metaFont = paragraph_FontId; 3596 const int metaFont = paragraph_FontId;
3554 /* TODO: Show status of an ongoing media request. */ 3597 /* TODO: Show status of an ongoing media request. */
3555 const int flags = linkFlags_GmDocument(doc, run->linkId); 3598 const int flags = linkFlags;
3556 const iRect linkRect = moved_Rect(run->visBounds, origin); 3599 const iRect linkRect = moved_Rect(run->visBounds, origin);
3557 iMediaRequest *mr = NULL; 3600 iMediaRequest *mr = NULL;
3558 /* Show metadata about inline content. */ 3601 /* Show metadata about inline content. */
@@ -3614,7 +3657,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
3614 else if (isHover) { 3657 else if (isHover) {
3615 const iGmLinkId linkId = d->widget->hoverLink->linkId; 3658 const iGmLinkId linkId = d->widget->hoverLink->linkId;
3616 const iString * url = linkUrl_GmDocument(doc, linkId); 3659 const iString * url = linkUrl_GmDocument(doc, linkId);
3617 const int flags = linkFlags_GmDocument(doc, linkId); 3660 const int flags = linkFlags;
3618 iUrl parts; 3661 iUrl parts;
3619 init_Url(&parts, url); 3662 init_Url(&parts, url);
3620 fg = linkColor_GmDocument(doc, linkId, textHover_GmLinkPart); 3663 fg = linkColor_GmDocument(doc, linkId, textHover_GmLinkPart);
@@ -4122,7 +4165,7 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
4122 if (altTextOpacity < 1) { 4165 if (altTextOpacity < 1) {
4123 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_BLEND); 4166 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_BLEND);
4124 } 4167 }
4125 fillRect_Paint(&ctx.paint, altRect, tmAltTextBackground_ColorId); 4168 fillRect_Paint(&ctx.paint, altRect, tmBackgroundAltText_ColorId);
4126 drawRect_Paint(&ctx.paint, altRect, tmQuoteIcon_ColorId); 4169 drawRect_Paint(&ctx.paint, altRect, tmQuoteIcon_ColorId);
4127 setOpacity_Text(altTextOpacity); 4170 setOpacity_Text(altTextOpacity);
4128 drawWrapRange_Text(altFont, addX_I2(pos, margin), wrap, 4171 drawWrapRange_Text(altFont, addX_I2(pos, margin), wrap,