diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-08 12:24:10 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-08 12:24:10 +0200 |
commit | 2fb1f5bed356520bc0b668f2a8ffef6c8d0318d2 (patch) | |
tree | 69f1511ff2e2baa2e45ba17ab6ed9372bc0b2077 /src | |
parent | 6f383d147fdcedd9626bfa3a80d4d5953eae398f (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.
Diffstat (limited to 'src')
-rw-r--r-- | src/gmdocument.c | 24 | ||||
-rw-r--r-- | src/gmdocument.h | 1 | ||||
-rw-r--r-- | src/ui/text.h | 7 |
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) | |||
40 | struct Impl_GmLink { | 40 | struct 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 | ||
74 | struct Impl_GmHeading { | 75 | struct 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 | } |
143 | iLocalDef iBool isDingbats_Char(iChar c) { | ||
144 | return c >= 0x2702 && c <= 0x27b0; | ||
145 | } | ||
146 | iLocalDef 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 | ||