[pango/line-height: 3/4] Add a spread to PangoLayout



commit d4ae0eed5bf5d11b352b77e52a749aa790d16042
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jul 5 00:00:16 2019 +0000

    Add a spread to PangoLayout
    
    If the spread is set to a non-zero value,
    we place lines so that
    
    baseline2 = baseline1 + spread * height2
    
    where height2 is the line height of the
    second line. In this case, we ignore
    spacing. If spread is set to zero,
    spacing is applied as before.

 pango/pango-layout-private.h |   1 +
 pango/pango-layout.c         | 102 +++++++++++++++++++++++++++++++++++--------
 pango/pango-layout.h         |   5 +++
 3 files changed, 89 insertions(+), 19 deletions(-)
---
diff --git a/pango/pango-layout-private.h b/pango/pango-layout-private.h
index 4b5327ee..d489bf8c 100644
--- a/pango/pango-layout-private.h
+++ b/pango/pango-layout-private.h
@@ -55,6 +55,7 @@ struct _PangoLayout
   int height;                  /* ellipsize width, in device units if positive, number of lines if negative 
*/
   int indent;                  /* amount by which first line should be shorter */
   int spacing;                 /* spacing between lines */
+  float spread;                 /* factor to apply to line spacing */
 
   guint justify : 1;
   guint alignment : 2;
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 0934e6c7..af929c6f 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -190,6 +190,7 @@ pango_layout_init (PangoLayout *layout)
   layout->height = -1;
   layout->indent = 0;
   layout->spacing = 0;
+  layout->spread = 0.0;
 
   layout->alignment = PANGO_ALIGN_LEFT;
   layout->justify = FALSE;
@@ -556,8 +557,11 @@ pango_layout_get_indent (PangoLayout *layout)
  * @layout: a #PangoLayout.
  * @spacing: the amount of spacing
  *
- * Sets the amount of spacing in Pango unit between the lines of the
- * layout.
+ * Sets the amount of spacing in Pango unit between
+ * the lines of the layout.
+ *
+ * See pango_layout_set_spread() for an alternative
+ * way to influence line spacing.
  **/
 void
 pango_layout_set_spacing (PangoLayout *layout,
@@ -587,6 +591,59 @@ pango_layout_get_spacing (PangoLayout *layout)
   return layout->spacing;
 }
 
+/**
+ * pango_layout_set_spread:
+ * @layout: a #PAngoLayout
+ * @spread: the new spread factor
+ *
+ * Set a spread factor for line spacing.
+ * Typical values are: 0, 1, 1.5, 2. 0 is
+ * the default.
+ *
+ * If @spread is non-zero, lines are placed
+ * so that
+ *
+ * baseline2 = baseline1 + spread * height2
+ *
+ * where height2 is the line height of the
+ * second line. In this case, the spacing
+ * set with pango_layout_set_spacing() is
+ * ignored.
+ *
+ * If @spread is zero, spacing is applied as
+ * before.
+ *
+ * Since: 1.44
+ */
+void
+pango_layout_set_spread (PangoLayout *layout,
+                        float        spread)
+{
+  g_return_if_fail (layout != NULL);
+
+  if (spread != layout->spread)
+    {
+      layout->spread = spread;
+      layout_changed (layout);
+    }
+}
+
+/**
+ * pango_layout_get_spread:
+ * @layout: a #PangoLayout
+ *
+ * Gets the spread value that has been
+ * set with pango_layout_set_spread().
+ *
+ * Since: 1.44
+ */
+float
+pango_layout_get_spread (PangoLayout *layout)
+{
+  g_return_val_if_fail (layout != NULL, 0.0);
+  return layout->spread;
+}
+
 /**
  * pango_layout_set_attributes:
  * @layout: a #PangoLayout
@@ -2492,7 +2549,6 @@ get_line_extents_layout_coords (PangoLayout     *layout,
                                int              layout_width,
                                int              y_offset,
                                int             *baseline,
-                               int             *height,
                                PangoRectangle  *line_ink_layout,
                                PangoRectangle  *line_logical_layout)
 {
@@ -2500,30 +2556,43 @@ get_line_extents_layout_coords (PangoLayout     *layout,
   /* Line extents in line coords (origin at line baseline) */
   PangoRectangle line_ink;
   PangoRectangle line_logical;
+  gboolean first_line;
+  int new_baseline;
+  int height;
+
+  if (layout->lines->data == line)
+    first_line = TRUE;
+  else
+    first_line = FALSE;
 
   pango_layout_line_get_extents_and_height (line, line_ink_layout ? &line_ink : NULL,
                                             &line_logical,
-                                            height);
+                                            &height);
 
   get_x_offset (layout, line, layout_width, line_logical.width, &x_offset);
 
+  if (first_line || !baseline || layout->spread == 0.0)
+    new_baseline = y_offset - line_logical.y;
+  else
+    new_baseline = *baseline + layout->spread * height;
+
   /* Convert the line's extents into layout coordinates */
   if (line_ink_layout)
     {
       *line_ink_layout = line_ink;
       line_ink_layout->x = line_ink.x + x_offset;
-      line_ink_layout->y = y_offset - line_logical.y + line_ink.y;
+      line_ink_layout->y = new_baseline + line_ink.y;
     }
 
   if (line_logical_layout)
     {
       *line_logical_layout = line_logical;
       line_logical_layout->x = line_logical.x + x_offset;
-      line_logical_layout->y = y_offset;
+      line_logical_layout->y = new_baseline + line_logical.y;
     }
 
   if (baseline)
-    *baseline = y_offset - line_logical.y;
+    *baseline = new_baseline;
 }
 
 /* if non-NULL line_extents returns a list of line extents
@@ -2540,6 +2609,7 @@ pango_layout_get_extents_internal (PangoLayout    *layout,
   int width;
   gboolean need_width = FALSE;
   int line_index = 0;
+  int baseline;
 
   g_return_if_fail (layout != NULL);
 
@@ -2606,6 +2676,7 @@ pango_layout_get_extents_internal (PangoLayout    *layout,
       *line_extents = g_malloc (sizeof (Extents) * layout->line_count);
     }
 
+  baseline = 0;
   line_list = layout->lines;
   while (line_list)
     {
@@ -2618,13 +2689,9 @@ pango_layout_get_extents_internal (PangoLayout    *layout,
 
       /* This block gets the line extents in layout coords */
       {
-       int baseline;
-        int height;
-
        get_line_extents_layout_coords (layout, line,
                                        width, y_offset,
                                        &baseline,
-                                        &height,
                                        ink_rect ? &line_ink_layout : NULL,
                                        &line_logical_layout);
 
@@ -2693,14 +2760,10 @@ pango_layout_get_extents_internal (PangoLayout    *layout,
                }
            }
 
-         logical_rect->height += line_logical_layout.height;
-
-         /* No space after the last line, of course. */
-         if (line_list->next != NULL)
-           logical_rect->height += layout->spacing;
+         logical_rect->height = line_logical_layout.y + line_logical_layout.height - logical_rect->y;
        }
 
-      y_offset += line_logical_layout.height + layout->spacing;
+      y_offset = line_logical_layout.y + line_logical_layout.height + layout->spacing;
       line_list = line_list->next;
       line_index ++;
     }
@@ -4739,7 +4802,7 @@ pango_layout_line_get_extents_and_height (PangoLayoutLine *line,
     }
 
   if (height)
-    height = 0;
+    *height = 0;
 
   tmp_list = line->runs;
   while (tmp_list)
@@ -4805,6 +4868,8 @@ pango_layout_line_get_extents_and_height (PangoLayoutLine *line,
        private->ink_rect = *ink_rect;
       if (&private->logical_rect != logical_rect)
        private->logical_rect = *logical_rect;
+      if (&private->height != height)
+        private->height = *height;
       private->cache_status = CACHED;
     }
 }
@@ -6437,7 +6502,6 @@ pango_layout_iter_get_line_extents (PangoLayoutIter *iter,
       get_line_extents_layout_coords (iter->layout, iter->line,
                                      iter->layout_width,
                                      ext->logical_rect.y,
-                                     NULL,
                                       NULL,
                                      ink_rect,
                                      NULL);
diff --git a/pango/pango-layout.h b/pango/pango-layout.h
index 2019a7b5..1931763c 100644
--- a/pango/pango-layout.h
+++ b/pango/pango-layout.h
@@ -206,6 +206,11 @@ void           pango_layout_set_spacing          (PangoLayout                *la
                                                  int                         spacing);
 PANGO_AVAILABLE_IN_ALL
 int            pango_layout_get_spacing          (PangoLayout                *layout);
+PANGO_AVAILABLE_IN_1_44
+void           pango_layout_set_spread           (PangoLayout                *layout,
+                                                  float                       spread);
+PANGO_AVAILABLE_IN_1_44
+float          pango_layout_get_spread           (PangoLayout                *layout);
 PANGO_AVAILABLE_IN_ALL
 void           pango_layout_set_justify          (PangoLayout                *layout,
                                                  gboolean                    justify);


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