bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#63731: [PATCH] Support Emoji Variation Sequence 16 (FE0F) where appr


From: Robert Pluim
Subject: bug#63731: [PATCH] Support Emoji Variation Sequence 16 (FE0F) where appropriate
Date: Mon, 05 Jun 2023 15:36:52 +0200

>>>>> On Mon, 05 Jun 2023 16:12:20 +0300, Eli Zaretskii <eliz@gnu.org> said:

    >> From: Robert Pluim <rpluim@gmail.com>
    >> Cc: 63731@debbugs.gnu.org,  steven@stebalien.com
    >> Date: Mon, 05 Jun 2023 15:08:08 +0200
    >> 
    >> >>>>> On Sat, 03 Jun 2023 08:36:59 +0300, Eli Zaretskii <eliz@gnu.org> 
said:
    >> 
    >> >> Sequence       Font             Result
    >> >> 23e9 fe0e      system           black box
    >> >> 23e9 fe0e      Symbola          correct text representation
    >> >> 23e9 fe0e      NotoEmoji        correct text representation
    >> >> 23e9 fe0e      NotoColorEmoji   blank
    >> >> 
    >> >> And on emacs-29, Symbola and NotoEmoji compose that sequence
    >> >> correctly. Now I just need to persuade emacs-30 to use one of them.
    >> 
    Eli> So you are saying that, in our default fontset, we should specify that
    Eli> #xFE0E should be displayed by Noto Emoji (with Symbola as fallback),
    Eli> and then make sure that font_range uses the same font for the likes of
    Eli> #x23E9?  IOW, specify a different font for VS-15 even though is script
    Eli> is 'emoji'?
    >> 
    >> Yes, that works (and we can remove VS-15 and VS-16 from the emoji
    >> script, so that theyʼll then be displayed via
    >> `glyphless-char-display-control' when theyʼre on their own).

    Eli> What about the rest of VS-nn? do they need to stay in 'emoji' script,
    Eli> and if so, why?

They were never in the 'emoji' script anyway.

    >> Thanks for the suggestion Eli, I was looking at it from the wrong
    >> direction.

    Eli> You are the one who did most of the footwork, so kudos to you.

    Eli> This is simple enough to install on emacs-29, I think?

The main change is in font.c, and looks like this. I think itʼs too
big for emacs-29 (breaking composition is very easy, itʼs entirely
possible Iʼve missed a few cases :-) )

diff --git a/src/font.c b/src/font.c
index e586277a5d3..30b088c818e 100644
--- a/src/font.c
+++ b/src/font.c
@@ -3633,10 +3633,14 @@ font_at (int c, ptrdiff_t pos, struct face *face, 
struct window *w,
 /* Check if CH is a codepoint for which we should attempt to use the
    emoji font, even if the codepoint itself has Emoji_Presentation =
    No.  Vauto_composition_emoji_eligible_codepoints is filled in for
-   us by admin/unidata/emoji-zwj.awk.  */
+   us by admin/unidata/emoji-zwj.awk.  We also check if there's a
+   VS-15 or VS-16 following CH, and select text/emoji presentation
+   respectively if so.  */
 static bool
-codepoint_is_emoji_eligible (int ch)
+codepoint_is_font_change_eligible (int ch, int next_c)
 {
+  if (next_c == 0xFE0E || next_c == 0xFE0F)
+    return true;
   if (EQ (CHAR_TABLE_REF (Vchar_script_table, ch), Qemoji))
     return true;
 
@@ -3690,21 +3694,43 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, 
ptrdiff_t *limit,
        }
       face = FACE_FROM_ID (f, face_id);
     }
-
-  /* If the composition was triggered by an emoji, use a character
-     from 'script-representative-chars', rather than the first
-     character in the string, to determine the font to use.  */
-  if (codepoint_is_emoji_eligible (ch))
+  int next_c = 0;
+  {
+    ptrdiff_t p = pos;
+    ptrdiff_t p_b = pos_byte;
+    int c;
+    c = (NILP (string)
+        ? fetch_char_advance_no_check (&p, &p_b)
+        : fetch_string_char_advance_no_check (string, &p, &p_b));
+    if (p < *limit)
+      {
+       c = (NILP (string)
+            ? fetch_char_advance_no_check (&p, &p_b)
+            : fetch_string_char_advance_no_check (string, &p, &p_b));
+       next_c = c;
+      }
+  }
+  if (codepoint_is_font_change_eligible (ch, next_c))
     {
-      Lisp_Object val = assq_no_quit (Qemoji, Vscript_representative_chars);
-      if (CONSP (val))
+      if (next_c == 0xFE0E)
        {
-         val = XCDR (val);
+         font_object = font_for_char (face, 0xFE0E, pos, string);
+       }
+      else
+       {
+         /* If the composition was triggered by an emoji, use a character
+            from 'script-representative-chars', rather than the first
+            character in the string, to determine the font to use.  */
+         Lisp_Object val = assq_no_quit (Qemoji, Vscript_representative_chars);
          if (CONSP (val))
-           val = XCAR (val);
-         else if (VECTORP (val))
-           val = AREF (val, 0);
-         font_object = font_for_char (face, XFIXNAT (val), pos, string);
+           {
+             val = XCDR (val);
+             if (CONSP (val))
+               val = XCAR (val);
+             else if (VECTORP (val))
+               val = AREF (val, 0);
+             font_object = font_for_char (face, XFIXNAT (val), pos, string);
+           }
        }
     }
 

Robert
-- 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]