summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-09-05 07:02:33 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-09-05 07:02:33 +0300
commitaa50c1e0028c6cb08524dcdfb7188906c817e46f (patch)
tree1f5d91bef261612680d589e0481dad99ef189619 /src
parentde53b815e09a1004b8fb70706199fb840f53514a (diff)
Option to force break very long lines
Even preformatted lines may need to be wrapped so the content remains visible, since there is no horizontal scrolling. However, this is off by default so ASCII art isn't broken in narrow windows.
Diffstat (limited to 'src')
-rw-r--r--src/app.c14
-rw-r--r--src/app.h1
-rw-r--r--src/gmdocument.c16
-rw-r--r--src/gmdocument.h4
-rw-r--r--src/ui/documentwidget.c23
-rw-r--r--src/ui/window.c2
6 files changed, 44 insertions, 16 deletions
diff --git a/src/app.c b/src/app.c
index 5bce7b19..da14f06c 100644
--- a/src/app.c
+++ b/src/app.c
@@ -94,6 +94,7 @@ struct Impl_App {
94 iRect initialWindowRect; 94 iRect initialWindowRect;
95 float uiScale; 95 float uiScale;
96 int zoomPercent; 96 int zoomPercent;
97 iBool forceWrap;
97 enum iColorTheme theme; 98 enum iColorTheme theme;
98 iBool useSystemTheme; 99 iBool useSystemTheme;
99 iString gopherProxy; 100 iString gopherProxy;
@@ -146,6 +147,9 @@ static iString *serializePrefs_App_(const iApp *d) {
146 if (isVisible_Widget(constAs_Widget(sidebar))) { 147 if (isVisible_Widget(constAs_Widget(sidebar))) {
147 appendCStr_String(str, "sidebar.toggle\n"); 148 appendCStr_String(str, "sidebar.toggle\n");
148 } 149 }
150 if (d->forceWrap) {
151 appendFormat_String(str, "forcewrap.toggle\n");
152 }
149 appendFormat_String(str, "sidebar.mode arg:%d\n", mode_SidebarWidget(sidebar)); 153 appendFormat_String(str, "sidebar.mode arg:%d\n", mode_SidebarWidget(sidebar));
150 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window)); 154 appendFormat_String(str, "uiscale arg:%f\n", uiScale_Window(d->window));
151 appendFormat_String(str, "zoom.set arg:%d\n", d->zoomPercent); 155 appendFormat_String(str, "zoom.set arg:%d\n", d->zoomPercent);
@@ -281,6 +285,7 @@ static void init_App_(iApp *d, int argc, char **argv) {
281 d->retainWindowSize = iTrue; 285 d->retainWindowSize = iTrue;
282 d->pendingRefresh = iFalse; 286 d->pendingRefresh = iFalse;
283 d->zoomPercent = 100; 287 d->zoomPercent = 100;
288 d->forceWrap = iFalse;
284 d->certs = new_GmCerts(dataDir_App_); 289 d->certs = new_GmCerts(dataDir_App_);
285 d->visited = new_Visited(); 290 d->visited = new_Visited();
286 d->bookmarks = new_Bookmarks(); 291 d->bookmarks = new_Bookmarks();
@@ -431,6 +436,10 @@ int zoom_App(void) {
431 return app_.zoomPercent; 436 return app_.zoomPercent;
432} 437}
433 438
439iBool isLineWrapForced_App(void) {
440 return app_.forceWrap;
441}
442
434enum iColorTheme colorTheme_App(void) { 443enum iColorTheme colorTheme_App(void) {
435 return app_.theme; 444 return app_.theme;
436} 445}
@@ -793,6 +802,11 @@ iBool handleCommand_App(const char *cmd) {
793 postCommand_App("window.unfreeze"); 802 postCommand_App("window.unfreeze");
794 return iTrue; 803 return iTrue;
795 } 804 }
805 else if (equal_Command(cmd, "forcewrap.toggle")) {
806 d->forceWrap = !d->forceWrap;
807 updateSize_DocumentWidget(document_App());
808 return iTrue;
809 }
796 else if (equal_Command(cmd, "bookmark.add")) { 810 else if (equal_Command(cmd, "bookmark.add")) {
797 iDocumentWidget *doc = document_App(); 811 iDocumentWidget *doc = document_App();
798 makeBookmarkCreation_Widget(url_DocumentWidget(doc), 812 makeBookmarkCreation_Widget(url_DocumentWidget(doc),
diff --git a/src/app.h b/src/app.h
index 3d4808bc..1cf9f8a8 100644
--- a/src/app.h
+++ b/src/app.h
@@ -56,6 +56,7 @@ iBool isRefreshPending_App (void);
56uint32_t elapsedSinceLastTicker_App (void); /* milliseconds */ 56uint32_t elapsedSinceLastTicker_App (void); /* milliseconds */
57 57
58int zoom_App (void); 58int zoom_App (void);
59iBool isLineWrapForced_App(void);
59enum iColorTheme colorTheme_App (void); 60enum iColorTheme colorTheme_App (void);
60const iString * schemeProxy_App (iRangecc scheme); 61const iString * schemeProxy_App (iRangecc scheme);
61 62
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 924eee32..e4ae03a8 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -104,6 +104,7 @@ struct Impl_GmDocument {
104 iString source; 104 iString source;
105 iString url; /* for resolving relative links */ 105 iString url; /* for resolving relative links */
106 iString localHost; 106 iString localHost;
107 int forceBreakWidth; /* force breaks on very long preformatted lines */
107 iInt2 size; 108 iInt2 size;
108 iArray layout; /* contents of source, laid out in document space */ 109 iArray layout; /* contents of source, laid out in document space */
109 iPtrArray links; 110 iPtrArray links;
@@ -506,12 +507,11 @@ static void doLayout_GmDocument_(iGmDocument *d) {
506 } 507 }
507 run.bounds.pos = addX_I2(pos, indent * gap_Text); 508 run.bounds.pos = addX_I2(pos, indent * gap_Text);
508 const char *contPos; 509 const char *contPos;
509 const int avail = d->size.x - run.bounds.pos.x; 510 const int avail = (isPreformat ? d->forceBreakWidth : d->size.x) - run.bounds.pos.x;
510 const iInt2 dims = 511 const iInt2 dims = tryAdvance_Text(run.font, runLine, avail, &contPos);
511 tryAdvance_Text(run.font, runLine, isPreformat ? 0 : avail, &contPos);
512 run.bounds.size.x = iMax(avail, dims.x); /* Extends to the right edge for selection. */ 512 run.bounds.size.x = iMax(avail, dims.x); /* Extends to the right edge for selection. */
513 run.bounds.size.y = dims.y; 513 run.bounds.size.y = dims.y;
514 run.visBounds = run.bounds; 514 run.visBounds = run.bounds;
515 run.visBounds.size.x = dims.x; 515 run.visBounds.size.x = dims.x;
516 if (contPos > runLine.start) { 516 if (contPos > runLine.start) {
517 run.text = (iRangecc){ runLine.start, contPos }; 517 run.text = (iRangecc){ runLine.start, contPos };
@@ -866,7 +866,8 @@ void setFormat_GmDocument(iGmDocument *d, enum iGmDocumentFormat format) {
866 d->format = format; 866 d->format = format;
867} 867}
868 868
869void setWidth_GmDocument(iGmDocument *d, int width) { 869void setWidth_GmDocument(iGmDocument *d, int width, int forceBreakWidth) {
870 d->forceBreakWidth = forceBreakWidth;
870 d->size.x = width; 871 d->size.x = width;
871 doLayout_GmDocument_(d); /* TODO: just flag need-layout and do it later */ 872 doLayout_GmDocument_(d); /* TODO: just flag need-layout and do it later */
872} 873}
@@ -939,11 +940,10 @@ void setUrl_GmDocument(iGmDocument *d, const iString *url) {
939 setRange_String(&d->localHost, parts.host); 940 setRange_String(&d->localHost, parts.host);
940} 941}
941 942
942void setSource_GmDocument(iGmDocument *d, const iString *source, int width) { 943void setSource_GmDocument(iGmDocument *d, const iString *source, int width, int forceBreakWidth) {
943 set_String(&d->source, source); 944 set_String(&d->source, source);
944 normalize_GmDocument(d); 945 normalize_GmDocument(d);
945 setWidth_GmDocument(d, width); 946 setWidth_GmDocument(d, width, forceBreakWidth); /* re-do layout */
946 /* TODO: just flag need-layout and do it later */
947} 947}
948 948
949void setImage_GmDocument(iGmDocument *d, iGmLinkId linkId, const iString *mime, const iBlock *data) { 949void setImage_GmDocument(iGmDocument *d, iGmLinkId linkId, const iString *mime, const iBlock *data) {
diff --git a/src/gmdocument.h b/src/gmdocument.h
index b6c1c6ab..e3c21097 100644
--- a/src/gmdocument.h
+++ b/src/gmdocument.h
@@ -94,9 +94,9 @@ enum iGmDocumentFormat {
94 94
95void setThemeSeed_GmDocument (iGmDocument *, const iBlock *seed); 95void setThemeSeed_GmDocument (iGmDocument *, const iBlock *seed);
96void setFormat_GmDocument (iGmDocument *, enum iGmDocumentFormat format); 96void setFormat_GmDocument (iGmDocument *, enum iGmDocumentFormat format);
97void setWidth_GmDocument (iGmDocument *, int width); 97void setWidth_GmDocument (iGmDocument *, int width, int forceBreakWidth);
98void setUrl_GmDocument (iGmDocument *, const iString *url); 98void setUrl_GmDocument (iGmDocument *, const iString *url);
99void setSource_GmDocument (iGmDocument *, const iString *source, int width); 99void setSource_GmDocument (iGmDocument *, const iString *source, int width, int forceBreakWidth);
100void setImage_GmDocument (iGmDocument *, iGmLinkId linkId, const iString *mime, const iBlock *data); 100void setImage_GmDocument (iGmDocument *, iGmLinkId linkId, const iString *mime, const iBlock *data);
101 101
102void reset_GmDocument (iGmDocument *); /* free images */ 102void reset_GmDocument (iGmDocument *); /* free images */
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 437e9468..2ccdc416 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -296,6 +296,15 @@ static iRect documentBounds_DocumentWidget_(const iDocumentWidget *d) {
296 return rect; 296 return rect;
297} 297}
298 298
299static int forceBreakWidth_DocumentWidget_(const iDocumentWidget *d) {
300 if (isLineWrapForced_App()) {
301 const iRect bounds = bounds_Widget(constAs_Widget(d));
302 const iRect docBounds = documentBounds_DocumentWidget_(d);
303 return right_Rect(bounds) - left_Rect(docBounds) - gap_UI * d->pageMargin;
304 }
305 return 0;
306}
307
299iLocalDef int documentToWindowY_DocumentWidget_(const iDocumentWidget *d, int docY) { 308iLocalDef int documentToWindowY_DocumentWidget_(const iDocumentWidget *d, int docY) {
300 return docY - d->scrollY + documentBounds_DocumentWidget_(d).pos.y; 309 return docY - d->scrollY + documentBounds_DocumentWidget_(d).pos.y;
301} 310}
@@ -488,7 +497,8 @@ static void invalidate_DocumentWidget_(iDocumentWidget *d) {
488 497
489static void setSource_DocumentWidget_(iDocumentWidget *d, const iString *source) { 498static void setSource_DocumentWidget_(iDocumentWidget *d, const iString *source) {
490 setUrl_GmDocument(d->doc, d->mod.url); 499 setUrl_GmDocument(d->doc, d->mod.url);
491 setSource_GmDocument(d->doc, source, documentWidth_DocumentWidget_(d)); 500 setSource_GmDocument(
501 d->doc, source, documentWidth_DocumentWidget_(d), forceBreakWidth_DocumentWidget_(d));
492 d->foundMark = iNullRange; 502 d->foundMark = iNullRange;
493 d->selectMark = iNullRange; 503 d->selectMark = iNullRange;
494 d->hoverLink = NULL; 504 d->hoverLink = NULL;
@@ -1021,8 +1031,10 @@ static void allocVisBuffer_DocumentWidget_(const iDocumentWidget *d) {
1021} 1031}
1022 1032
1023void updateSize_DocumentWidget(iDocumentWidget *d) { 1033void updateSize_DocumentWidget(iDocumentWidget *d) {
1024 setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); 1034 setWidth_GmDocument(
1035 d->doc, documentWidth_DocumentWidget_(d), forceBreakWidth_DocumentWidget_(d));
1025 updateVisible_DocumentWidget_(d); 1036 updateVisible_DocumentWidget_(d);
1037 invalidate_DocumentWidget_(d);
1026} 1038}
1027 1039
1028static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { 1040static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
@@ -1030,9 +1042,9 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
1030 if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { 1042 if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) {
1031 const iGmRun *mid = middleRun_DocumentWidget_(d); 1043 const iGmRun *mid = middleRun_DocumentWidget_(d);
1032 const char *midLoc = (mid ? mid->text.start : NULL); 1044 const char *midLoc = (mid ? mid->text.start : NULL);
1033 setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); 1045 setWidth_GmDocument(
1046 d->doc, documentWidth_DocumentWidget_(d), forceBreakWidth_DocumentWidget_(d));
1034 scroll_DocumentWidget_(d, 0); 1047 scroll_DocumentWidget_(d, 0);
1035 updateVisible_DocumentWidget_(d);
1036 if (midLoc) { 1048 if (midLoc) {
1037 mid = findRunAtLoc_GmDocument(d->doc, midLoc); 1049 mid = findRunAtLoc_GmDocument(d->doc, midLoc);
1038 if (mid) { 1050 if (mid) {
@@ -1055,8 +1067,7 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
1055 /* Set palette for our document. */ 1067 /* Set palette for our document. */
1056 updateTheme_DocumentWidget_(d); 1068 updateTheme_DocumentWidget_(d);
1057 updateTrust_DocumentWidget_(d, NULL); 1069 updateTrust_DocumentWidget_(d, NULL);
1058 setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); 1070 updateSize_DocumentWidget(d);
1059 updateVisible_DocumentWidget_(d);
1060 } 1071 }
1061 updateWindowTitle_DocumentWidget_(d); 1072 updateWindowTitle_DocumentWidget_(d);
1062 allocVisBuffer_DocumentWidget_(d); 1073 allocVisBuffer_DocumentWidget_(d);
diff --git a/src/ui/window.c b/src/ui/window.c
index b7b4a8fd..66f1c513 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -141,6 +141,8 @@ static const iMenuItem viewMenuItems[] = {
141 { "Zoom In", SDLK_EQUALS, KMOD_PRIMARY, "zoom.delta arg:10" }, 141 { "Zoom In", SDLK_EQUALS, KMOD_PRIMARY, "zoom.delta arg:10" },
142 { "Zoom Out", SDLK_MINUS, KMOD_PRIMARY, "zoom.delta arg:-10" }, 142 { "Zoom Out", SDLK_MINUS, KMOD_PRIMARY, "zoom.delta arg:-10" },
143 { "Reset Zoom", SDLK_0, KMOD_PRIMARY, "zoom.set arg:100" }, 143 { "Reset Zoom", SDLK_0, KMOD_PRIMARY, "zoom.set arg:100" },
144 { "---", 0, 0, NULL },
145 { "Wrap Preformatted", 0, 0, "forcewrap.toggle" }
144}; 146};
145 147
146static const iMenuItem helpMenuItems[] = { 148static const iMenuItem helpMenuItems[] = {