summaryrefslogtreecommitdiff
path: root/src/ui/documentwidget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-10-13 09:49:44 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-10-13 09:49:44 +0300
commit6b931c95725eef2ebb7e831c4017d3d67b33294f (patch)
tree254595663d93c0dcc33baad475fb2f6c3ddeec40 /src/ui/documentwidget.c
parentdd0a8798f32bf192ed703c6c512d4a76c4d407bc (diff)
Text attributes that change inside a run
These changes concern the situation when the attributes of text (i.e., font, color) are changed via escape sequences. The concept of "base attributes" was added so that the low-level text renderer knows which font/color to set when a "reset" escape sequence is encountered. This depends on what kind of text is being renderer, e.g., preformatted or regular paragraphs. The base attributes were added as variables in Text because it was getting unwieldy to pass all the information via the draw/measure/WrapText functions. GmDocument now has a GmTheme struct that collects the font and color information into a single place.
Diffstat (limited to 'src/ui/documentwidget.c')
-rw-r--r--src/ui/documentwidget.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 8c87ba1a..8b2d6a5a 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -569,7 +569,7 @@ static void addVisible_DocumentWidget_(void *context, const iGmRun *run) {
569 } 569 }
570 d->visibleRuns.end = run; 570 d->visibleRuns.end = run;
571 } 571 }
572 if (run->preId) { 572 if (preId_GmRun(run)) {
573 pushBack_PtrArray(&d->visiblePre, run); 573 pushBack_PtrArray(&d->visiblePre, run);
574 if (run->flags & wide_GmRunFlag) { 574 if (run->flags & wide_GmRunFlag) {
575 pushBack_PtrArray(&d->visibleWideRuns, run); 575 pushBack_PtrArray(&d->visibleWideRuns, run);
@@ -635,14 +635,14 @@ static void invalidateVisibleLinks_DocumentWidget_(iDocumentWidget *d) {
635} 635}
636 636
637static int runOffset_DocumentWidget_(const iDocumentWidget *d, const iGmRun *run) { 637static int runOffset_DocumentWidget_(const iDocumentWidget *d, const iGmRun *run) {
638 if (run->preId && run->flags & wide_GmRunFlag) { 638 if (preId_GmRun(run) && run->flags & wide_GmRunFlag) {
639 if (d->animWideRunId == run->preId) { 639 if (d->animWideRunId == preId_GmRun(run)) {
640 return -value_Anim(&d->animWideRunOffset); 640 return -value_Anim(&d->animWideRunOffset);
641 } 641 }
642 const size_t numOffsets = size_Array(&d->wideRunOffsets); 642 const size_t numOffsets = size_Array(&d->wideRunOffsets);
643 const int *offsets = constData_Array(&d->wideRunOffsets); 643 const int *offsets = constData_Array(&d->wideRunOffsets);
644 if (run->preId <= numOffsets) { 644 if (preId_GmRun(run) <= numOffsets) {
645 return -offsets[run->preId - 1]; 645 return -offsets[preId_GmRun(run) - 1];
646 } 646 }
647 } 647 }
648 return 0; 648 return 0;
@@ -731,7 +731,7 @@ static void updateHover_DocumentWidget_(iDocumentWidget *d, iInt2 mouse) {
731 } 731 }
732 } 732 }
733 else if (d->hoverPre && 733 else if (d->hoverPre &&
734 preHasAltText_GmDocument(d->doc, d->hoverPre->preId) && 734 preHasAltText_GmDocument(d->doc, preId_GmRun(d->hoverPre)) &&
735 ~d->flags & noHoverWhileScrolling_DocumentWidgetFlag) { 735 ~d->flags & noHoverWhileScrolling_DocumentWidgetFlag) {
736 setValueSpeed_Anim(&d->altTextOpacity, 1.0f, 1.5f); 736 setValueSpeed_Anim(&d->altTextOpacity, 1.0f, 1.5f);
737 if (!isFinished_Anim(&d->altTextOpacity)) { 737 if (!isFinished_Anim(&d->altTextOpacity)) {
@@ -1812,10 +1812,10 @@ static void scrollWideBlock_DocumentWidget_(iDocumentWidget *d, iInt2 mousePos,
1812 maxWidth = iMax(maxWidth, width_Rect(r->visBounds)); 1812 maxWidth = iMax(maxWidth, width_Rect(r->visBounds));
1813 } 1813 }
1814 const int maxOffset = maxWidth - documentWidth_DocumentWidget_(d) + d->pageMargin * gap_UI; 1814 const int maxOffset = maxWidth - documentWidth_DocumentWidget_(d) + d->pageMargin * gap_UI;
1815 if (size_Array(&d->wideRunOffsets) <= run->preId) { 1815 if (size_Array(&d->wideRunOffsets) <= preId_GmRun(run)) {
1816 resize_Array(&d->wideRunOffsets, run->preId + 1); 1816 resize_Array(&d->wideRunOffsets, preId_GmRun(run) + 1);
1817 } 1817 }
1818 int *offset = at_Array(&d->wideRunOffsets, run->preId - 1); 1818 int *offset = at_Array(&d->wideRunOffsets, preId_GmRun(run) - 1);
1819 const int oldOffset = *offset; 1819 const int oldOffset = *offset;
1820 *offset = iClamp(*offset + delta, 0, maxOffset); 1820 *offset = iClamp(*offset + delta, 0, maxOffset);
1821 /* Make sure the whole block gets redraw. */ 1821 /* Make sure the whole block gets redraw. */
@@ -1828,8 +1828,8 @@ static void scrollWideBlock_DocumentWidget_(iDocumentWidget *d, iInt2 mousePos,
1828 d->foundMark = iNullRange; 1828 d->foundMark = iNullRange;
1829 } 1829 }
1830 if (duration) { 1830 if (duration) {
1831 if (d->animWideRunId != run->preId || isFinished_Anim(&d->animWideRunOffset)) { 1831 if (d->animWideRunId != preId_GmRun(run) || isFinished_Anim(&d->animWideRunOffset)) {
1832 d->animWideRunId = run->preId; 1832 d->animWideRunId = preId_GmRun(run);
1833 init_Anim(&d->animWideRunOffset, oldOffset); 1833 init_Anim(&d->animWideRunOffset, oldOffset);
1834 } 1834 }
1835 setValueEased_Anim(&d->animWideRunOffset, *offset, duration); 1835 setValueEased_Anim(&d->animWideRunOffset, *offset, duration);
@@ -3814,7 +3814,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
3814 } 3814 }
3815 /* Fold/unfold a preformatted block. */ 3815 /* Fold/unfold a preformatted block. */
3816 if (~d->flags & selecting_DocumentWidgetFlag && d->hoverPre && 3816 if (~d->flags & selecting_DocumentWidgetFlag && d->hoverPre &&
3817 preIsFolded_GmDocument(d->doc, d->hoverPre->preId)) { 3817 preIsFolded_GmDocument(d->doc, preId_GmRun(d->hoverPre))) {
3818 return iTrue; 3818 return iTrue;
3819 } 3819 }
3820 /* Begin selecting a range of text. */ 3820 /* Begin selecting a range of text. */
@@ -3925,7 +3925,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
3925 } 3925 }
3926 } 3926 }
3927 if (d->hoverPre) { 3927 if (d->hoverPre) {
3928 togglePreFold_DocumentWidget_(d, d->hoverPre->preId); 3928 togglePreFold_DocumentWidget_(d, preId_GmRun(d->hoverPre));
3929 return iTrue; 3929 return iTrue;
3930 } 3930 }
3931 if (d->hoverLink) { 3931 if (d->hoverLink) {
@@ -4124,7 +4124,7 @@ static void fillRange_DrawContext_(iDrawContext *d, const iGmRun *run, enum iCol
4124 4124
4125static void drawMark_DrawContext_(void *context, const iGmRun *run) { 4125static void drawMark_DrawContext_(void *context, const iGmRun *run) {
4126 iDrawContext *d = context; 4126 iDrawContext *d = context;
4127 if (run->mediaType == none_MediaType) { 4127 if (!isMedia_GmRun(run)) {
4128 fillRange_DrawContext_(d, run, uiMatching_ColorId, d->widget->foundMark, &d->inFoundMark); 4128 fillRange_DrawContext_(d, run, uiMatching_ColorId, d->widget->foundMark, &d->inFoundMark);
4129 fillRange_DrawContext_(d, run, uiMarked_ColorId, d->widget->selectMark, &d->inSelectMark); 4129 fillRange_DrawContext_(d, run, uiMarked_ColorId, d->widget->selectMark, &d->inSelectMark);
4130 } 4130 }
@@ -4249,7 +4249,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
4249 } 4249 }
4250 return; 4250 return;
4251 } 4251 }
4252 else if (run->mediaType) { 4252 else if (isMedia_GmRun(run)) {
4253 /* Media UIs are drawn afterwards as a dynamic overlay. */ 4253 /* Media UIs are drawn afterwards as a dynamic overlay. */
4254 return; 4254 return;
4255 } 4255 }
@@ -4317,7 +4317,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
4317 } 4317 }
4318 } 4318 }
4319 if (run->flags & altText_GmRunFlag) { 4319 if (run->flags & altText_GmRunFlag) {
4320 const iInt2 margin = preRunMargin_GmDocument(doc, run->preId); 4320 const iInt2 margin = preRunMargin_GmDocument(doc, preId_GmRun(run));
4321 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmBackgroundAltText_ColorId); 4321 fillRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmBackgroundAltText_ColorId);
4322 drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmQuoteIcon_ColorId); 4322 drawRect_Paint(&d->paint, (iRect){ visPos, run->visBounds.size }, tmQuoteIcon_ColorId);
4323 drawWrapRange_Text(run->font, 4323 drawWrapRange_Text(run->font,
@@ -4368,11 +4368,17 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
4368 height_Rect(run->visBounds), 4368 height_Rect(run->visBounds),
4369 tmQuoteIcon_ColorId); 4369 tmQuoteIcon_ColorId);
4370 } 4370 }
4371 /* Base attributes. */ {
4372 int f, c;
4373 runBaseAttributes_GmDocument(doc, run, &f, &c);
4374 setBaseAttributes_Text(f, c);
4375 }
4371 drawBoundRange_Text(run->font, 4376 drawBoundRange_Text(run->font,
4372 visPos, 4377 visPos,
4373 (run->isRTL ? -1 : 1) * width_Rect(run->visBounds), 4378 (run->isRTL ? -1 : 1) * width_Rect(run->visBounds),
4374 fg, 4379 fg,
4375 run->text); 4380 run->text);
4381 setBaseAttributes_Text(-1, -1);
4376 runDrawn:; 4382 runDrawn:;
4377 } 4383 }
4378 /* Presentation of links. */ 4384 /* Presentation of links. */
@@ -4944,7 +4950,7 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
4944 /* Alt text. */ 4950 /* Alt text. */
4945 const float altTextOpacity = value_Anim(&d->altTextOpacity) * 6 - 5; 4951 const float altTextOpacity = value_Anim(&d->altTextOpacity) * 6 - 5;
4946 if (d->hoverAltPre && altTextOpacity > 0) { 4952 if (d->hoverAltPre && altTextOpacity > 0) {
4947 const iGmPreMeta *meta = preMeta_GmDocument(d->doc, d->hoverAltPre->preId); 4953 const iGmPreMeta *meta = preMeta_GmDocument(d->doc, preId_GmRun(d->hoverAltPre));
4948 if (meta->flags & topLeft_GmPreMetaFlag && ~meta->flags & decoration_GmRunFlag && 4954 if (meta->flags & topLeft_GmPreMetaFlag && ~meta->flags & decoration_GmRunFlag &&
4949 !isEmpty_Range(&meta->altText)) { 4955 !isEmpty_Range(&meta->altText)) {
4950 const int margin = 3 * gap_UI / 2; 4956 const int margin = 3 * gap_UI / 2;