Package: emacs;
Reported by: Mike FABIAN <mfabian <at> redhat.com>
Date: Wed, 26 Feb 2020 14:30:03 UTC
Severity: normal
Found in version 28.0.50
Fixed in version 28.1
Done: Lars Ingebrigtsen <larsi <at> gnus.org>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Robert Pluim <rpluim <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: rgm <at> gnu.org, 39799 <at> debbugs.gnu.org, mfabian <at> redhat.com Subject: bug#39799: 28.0.50; Most emoji sequences don’t render correctly Date: Tue, 21 Sep 2021 19:43:05 +0200
>>>>> On Tue, 21 Sep 2021 14:31:10 +0300, Eli Zaretskii <eliz <at> gnu.org> said: >> Date: Tue, 21 Sep 2021 13:54:02 +0300 >> From: Eli Zaretskii <eliz <at> gnu.org> >> Cc: rgm <at> gnu.org, 39799 <at> debbugs.gnu.org, mfabian <at> redhat.com >> >> > I think this means you'd have to add the Variation Selectors to the >> > emoji script >> >> Yes, of course. Eli> Btw, we could recognize VS-16 explicitly in font_range, and avoid Eli> putting them into the 'emoji' script. But that would be too kludgey, Eli> I guess. FE0F is already in script-representative-chars for emoji :-) Eli, is this the kind of thing you were thinking of? Seems to work so far (with a small addition to blocks.awk). We'll need to find a better name for the new arg than 'trigger' though. diff --git a/src/composite.c b/src/composite.c index e97f8e2b4c..85485e9358 100644 --- a/src/composite.c +++ b/src/composite.c @@ -882,14 +882,15 @@ fill_gstring_body (Lisp_Object gstring) /* Try to compose the characters at CHARPOS according to composition rule RULE ([PATTERN PREV-CHARS FUNC]). LIMIT limits the characters to compose. STRING, if not nil, is a target string. WIN is a - window where the characters are being displayed. If characters are + window where the characters are being displayed. TRIGGER is the + character that triggered the composition check. If characters are successfully composed, return the composition as a glyph-string object. Otherwise return nil. */ static Lisp_Object autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t limit, struct window *win, struct face *face, - Lisp_Object string, Lisp_Object direction) + Lisp_Object string, Lisp_Object direction, int trigger) { ptrdiff_t count = SPECPDL_INDEX (); Lisp_Object pos = make_fixnum (charpos); @@ -920,7 +921,7 @@ autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos, struct frame *f = XFRAME (font_object); if (FRAME_WINDOW_P (f)) { - font_object = font_range (charpos, bytepos, &to, win, face, string); + font_object = font_range (charpos, bytepos, &to, win, face, string, trigger); if (! FONT_OBJECT_P (font_object) || (! NILP (re) && to < limit @@ -1269,7 +1270,7 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos, if (XFIXNAT (AREF (elt, 1)) != cmp_it->lookback) goto no_composition; lgstring = autocmp_chars (elt, charpos, bytepos, endpos, - w, face, string, direction); + w, face, string, direction, cmp_it->ch); if (composition_gstring_p (lgstring)) break; lgstring = Qnil; @@ -1307,7 +1308,7 @@ composition_reseat_it (struct composition_it *cmp_it, ptrdiff_t charpos, else direction = QR2L; lgstring = autocmp_chars (elt, cpos, bpos, charpos + 1, w, face, - string, direction); + string, direction, cmp_it->ch); if (! composition_gstring_p (lgstring) || cpos + LGSTRING_CHAR_LEN (lgstring) - 1 != charpos) /* Composition failed or didn't cover the current @@ -1676,7 +1677,7 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim, for (check = cur; check_pos < check.pos; ) BACKWARD_CHAR (check, stop); *gstring = autocmp_chars (elt, check.pos, check.pos_byte, - tail, w, NULL, string, Qnil); + tail, w, NULL, string, Qnil, c); need_adjustment = 1; if (NILP (*gstring)) { diff --git a/src/font.c b/src/font.c index e043ef8d01..74a1214b38 100644 --- a/src/font.c +++ b/src/font.c @@ -3866,6 +3866,9 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, If STRING is not nil, it is the string to check instead of the current buffer. In that case, FACE must be not NULL. + TRIGGER is the character that actually caused the composition + process to start, it may be different from the character at POS. + The return value is the font-object for the character at POS. *LIMIT is set to the position where that font can't be used. @@ -3873,15 +3876,16 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, Lisp_Object font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, - struct window *w, struct face *face, Lisp_Object string) + struct window *w, struct face *face, Lisp_Object string, + int trigger) { ptrdiff_t ignore; int c; Lisp_Object font_object = Qnil; + struct frame *f = XFRAME (w->frame); if (!face) { - struct frame *f = XFRAME (w->frame); int face_id; if (NILP (string)) @@ -3912,6 +3916,23 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, continue; if (NILP (font_object)) { + if (EQ (CHAR_TABLE_REF (Vchar_script_table, trigger), + Qemoji)) + { + Lisp_Object val = assq_no_quit (Qemoji, Vscript_representative_chars); + if (CONSP (val)) + { + int face_id; + val = XCDR (val); + if (CONSP (val)) + val = XCAR (val); + else if (VECTORP (val)) + val = AREF (val, 0); + c = XFIXNAT (val); + face_id = FACE_FOR_CHAR (f, face, c, pos - 1, string); + face = FACE_FROM_ID (f, face_id); + } + } font_object = font_for_char (face, c, pos - 1, string); if (NILP (font_object)) return Qnil; @@ -5423,6 +5444,7 @@ syms_of_font (void) DEFSYM (Qiso8859_1, "iso8859-1"); DEFSYM (Qiso10646_1, "iso10646-1"); DEFSYM (Qunicode_bmp, "unicode-bmp"); + DEFSYM (Qemoji, "emoji"); /* Symbols representing keys of font extra info. */ DEFSYM (QCotf, ":otf"); diff --git a/src/font.h b/src/font.h index d3e1530642..1da72cca07 100644 --- a/src/font.h +++ b/src/font.h @@ -885,7 +885,7 @@ valid_font_driver (struct font_driver const *d) extern Lisp_Object font_update_drivers (struct frame *f, Lisp_Object list); extern Lisp_Object font_range (ptrdiff_t, ptrdiff_t, ptrdiff_t *, struct window *, struct face *, - Lisp_Object); + Lisp_Object, int); extern void font_fill_lglyph_metrics (Lisp_Object, struct font *, unsigned int); extern Lisp_Object font_put_extra (Lisp_Object font, Lisp_Object prop,
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.