summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-12-18 07:01:20 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-12-18 07:01:20 +0200
commitcc798c0f7ca53cc0f14a29439049309ae20616a8 (patch)
tree5d7a439a982333b711703e890d75adab6d762811
parent2b78e40ce5d86a517ec081214d369f0064a72250 (diff)
Nicer image metadata and open URLs highlight
Metadata of inlined images shouldn't overlap the caption text. Open URL highlights are not drawn fullwidth to avoid clashing with side elements and generally to look more consistent.
-rw-r--r--src/gmdocument.c37
-rw-r--r--src/gmdocument.h2
-rw-r--r--src/ui/documentwidget.c24
3 files changed, 44 insertions, 19 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c
index bec89ca0..29e97300 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
37#include <the_Foundation/intset.h> 37#include <the_Foundation/intset.h>
38#include <the_Foundation/ptrarray.h> 38#include <the_Foundation/ptrarray.h>
39#include <the_Foundation/regexp.h> 39#include <the_Foundation/regexp.h>
40#include <the_Foundation/stringarray.h>
40#include <the_Foundation/stringset.h> 41#include <the_Foundation/stringset.h>
41 42
42#include <ctype.h> 43#include <ctype.h>
@@ -163,6 +164,7 @@ struct Impl_GmDocument {
163 iBool enableCommandLinks; /* `about:command?` only allowed on selected pages */ 164 iBool enableCommandLinks; /* `about:command?` only allowed on selected pages */
164 iBool isLayoutInvalidated; 165 iBool isLayoutInvalidated;
165 iArray layout; /* contents of source, laid out in document space */ 166 iArray layout; /* contents of source, laid out in document space */
167 iStringArray auxText; /* generated text that appears on the page but is not part of the source */
166 iPtrArray links; 168 iPtrArray links;
167 iString title; /* the first top-level title */ 169 iString title; /* the first top-level title */
168 iArray headings; 170 iArray headings;
@@ -638,6 +640,7 @@ static void doLayout_GmDocument_(iGmDocument *d) {
638 static const char *uploadArrow = upload_Icon; 640 static const char *uploadArrow = upload_Icon;
639 static const char *image = photo_Icon; 641 static const char *image = photo_Icon;
640 clear_Array(&d->layout); 642 clear_Array(&d->layout);
643 clear_StringArray(&d->auxText);
641 clearLinks_GmDocument_(d); 644 clearLinks_GmDocument_(d);
642 clear_Array(&d->headings); 645 clear_Array(&d->headings);
643 const iArray *oldPreMeta = collect_Array(copy_Array(&d->preMeta)); /* remember fold states */ 646 const iArray *oldPreMeta = collect_Array(copy_Array(&d->preMeta)); /* remember fold states */
@@ -1070,7 +1073,9 @@ static void doLayout_GmDocument_(iGmDocument *d) {
1070 run.bounds.pos.x -= d->outsideMargin; 1073 run.bounds.pos.x -= d->outsideMargin;
1071 } 1074 }
1072 run.visBounds = run.bounds; 1075 run.visBounds = run.bounds;
1073 const iInt2 maxSize = mulf_I2(imgSize, get_Window()->pixelRatio); 1076 const iInt2 maxSize = mulf_I2(
1077 imgSize,
1078 get_Window()->pixelRatio * iMax(1.0f, (prefs_App()->zoomPercent / 100.0f)));
1074 if (width_Rect(run.visBounds) > maxSize.x) { 1079 if (width_Rect(run.visBounds) > maxSize.x) {
1075 /* Don't scale the image up. */ 1080 /* Don't scale the image up. */
1076 run.visBounds.size.y = 1081 run.visBounds.size.y =
@@ -1080,6 +1085,34 @@ static void doLayout_GmDocument_(iGmDocument *d) {
1080 run.bounds.size.y = run.visBounds.size.y; 1085 run.bounds.size.y = run.visBounds.size.y;
1081 } 1086 }
1082 pushBack_Array(&d->layout, &run); 1087 pushBack_Array(&d->layout, &run);
1088 pos.y += run.bounds.size.y + margin / 2;
1089 /* Image metadata caption. */ {
1090 run.font = FONT_ID(documentBody_FontId, semiBold_FontStyle, contentSmall_FontSize);
1091 run.color = tmQuoteIcon_ColorId;
1092 run.flags = decoration_GmRunFlag;
1093 run.mediaId = 0;
1094 run.mediaType = 0;
1095 run.visBounds.pos.y = pos.y;
1096 run.visBounds.size.y = lineHeight_Text(run.font);
1097 run.bounds = zero_Rect();
1098 iString caption;
1099 init_String(&caption);
1100 format_String(&caption,
1101 "%s \u2014 %d x %d \u2014 %.1f%s",
1102 info.type,
1103 imgSize.x,
1104 imgSize.y,
1105 info.numBytes / 1.0e6f,
1106 cstr_Lang("mb"));
1107 pushBack_StringArray(&d->auxText, &caption);
1108 run.text = range_String(&caption);
1109 /* Center it. */
1110 run.visBounds.size.x = measureRange_Text(run.font, range_String(&caption)).bounds.size.x;
1111 run.visBounds.pos.x = d->size.x / 2 - run.visBounds.size.x / 2;
1112 deinit_String(&caption);
1113 pushBack_Array(&d->layout, &run);
1114 pos.y += run.visBounds.size.y + margin;
1115 }
1083 break; 1116 break;
1084 } 1117 }
1085 case audio_MediaType: { 1118 case audio_MediaType: {
@@ -1152,6 +1185,7 @@ void init_GmDocument(iGmDocument *d) {
1152 d->enableCommandLinks = iFalse; 1185 d->enableCommandLinks = iFalse;
1153 d->isLayoutInvalidated = iFalse; 1186 d->isLayoutInvalidated = iFalse;
1154 init_Array(&d->layout, sizeof(iGmRun)); 1187 init_Array(&d->layout, sizeof(iGmRun));
1188 init_StringArray(&d->auxText);
1155 init_PtrArray(&d->links); 1189 init_PtrArray(&d->links);
1156 init_String(&d->title); 1190 init_String(&d->title);
1157 init_Array(&d->headings, sizeof(iGmHeading)); 1191 init_Array(&d->headings, sizeof(iGmHeading));
@@ -1173,6 +1207,7 @@ void deinit_GmDocument(iGmDocument *d) {
1173 deinit_PtrArray(&d->links); 1207 deinit_PtrArray(&d->links);
1174 deinit_Array(&d->preMeta); 1208 deinit_Array(&d->preMeta);
1175 deinit_Array(&d->headings); 1209 deinit_Array(&d->headings);
1210 deinit_StringArray(&d->auxText);
1176 deinit_Array(&d->layout); 1211 deinit_Array(&d->layout);
1177 deinit_String(&d->localHost); 1212 deinit_String(&d->localHost);
1178 deinit_String(&d->url); 1213 deinit_String(&d->url);
diff --git a/src/gmdocument.h b/src/gmdocument.h
index 58fc3db3..eb02a26c 100644
--- a/src/gmdocument.h
+++ b/src/gmdocument.h
@@ -139,7 +139,7 @@ struct Impl_GmRun {
139 139
140 uint32_t font : 14; 140 uint32_t font : 14;
141 uint32_t mediaType : 3; /* note: max_MediaType means preformatted block */ 141 uint32_t mediaType : 3; /* note: max_MediaType means preformatted block */
142 uint32_t mediaId : 11; /* zero if not an image */ 142 uint32_t mediaId : 11;
143 uint32_t lineType : 3; 143 uint32_t lineType : 3;
144 uint32_t isLede : 1; 144 uint32_t isLede : 1;
145 }; 145 };
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 1449d10d..06e3475a 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -1529,7 +1529,7 @@ static void postProcessRequestContent_DocumentWidget_(iDocumentWidget *d, iBool
1529 } 1529 }
1530 else { 1530 else {
1531 postCommandf_App( 1531 postCommandf_App(
1532 "open newtab:%d url:%s", otherRoot_OpenTabFlag, cstr_String(navStart)); 1532 "open splitmode:1 newtab:%d url:%s", otherRoot_OpenTabFlag, cstr_String(navStart));
1533 } 1533 }
1534 } 1534 }
1535 } 1535 }
@@ -4753,9 +4753,9 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
4753 /* Open links get a highlighted background. */ 4753 /* Open links get a highlighted background. */
4754 int bg = tmBackgroundOpenLink_ColorId; 4754 int bg = tmBackgroundOpenLink_ColorId;
4755 const int frame = tmFrameOpenLink_ColorId; 4755 const int frame = tmFrameOpenLink_ColorId;
4756 iRect wideRect = { init_I2(left_Rect(d->widgetBounds), visPos.y), 4756 const int pad = gap_Text;
4757 init_I2(width_Rect(d->widgetBounds) + 4757 iRect wideRect = { init_I2(d->docBounds.pos.x - pad, visPos.y),
4758 width_Widget(d->widget->scroll), 4758 init_I2(d->docBounds.size.x + 2 * pad,
4759 height_Rect(run->visBounds)) }; 4759 height_Rect(run->visBounds)) };
4760 /* The first line is composed of two runs that may be drawn in either order, so 4760 /* The first line is composed of two runs that may be drawn in either order, so
4761 only draw half of the background. */ 4761 only draw half of the background. */
@@ -4767,14 +4767,6 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
4767 wideRect.pos.x = left_Rect(visRect); 4767 wideRect.pos.x = left_Rect(visRect);
4768 } 4768 }
4769 fillRect_Paint(&d->paint, wideRect, bg); 4769 fillRect_Paint(&d->paint, wideRect, bg);
4770 if (run->flags & (startOfLine_GmRunFlag | decoration_GmRunFlag)) {
4771 drawHLine_Paint(&d->paint, topLeft_Rect(wideRect), width_Rect(wideRect), frame);
4772 }
4773 /* TODO: The decoration is not marked as endOfLine, so it lacks the bottom line. */
4774// if (run->flags & endOfLine_GmRunFlag) {
4775// drawHLine_Paint(
4776// &d->paint, addY_I2(bottomLeft_Rect(wideRect), -1), width_Rect(wideRect), frame);
4777// }
4778 } 4770 }
4779 else { 4771 else {
4780 /* Normal background for other runs. There are cases when runs get drawn multiple times, 4772 /* Normal background for other runs. There are cases when runs get drawn multiple times,
@@ -4866,11 +4858,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
4866 info_Media(constMedia_GmDocument(doc), linkMedia, &info); 4858 info_Media(constMedia_GmDocument(doc), linkMedia, &info);
4867 switch (linkMedia.type) { 4859 switch (linkMedia.type) {
4868 case image_MediaType: { 4860 case image_MediaType: {
4869 iAssert(!isEmpty_Rect(run->bounds)); 4861 /* There's a separate decorative GmRun for the metadata. */
4870 const iInt2 imgSize = imageSize_Media(constMedia_GmDocument(doc), linkMedia);
4871 format_String(&text, "%s \u2014 %d x %d \u2014 %.1f%s",
4872 info.type, imgSize.x, imgSize.y, info.numBytes / 1.0e6f,
4873 cstr_Lang("mb"));
4874 break; 4862 break;
4875 } 4863 }
4876 case audio_MediaType: 4864 case audio_MediaType:
@@ -4883,6 +4871,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
4883 break; 4871 break;
4884 } 4872 }
4885 if (linkMedia.type != download_MediaType && /* can't cancel downloads currently */ 4873 if (linkMedia.type != download_MediaType && /* can't cancel downloads currently */
4874 linkMedia.type != image_MediaType &&
4886 findMediaRequest_DocumentWidget_(d->widget, run->linkId)) { 4875 findMediaRequest_DocumentWidget_(d->widget, run->linkId)) {
4887 appendFormat_String( 4876 appendFormat_String(
4888 &text, " %s" close_Icon, isHover ? escape_Color(tmLinkText_ColorId) : ""); 4877 &text, " %s" close_Icon, isHover ? escape_Color(tmLinkText_ColorId) : "");
@@ -4911,6 +4900,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
4911 } 4900 }
4912 } 4901 }
4913 else if (isHover) { 4902 else if (isHover) {
4903 /* TODO: Make this a dynamic overlay, not part of the VisBuf content. */
4914 const iGmLinkId linkId = d->widget->hoverLink->linkId; 4904 const iGmLinkId linkId = d->widget->hoverLink->linkId;
4915 const iString * url = linkUrl_GmDocument(doc, linkId); 4905 const iString * url = linkUrl_GmDocument(doc, linkId);
4916 const int flags = linkFlags; 4906 const int flags = linkFlags;