From ea964864a66828ce2457e44c4c670160d5879ec6 Mon Sep 17 00:00:00 2001 From: Kenichi Handa Date: Sat, 15 Sep 2012 11:24:26 +0900 Subject: [PATCH] font.c (Ffont_shape_gstring): Don't adjust grapheme cluster here, but just check the validity of glyphs in the glyph-string. --- src/ChangeLog | 5 ++++ src/font.c | 70 +++++++++++++++++++++++++++------------------------ 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 5cda8241916..e598d4d465a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2012-09-15 Kenichi Handa + + * font.c (Ffont_shape_gstring): Don't adjust grapheme cluster + here, but just check the validity of glyphs in the glyph-string. + 2012-09-14 Martin Rudalics * xdisp.c (Fformat_mode_line): Unconditionally save/restore diff --git a/src/font.c b/src/font.c index 49a09bced28..ccbeb9956f4 100644 --- a/src/font.c +++ b/src/font.c @@ -4296,7 +4296,10 @@ to get the correct visual image of character sequences set in the header of the glyph-string. If the shaping was successful, the value is GSTRING itself or a newly -created glyph-string. Otherwise, the value is nil. */) +created glyph-string. Otherwise, the value is nil. + +See the documentation of `composition-get-gstring' for the format of +GSTRING. */) (Lisp_Object gstring) { struct font *font; @@ -4327,44 +4330,45 @@ created glyph-string. Otherwise, the value is nil. */) if (XINT (n) < LGSTRING_GLYPH_LEN (gstring)) LGSTRING_SET_GLYPH (gstring, XINT (n), Qnil); + /* Check FROM_IDX and TO_IDX of each GLYPH in GSTRING to assure that + GLYPHS covers all characters in GSTRING. More formally, provided + that NCHARS is the number of characters in GSTRING, N is the + number of glyphs, and GLYPHS[i] is the ith glyph, FROM_IDX and + TO_IDX of each glyph must satisfy these conditions: + + GLYPHS[0].FROM_IDX == 0 + GLYPHS[i].FROM_IDX <= GLYPHS[i].TO_IDX + if (GLYPHS[i].FROM_IDX == GLYPHS[i-1].FROM_IDX) + ;; GLYPHS[i] and GLYPHS[i-1] belongs to the same grapheme cluster + GLYPHS[i].TO_IDX == GLYPHS[i-1].TO_IDX + else + ;; Be sure to cover all characters. + GLYPHS[i].FROM_IDX == GLYPHS[i-1].TO_IDX + 1 + GLYPHS[N-1].TO_IDX == NCHARS - 1 */ glyph = LGSTRING_GLYPH (gstring, 0); from = LGLYPH_FROM (glyph); to = LGLYPH_TO (glyph); - for (i = 1, j = 0; i < LGSTRING_GLYPH_LEN (gstring); i++) + if (from != 0 || to < from) + goto shaper_error; + for (i = 1; i < LGSTRING_GLYPH_LEN (gstring); i++) { - Lisp_Object this = LGSTRING_GLYPH (gstring, i); - - if (NILP (this)) + glyph = LGSTRING_GLYPH (gstring, i); + if (NILP (glyph)) break; - if (NILP (LGLYPH_ADJUSTMENT (this))) - { - if (j < i - 1) - for (; j < i; j++) - { - glyph = LGSTRING_GLYPH (gstring, j); - LGLYPH_SET_FROM (glyph, from); - LGLYPH_SET_TO (glyph, to); - } - from = LGLYPH_FROM (this); - to = LGLYPH_TO (this); - j = i; - } - else - { - if (from > LGLYPH_FROM (this)) - from = LGLYPH_FROM (this); - if (to < LGLYPH_TO (this)) - to = LGLYPH_TO (this); - } - } - if (j < i - 1) - for (; j < i; j++) - { - glyph = LGSTRING_GLYPH (gstring, j); - LGLYPH_SET_FROM (glyph, from); - LGLYPH_SET_TO (glyph, to); - } + if (! (LGLYPH_FROM (glyph) <= LGLYPH_TO (glyph) + && (LGLYPH_FROM (glyph) == from + ? LGLYPH_TO (glyph) == to + : LGLYPH_FROM (glyph) == to + 1))) + goto shaper_error; + from = LGLYPH_FROM (glyph); + to = LGLYPH_TO (glyph); + } + if (to != LGSTRING_CHAR_LEN (gstring) - 1) + goto shaper_error; return composition_gstring_put_cache (gstring, XINT (n)); + + shaper_error: + return Qnil; } DEFUN ("font-variation-glyphs", Ffont_variation_glyphs, Sfont_variation_glyphs, -- 2.39.2