[pango/break-tailoring: 26/28] Add an allow-line-breaks attribute
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/break-tailoring: 26/28] Add an allow-line-breaks attribute
- Date: Sun, 22 Aug 2021 06:54:54 +0000 (UTC)
commit a5a606d988152a4269d5e9486b1b58c772ce69a9
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Aug 21 13:17:58 2021 -0400
Add an allow-line-breaks attribute
This is more flexible than the boolean allow-breaks attribute,
it lets you say: strip line breaks, but keep the char breaks.
Tests included, and output of affected tests updated.
docs/pango_markup.md | 8 ++++---
pango/break.c | 29 +++++++++++++++++++-----
pango/pango-attributes.c | 49 +++++++++++++++++++++++++++++++++++++++++
pango/pango-attributes.h | 5 +++++
pango/pango-layout.c | 1 +
pango/pango-markup.c | 20 +++++++++++++----
tests/breaks/thirteen.break | 2 ++
tests/breaks/thirteen.expected | 6 +++++
tests/markups/fail-33.expected | 2 +-
tests/markups/valid-25.expected | 21 ++++++++++++++++++
tests/markups/valid-25.markup | 1 +
tests/test-common.c | 1 +
tests/testattributes.c | 2 ++
13 files changed, 134 insertions(+), 13 deletions(-)
---
diff --git a/docs/pango_markup.md b/docs/pango_markup.md
index d35c2a18..b84bffef 100644
--- a/docs/pango_markup.md
+++ b/docs/pango_markup.md
@@ -187,12 +187,14 @@ insert_hyphens
lines in the middle of words. Available since Pango 1.44.
allow_breaks
-: 'true' or 'false' to indicate whether breaking lines is allowed. Available
- since Pango 1.44.
+: 'true' or 'false' to indicate whether breaking lines is allowed, or one of the
+ values 'non', 'char', 'line' or 'mandatory' to indicate what kinds of line break
+ opportunities are allowed. Available since Pango 1.44. Values other than 'true'
+ and 'false' are possible since Pango 1.50.
break_before
break_after
-: The value can be one of 'none','char', 'line', or 'mandatory', to override
+: The value can be one of 'none', 'char', 'line', or 'mandatory', to override
the line break classification at the beginning or end of the span. Available
since Pango 1.50.
diff --git a/pango/break.c b/pango/break.c
index 0bab3abd..9e3d94d7 100644
--- a/pango/break.c
+++ b/pango/break.c
@@ -1645,6 +1645,17 @@ break_attrs (const char *text,
PangoAttribute *attr = l->data;
if (attr->klass->type == PANGO_ATTR_ALLOW_BREAKS)
+ {
+ PangoAttribute *attr2;
+
+ attr2 = pango_attr_allow_line_breaks_new (((PangoAttrInt*)attr)->value
+ ? PANGO_LINE_BREAK_MANDATORY
+ : PANGO_LINE_BREAK_NONE);
+ attr2->start_index = attr->start_index;
+ attr2->end_index = attr->end_index;
+ pango_attr_list_insert (&allow_breaks, attr2);
+ }
+ else if (attr->klass->type == PANGO_ATTR_ALLOW_LINE_BREAKS)
pango_attr_list_insert (&allow_breaks, pango_attribute_copy (attr));
else if (attr->klass->type == PANGO_ATTR_LINE_BREAK)
pango_attr_list_insert (&line_breaks, pango_attribute_copy (attr));
@@ -1657,9 +1668,15 @@ break_attrs (const char *text,
_pango_attr_list_get_iterator (&allow_breaks, &iter);
do
{
- const PangoAttribute *attr = pango_attr_iterator_get (&iter, PANGO_ATTR_ALLOW_BREAKS);
+ const PangoAttribute *attr = pango_attr_iterator_get (&iter, PANGO_ATTR_ALLOW_LINE_BREAKS);
+ PangoLineBreak allowed;
+
+ if (!attr)
+ continue;
+
+ allowed = ((PangoAttrInt*)attr)->value;
- if (attr && ((PangoAttrInt*)attr)->value == 0)
+ if (allowed != PANGO_LINE_BREAK_MANDATORY)
{
int start, end;
int start_pos, end_pos;
@@ -1678,9 +1695,9 @@ break_attrs (const char *text,
for (pos = start_pos + 1; pos < end_pos; pos++)
{
- log_attrs[pos].is_mandatory_break = FALSE;
- log_attrs[pos].is_line_break = FALSE;
- log_attrs[pos].is_char_break = FALSE;
+ log_attrs[pos].is_mandatory_break &= allowed >= PANGO_LINE_BREAK_MANDATORY;
+ log_attrs[pos].is_line_break &= allowed >= PANGO_LINE_BREAK_LINE;
+ log_attrs[pos].is_char_break &= allowed >= PANGO_LINE_BREAK_CHAR;
tailored = TRUE;
}
@@ -1717,6 +1734,7 @@ break_attrs (const char *text,
log_attrs[pos].is_char_break = TRUE;
log_attrs[pos].is_line_break = before >= PANGO_LINE_BREAK_LINE;
log_attrs[pos].is_mandatory_break = before == PANGO_LINE_BREAK_MANDATORY;
+
tailored = TRUE;
}
@@ -1729,6 +1747,7 @@ break_attrs (const char *text,
log_attrs[pos].is_char_break = TRUE;
log_attrs[pos].is_line_break = after >= PANGO_LINE_BREAK_LINE;
log_attrs[pos].is_mandatory_break = after == PANGO_LINE_BREAK_MANDATORY;
+
tailored = TRUE;
}
}
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c
index 501203f3..fbecd125 100644
--- a/pango/pango-attributes.c
+++ b/pango/pango-attributes.c
@@ -1228,6 +1228,10 @@ pango_attr_background_alpha_new (guint16 alpha)
* If breaks are disabled, the range will be kept in a
* single run, as far as possible.
*
+ * See [func@Pango.attr_allow_line_breaks_new] and
+ * [func@Pango.attr_line_breaks_new] for more flexible
+ * control over line breaks.
+ *
* Return value: (transfer full): the newly allocated
* `PangoAttribute`, which should be freed with
* [method@Pango.Attribute.destroy]
@@ -1302,6 +1306,49 @@ pango_attr_show_new (PangoShowFlags flags)
return pango_attr_int_new (&klass, (int)flags);
}
+/**
+ * pango_attr_allow_line_breaks_new:
+ * @allow: what line breaks to allow
+ *
+ * Create a new allow-line-breaks attribute.
+ *
+ * In contrast to [func@Pango.attr_allow_breaks_new],
+ * this attribute allows some control over which of the
+ * algorithmically determined line break opportunities
+ * to keep, and which to remove:
+ *
+ * `PANGO_LINE_BREAK_IGNORE`
+ * : No changes.
+ * `PANGO_LINE_BREAK_NONE`
+ * : All break opportunities are removed.
+ * `PANGO_LINE_BEAK_CHAR`
+ * : Only break opportunities during character breaking
+ * are retained.
+ * `PANGO_LINE_BREAK_LINE`
+ * : Regular line break opportunities are retained, mandatory
+ * breaks are removed.
+ * `PANGO_LINE_BREAK_MANDATORY:
+ * : All line break opportunities are retained.
+ *
+ * Return value: (transfer full): the newly allocated
+ * `PangoAttribute`, which should be freed with
+ * [method@Pango.Attribute.destroy]
+ *
+ * Since: 1.50
+ */
+PangoAttribute *
+pango_attr_allow_line_breaks_new (PangoLineBreak allow)
+{
+ static const PangoAttrClass klass = {
+ PANGO_ATTR_ALLOW_LINE_BREAKS,
+ pango_attr_int_copy,
+ pango_attr_int_destroy,
+ pango_attr_int_equal,
+ };
+
+ return pango_attr_int_new (&klass, allow);
+}
+
/**
* pango_attr_line_break_new:
* @before: override for the beginning of the range
@@ -1343,6 +1390,7 @@ pango_attr_line_break_new (PangoLineBreak before,
return pango_attr_int_new (&klass, before | (after << 16));
}
+
/**
* pango_attr_overline_new:
* @overline: the overline style
@@ -1513,6 +1561,7 @@ pango_attribute_as_int (PangoAttribute *attr)
case PANGO_ATTR_FOREGROUND_ALPHA:
case PANGO_ATTR_BACKGROUND_ALPHA:
case PANGO_ATTR_ALLOW_BREAKS:
+ case PANGO_ATTR_ALLOW_LINE_BREAKS:
case PANGO_ATTR_LINE_BREAK:
case PANGO_ATTR_SHOW:
case PANGO_ATTR_INSERT_HYPHENS:
diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h
index ae193448..8d7be7d2 100644
--- a/pango/pango-attributes.h
+++ b/pango/pango-attributes.h
@@ -77,6 +77,8 @@ typedef struct _PangoAttrFontFeatures PangoAttrFontFeatures;
* @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
* @PANGO_ATTR_ABSOLUTE_LINE_HEIGHT: line height ([struct@Pango.AttrInt]). Since: 1.50
+ * @PANGO_ATTR_ALLOW_LINE_BREAKS: what algorithmically determined line breaks to allow
([struct@Pango.AttrInt]). Since 1.50
+ * @PANGO_ATTR_LINE_BREAK: override line breaks at the ends of the range ([struct@Pango.AttrInt]). Since 1.50
*
* The `PangoAttrType` distinguishes between different types of attributes.
*
@@ -121,6 +123,7 @@ typedef enum
PANGO_ATTR_LINE_HEIGHT, /* PangoAttrFloat */
PANGO_ATTR_ABSOLUTE_LINE_HEIGHT, /* PangoAttrInt */
PANGO_ATTR_TEXT_TRANSFORM, /* PangoAttrInt */
+ PANGO_ATTR_ALLOW_LINE_BREAKS, /* PangoAttrInt */
PANGO_ATTR_LINE_BREAK, /* PangoAttrInt */
} PangoAttrType;
@@ -561,6 +564,8 @@ PangoAttribute * pango_attr_background_alpha_new (guint16
PANGO_AVAILABLE_IN_1_44
PangoAttribute * pango_attr_allow_breaks_new (gboolean allow_breaks);
PANGO_AVAILABLE_IN_1_50
+PangoAttribute * pango_attr_allow_line_breaks_new (PangoLineBreak allow);
+PANGO_AVAILABLE_IN_1_50
PangoAttribute * pango_attr_line_break_new (PangoLineBreak before,
PangoLineBreak after);
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index e832445c..545bcc1f 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -4369,6 +4369,7 @@ affects_break_or_shape (PangoAttribute *attr,
{
/* Affects breaks */
case PANGO_ATTR_ALLOW_BREAKS:
+ case PANGO_ATTR_ALLOW_LINE_BREAKS:
case PANGO_ATTR_LINE_BREAK:
/* Affects shaping */
case PANGO_ATTR_INSERT_HYPHENS:
diff --git a/pango/pango-markup.c b/pango/pango-markup.c
index f9c143c6..ab0a9487 100644
--- a/pango/pango-markup.c
+++ b/pango/pango-markup.c
@@ -1714,11 +1714,23 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED,
if (G_UNLIKELY (allow_breaks))
{
gboolean b = FALSE;
+ PangoLineBreak allowed;
- if (!span_parse_boolean ("allow_breaks", allow_breaks, &b, line_number, error))
- goto error;
-
- add_attribute (tag, pango_attr_allow_breaks_new (b));
+ if (span_parse_boolean ("allow_breaks", allow_breaks, &b, line_number, NULL))
+ add_attribute (tag, pango_attr_allow_breaks_new (b));
+ else if (span_parse_enum ("allow_breaks", allow_breaks, PANGO_TYPE_LINE_BREAK, (int*)(void*)&allowed,
line_number, NULL))
+ add_attribute (tag, pango_attr_allow_line_breaks_new (allowed));
+ else
+ {
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Value of 'allow_breaks' attribute on <span> tag on line %d "
+ "could not be parsed; should be a boolean, or one of "
+ "'none', 'char', 'line', 'mandatory', not '%s'"),
+ line_number, allow_breaks);
+ goto error;
+ }
}
if (G_UNLIKELY (break_before || break_after))
diff --git a/tests/breaks/thirteen.break b/tests/breaks/thirteen.break
new file mode 100644
index 00000000..c92bf4f9
--- /dev/null
+++ b/tests/breaks/thirteen.break
@@ -0,0 +1,2 @@
+# test line break attributes
+the file <span allow_breaks='char' break_after='mandatory'><span break_before='mandatory'
break_after='line'>/path/</span><span break_after='line'>to/</span><span break_after='line'>my/</span>home
</span>is cursed.
diff --git a/tests/breaks/thirteen.expected b/tests/breaks/thirteen.expected
new file mode 100644
index 00000000..08ae37ee
--- /dev/null
+++ b/tests/breaks/thirteen.expected
@@ -0,0 +1,6 @@
+Text: t h e [ ] f i l e [ ] / p a t h / t o / m y /
h o m e [ ] i s [ ] c u r s e d . [0x0a]
+Breaks: c c c c lc c c c c Lc c c c c c lc c c lc c c lc c c c c Lc c c lc c c c c c c
c c
+Whitespace: x x x x
w w
+Sentences: bs
e b
+Words: bs be bs be b bs be bs be bs be bs be bs be bs be
b b
+Graphemes: b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b
b b
diff --git a/tests/markups/fail-33.expected b/tests/markups/fail-33.expected
index f5c97686..030849b0 100644
--- a/tests/markups/fail-33.expected
+++ b/tests/markups/fail-33.expected
@@ -1 +1 @@
-ERROR: Value of 'allow_breaks' attribute on <span> tag line 1 should have one of 'true/yes/t/y' or
'false/no/f/n': 'blue' is not valid
\ No newline at end of file
+ERROR: Value of 'allow_breaks' attribute on <span> tag on line 1 could not be parsed; should be a boolean,
or one of 'none', 'char', 'line', 'mandatory', not 'blue'
\ No newline at end of file
diff --git a/tests/markups/valid-25.expected b/tests/markups/valid-25.expected
new file mode 100644
index 00000000..73420aad
--- /dev/null
+++ b/tests/markups/valid-25.expected
@@ -0,0 +1,21 @@
+one two three four
+
+
+---
+
+range 0 4
+[0,18]allow-line-breaks=2
+range 4 7
+[0,18]allow-line-breaks=2
+[4,7]line-break=4, 3
+range 7 18
+[0,18]allow-line-breaks=2
+range 18 2147483647
+
+
+---
+
+[0:4] (null) Normal
+[4:7] (null) Normal
+[7:18] (null) Normal
+[18:2147483647] (null) Normal
diff --git a/tests/markups/valid-25.markup b/tests/markups/valid-25.markup
new file mode 100644
index 00000000..08d6a040
--- /dev/null
+++ b/tests/markups/valid-25.markup
@@ -0,0 +1 @@
+<span allow_breaks='char'>one <span break_before='mandatory' break_after='line'>two</span> three four</span>
diff --git a/tests/test-common.c b/tests/test-common.c
index 12ea1cb0..c93197eb 100644
--- a/tests/test-common.c
+++ b/tests/test-common.c
@@ -140,6 +140,7 @@ print_attribute (PangoAttribute *attr, GString *string)
case PANGO_ATTR_FOREGROUND_ALPHA:
case PANGO_ATTR_BACKGROUND_ALPHA:
case PANGO_ATTR_ALLOW_BREAKS:
+ case PANGO_ATTR_ALLOW_LINE_BREAKS:
case PANGO_ATTR_INSERT_HYPHENS:
case PANGO_ATTR_SHOW:
case PANGO_ATTR_TEXT_TRANSFORM:
diff --git a/tests/testattributes.c b/tests/testattributes.c
index 531fa1cc..d491a380 100644
--- a/tests/testattributes.c
+++ b/tests/testattributes.c
@@ -76,6 +76,7 @@ test_attributes_basic (void)
test_copy (pango_attr_line_height_new (1.5));
test_copy (pango_attr_line_height_new_absolute (3000));
test_copy (pango_attr_line_break_new (PANGO_LINE_BREAK_CHAR, PANGO_LINE_BREAK_MANDATORY));
+ test_copy (pango_attr_allow_line_breaks_new (PANGO_LINE_BREAK_LINE));
}
static void
@@ -209,6 +210,7 @@ test_binding_helpers (void)
test_binding (pango_attr_line_height_new (1.5));
test_binding (pango_attr_line_height_new_absolute (3000));
test_binding (pango_attr_line_break_new (PANGO_LINE_BREAK_CHAR, PANGO_LINE_BREAK_MANDATORY));
+ test_binding (pango_attr_allow_line_breaks_new (PANGO_LINE_BREAK_LINE));
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]