From c9f3cc464c4f06cc31c2b42e5c305a7fd7ae5879 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 27 Aug 2021 10:29:13 -0400 Subject: Try harder to find positions in clusters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Try to find a single non-mark glyph in a multi-glyph cluster to use its ligature caret information. This fixes situations in Arabic where you can have marks on top of ligatures, e.g. ﻉﻭ. --- pango/glyphstring.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/pango/glyphstring.c b/pango/glyphstring.c index cda4cf40..30d68220 100644 --- a/pango/glyphstring.c +++ b/pango/glyphstring.c @@ -520,17 +520,46 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs, * with an m-n situation, where LigatureCaretList is * not going to help. Just give up and do the simple thing. */ - if (cluster_offset > 0 && cluster_offset < cluster_chars && - start_glyph_pos == end_glyph_pos) + if (cluster_offset > 0 && cluster_offset < cluster_chars) { hb_font_t *hb_font; hb_position_t caret; unsigned int caret_count = 1; + int glyph_pos; hb_font = pango_font_get_hb_font (analysis->font); + + if (start_glyph_pos == end_glyph_pos) + glyph_pos = start_glyph_pos; + else + { + hb_face_t *hb_face; + + hb_face = hb_font_get_face (hb_font); + + glyph_pos = -1; + for (i = start_glyph_pos; i <= end_glyph_pos; i++) + { + if (hb_ot_layout_get_glyph_class (hb_face, glyphs->glyphs[i].glyph) != HB_OT_LAYOUT_GLYPH_CLASS_MARK) + { + if (glyph_pos != -1) + { + /* multiple non-mark glyphs in cluster, giving up */ + goto fallback; + } + glyph_pos = i; + } + } + if (glyph_pos == -1) + { + /* no non-mark glyph in a multi-glyph cluster, giving up */ + goto fallback; + } + } + hb_ot_layout_get_ligature_carets (hb_font, (analysis->level % 2) ? HB_DIRECTION_RTL : HB_DIRECTION_LTR, - glyphs->glyphs[start_glyph_pos].glyph, + glyphs->glyphs[glyph_pos].glyph, cluster_offset - 1, &caret_count, &caret); if (caret_count > 0) { -- cgit v1.2.1