From cd88f6de4be1f8eba1db038b371d769f584be53b Mon Sep 17 00:00:00 2001 From: YAMAMOTO Mitsuharu Date: Tue, 27 Sep 2022 09:20:58 +0900 Subject: [PATCH] Adjust zero-width grapheme clusters so they are displayed (Bug#50951) * 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 | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/composite.h | 1 + src/font.c | 1 + 3 files changed, 46 insertions(+) diff --git a/src/composite.c b/src/composite.c index 249d7587f61..0417bc866d4 100644 --- a/src/composite.c +++ b/src/composite.c @@ -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; diff --git a/src/composite.h b/src/composite.h index d77dd0d5062..8a6fd203d09 100644 --- a/src/composite.h +++ b/src/composite.h @@ -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 *, diff --git a/src/font.c b/src/font.c index 413cb381eeb..defbb5084b5 100644 --- a/src/font.c +++ b/src/font.c @@ -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: -- 2.39.2