summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.c2
-rw-r--r--src/ui/documentwidget.c131
-rw-r--r--src/ui/text.c4
-rw-r--r--src/ui/window.c4
-rw-r--r--src/ui/window.h5
5 files changed, 96 insertions, 50 deletions
diff --git a/src/app.c b/src/app.c
index ba282440..54f35373 100644
--- a/src/app.c
+++ b/src/app.c
@@ -129,7 +129,7 @@ struct Impl_App {
129 iTime lastDropTime; /* for detecting drops of multiple items */ 129 iTime lastDropTime; /* for detecting drops of multiple items */
130 int autoReloadTimer; 130 int autoReloadTimer;
131 iPeriodic periodic; 131 iPeriodic periodic;
132 int warmupFrames; /* forced refresh just after resuming from background */ 132 int warmupFrames; /* forced refresh just after resuming from background; FIXME: shouldn't be needed */
133 /* Preferences: */ 133 /* Preferences: */
134 iBool commandEcho; /* --echo */ 134 iBool commandEcho; /* --echo */
135 iBool forceSoftwareRender; /* --sw */ 135 iBool forceSoftwareRender; /* --sw */
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 9a50b611..0c7ebd54 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -144,8 +144,38 @@ iDefineTypeConstruction(PersistentDocumentState)
144 144
145/*----------------------------------------------------------------------------------------------*/ 145/*----------------------------------------------------------------------------------------------*/
146 146
147static void animateMedia_DocumentWidget_ (iDocumentWidget *d); 147iDeclareType(DrawBufs)
148static void updateSideIconBuf_DocumentWidget_ (iDocumentWidget *d); 148
149enum iDrawBufsFlag {
150 updateSideBuf_DrawBufsFlag = iBit(1),
151 updateTimestampBuf_DrawBufsFlag = iBit(2),
152};
153
154struct Impl_DrawBufs {
155 int flags;
156 SDL_Texture * sideIconBuf;
157 iTextBuf * timestampBuf;
158};
159
160static void init_DrawBufs(iDrawBufs *d) {
161 d->flags = 0;
162 d->sideIconBuf = NULL;
163 d->timestampBuf = NULL;
164}
165
166static void deinit_DrawBufs(iDrawBufs *d) {
167 delete_TextBuf(d->timestampBuf);
168 if (d->sideIconBuf) {
169 SDL_DestroyTexture(d->sideIconBuf);
170 }
171}
172
173iDefineTypeConstruction(DrawBufs)
174
175/*----------------------------------------------------------------------------------------------*/
176
177static void animateMedia_DocumentWidget_ (iDocumentWidget *d);
178static void updateSideIconBuf_DocumentWidget_ (const iDocumentWidget *d);
149 179
150static const int smoothDuration_DocumentWidget_ = 600; /* milliseconds */ 180static const int smoothDuration_DocumentWidget_ = 600; /* milliseconds */
151static const int outlineMinWidth_DocumentWdiget_ = 45; /* times gap_UI */ 181static const int outlineMinWidth_DocumentWdiget_ = 45; /* times gap_UI */
@@ -229,8 +259,7 @@ struct Impl_DocumentWidget {
229 iWidget * playerMenu; 259 iWidget * playerMenu;
230 iVisBuf * visBuf; 260 iVisBuf * visBuf;
231 iPtrSet * invalidRuns; 261 iPtrSet * invalidRuns;
232 SDL_Texture * sideIconBuf; 262 iDrawBufs * drawBufs; /* dynamic state for drawing */
233 iTextBuf * timestampBuf;
234 iTranslation * translation; 263 iTranslation * translation;
235 iWidget * phoneToolbar; 264 iWidget * phoneToolbar;
236}; 265};
@@ -291,8 +320,7 @@ void init_DocumentWidget(iDocumentWidget *d) {
291 addChild_Widget(w, iClob(d->scroll = new_ScrollWidget())); 320 addChild_Widget(w, iClob(d->scroll = new_ScrollWidget()));
292 d->menu = NULL; /* created when clicking */ 321 d->menu = NULL; /* created when clicking */
293 d->playerMenu = NULL; 322 d->playerMenu = NULL;
294 d->sideIconBuf = NULL; 323 d->drawBufs = new_DrawBufs();
295 d->timestampBuf = NULL;
296 d->translation = NULL; 324 d->translation = NULL;
297 addChildFlags_Widget(w, 325 addChildFlags_Widget(w,
298 iClob(new_IndicatorWidget()), 326 iClob(new_IndicatorWidget()),
@@ -311,10 +339,7 @@ void init_DocumentWidget(iDocumentWidget *d) {
311 339
312void deinit_DocumentWidget(iDocumentWidget *d) { 340void deinit_DocumentWidget(iDocumentWidget *d) {
313 delete_Translation(d->translation); 341 delete_Translation(d->translation);
314 if (d->sideIconBuf) { 342 delete_DrawBufs(d->drawBufs);
315 SDL_DestroyTexture(d->sideIconBuf);
316 }
317 delete_TextBuf(d->timestampBuf);
318 delete_VisBuf(d->visBuf); 343 delete_VisBuf(d->visBuf);
319 delete_PtrSet(d->invalidRuns); 344 delete_PtrSet(d->invalidRuns);
320 iRelease(d->media); 345 iRelease(d->media);
@@ -697,7 +722,7 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) {
697 } 722 }
698 const iRangecc newHeading = currentHeading_DocumentWidget_(d); 723 const iRangecc newHeading = currentHeading_DocumentWidget_(d);
699 if (memcmp(&oldHeading, &newHeading, sizeof(oldHeading))) { 724 if (memcmp(&oldHeading, &newHeading, sizeof(oldHeading))) {
700 updateSideIconBuf_DocumentWidget_(d); 725 d->drawBufs->flags |= updateSideBuf_DrawBufsFlag;
701 } 726 }
702 updateHover_DocumentWidget_(d, mouseCoord_Window(get_Window())); 727 updateHover_DocumentWidget_(d, mouseCoord_Window(get_Window()));
703 updateSideOpacity_DocumentWidget_(d, iTrue); 728 updateSideOpacity_DocumentWidget_(d, iTrue);
@@ -779,17 +804,21 @@ static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) {
779 } 804 }
780} 805}
781 806
782static void updateTimestampBuf_DocumentWidget_(iDocumentWidget *d) { 807static void updateTimestampBuf_DocumentWidget_(const iDocumentWidget *d) {
783 if (d->timestampBuf) { 808 if (!isExposed_Window(get_Window())) {
784 delete_TextBuf(d->timestampBuf); 809 return;
785 d->timestampBuf = NULL; 810 }
811 if (d->drawBufs->timestampBuf) {
812 delete_TextBuf(d->drawBufs->timestampBuf);
813 d->drawBufs->timestampBuf = NULL;
786 } 814 }
787 if (isValid_Time(&d->sourceTime)) { 815 if (isValid_Time(&d->sourceTime)) {
788 d->timestampBuf = new_TextBuf( 816 d->drawBufs->timestampBuf = new_TextBuf(
789 uiLabel_FontId, 817 uiLabel_FontId,
790 white_ColorId, 818 white_ColorId,
791 cstrCollect_String(format_Time(&d->sourceTime, cstr_Lang("page.timestamp")))); 819 cstrCollect_String(format_Time(&d->sourceTime, cstr_Lang("page.timestamp"))));
792 } 820 }
821 d->drawBufs->flags &= ~updateTimestampBuf_DrawBufsFlag;
793} 822}
794 823
795static void invalidate_DocumentWidget_(iDocumentWidget *d) { 824static void invalidate_DocumentWidget_(iDocumentWidget *d) {
@@ -819,7 +848,7 @@ void setSource_DocumentWidget(iDocumentWidget *d, const iString *source) {
819 documentRunsInvalidated_DocumentWidget_(d); 848 documentRunsInvalidated_DocumentWidget_(d);
820 updateWindowTitle_DocumentWidget_(d); 849 updateWindowTitle_DocumentWidget_(d);
821 updateVisible_DocumentWidget_(d); 850 updateVisible_DocumentWidget_(d);
822 updateSideIconBuf_DocumentWidget_(d); 851 d->drawBufs->flags |= updateSideBuf_DrawBufsFlag;
823 invalidate_DocumentWidget_(d); 852 invalidate_DocumentWidget_(d);
824 refresh_Widget(as_Widget(d)); 853 refresh_Widget(as_Widget(d));
825} 854}
@@ -832,7 +861,7 @@ static void updateTheme_DocumentWidget_(iDocumentWidget *d) {
832 else { 861 else {
833 setThemeSeed_GmDocument(d->doc, &d->titleUser->chars); 862 setThemeSeed_GmDocument(d->doc, &d->titleUser->chars);
834 } 863 }
835 updateTimestampBuf_DocumentWidget_(d); 864 d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag;
836} 865}
837 866
838static enum iGmDocumentBanner bannerType_DocumentWidget_(const iDocumentWidget *d) { 867static enum iGmDocumentBanner bannerType_DocumentWidget_(const iDocumentWidget *d) {
@@ -928,7 +957,7 @@ static void updateDocument_DocumentWidget_(iDocumentWidget *d, const iGmResponse
928 } 957 }
929 clear_String(&d->sourceMime); 958 clear_String(&d->sourceMime);
930 d->sourceTime = response->when; 959 d->sourceTime = response->when;
931 updateTimestampBuf_DocumentWidget_(d); 960 d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag;
932 initBlock_String(&str, &response->body); 961 initBlock_String(&str, &response->body);
933 if (isSuccess_GmStatusCode(statusCode)) { 962 if (isSuccess_GmStatusCode(statusCode)) {
934 /* Check the MIME type. */ 963 /* Check the MIME type. */
@@ -1075,7 +1104,9 @@ static void cacheRunGlyphs_(void *data, const iGmRun *run) {
1075} 1104}
1076 1105
1077static void cacheDocumentGlyphs_DocumentWidget_(const iDocumentWidget *d) { 1106static void cacheDocumentGlyphs_DocumentWidget_(const iDocumentWidget *d) {
1078 render_GmDocument(d->doc, (iRangei){ 0, size_GmDocument(d->doc).y }, cacheRunGlyphs_, NULL); 1107 if (isExposed_Window(get_Window())) {
1108 render_GmDocument(d->doc, (iRangei){ 0, size_GmDocument(d->doc).y }, cacheRunGlyphs_, NULL);
1109 }
1079} 1110}
1080 1111
1081static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) { 1112static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) {
@@ -1092,14 +1123,14 @@ static iBool updateFromHistory_DocumentWidget_(iDocumentWidget *d) {
1092 d->sourceTime = resp->when; 1123 d->sourceTime = resp->when;
1093 d->sourceStatus = success_GmStatusCode; 1124 d->sourceStatus = success_GmStatusCode;
1094 format_String(&d->sourceHeader, cstr_Lang("pageinfo.header.cached")); 1125 format_String(&d->sourceHeader, cstr_Lang("pageinfo.header.cached"));
1095 updateTimestampBuf_DocumentWidget_(d); 1126 d->drawBufs->flags |= updateTimestampBuf_DrawBufsFlag;
1096 set_Block(&d->sourceContent, &resp->body); 1127 set_Block(&d->sourceContent, &resp->body);
1097 updateDocument_DocumentWidget_(d, resp, iTrue); 1128 updateDocument_DocumentWidget_(d, resp, iTrue);
1098 init_Anim(&d->scrollY, d->initNormScrollY * size_GmDocument(d->doc).y); 1129 init_Anim(&d->scrollY, d->initNormScrollY * size_GmDocument(d->doc).y);
1099 init_Anim(&d->altTextOpacity, 0); 1130 init_Anim(&d->altTextOpacity, 0);
1100 d->state = ready_RequestState; 1131 d->state = ready_RequestState;
1101 updateSideOpacity_DocumentWidget_(d, iFalse); 1132 updateSideOpacity_DocumentWidget_(d, iFalse);
1102 updateSideIconBuf_DocumentWidget_(d); 1133 d->drawBufs->flags |= updateSideBuf_DrawBufsFlag;
1103 updateVisible_DocumentWidget_(d); 1134 updateVisible_DocumentWidget_(d);
1104 cacheDocumentGlyphs_DocumentWidget_(d); 1135 cacheDocumentGlyphs_DocumentWidget_(d);
1105 postCommandf_App("document.changed doc:%p url:%s", d, cstr_String(d->mod.url)); 1136 postCommandf_App("document.changed doc:%p url:%s", d, cstr_String(d->mod.url));
@@ -1622,7 +1653,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
1622 d->phoneToolbar = findWidget_App("toolbar"); 1653 d->phoneToolbar = findWidget_App("toolbar");
1623 const iBool keepCenter = equal_Command(cmd, "font.changed"); 1654 const iBool keepCenter = equal_Command(cmd, "font.changed");
1624 updateDocumentWidthRetainingScrollPosition_DocumentWidget_(d, keepCenter); 1655 updateDocumentWidthRetainingScrollPosition_DocumentWidget_(d, keepCenter);
1625 updateSideIconBuf_DocumentWidget_(d); 1656 d->drawBufs->flags |= updateSideBuf_DrawBufsFlag;
1626 invalidate_DocumentWidget_(d); 1657 invalidate_DocumentWidget_(d);
1627 dealloc_VisBuf(d->visBuf); 1658 dealloc_VisBuf(d->visBuf);
1628 updateWindowTitle_DocumentWidget_(d); 1659 updateWindowTitle_DocumentWidget_(d);
@@ -1643,7 +1674,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
1643 updateTheme_DocumentWidget_(d); 1674 updateTheme_DocumentWidget_(d);
1644 updateVisible_DocumentWidget_(d); 1675 updateVisible_DocumentWidget_(d);
1645 updateTrust_DocumentWidget_(d, NULL); 1676 updateTrust_DocumentWidget_(d, NULL);
1646 updateSideIconBuf_DocumentWidget_(d); 1677 d->drawBufs->flags |= updateSideBuf_DrawBufsFlag;
1647 invalidate_DocumentWidget_(d); 1678 invalidate_DocumentWidget_(d);
1648 refresh_Widget(w); 1679 refresh_Widget(w);
1649 } 1680 }
@@ -1875,7 +1906,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
1875 } 1906 }
1876 iReleasePtr(&d->request); 1907 iReleasePtr(&d->request);
1877 updateVisible_DocumentWidget_(d); 1908 updateVisible_DocumentWidget_(d);
1878 updateSideIconBuf_DocumentWidget_(d); 1909 d->drawBufs->flags |= updateSideBuf_DrawBufsFlag;
1879 postCommandf_App("document.changed doc:%p url:%s", d, cstr_String(d->mod.url)); 1910 postCommandf_App("document.changed doc:%p url:%s", d, cstr_String(d->mod.url));
1880 /* Check for a pending goto. */ 1911 /* Check for a pending goto. */
1881 if (!isEmpty_String(&d->pendingGotoHeading)) { 1912 if (!isEmpty_String(&d->pendingGotoHeading)) {
@@ -3258,10 +3289,15 @@ static iBool isSideHeadingVisible_DocumentWidget_(const iDocumentWidget *d) {
3258 return sideElementAvailWidth_DocumentWidget_(d) >= lineHeight_Text(banner_FontId) * 4.5f; 3289 return sideElementAvailWidth_DocumentWidget_(d) >= lineHeight_Text(banner_FontId) * 4.5f;
3259} 3290}
3260 3291
3261static void updateSideIconBuf_DocumentWidget_(iDocumentWidget *d) { 3292static void updateSideIconBuf_DocumentWidget_(const iDocumentWidget *d) {
3262 if (d->sideIconBuf) { 3293 if (!isExposed_Window(get_Window())) {
3263 SDL_DestroyTexture(d->sideIconBuf); 3294 return;
3264 d->sideIconBuf = NULL; 3295 }
3296 iDrawBufs *dbuf = d->drawBufs;
3297 dbuf->flags &= ~updateSideBuf_DrawBufsFlag;
3298 if (dbuf->sideIconBuf) {
3299 SDL_DestroyTexture(dbuf->sideIconBuf);
3300 dbuf->sideIconBuf = NULL;
3265 } 3301 }
3266 const iGmRun *banner = siteBanner_GmDocument(d->doc); 3302 const iGmRun *banner = siteBanner_GmDocument(d->doc);
3267 if (!banner) { 3303 if (!banner) {
@@ -3286,13 +3322,13 @@ static void updateSideIconBuf_DocumentWidget_(iDocumentWidget *d) {
3286 } 3322 }
3287 } 3323 }
3288 SDL_Renderer *render = renderer_Window(get_Window()); 3324 SDL_Renderer *render = renderer_Window(get_Window());
3289 d->sideIconBuf = SDL_CreateTexture(render, 3325 dbuf->sideIconBuf = SDL_CreateTexture(render,
3290 SDL_PIXELFORMAT_RGBA4444, 3326 SDL_PIXELFORMAT_RGBA4444,
3291 SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET, 3327 SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET,
3292 bufSize.x, bufSize.y); 3328 bufSize.x, bufSize.y);
3293 iPaint p; 3329 iPaint p;
3294 init_Paint(&p); 3330 init_Paint(&p);
3295 beginTarget_Paint(&p, d->sideIconBuf); 3331 beginTarget_Paint(&p, dbuf->sideIconBuf);
3296 const iColor back = get_Color(tmBannerSideTitle_ColorId); 3332 const iColor back = get_Color(tmBannerSideTitle_ColorId);
3297 SDL_SetRenderDrawColor(render, back.r, back.g, back.b, 0); /* better blending of the edge */ 3333 SDL_SetRenderDrawColor(render, back.r, back.g, back.b, 0); /* better blending of the edge */
3298 SDL_RenderClear(render); 3334 SDL_RenderClear(render);
@@ -3309,7 +3345,7 @@ static void updateSideIconBuf_DocumentWidget_(iDocumentWidget *d) {
3309 drawWrapRange_Text(font, pos, avail, tmBannerSideTitle_ColorId, text); 3345 drawWrapRange_Text(font, pos, avail, tmBannerSideTitle_ColorId, text);
3310 } 3346 }
3311 endTarget_Paint(&p); 3347 endTarget_Paint(&p);
3312 SDL_SetTextureBlendMode(d->sideIconBuf, SDL_BLENDMODE_BLEND); 3348 SDL_SetTextureBlendMode(dbuf->sideIconBuf, SDL_BLENDMODE_BLEND);
3313} 3349}
3314 3350
3315static void drawSideElements_DocumentWidget_(const iDocumentWidget *d) { 3351static void drawSideElements_DocumentWidget_(const iDocumentWidget *d) {
@@ -3319,12 +3355,13 @@ static void drawSideElements_DocumentWidget_(const iDocumentWidget *d) {
3319 const int margin = gap_UI * d->pageMargin; 3355 const int margin = gap_UI * d->pageMargin;
3320 float opacity = value_Anim(&d->sideOpacity); 3356 float opacity = value_Anim(&d->sideOpacity);
3321 const int avail = left_Rect(docBounds) - left_Rect(bounds) - 2 * margin; 3357 const int avail = left_Rect(docBounds) - left_Rect(bounds) - 2 * margin;
3322 iPaint p; 3358 iDrawBufs * dbuf = d->drawBufs;
3359 iPaint p;
3323 init_Paint(&p); 3360 init_Paint(&p);
3324 setClip_Paint(&p, bounds); 3361 setClip_Paint(&p, bounds);
3325 /* Side icon and current heading. */ 3362 /* Side icon and current heading. */
3326 if (prefs_App()->sideIcon && opacity > 0 && d->sideIconBuf) { 3363 if (prefs_App()->sideIcon && opacity > 0 && dbuf->sideIconBuf) {
3327 const iInt2 texSize = size_SDLTexture(d->sideIconBuf); 3364 const iInt2 texSize = size_SDLTexture(dbuf->sideIconBuf);
3328 if (avail > texSize.x) { 3365 if (avail > texSize.x) {
3329 const int minBannerSize = lineHeight_Text(banner_FontId) * 2; 3366 const int minBannerSize = lineHeight_Text(banner_FontId) * 2;
3330 iInt2 pos = addY_I2(add_I2(topLeft_Rect(bounds), init_I2(margin, 0)), 3367 iInt2 pos = addY_I2(add_I2(topLeft_Rect(bounds), init_I2(margin, 0)),
@@ -3332,20 +3369,20 @@ static void drawSideElements_DocumentWidget_(const iDocumentWidget *d) {
3332 (texSize.y > minBannerSize 3369 (texSize.y > minBannerSize
3333 ? (gap_Text + lineHeight_Text(heading3_FontId)) / 2 3370 ? (gap_Text + lineHeight_Text(heading3_FontId)) / 2
3334 : 0)); 3371 : 0));
3335 SDL_SetTextureAlphaMod(d->sideIconBuf, 255 * opacity); 3372 SDL_SetTextureAlphaMod(dbuf->sideIconBuf, 255 * opacity);
3336 SDL_RenderCopy(renderer_Window(get_Window()), 3373 SDL_RenderCopy(renderer_Window(get_Window()),
3337 d->sideIconBuf, NULL, 3374 dbuf->sideIconBuf, NULL,
3338 &(SDL_Rect){ pos.x, pos.y, texSize.x, texSize.y }); 3375 &(SDL_Rect){ pos.x, pos.y, texSize.x, texSize.y });
3339 } 3376 }
3340 } 3377 }
3341 /* Reception timestamp. */ 3378 /* Reception timestamp. */
3342 if (d->timestampBuf && d->timestampBuf->size.x <= avail) { 3379 if (dbuf->timestampBuf && dbuf->timestampBuf->size.x <= avail) {
3343 draw_TextBuf( 3380 draw_TextBuf(
3344 d->timestampBuf, 3381 dbuf->timestampBuf,
3345 add_I2( 3382 add_I2(
3346 bottomLeft_Rect(bounds), 3383 bottomLeft_Rect(bounds),
3347 init_I2(margin, 3384 init_I2(margin,
3348 -margin + -d->timestampBuf->size.y + 3385 -margin + -dbuf->timestampBuf->size.y +
3349 iMax(0, scrollMax_DocumentWidget_(d) - value_Anim(&d->scrollY)))), 3386 iMax(0, scrollMax_DocumentWidget_(d) - value_Anim(&d->scrollY)))),
3350 tmQuoteIcon_ColorId); 3387 tmQuoteIcon_ColorId);
3351 } 3388 }
@@ -3378,6 +3415,12 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) {
3378 return; 3415 return;
3379 } 3416 }
3380 draw_Widget(w); 3417 draw_Widget(w);
3418 if (d->drawBufs->flags & updateTimestampBuf_DrawBufsFlag) {
3419 updateTimestampBuf_DocumentWidget_(d);
3420 }
3421 if (d->drawBufs->flags & updateSideBuf_DrawBufsFlag) {
3422 updateSideIconBuf_DocumentWidget_(d);
3423 }
3381 allocVisBuffer_DocumentWidget_(d); 3424 allocVisBuffer_DocumentWidget_(d);
3382 const iRect ctxWidgetBounds = init_Rect( 3425 const iRect ctxWidgetBounds = init_Rect(
3383 0, 0, width_Rect(bounds) - constAs_Widget(d->scroll)->rect.size.x, height_Rect(bounds)); 3426 0, 0, width_Rect(bounds) - constAs_Widget(d->scroll)->rect.size.x, height_Rect(bounds));
@@ -3617,7 +3660,7 @@ iBool isRequestOngoing_DocumentWidget(const iDocumentWidget *d) {
3617void updateSize_DocumentWidget(iDocumentWidget *d) { 3660void updateSize_DocumentWidget(iDocumentWidget *d) {
3618 updateDocumentWidthRetainingScrollPosition_DocumentWidget_(d, iFalse); 3661 updateDocumentWidthRetainingScrollPosition_DocumentWidget_(d, iFalse);
3619 resetWideRuns_DocumentWidget_(d); 3662 resetWideRuns_DocumentWidget_(d);
3620 updateSideIconBuf_DocumentWidget_(d); 3663 d->drawBufs->flags |= updateSideBuf_DrawBufsFlag;
3621 updateVisible_DocumentWidget_(d); 3664 updateVisible_DocumentWidget_(d);
3622 invalidate_DocumentWidget_(d); 3665 invalidate_DocumentWidget_(d);
3623} 3666}
diff --git a/src/ui/text.c b/src/ui/text.c
index 674e2a72..6af7d6d1 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -24,6 +24,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
24#include "color.h" 24#include "color.h"
25#include "metrics.h" 25#include "metrics.h"
26#include "embedded.h" 26#include "embedded.h"
27#include "window.h"
27#include "app.h" 28#include "app.h"
28 29
29#define STB_TRUETYPE_IMPLEMENTATION 30#define STB_TRUETYPE_IMPLEMENTATION
@@ -702,6 +703,7 @@ void cacheTextGlyphs_Font_(iFont *d, const iRangecc text) {
702 iArray * rasters = NULL; 703 iArray * rasters = NULL;
703 SDL_Texture *oldTarget = NULL; 704 SDL_Texture *oldTarget = NULL;
704 iBool isTargetChanged = iFalse; 705 iBool isTargetChanged = iFalse;
706 iAssert(isExposed_Window(get_Window()));
705 /* We'll flush the buffered rasters periodically until everything is cached. */ 707 /* We'll flush the buffered rasters periodically until everything is cached. */
706 while (chPos < text.end) { 708 while (chPos < text.end) {
707 while (chPos < text.end) { 709 while (chPos < text.end) {
@@ -1017,7 +1019,7 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1017 int x1 = iMax(xpos, xposExtend); 1019 int x1 = iMax(xpos, xposExtend);
1018 /* Which half of the pixel the glyph falls on? */ 1020 /* Which half of the pixel the glyph falls on? */
1019 const int hoff = enableHalfPixelGlyphs_Text ? (xpos - x1 > 0.5f ? 1 : 0) : 0; 1021 const int hoff = enableHalfPixelGlyphs_Text ? (xpos - x1 > 0.5f ? 1 : 0) : 0;
1020 if (!isRasterized_Glyph_(glyph, hoff)) { 1022 if (mode & draw_RunMode && !isRasterized_Glyph_(glyph, hoff)) {
1021 /* Need to pause here and make sure all glyphs have been cached in the text. */ 1023 /* Need to pause here and make sure all glyphs have been cached in the text. */
1022 cacheTextGlyphs_Font_(d, args->text); 1024 cacheTextGlyphs_Font_(d, args->text);
1023 glyph = glyph_Font_(d, ch); /* cache may have been reset */ 1025 glyph = glyph_Font_(d, ch); /* cache may have been reset */
diff --git a/src/ui/window.c b/src/ui/window.c
index f92107e3..27740326 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -1769,12 +1769,8 @@ iBool processEvent_Window(iWindow *d, const SDL_Event *ev) {
1769 SDL_Event event = *ev; 1769 SDL_Event event = *ev;
1770 if (event.type == SDL_USEREVENT && isCommand_UserEvent(ev, "window.unfreeze")) { 1770 if (event.type == SDL_USEREVENT && isCommand_UserEvent(ev, "window.unfreeze")) {
1771 d->isDrawFrozen = iFalse; 1771 d->isDrawFrozen = iFalse;
1772 /* When the window is shown for the first time, ensure glyphs get
1773 re-cached correctly. */
1774 if (SDL_GetWindowFlags(d->win) & SDL_WINDOW_HIDDEN) { 1772 if (SDL_GetWindowFlags(d->win) & SDL_WINDOW_HIDDEN) {
1775 SDL_ShowWindow(d->win); 1773 SDL_ShowWindow(d->win);
1776 resetFonts_Text();
1777 postCommand_App("theme.changed");
1778 } 1774 }
1779 postRefresh_App(); 1775 postRefresh_App();
1780 return iTrue; 1776 return iTrue;
diff --git a/src/ui/window.h b/src/ui/window.h
index 7303acb2..6960e03e 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -113,3 +113,8 @@ iWindow * get_Window (void);
113#if defined (LAGRANGE_CUSTOM_FRAME) 113#if defined (LAGRANGE_CUSTOM_FRAME)
114SDL_HitTestResult hitTest_Window(const iWindow *d, iInt2 pos); 114SDL_HitTestResult hitTest_Window(const iWindow *d, iInt2 pos);
115#endif 115#endif
116
117iLocalDef iBool isExposed_Window(const iWindow *d) {
118 iAssert(d);
119 return d->isExposed;
120}