[pango/line-height-attribute: 29/30] Fix up logical rectangle reporting




commit e2def596629bd6e9499d6b455cd645b360a9b7aa
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Aug 7 21:02:36 2021 -0400

    Fix up logical rectangle reporting
    
    Fix up the various apis that are reporting logical
    rects to follow these rules:
    
    Logical rectangles of lines are affected by the
    line-height attribute, logical rectangles of smaller
    units (runs, clusters, chars, cursors, etc) are not.
    
    This fixes the text cursors and block cursors in
    GTK to be 'normal' height, even when applying
    line-height for double-spacing.

 pango/pango-layout.c | 100 ++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 76 insertions(+), 24 deletions(-)
---
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 447bf890..2a3cb5a2 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -180,7 +180,8 @@ static void              pango_layout_line_postprocess (PangoLayoutLine *line,
 static void pango_layout_line_leaked (PangoLayoutLine *line);
 
 /* doesn't leak line */
-static PangoLayoutLine* _pango_layout_iter_get_line (PangoLayoutIter *iter);
+static PangoLayoutLine * _pango_layout_iter_get_line (PangoLayoutIter *iter);
+static PangoLayoutRun *  _pango_layout_iter_get_run  (PangoLayoutIter *iter);
 
 static void pango_layout_get_item_properties (PangoItem      *item,
                                               ItemProperties *properties);
@@ -1802,7 +1803,8 @@ pango_layout_index_to_line (PangoLayout      *layout,
 static PangoLayoutLine *
 pango_layout_index_to_line_and_extents (PangoLayout     *layout,
                                         int              index,
-                                        PangoRectangle  *line_rect)
+                                        PangoRectangle  *line_rect,
+                                        PangoRectangle  *run_rect)
 {
   PangoLayoutIter iter;
   PangoLayoutLine *line = NULL;
@@ -1822,7 +1824,26 @@ pango_layout_index_to_line_and_extents (PangoLayout     *layout,
         pango_layout_iter_get_line_extents (&iter, NULL, line_rect);
 
         if (line->start_index + line->length > index)
-          break;
+          {
+            if (run_rect)
+              {
+                while (TRUE)
+                  {
+                    PangoLayoutRun *run = _pango_layout_iter_get_run (&iter);
+
+                    if (run->item->offset <= index && index < run->item->offset + run->item->length)
+                      {
+                        pango_layout_iter_get_run_extents (&iter, NULL, run_rect);
+                        break;
+                      }
+
+                    if (!pango_layout_iter_next_run (&iter))
+                      break;
+                  }
+              }
+
+            break;
+          }
 
         if (!pango_layout_iter_next_line (&iter))
           break; /* Use end of last line */
@@ -2300,10 +2321,24 @@ pango_layout_index_to_pos (PangoLayout    *layout,
 
           layout_line = tmp_line;
 
-          pango_layout_iter_get_line_extents (&iter, NULL, &logical_rect);
-
           if (layout_line->start_index + layout_line->length > index)
-            break;
+            {
+              while (TRUE)
+                {
+                  PangoLayoutRun *run = _pango_layout_iter_get_run (&iter);
+
+                  if (run->item->offset <= index && index < run->item->offset + run->item->length)
+                    {
+                      pango_layout_iter_get_run_extents (&iter, NULL, &logical_rect);
+                      break;
+                    }
+
+                  if (!pango_layout_iter_next_run (&iter))
+                    break;
+                }
+
+              break;
+            }
 
           if (!pango_layout_iter_next_line (&iter))
             {
@@ -2376,7 +2411,7 @@ pango_layout_get_direction (PangoLayout *layout,
 {
   PangoLayoutLine *line;
 
-  line = pango_layout_index_to_line_and_extents (layout, index, NULL);
+  line = pango_layout_index_to_line_and_extents (layout, index, NULL, NULL);
 
   if (line)
     return pango_layout_line_get_char_direction (line, index);
@@ -2409,6 +2444,7 @@ pango_layout_get_cursor_pos (PangoLayout    *layout,
   PangoDirection dir1, dir2;
   int level1, level2;
   PangoRectangle line_rect;
+  PangoRectangle run_rect;
   PangoLayoutLine *layout_line = NULL; /* Quiet GCC */
   int x1_trailing;
   int x2;
@@ -2417,7 +2453,7 @@ pango_layout_get_cursor_pos (PangoLayout    *layout,
   g_return_if_fail (index >= 0 && index <= layout->length);
 
   layout_line = pango_layout_index_to_line_and_extents (layout, index,
-                                                        &line_rect);
+                                                        &line_rect, &run_rect);
 
   g_assert (index >= layout_line->start_index);
 
@@ -2466,9 +2502,9 @@ pango_layout_get_cursor_pos (PangoLayout    *layout,
       else
         strong_pos->x += x2;
 
-      strong_pos->y = line_rect.y;
+      strong_pos->y = run_rect.y;
       strong_pos->width = 0;
-      strong_pos->height = line_rect.height;
+      strong_pos->height = run_rect.height;
     }
 
   if (weak_pos)
@@ -2481,9 +2517,9 @@ pango_layout_get_cursor_pos (PangoLayout    *layout,
       else
         weak_pos->x += x1_trailing;
 
-      weak_pos->y = line_rect.y;
+      weak_pos->y = run_rect.y;
       weak_pos->width = 0;
-      weak_pos->height = line_rect.height;
+      weak_pos->height = run_rect.height;
     }
 }
 
@@ -5022,6 +5058,7 @@ static void
 pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
                                          PangoRectangle *run_ink,
                                          PangoRectangle *run_logical,
+                                         PangoRectangle *line_logical,
                                          int            *height)
 {
   PangoRectangle logical;
@@ -5030,7 +5067,7 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
   gboolean has_underline;
   gboolean has_overline;
 
-  if (G_UNLIKELY (!run_ink && !run_logical && !height))
+  if (G_UNLIKELY (!run_ink && !run_logical && !line_logical && !height))
     return;
 
   pango_layout_get_item_properties (run->item, &properties);
@@ -5045,6 +5082,9 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
   if (!run_logical && (has_underline || has_overline || properties.strikethrough))
     run_logical = &logical;
 
+  if (!run_logical && line_logical)
+    run_logical = &logical;
+
   if (properties.shape_set)
     _pango_shape_get_extents (run->item->num_chars,
                               properties.shape_ink_rect,
@@ -5119,16 +5159,6 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
       *height = pango_font_metrics_get_height (metrics);
     }
 
-  if (properties.absolute_line_height != 0 || properties.line_height != 0.0)
-    {
-      int line_height, leading;
-
-      line_height = MAX (properties.absolute_line_height, ceilf (properties.line_height * 
run_logical->height));
-      leading = line_height - run_logical->height;
-      run_logical->y -= leading / 2;
-      run_logical->height += leading;
-    }
-
   if (run->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE)
     {
       gboolean is_hinted = (run_logical->y & run_logical->height & (PANGO_SCALE - 1)) == 0;
@@ -5149,6 +5179,21 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
         run_logical->y -= properties.rise;
     }
 
+  if (line_logical)
+    {
+      *line_logical = *run_logical;
+
+      if (properties.absolute_line_height != 0 || properties.line_height != 0.0)
+        {
+          int line_height, leading;
+
+          line_height = MAX (properties.absolute_line_height, ceilf (properties.line_height * 
line_logical->height));
+          leading = line_height - line_logical->height;
+          line_logical->y -= leading / 2;
+          line_logical->height += leading;
+        }
+    }
+
   if (metrics)
     pango_font_metrics_unref (metrics);
 }
@@ -5228,6 +5273,7 @@ pango_layout_line_get_extents_and_height (PangoLayoutLine *line,
 
       pango_layout_run_get_extents_and_height (run,
                                                ink_rect ? &run_ink : NULL,
+                                               NULL,
                                                &run_logical,
                                                height ? &run_height : NULL);
 
@@ -6478,6 +6524,12 @@ _pango_layout_iter_get_line (PangoLayoutIter *iter)
   return iter->line;
 }
 
+static PangoLayoutRun *
+_pango_layout_iter_get_run (PangoLayoutIter *iter)
+{
+  return iter->run;
+}
+
 /**
  * pango_layout_iter_get_line:
  * @iter: a `PangoLayoutIter`
@@ -6939,7 +6991,7 @@ pango_layout_iter_get_run_extents (PangoLayoutIter *iter,
 
   if (iter->run)
     {
-      pango_layout_run_get_extents_and_height (iter->run, ink_rect, logical_rect, NULL);
+      pango_layout_run_get_extents_and_height (iter->run, ink_rect, logical_rect, NULL, NULL);
 
       if (ink_rect)
         {


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