[pango/ligature-carets] wip: Use ligature caret lists




commit 2868ec82f063c925f99ba9efce282bafc304f9d9
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Aug 25 14:37:24 2021 -0400

    wip: Use ligature caret lists
    
    Some fonts provide information about where to
    place carets inside ligatures. Use it.
    
    Fixes: #39

 pango/glyphstring.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 45 insertions(+), 3 deletions(-)
---
diff --git a/pango/glyphstring.c b/pango/glyphstring.c
index 89dec64e..b003aa34 100644
--- a/pango/glyphstring.c
+++ b/pango/glyphstring.c
@@ -25,6 +25,8 @@
 #include "pango-font.h"
 #include "pango-impl-utils.h"
 
+#include <hb-ot.h>
+
 /**
  * pango_glyph_string_new:
  *
@@ -390,6 +392,8 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
 
   int cluster_chars = 0;
   int cluster_offset = 0;
+  int start_glyph_pos = -1;
+  int end_glyph_pos = -1;
 
   const char *p;
 
@@ -428,6 +432,12 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
              start_index = glyphs->log_clusters[i];
              start_xpos = width;
            }
+          else
+            {
+              if (end_glyph_pos < 0)
+                end_glyph_pos = i;
+              start_glyph_pos = i;
+            }
 
          width -= glyphs->glyphs[i].geometry.width;
        }
@@ -448,6 +458,12 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
              start_index = glyphs->log_clusters[i];
              start_xpos = width;
            }
+          else
+            {
+              if (start_glyph_pos < 0)
+                start_glyph_pos = i;
+              end_glyph_pos = i;
+            }
 
          width += glyphs->glyphs[i].geometry.width;
        }
@@ -461,13 +477,13 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
 
   /* Calculate offset of character within cluster */
 
-  p = text + start_index;
-  while (p < text + end_index)
+  for (p = text + start_index;
+       p < text + end_index;
+       p = g_utf8_next_char (p))
     {
       if (p < text + index)
        cluster_offset++;
       cluster_chars++;
-      p = g_utf8_next_char (p);
     }
 
   if (trailing)
@@ -479,6 +495,32 @@ pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
       return;
     }
 
+  /* Try to get a ligature caret position for the glyph
+   * from the font.
+   *
+   * If start_glyph_pos != end_glyph_pos, we are dealing
+   * 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)
+    {
+      hb_font_t *hb_font;
+      hb_position_t caret;
+      unsigned int caret_count = 1;
+
+      hb_font = pango_font_get_hb_font (analysis->font);
+      hb_ot_layout_get_ligature_carets (hb_font,
+                                        (analysis->level % 2) ? HB_DIRECTION_RTL : HB_DIRECTION_LTR,
+                                        glyphs->glyphs[start_glyph_pos].glyph,
+                                        cluster_offset, &caret_count, &caret);
+      if (caret_count > 0)
+        {
+          *x_pos = caret;
+          return;
+        }
+    }
+
   *x_pos = ((cluster_chars - cluster_offset) * start_xpos +
            cluster_offset * end_xpos) / cluster_chars;
 }


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