summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-08-07 10:37:07 -0400
committerMatthias Clasen <mclasen@redhat.com>2021-08-08 21:35:55 -0400
commit623134f48ad998e1392839f7346c780228ddac45 (patch)
tree606d44e9f51b5a692b69e183999253e96080f06c
parented13e662d1a327671fc9f1a3ec7d71c4bbfe1280 (diff)
downloadpango-623134f48ad998e1392839f7346c780228ddac45.tar.gz
Add line-height attributes
Add attributes for line-height, in a relative and absolute variant. This will be used to grow the logical extents of runs in a way that is compatible with CSS semantics. In markup, we support a new line_height attribute that will be interpreted as absolute if it is an integer > 1024, and as a relative factor otherwise.
-rw-r--r--docs/pango_markup.md6
-rw-r--r--pango/pango-attributes.c53
-rw-r--r--pango/pango-attributes.h8
-rw-r--r--pango/pango-layout.c3
-rw-r--r--pango/pango-markup.c38
5 files changed, 108 insertions, 0 deletions
diff --git a/docs/pango_markup.md b/docs/pango_markup.md
index 16359777..03718907 100644
--- a/docs/pango_markup.md
+++ b/docs/pango_markup.md
@@ -190,6 +190,12 @@ allow_breaks
: 'true' or 'false' to indicate whether breaking lines is allowed. Available
since Pango 1.44.
+line_height
+: Overrides the line height. The value can be either a factor (< 1024) that is
+ used to scale up the logical extents of runs or an absolute value (in 1024th
+ of a point).
+ Available since Pango 1.50.
+
## Convenience Tags
`<b>`
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c
index 1a4a9443..fdb37f56 100644
--- a/pango/pango-attributes.c
+++ b/pango/pango-attributes.c
@@ -1341,6 +1341,58 @@ pango_attr_overline_color_new (guint16 red,
return pango_attr_color_new (&klass, red, green, blue);
}
+/**
+ * pango_attr_line_height_new:
+ * @factor: the scaling factor to apply to the logical height
+ *
+ * Modify the height of logical line extents by a factor.
+ *
+ * This affects the values returned by
+ * [method@Pango.LayoutLine.get_extents],
+ * [method@Pango.LayoutLine.get_pixel_extents] and
+ * [method@Pango.LayoutIter.get_line_extents].
+ *
+ *
+ * Since: 1.50
+ */
+PangoAttribute *
+pango_attr_line_height_new (double factor)
+{
+ static const PangoAttrClass klass = {
+ PANGO_ATTR_LINE_HEIGHT,
+ pango_attr_float_copy,
+ pango_attr_float_destroy,
+ pango_attr_float_equal
+ };
+
+ return pango_attr_float_new (&klass, factor);
+}
+
+/**
+ * pango_attr_line_height_new_absolute:
+ * @height: the line height, in %PANGO_SCALE-ths of a point
+ *
+ * Override the height of logical line extents to be @height.
+ *
+ * This affects the values returned by
+ * [method@Pango.LayoutLine.get_extents],
+ * [method@Pango.LayoutLine.get_pixel_extents] and
+ * [method@Pango.LayoutIter.get_line_extents].
+ *
+ * Since: 1.50
+ */
+PangoAttribute *
+pango_attr_line_height_new_absolute (int height)
+{
+ static const PangoAttrClass klass = {
+ PANGO_ATTR_ABSOLUTE_LINE_HEIGHT,
+ pango_attr_int_copy,
+ pango_attr_int_destroy,
+ pango_attr_int_equal
+ };
+
+ return pango_attr_int_new (&klass, height);
+}
/*
* Attribute List
*/
@@ -2559,6 +2611,7 @@ pango_attribute_as_float (PangoAttribute *attr)
switch (attr->klass->type)
{
case PANGO_ATTR_SCALE:
+ case PANGO_ATTR_LINE_HEIGHT:
return (PangoAttrFloat *)attr;
default:
diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h
index 6f18718e..c28623fb 100644
--- a/pango/pango-attributes.h
+++ b/pango/pango-attributes.h
@@ -160,6 +160,7 @@ typedef struct _PangoAttrIterator PangoAttrIterator;
* @PANGO_ATTR_INSERT_HYPHENS: whether to insert hyphens at intra-word line breaks ([struct@Pango.AttrInt]). Since 1.44
* @PANGO_ATTR_OVERLINE: whether the text has an overline ([struct@Pango.AttrInt]). Since 1.46
* @PANGO_ATTR_OVERLINE_COLOR: overline color ([struct@Pango.AttrColor]). Since 1.46
+ * @PANGO_ATTR_LINE_HEIGHT: line height factor ([struct@Pango.AttrFloat]). Since: 1.50
*
* The `PangoAttrType` distinguishes between different types of attributes.
*
@@ -201,6 +202,8 @@ typedef enum
PANGO_ATTR_INSERT_HYPHENS, /* PangoAttrInt */
PANGO_ATTR_OVERLINE, /* PangoAttrInt */
PANGO_ATTR_OVERLINE_COLOR, /* PangoAttrColor */
+ PANGO_ATTR_LINE_HEIGHT, /* PangoAttrFloat */
+ PANGO_ATTR_ABSOLUTE_LINE_HEIGHT, /* PangoAttrInt */
} PangoAttrType;
/**
@@ -611,6 +614,11 @@ typedef enum {
PANGO_AVAILABLE_IN_1_44
PangoAttribute *pango_attr_show_new (PangoShowFlags flags);
+PANGO_AVAILABLE_IN_1_50
+PangoAttribute *pango_attr_line_height_new (double factor);
+PANGO_AVAILABLE_IN_1_50
+PangoAttribute *pango_attr_line_height_new_absolute (int height);
+
PANGO_AVAILABLE_IN_ALL
GType pango_attr_list_get_type (void) G_GNUC_CONST;
PANGO_AVAILABLE_IN_ALL
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index e0475a5e..20208dec 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -638,6 +638,9 @@ pango_layout_get_spacing (PangoLayout *layout)
*
* If @factor is zero (the default), spacing is applied as before.
*
+ * Note: for semantics that are closer to the CSS line-height
+ * property, see [func@Pango.attr_line_height_new].
+ *
* Since: 1.44
*/
void
diff --git a/pango/pango-markup.c b/pango/pango-markup.c
index 5394c772..00b16943 100644
--- a/pango/pango-markup.c
+++ b/pango/pango-markup.c
@@ -977,6 +977,29 @@ span_parse_int (const char *attr_name,
}
static gboolean
+span_parse_float (const char *attr_name,
+ const char *attr_val,
+ double *val,
+ int line_number,
+ GError **error)
+{
+ *val = g_ascii_strtod (attr_val, NULL);
+ if (errno != 0)
+ {
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Value of '%s' attribute on <span> tag "
+ "on line %d could not be parsed; "
+ "should be a number, not '%s'"),
+ attr_name, line_number, attr_val);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
span_parse_boolean (const char *attr_name,
const char *attr_val,
gboolean *val,
@@ -1200,6 +1223,7 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED,
const char *allow_breaks = NULL;
const char *insert_hyphens = NULL;
const char *show = NULL;
+ const char *line_height = NULL;
g_markup_parse_context_get_position (context,
&line_number, &char_number);
@@ -1278,6 +1302,7 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED,
case 'l':
CHECK_ATTRIBUTE (lang);
CHECK_ATTRIBUTE (letter_spacing);
+ CHECK_ATTRIBUTE (line_height);
break;
case 'o':
CHECK_ATTRIBUTE (overline);
@@ -1639,6 +1664,19 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED,
add_attribute (tag, pango_attr_letter_spacing_new (n));
}
+ if (G_UNLIKELY (line_height))
+ {
+ double f = 0;
+
+ if (!span_parse_float ("line_height", line_height, &f, line_number, error))
+ goto error;
+
+ if (f > 1024.0 && strchr (line_height, ".") == 0)
+ add_attribute (tag, pango_attr_line_height_new_absolute ((int)f));
+ else
+ add_attribute (tag, pango_attr_line_height_new (f));
+ }
+
if (G_UNLIKELY (lang))
{
add_attribute (tag,