[pango/line-breaker: 2/16] Add pango_glyph_item_get_extents




commit 1f8d422a83e12e5c7d58879d6678f307535dbb26
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Jan 15 18:22:44 2022 -0500

    Add pango_glyph_item_get_extents
    
    Move this code to pango-glyph-item.c where it belongs.
    At the same time, split it into separate functions
    for ink and logical extents.

 pango/pango-glyph-item.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++
 pango/pango-glyph-item.h |   5 ++
 2 files changed, 131 insertions(+)
---
diff --git a/pango/pango-glyph-item.c b/pango/pango-glyph-item.c
index 7eb1737d..6c8cd69c 100644
--- a/pango/pango-glyph-item.c
+++ b/pango/pango-glyph-item.c
@@ -21,10 +21,12 @@
 
 #include "config.h"
 #include <string.h>
+#include <math.h>
 
 #include "pango-glyph-item.h"
 #include "pango-impl-utils.h"
 #include "pango-attributes-private.h"
+#include "pango-item-private.h"
 
 #define LTR(glyph_item) (((glyph_item)->item->analysis.level % 2) == 0)
 
@@ -860,3 +862,127 @@ pango_glyph_item_get_logical_widths (PangoGlyphItem *glyph_item,
        }
     }
 }
+
+void
+pango_glyph_item_get_extents (PangoGlyphItem *glyph_item,
+                              PangoRectangle *run_ink,
+                              PangoRectangle *run_logical,
+                              gboolean        apply_line_height)
+{
+  ItemProperties properties;
+  gboolean has_underline;
+  gboolean has_overline;
+  PangoRectangle logical;
+  PangoFontMetrics *metrics = NULL;
+  int y_offset;
+
+  pango_item_get_properties (glyph_item->item, &properties);
+
+  has_underline = properties.uline_single || properties.uline_double ||
+                  properties.uline_low || properties.uline_error;
+  has_overline = properties.oline_single;
+
+  if (!run_logical && (glyph_item->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE))
+    run_logical = &logical;
+
+  if (!run_logical && (has_underline || has_overline || properties.strikethrough))
+    run_logical = &logical;
+
+  if (properties.shape_set)
+    _pango_shape_get_extents (glyph_item->item->num_chars,
+                              properties.shape_ink_rect, properties.shape_logical_rect,
+                              run_ink, run_logical);
+  else
+    pango_glyph_string_extents (glyph_item->glyphs, glyph_item->item->analysis.font,
+                                run_ink, run_logical);
+
+  if (run_ink && (has_underline || has_overline || properties.strikethrough))
+    {
+      int underline_thickness;
+      int underline_position;
+      int strikethrough_thickness;
+      int strikethrough_position;
+      int new_pos;
+
+      if (!metrics)
+        metrics = pango_font_get_metrics (glyph_item->item->analysis.font,
+                                          glyph_item->item->analysis.language);
+
+      underline_thickness = pango_font_metrics_get_underline_thickness (metrics);
+      underline_position = pango_font_metrics_get_underline_position (metrics);
+      strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness (metrics);
+      strikethrough_position = pango_font_metrics_get_strikethrough_position (metrics);
+
+      /* the underline/strikethrough takes x, width of run_logical.
+       * Reflect that into run_ink.
+       */
+      new_pos = MIN (run_ink->x, run_logical->x);
+      run_ink->width = MAX (run_ink->x + run_ink->width, run_logical->x + run_logical->width) - new_pos;
+      run_ink->x = new_pos;
+
+      /* We should better handle the case of height==0 in the following cases.
+       * If run_ink->height == 0, we should adjust run_ink->y appropriately.
+       */
+
+      if (properties.strikethrough)
+        {
+          if (run_ink->height == 0)
+            {
+              run_ink->height = strikethrough_thickness;
+              run_ink->y = -strikethrough_position;
+            }
+        }
+
+      if (properties.oline_single)
+        {
+          run_ink->y -= underline_thickness;
+          run_ink->height += underline_thickness;
+        }
+
+      if (properties.uline_low)
+        run_ink->height += 2 * underline_thickness;
+      if (properties.uline_single)
+        run_ink->height = MAX (run_ink->height,
+                               underline_thickness - underline_position - run_ink->y);
+      if (properties.uline_double)
+        run_ink->height = MAX (run_ink->height,
+                                 3 * underline_thickness - underline_position - run_ink->y);
+      if (properties.uline_error)
+        run_ink->height = MAX (run_ink->height,
+                               3 * underline_thickness - underline_position - run_ink->y);
+    }
+
+  y_offset = glyph_item->y_offset;
+
+  if (glyph_item->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE)
+    {
+      gboolean is_hinted = (run_logical->y & run_logical->height & (PANGO_SCALE - 1)) == 0;
+      int adjustment = run_logical->y + run_logical->height / 2;
+
+      if (is_hinted)
+        adjustment = PANGO_UNITS_ROUND (adjustment);
+
+      y_offset += adjustment;
+    }
+
+  if (run_ink)
+    run_ink->y -= y_offset;
+
+  if (run_logical)
+    run_logical->y -= y_offset;
+
+  if (apply_line_height && run_logical &&
+      (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 (metrics)
+    pango_font_metrics_unref (metrics);
+}
diff --git a/pango/pango-glyph-item.h b/pango/pango-glyph-item.h
index fd8951d2..bc30d35e 100644
--- a/pango/pango-glyph-item.h
+++ b/pango/pango-glyph-item.h
@@ -85,6 +85,11 @@ void           pango_glyph_item_get_logical_widths (PangoGlyphItem *glyph_item,
                                               const char     *text,
                                               int            *logical_widths);
 
+PANGO_AVAILABLE_IN_ALL
+void            pango_glyph_item_get_extents  (PangoGlyphItem *glyph_item,
+                                               PangoRectangle *ink_rect,
+                                               PangoRectangle *logical_rect,
+                                               gboolean        apply_line_height);
 
 /**
  * PangoGlyphItemIter:


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