[pango/pango2: 63/301] Add PangoLayoutRun




commit 8ba528cafbf0059c9ba3d949b3dad1665d0a6f2f
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jan 23 18:39:08 2022 -0500

    Add PangoLayoutRun
    
    Make this a separate type from PangoGlyphItem,
    and give it some minimal api.

 pango/meson.build                |   2 +
 pango/pango-layout-run-private.h |  33 +++++++
 pango/pango-layout-run.c         | 204 +++++++++++++++++++++++++++++++++++++++
 pango/pango-layout-run.h         |  39 ++++++++
 pango/pango.h                    |   1 +
 5 files changed, 279 insertions(+)
---
diff --git a/pango/meson.build b/pango/meson.build
index 95883183b..77cd58f67 100644
--- a/pango/meson.build
+++ b/pango/meson.build
@@ -33,6 +33,7 @@ pango_sources = [
   'serializer.c',
   'json/gtkjsonparser.c',
   'json/gtkjsonprinter.c',
+  'pango-layout-run.c',
 ]
 
 pango_headers = [
@@ -56,6 +57,7 @@ pango_headers = [
   'pango-gravity.h',
   'pango-item.h',
   'pango-language.h',
+  'pango-layout-run.h',
   'pango-layout.h',
   'pango-matrix.h',
   'pango-markup.h',
diff --git a/pango/pango-layout-run-private.h b/pango/pango-layout-run-private.h
new file mode 100644
index 000000000..dc19d09d8
--- /dev/null
+++ b/pango/pango-layout-run-private.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2022 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "config.h"
+
+#include "pango-layout-run.h"
+#include "pango-glyph-item.h"
+#include "pango-item-private.h"
+
+
+static inline PangoGlyphItem *
+pango_layout_run_get_glyph_item (PangoLayoutRun *run)
+{
+  return (PangoGlyphItem *)run;
+}
diff --git a/pango/pango-layout-run.c b/pango/pango-layout-run.c
new file mode 100644
index 000000000..8e86d14bb
--- /dev/null
+++ b/pango/pango-layout-run.c
@@ -0,0 +1,204 @@
+#include "config.h"
+
+#include "pango-layout-run-private.h"
+#include "pango-item-private.h"
+#include "pango-impl-utils.h"
+
+#include <math.h>
+
+/**
+ * PangoLayoutRun:
+ *
+ * A `PangoLayoutRun` represents a single run within a `PangoLayoutLine`.
+ *
+ * A run is a range of text with uniform script, font and attributes that
+ * is shaped as a unit.
+ *
+ * Script, font and attributes of a run can be accessed via
+ * [method@Pango.LayoutRun.get_item]. The glyphs that result from shaping
+ * the text of the run can be obtained via [method@Pango.LayoutRun.get_glyphs].
+ */
+
+/**
+ * pango_layout_run_get_item:
+ * @run: a `PangoLayoutRun`
+ *
+ * Gets the `PangoItem` for the run.
+ *
+ * Returns: (transfer none): the `PangoItem` of @run
+ */
+PangoItem *
+pango_layout_run_get_item (PangoLayoutRun *run)
+{
+  return run->item;
+}
+
+/**
+ * pango_layout_run_get_glyphs:
+ * @run: a `PangoLayoutRun`
+ *
+ * Gets the `PangoGlyphString` for the run.
+ *
+ * Returns: (transfer none): the `PangoGlyphString` of @run
+ */
+PangoGlyphString *
+pango_layout_run_get_glyphs (PangoLayoutRun *run)
+{
+  return run->glyphs;
+}
+
+/**
+ * pango_layout_run_get_extents:
+ * @run: a `PangoLayoutRun`
+ * @trim: `PangoLeadingTrim` flags
+ * @ink_rect: (out caller-allocates) (optional): return location
+ *   for the ink extents
+ * @logical_rect: (out caller-allocates) (optional): return location
+ *   for the logical extents
+ *
+ * Gets the extents of a `PangoLayoutRun`.
+ *
+ * The @trim flags specify if line-height attributes are taken
+ * into consideration for determining the logical height. See the
+ * [CSS inline layout](https://www.w3.org/TR/css-inline-3/#inline-height)
+ * specification for details.
+ */
+void
+pango_layout_run_get_extents (PangoLayoutRun   *run,
+                              PangoLeadingTrim  trim,
+                              PangoRectangle   *ink_rect,
+                              PangoRectangle   *logical_rect)
+{
+  PangoGlyphItem *glyph_item = run;
+  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 (!logical_rect && (glyph_item->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE))
+    logical_rect = &logical;
+
+  if (!logical_rect && (has_underline || has_overline || properties.strikethrough))
+    logical_rect = &logical;
+
+  if (properties.shape_set)
+    _pango_shape_get_extents (glyph_item->item->num_chars,
+                              properties.shape_ink_rect, properties.shape_logical_rect,
+                              ink_rect, logical_rect);
+  else
+    pango_glyph_string_extents (glyph_item->glyphs, glyph_item->item->analysis.font,
+                                ink_rect, logical_rect);
+
+  if (ink_rect && (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 logical_rect.
+       * Reflect that into ink_rect.
+       */
+      new_pos = MIN (ink_rect->x, logical_rect->x);
+      ink_rect->width = MAX (ink_rect->x + ink_rect->width, logical_rect->x + logical_rect->width) - new_pos;
+      ink_rect->x = new_pos;
+
+      /* We should better handle the case of height==0 in the following cases.
+       * If ink_rect->height == 0, we should adjust ink_rect->y appropriately.
+       */
+
+      if (properties.strikethrough)
+        {
+          if (ink_rect->height == 0)
+            {
+              ink_rect->height = strikethrough_thickness;
+              ink_rect->y = -strikethrough_position;
+            }
+        }
+
+      if (properties.oline_single)
+        {
+          ink_rect->y -= underline_thickness;
+          ink_rect->height += underline_thickness;
+        }
+
+      if (properties.uline_low)
+        ink_rect->height += 2 * underline_thickness;
+      if (properties.uline_single)
+        ink_rect->height = MAX (ink_rect->height,
+                               underline_thickness - underline_position - ink_rect->y);
+      if (properties.uline_double)
+        ink_rect->height = MAX (ink_rect->height,
+                                 3 * underline_thickness - underline_position - ink_rect->y);
+      if (properties.uline_error)
+        ink_rect->height = MAX (ink_rect->height,
+                               3 * underline_thickness - underline_position - ink_rect->y);
+    }
+
+  y_offset = glyph_item->y_offset;
+
+  if (glyph_item->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE)
+    {
+      gboolean is_hinted = (logical_rect->y & logical_rect->height & (PANGO_SCALE - 1)) == 0;
+      int adjustment = logical_rect->y + logical_rect->height / 2;
+
+      if (is_hinted)
+        adjustment = PANGO_UNITS_ROUND (adjustment);
+
+      y_offset += adjustment;
+    }
+
+  if (ink_rect)
+    ink_rect->y -= y_offset;
+
+  if (logical_rect)
+    logical_rect->y -= y_offset;
+
+  if (logical_rect && trim != PANGO_LEADING_TRIM_BOTH)
+    {
+      int leading;
+
+      if (properties.absolute_line_height != 0 || properties.line_height != 0.0)
+        {
+          int line_height;
+
+          line_height = MAX (properties.absolute_line_height, ceilf (properties.line_height * 
logical_rect->height));
+          leading = (line_height - logical_rect->height);
+        }
+      else
+        {
+          /* line-height 'normal' in the CSS inline layout spec */
+          if (!metrics)
+            metrics = pango_font_get_metrics (glyph_item->item->analysis.font,
+                                              glyph_item->item->analysis.language);
+          leading = MAX (metrics->height - (metrics->ascent + metrics->descent), 0);
+        }
+      if ((trim & PANGO_LEADING_TRIM_START) == 0)
+        logical_rect->y -= leading / 2;
+      if (trim == PANGO_LEADING_TRIM_NONE)
+        logical_rect->height += leading;
+      else
+        logical_rect->height += (leading - leading / 2);
+    }
+
+  if (metrics)
+    pango_font_metrics_unref (metrics);
+}
diff --git a/pango/pango-layout-run.h b/pango/pango-layout-run.h
new file mode 100644
index 000000000..1f6764055
--- /dev/null
+++ b/pango/pango-layout-run.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+#include <pango/pango-types.h>
+#include <pango/pango-item.h>
+#include <pango/pango-glyph.h>
+#include <pango/pango-layout.h>
+
+
+PANGO_AVAILABLE_IN_ALL
+PangoItem *             pango_layout_run_get_item     (PangoLayoutRun   *run);
+
+PANGO_AVAILABLE_IN_ALL
+PangoGlyphString *      pango_layout_run_get_glyphs   (PangoLayoutRun   *run);
+
+PANGO_AVAILABLE_IN_ALL
+void                    pango_layout_run_get_extents  (PangoLayoutRun   *run,
+                                                       PangoLeadingTrim  trim,
+                                                       PangoRectangle   *ink_rect,
+                                                       PangoRectangle   *logical_rect);
diff --git a/pango/pango.h b/pango/pango.h
index b5200b8fa..107e4b773 100644
--- a/pango/pango.h
+++ b/pango/pango.h
@@ -44,6 +44,7 @@
 #include <pango/pango-item.h>
 #include <pango/pango-language.h>
 #include <pango/pango-layout.h>
+#include <pango/pango-layout-run.h>
 #include <pango/pango-matrix.h>
 #include <pango/pango-markup.h>
 #include <pango/pango-renderer.h>


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