]> git.eshelyaron.com Git - emacs.git/commitdiff
Adjust zero-width grapheme clusters so they are displayed (Bug#50951)
authorYAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
Tue, 27 Sep 2022 00:20:58 +0000 (09:20 +0900)
committerYAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
Tue, 27 Sep 2022 00:22:00 +0000 (09:22 +0900)
* src/composite.c (composition_gstring_adjust_zero_width): New function.
* src/composite.h: Declare it.
* src/font.c (Ffont_shape_gstring): Use it before putting gstring to cache.

src/composite.c
src/composite.h
src/font.c

index 249d7587f6151125b872dcf5f12c7dc9391fccc2..0417bc866d488fd0f52c8097a9cd5dbf389eec9a 100644 (file)
@@ -800,6 +800,50 @@ composition_gstring_width (Lisp_Object gstring, ptrdiff_t from, ptrdiff_t to,
   return width;
 }
 
+/* Adjust the width of each grapheme cluster of GSTRING because
+   zero-width grapheme clusters are not displayed.  If the width is
+   zero, then the width of the last glyph in the cluster is
+   incremented.  */
+
+void
+composition_gstring_adjust_zero_width (Lisp_Object gstring)
+{
+  ptrdiff_t from = 0;
+  int width = 0;
+
+  for (ptrdiff_t i = 0; ; i++)
+    {
+      Lisp_Object glyph;
+
+      if (i == LGSTRING_GLYPH_LEN (gstring)
+         || (glyph = LGSTRING_GLYPH (gstring, i),
+             (NILP (glyph) || from != LGLYPH_FROM (glyph))))
+       {
+         eassert (i > 0);
+         Lisp_Object last = LGSTRING_GLYPH (gstring, i - 1);
+
+         if (width == 0)
+           {
+             if (NILP (LGLYPH_ADJUSTMENT (last)))
+               LGLYPH_SET_ADJUSTMENT (last,
+                                      CALLN (Fvector,
+                                             make_fixnum (0), make_fixnum (0),
+                                             make_fixnum (LGLYPH_WIDTH (last)
+                                                          + 1)));
+             else
+               ASET (LGLYPH_ADJUSTMENT (last), 2,
+                     make_fixnum (LGLYPH_WADJUST (last) + 1));
+           }
+         if (i == LGSTRING_GLYPH_LEN (gstring) || NILP (glyph))
+           break;
+         from = LGLYPH_FROM (glyph);
+         width = 0;
+       }
+      width += (NILP (LGLYPH_ADJUSTMENT (glyph))
+               ? LGLYPH_WIDTH (glyph) : LGLYPH_WADJUST (glyph));
+    }
+}
+
 
 static Lisp_Object gstring_work;
 static Lisp_Object gstring_work_headers;
index d77dd0d5062109cab3b8c309aa083a88d288544d..8a6fd203d092efad89e78c13d8bde8c50ab1312f 100644 (file)
@@ -340,6 +340,7 @@ extern Lisp_Object composition_gstring_from_id (ptrdiff_t);
 extern bool composition_gstring_p (Lisp_Object);
 extern int composition_gstring_width (Lisp_Object, ptrdiff_t, ptrdiff_t,
                                       struct font_metrics *);
+extern void composition_gstring_adjust_zero_width (Lisp_Object);
 
 extern bool find_automatic_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t,
                                        ptrdiff_t *, ptrdiff_t *,
index 413cb381eeb4994da23f7bef5f85f7e28bf875f1..defbb5084b502885472153701218297b72563d62 100644 (file)
@@ -4678,6 +4678,7 @@ GSTRING.  */)
       from = LGLYPH_FROM (glyph);
       to = LGLYPH_TO (glyph);
     }
+  composition_gstring_adjust_zero_width (gstring);
   return composition_gstring_put_cache (gstring, XFIXNUM (n));
 
  shaper_error: