diff options
| author | Robert Pluim | 2021-10-18 11:51:10 +0200 |
|---|---|---|
| committer | Robert Pluim | 2021-10-19 14:40:26 +0200 |
| commit | 9bd2f59db608def1b588b03eff846d3fe8a7fa00 (patch) | |
| tree | 39a768d3990701aef8461a40f7c595c424382766 | |
| parent | e55e2d4a110447540db6bbdb9cb1c12313b4b8ad (diff) | |
| download | emacs-9bd2f59db608def1b588b03eff846d3fe8a7fa00.tar.gz emacs-9bd2f59db608def1b588b03eff846d3fe8a7fa00.zip | |
Handle VS-16 correctly for non-emoji codepoints
* admin/unidata/blocks.awk: Remove emoji overrides for codepoints with
Emoji_Presentation = No, they're no longer necessary.
* lisp/composite.el: Remove #xFE0F (VS-16) from the range handled by
`compose-gstring-for-variation-glyph' so it can be handled by
`font_range'.
* src/composite.c (syms_of_composite): New variable
`auto-composition-emoji-eligible-codepoints'.
* admin/unidata/emoji-zwj.awk: Generate value for
`auto-composition-emoji-eligible-codepoints'. Add
`composition-function-table' entries for 'codepoint + U+FE0F' for
them.
* src/font.c (codepoint_is_emoji_eligible): New function to check if
we should try to use the emoji font for a codepoint.
(font_range): Use it.
| -rwxr-xr-x | admin/unidata/blocks.awk | 26 | ||||
| -rw-r--r-- | admin/unidata/emoji-zwj.awk | 41 | ||||
| -rw-r--r-- | lisp/composite.el | 9 | ||||
| -rw-r--r-- | src/composite.c | 11 | ||||
| -rw-r--r-- | src/font.c | 20 |
5 files changed, 78 insertions, 29 deletions
diff --git a/admin/unidata/blocks.awk b/admin/unidata/blocks.awk index 96b0413875d..314ac3e9394 100755 --- a/admin/unidata/blocks.awk +++ b/admin/unidata/blocks.awk | |||
| @@ -221,31 +221,9 @@ FILENAME ~ "emoji-data.txt" && /^[0-9A-F].*; Emoji_Presentation / { | |||
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | END { | 223 | END { |
| 224 | ## These codepoints have Emoji_Presentation = No, but they are | ||
| 225 | ## used in emoji-sequences.txt and emoji-zwj-sequences.txt (with a | ||
| 226 | ## Variation Selector), so force them into the emoji script so | ||
| 227 | ## they will get composed correctly. FIXME: delete this when we | ||
| 228 | ## can change the font used for a codepoint based on whether it's | ||
| 229 | ## followed by a VS (usually VS-16) | ||
| 230 | idx = 0 | 224 | idx = 0 |
| 231 | override_start[idx] = "1F3CB" | 225 | # ## These are here so that font_range can choose Emoji presentation |
| 232 | override_end[idx] = "1F3CC" | 226 | # ## for the preceding codepoint when it encounters a VS |
| 233 | idx++ | ||
| 234 | override_start[idx] = "1F3F3" | ||
| 235 | override_end[idx] = "1F3F4" | ||
| 236 | idx++ | ||
| 237 | override_start[idx] = "1F441" | ||
| 238 | override_end[idx] = "1F441" | ||
| 239 | idx++ | ||
| 240 | override_start[idx] = "1F574" | ||
| 241 | override_end[idx] = "1F575" | ||
| 242 | idx++ | ||
| 243 | override_start[idx] = "1F590" | ||
| 244 | override_end[idx] = "1F590" | ||
| 245 | |||
| 246 | ## These are here so that font_range can choose Emoji presentation | ||
| 247 | ## for the preceding codepoint when it encounters a VS | ||
| 248 | idx++ | ||
| 249 | override_start[idx] = "FE00" | 227 | override_start[idx] = "FE00" |
| 250 | override_end[idx] = "FE0F" | 228 | override_end[idx] = "FE0F" |
| 251 | 229 | ||
diff --git a/admin/unidata/emoji-zwj.awk b/admin/unidata/emoji-zwj.awk index 5aca157cbd4..d4e2944ca34 100644 --- a/admin/unidata/emoji-zwj.awk +++ b/admin/unidata/emoji-zwj.awk | |||
| @@ -64,6 +64,44 @@ END { | |||
| 64 | print ";;; emoji-zwj.el --- emoji zwj character composition table -*- lexical-binding:t -*-" | 64 | print ";;; emoji-zwj.el --- emoji zwj character composition table -*- lexical-binding:t -*-" |
| 65 | print ";;; Automatically generated from admin/unidata/emoji-{zwj-,}sequences.txt" | 65 | print ";;; Automatically generated from admin/unidata/emoji-{zwj-,}sequences.txt" |
| 66 | print "(eval-when-compile (require 'regexp-opt))" | 66 | print "(eval-when-compile (require 'regexp-opt))" |
| 67 | |||
| 68 | # The following codepoints are not emoji, but they are part of | ||
| 69 | # emoji sequences. We have code in font.c:font_range that will | ||
| 70 | # try to display them with the emoji font anyway. | ||
| 71 | |||
| 72 | trigger_codepoints[1] = "261D" | ||
| 73 | trigger_codepoints[2] = "26F9" | ||
| 74 | trigger_codepoints[3] = "270C" | ||
| 75 | trigger_codepoints[4] = "270D" | ||
| 76 | trigger_codepoints[5] = "2764" | ||
| 77 | trigger_codepoints[6] = "1F3CB" | ||
| 78 | trigger_codepoints[7] = "1F3CC" | ||
| 79 | trigger_codepoints[8] = "1F3F3" | ||
| 80 | trigger_codepoints[9] = "1F3F4" | ||
| 81 | trigger_codepoints[10] = "1F441" | ||
| 82 | trigger_codepoints[11] = "1F574" | ||
| 83 | trigger_codepoints[12] = "1F575" | ||
| 84 | trigger_codepoints[13] = "1F590" | ||
| 85 | |||
| 86 | printf "(setq auto-composition-emoji-eligible-codepoints\n" | ||
| 87 | printf "'(" | ||
| 88 | |||
| 89 | for (trig in trigger_codepoints) | ||
| 90 | { | ||
| 91 | printf("\n?\\N{U+%s}", trigger_codepoints[trig]) | ||
| 92 | } | ||
| 93 | printf "\n))\n\n" | ||
| 94 | |||
| 95 | # We add entries for 'codepoint U+FE0F' here to ensure that the | ||
| 96 | # code in font_range is triggered. | ||
| 97 | |||
| 98 | for (trig in trigger_codepoints) | ||
| 99 | { | ||
| 100 | codepoint = trigger_codepoints[trig] | ||
| 101 | c = sprintf("\\N{U+%s}", codepoint) | ||
| 102 | vec[codepoint] = vec[codepoint] "\n\"" c "\\N{U+FE0F}\"" | ||
| 103 | } | ||
| 104 | |||
| 67 | print "(dolist (elt `(" | 105 | print "(dolist (elt `(" |
| 68 | 106 | ||
| 69 | for (elt in ch) | 107 | for (elt in ch) |
| @@ -98,6 +136,5 @@ END { | |||
| 98 | print " 0" | 136 | print " 0" |
| 99 | print " 'compose-gstring-for-graphic))))" | 137 | print " 'compose-gstring-for-graphic))))" |
| 100 | 138 | ||
| 101 | print "\n" | 139 | printf "\n(provide 'emoji-zwj)" |
| 102 | print "(provide 'emoji-zwj)" | ||
| 103 | } | 140 | } |
diff --git a/lisp/composite.el b/lisp/composite.el index 859253ec7e2..99f528a0779 100644 --- a/lisp/composite.el +++ b/lisp/composite.el | |||
| @@ -834,8 +834,15 @@ and the second is a glyph for a variation selector." | |||
| 834 | (lgstring-set-glyph gstring 1 nil) | 834 | (lgstring-set-glyph gstring 1 nil) |
| 835 | (throw 'tag gstring))))))) | 835 | (throw 'tag gstring))))))) |
| 836 | 836 | ||
| 837 | ;; We explicitly don't handle #xFE0F (VS-16) here, because that's | ||
| 838 | ;; taken care of by font_range in font.c, which will check for an | ||
| 839 | ;; emoji font for codepoints used in compositions even if they're not | ||
| 840 | ;; emoji themselves, and thus choose the Emoji presentation for them | ||
| 841 | ;; when followed by VS-16. VS-15 *is* handled here, because if it's | ||
| 842 | ;; handled in font_range, we end up choosing the Emoji presentation | ||
| 843 | ;; rather than the Text presentation. | ||
| 837 | (let ((elt '([".." 1 compose-gstring-for-variation-glyph]))) | 844 | (let ((elt '([".." 1 compose-gstring-for-variation-glyph]))) |
| 838 | (set-char-table-range composition-function-table '(#xFE00 . #xFE0F) elt) | 845 | (set-char-table-range composition-function-table '(#xFE00 . #xFE0E) elt) |
| 839 | (set-char-table-range composition-function-table '(#xE0100 . #xE01EF) elt)) | 846 | (set-char-table-range composition-function-table '(#xE0100 . #xE01EF) elt)) |
| 840 | 847 | ||
| 841 | (defun auto-compose-chars (func from to font-object string direction) | 848 | (defun auto-compose-chars (func from to font-object string direction) |
diff --git a/src/composite.c b/src/composite.c index f456e7a835d..c170805d9dd 100644 --- a/src/composite.c +++ b/src/composite.c | |||
| @@ -2124,6 +2124,17 @@ GSTRING, or modify GSTRING itself and return it. | |||
| 2124 | See also the documentation of `auto-composition-mode'. */); | 2124 | See also the documentation of `auto-composition-mode'. */); |
| 2125 | Vcomposition_function_table = Fmake_char_table (Qnil, Qnil); | 2125 | Vcomposition_function_table = Fmake_char_table (Qnil, Qnil); |
| 2126 | 2126 | ||
| 2127 | DEFVAR_LISP ("auto-composition-emoji-eligible-codepoints", Vauto_composition_emoji_eligible_codepoints, | ||
| 2128 | doc: /* List of codepoints for which auto-composition will check for an emoji font. | ||
| 2129 | |||
| 2130 | These are codepoints which have Emoji_Presentation = No, and thus by | ||
| 2131 | default are not displayed as emoji. In certain circumstances, such as | ||
| 2132 | when followed by U+FE0F (VS-16) the emoji font should be used for | ||
| 2133 | them anyway. | ||
| 2134 | |||
| 2135 | This list is auto-generated, you should not need to modify it. */); | ||
| 2136 | Vauto_composition_emoji_eligible_codepoints = Qnil; | ||
| 2137 | |||
| 2127 | defsubr (&Scompose_region_internal); | 2138 | defsubr (&Scompose_region_internal); |
| 2128 | defsubr (&Scompose_string_internal); | 2139 | defsubr (&Scompose_string_internal); |
| 2129 | defsubr (&Sfind_composition_internal); | 2140 | defsubr (&Sfind_composition_internal); |
diff --git a/src/font.c b/src/font.c index 83f0f8296ad..6cd4a6b5c11 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -3860,6 +3860,23 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, | |||
| 3860 | 3860 | ||
| 3861 | #ifdef HAVE_WINDOW_SYSTEM | 3861 | #ifdef HAVE_WINDOW_SYSTEM |
| 3862 | 3862 | ||
| 3863 | /* Check if CH is a codepoint for which we should attempt to use the | ||
| 3864 | emoji font, even if the codepoint itself has Emoji_Presentation = | ||
| 3865 | No. Vauto_composition_emoji_eligible_codepoints is filled in for | ||
| 3866 | us by admin/unidata/emoji-zwj.awk. */ | ||
| 3867 | static bool | ||
| 3868 | codepoint_is_emoji_eligible (int ch) | ||
| 3869 | { | ||
| 3870 | if (EQ (CHAR_TABLE_REF (Vchar_script_table, ch), Qemoji)) | ||
| 3871 | return true; | ||
| 3872 | |||
| 3873 | if (! NILP (Fmemq (make_fixnum (ch), | ||
| 3874 | Vauto_composition_emoji_eligible_codepoints))) | ||
| 3875 | return true; | ||
| 3876 | |||
| 3877 | return false; | ||
| 3878 | } | ||
| 3879 | |||
| 3863 | /* Check how many characters after character/byte position POS/POS_BYTE | 3880 | /* Check how many characters after character/byte position POS/POS_BYTE |
| 3864 | (at most to *LIMIT) can be displayed by the same font in the window W. | 3881 | (at most to *LIMIT) can be displayed by the same font in the window W. |
| 3865 | FACE, if non-NULL, is the face selected for the character at POS. | 3882 | FACE, if non-NULL, is the face selected for the character at POS. |
| @@ -3907,8 +3924,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, | |||
| 3907 | /* If the composition was triggered by an emoji, use a character | 3924 | /* If the composition was triggered by an emoji, use a character |
| 3908 | from 'script-representative-chars', rather than the first | 3925 | from 'script-representative-chars', rather than the first |
| 3909 | character in the string, to determine the font to use. */ | 3926 | character in the string, to determine the font to use. */ |
| 3910 | if (EQ (CHAR_TABLE_REF (Vchar_script_table, ch), | 3927 | if (codepoint_is_emoji_eligible (ch)) |
| 3911 | Qemoji)) | ||
| 3912 | { | 3928 | { |
| 3913 | Lisp_Object val = assq_no_quit (Qemoji, Vscript_representative_chars); | 3929 | Lisp_Object val = assq_no_quit (Qemoji, Vscript_representative_chars); |
| 3914 | if (CONSP (val)) | 3930 | if (CONSP (val)) |