[pango/more-rtl-cluster-fixes] Try harder to disect clusters




commit 50f3835df46710a4532c42e1c39ec599718d49d0
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Aug 27 23:54:59 2021 -0400

    Try harder to disect clusters
    
    We need to take into account whether the characters
    we are counting are actually cursor positions, else
    we are bound to look for more carets than the font
    has available, sometimes.

 pango/glyphstring.c | 49 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 34 insertions(+), 15 deletions(-)
---
diff --git a/pango/glyphstring.c b/pango/glyphstring.c
index 30d68220..11eeffbf 100644
--- a/pango/glyphstring.c
+++ b/pango/glyphstring.c
@@ -404,6 +404,9 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
 
   const char *p;
 
+  int attrs_len;
+  PangoLogAttr *attrs = NULL;
+
   g_return_if_fail (glyphs != NULL);
   g_return_if_fail (length >= 0);
   g_return_if_fail (length == 0 || text != NULL);
@@ -495,10 +498,20 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
 
   /* Calculate offset of character within cluster */
 
-  for (p = text + start_index;
+  if (g_utf8_next_char (text + start_index) != text + end_index)
+    {
+      /* FIXME: should allow log attrs to be passed in */
+      attrs_len = g_utf8_strlen (text, length) + 1;
+      attrs = g_new0 (PangoLogAttr, attrs_len + 1);
+      pango_default_break (text, length, analysis, attrs, attrs_len);
+    }
+
+  for (p = text + start_index, i = g_utf8_pointer_to_offset (text, text + start_index);
        p < text + end_index;
-       p = g_utf8_next_char (p))
+       p = g_utf8_next_char (p), i++)
     {
+      if (!attrs[i].is_cursor_position)
+        continue;
       if (p < text + index)
         cluster_offset++;
       cluster_chars++;
@@ -526,6 +539,7 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
       hb_position_t caret;
       unsigned int caret_count = 1;
       int glyph_pos;
+      int num_carets;
 
       hb_font = pango_font_get_hb_font (analysis->font);
 
@@ -544,7 +558,7 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
                 {
                   if (glyph_pos != -1)
                     {
-                      /* multiple non-mark glyphs in cluster, giving up */
+                      g_print ("multiple non-mark glyphs in cluster, giving up\n");
                       goto fallback;
                     }
                   glyph_pos = i;
@@ -552,24 +566,29 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
             }
           if (glyph_pos == -1)
             {
-              /* no non-mark glyph in a multi-glyph cluster, giving up */
+              g_print ("no non-mark glyph in a multi-glyph cluster, giving up\n");
               goto fallback;
             }
         }
 
-      hb_ot_layout_get_ligature_carets (hb_font,
-                                        (analysis->level % 2) ? HB_DIRECTION_RTL : HB_DIRECTION_LTR,
-                                        glyphs->glyphs[glyph_pos].glyph,
-                                        cluster_offset - 1, &caret_count, &caret);
-      if (caret_count > 0)
+      num_carets = hb_ot_layout_get_ligature_carets (hb_font,
+                                                     (analysis->level % 2) ? HB_DIRECTION_RTL : 
HB_DIRECTION_LTR,
+                                                      glyphs->glyphs[glyph_pos].glyph,
+                                                      cluster_offset - 1, &caret_count, &caret);
+      if (caret_count == 0)
         {
-          if (analysis->level % 2) /* Right to left */
-            *x_pos = end_xpos + caret;
-          else
-            *x_pos = start_xpos + caret;
-          *x_pos += glyphs->glyphs[glyph_pos].geometry.x_offset;
-          return;
+          g_print ("no ligature caret information found for glyph %d, caret %d / %d. font has %d ligature 
carets\n", glyphs->glyphs[glyph_pos].glyph, cluster_offset - 1, cluster_chars, num_carets);
+          goto fallback;
         }
+
+      g_print ("using ligature caret information for glyph %d, caret %d / %d. font has %d ligature 
carets\n", glyphs->glyphs[glyph_pos].glyph, cluster_offset - 1, cluster_chars, num_carets);
+
+      if (analysis->level % 2) /* Right to left */
+        *x_pos = end_xpos + caret;
+      else
+        *x_pos = start_xpos + caret;
+      *x_pos += glyphs->glyphs[glyph_pos].geometry.x_offset;
+      return;
     }
 
 fallback:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]