summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-03-08 12:24:10 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-03-08 12:24:10 +0200
commit2fb1f5bed356520bc0b668f2a8ffef6c8d0318d2 (patch)
tree69f1511ff2e2baa2e45ba17ab6ed9372bc0b2077
parent6f383d147fdcedd9626bfa3a80d4d5953eae398f (diff)
Local Gemini links can use Emoji/symbol from label text
Instead of the default link icon, if a label starts with an Emoji or symbol, use that as the icon. This only works with local Gemini links so important information about link destination is not hidden.
-rw-r--r--src/gmdocument.c24
-rw-r--r--src/gmdocument.h1
-rw-r--r--src/ui/text.h7
3 files changed, 32 insertions, 0 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 0d008181..54b7ad56 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -40,6 +40,7 @@ iDeclareType(GmLink)
40struct Impl_GmLink { 40struct Impl_GmLink {
41 iString url; 41 iString url;
42 iRangecc urlRange; /* URL in the source */ 42 iRangecc urlRange; /* URL in the source */
43 iRangecc labelIcon; /* special icon defined in the label text */
43 iTime when; 44 iTime when;
44 int flags; 45 int flags;
45}; 46};
@@ -227,9 +228,24 @@ static iRangecc addLink_GmDocument_(iGmDocument *d, iRangecc line, iGmLinkId *li
227 *linkId = size_PtrArray(&d->links); /* index + 1 */ 228 *linkId = size_PtrArray(&d->links); /* index + 1 */
228 iRangecc desc = capturedRange_RegExpMatch(&m, 2); 229 iRangecc desc = capturedRange_RegExpMatch(&m, 2);
229 trim_Rangecc(&desc); 230 trim_Rangecc(&desc);
231 link->labelIcon = iNullRange;
230 if (!isEmpty_Range(&desc)) { 232 if (!isEmpty_Range(&desc)) {
231 line = desc; /* Just show the description. */ 233 line = desc; /* Just show the description. */
232 link->flags |= humanReadable_GmLinkFlag; 234 link->flags |= humanReadable_GmLinkFlag;
235 /* Check for a custom icon. */
236 if (link->flags & gemini_GmLinkFlag && ~link->flags & remote_GmLinkFlag) {
237 iChar icon = 0;
238 int len = 0;
239 if ((len = decodeBytes_MultibyteChar(desc.start, size_Range(&desc), &icon)) > 0) {
240 if (desc.start + len < desc.end && (isSymbol_Char(icon) || isEmoji_Char(icon)) &&
241 !isFitzpatrickType_Char(icon)) {
242 link->flags |= iconFromLabel_GmLinkFlag;
243 link->labelIcon = (iRangecc){ desc.start, desc.start + len };
244 line.start += len;
245 line.start = skipSpace_CStr(line.start);
246 }
247 }
248 }
233 } 249 }
234 else { 250 else {
235 line = capturedRange_RegExpMatch(&m, 1); /* Show the URL. */ 251 line = capturedRange_RegExpMatch(&m, 1); /* Show the URL. */
@@ -520,6 +536,10 @@ static void doLayout_GmDocument_(iGmDocument *d) {
520 : link->flags & mailto_GmLinkFlag ? envelope 536 : link->flags & mailto_GmLinkFlag ? envelope
521 : link->flags & remote_GmLinkFlag ? globe 537 : link->flags & remote_GmLinkFlag ? globe
522 : arrow); 538 : arrow);
539 /* Custom link icon is shown on local Gemini links only. */
540 if (!isEmpty_Range(&link->labelIcon)) {
541 icon.text = link->labelIcon;
542 }
523 icon.font = regular_FontId; 543 icon.font = regular_FontId;
524 if (link->flags & remote_GmLinkFlag) { 544 if (link->flags & remote_GmLinkFlag) {
525 icon.visBounds.pos.x -= gap_Text / 2; 545 icon.visBounds.pos.x -= gap_Text / 2;
@@ -1450,6 +1470,10 @@ enum iColorId linkColor_GmDocument(const iGmDocument *d, iGmLinkId linkId, enum
1450 if (isUnsupported) { 1470 if (isUnsupported) {
1451 return tmBadLink_ColorId; 1471 return tmBadLink_ColorId;
1452 } 1472 }
1473 if (link->flags & iconFromLabel_GmLinkFlag) {
1474 return link->flags & visited_GmLinkFlag ? tmLinkTextHover_ColorId
1475 : tmLinkText_ColorId;
1476 }
1453 if (link->flags & visited_GmLinkFlag) { 1477 if (link->flags & visited_GmLinkFlag) {
1454 return link->flags & www_GmLinkFlag ? tmHypertextLinkIconVisited_ColorId 1478 return link->flags & www_GmLinkFlag ? tmHypertextLinkIconVisited_ColorId
1455 : link->flags & gopherOrFinger_GmLinkFlag ? tmGopherLinkIconVisited_ColorId 1479 : link->flags & gopherOrFinger_GmLinkFlag ? tmGopherLinkIconVisited_ColorId
diff --git a/src/gmdocument.h b/src/gmdocument.h
index 16127ea3..92f62ba4 100644
--- a/src/gmdocument.h
+++ b/src/gmdocument.h
@@ -69,6 +69,7 @@ enum iGmLinkFlags {
69 visited_GmLinkFlag = iBit(14), /* in the history */ 69 visited_GmLinkFlag = iBit(14), /* in the history */
70 permanent_GmLinkFlag = iBit(15), /* content cannot be dismissed; media link */ 70 permanent_GmLinkFlag = iBit(15), /* content cannot be dismissed; media link */
71 query_GmLinkFlag = iBit(16), /* Gopher query link */ 71 query_GmLinkFlag = iBit(16), /* Gopher query link */
72 iconFromLabel_GmLinkFlag = iBit(17), /* use an Emoji/special character from label */
72}; 73};
73 74
74struct Impl_GmHeading { 75struct Impl_GmHeading {
diff --git a/src/ui/text.h b/src/ui/text.h
index acce286b..d57c2c62 100644
--- a/src/ui/text.h
+++ b/src/ui/text.h
@@ -140,6 +140,13 @@ iLocalDef iBool isEmoji_Char(iChar c) {
140 return (c >= 0x1f300 && c < 0x1f700) || (c >= 0x1f7e0 && c <= 0x1f7eb) || 140 return (c >= 0x1f300 && c < 0x1f700) || (c >= 0x1f7e0 && c <= 0x1f7eb) ||
141 (c >= 0x1f900 && c <= 0x1f9ff); 141 (c >= 0x1f900 && c <= 0x1f9ff);
142} 142}
143iLocalDef iBool isDingbats_Char(iChar c) {
144 return c >= 0x2702 && c <= 0x27b0;
145}
146iLocalDef iBool isSymbol_Char(iChar c) {
147 return (c == 0x2218 || c == 0x2219) || (c >= 0x1f680 && c <= 0x1f6c0) ||
148 (c >= 0x2300 && c <= 0x26ff);
149}
143 150
144#define emojiVariationSelector_Char ((iChar) 0xfe0f) 151#define emojiVariationSelector_Char ((iChar) 0xfe0f)
145 152