[pango/break-tailoring: 2/2] Add an allow-line-breaks attribute
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/break-tailoring: 2/2] Add an allow-line-breaks attribute
- Date: Sat, 21 Aug 2021 18:08:03 +0000 (UTC)
commit 96719ced78c0726da321ef32649961f7c339e72d
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.
docs/pango_markup.md | 8 ++++---
pango/break.c | 29 +++++++++++++++++++++-----
pango/pango-attributes.c | 46 +++++++++++++++++++++++++++++++++++++++++
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/valid-24.expected | 21 +++++++++++++++++++
tests/markups/valid-24.markup | 1 +
tests/test-common.c | 1 +
tests/testattributes.c | 1 +
12 files changed, 129 insertions(+), 12 deletions(-)
---
diff --git a/docs/pango_markup.md b/docs/pango_markup.md
index 8143570d..614fc6db 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 96fef800..b6b32846 100644
--- a/pango/break.c
+++ b/pango/break.c
@@ -1850,6 +1850,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));
@@ -1862,9 +1873,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;
@@ -1883,9 +1900,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;
}
@@ -1922,6 +1939,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;
}
@@ -1934,6 +1952,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 97ec8ad4..ba97c8b4 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,47 @@ pango_attr_show_new (PangoShowFlags flags)
return pango_attr_int_new (&klass, (int)flags);
}
+/**
+ * pango_attr_allow_line_breaks_new:
+ * @allowed: 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_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 allowed)
+{
+ 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, allowed);
+}
+
/**
* pango_attr_line_break_new:
* @before: override for the beginning of the range
@@ -1343,6 +1388,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
diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h
index 96bd3e01..fc9a2dc7 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.
*
@@ -120,6 +122,7 @@ typedef enum
PANGO_ATTR_OVERLINE_COLOR, /* PangoAttrColor */
PANGO_ATTR_LINE_HEIGHT, /* PangoAttrFloat */
PANGO_ATTR_ABSOLUTE_LINE_HEIGHT, /* PangoAttrInt */
+ PANGO_ATTR_ALLOW_LINE_BREAKS, /* PangoAttrInt */
PANGO_ATTR_LINE_BREAK, /* PangoAttrInt */
} PangoAttrType;
@@ -541,6 +544,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 0bfa213d..b1f5387c 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -4313,6 +4313,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 75215379..f70e4227 100644
--- a/pango/pango-markup.c
+++ b/pango/pango-markup.c
@@ -1697,11 +1697,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..89f5fe8d
--- /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
+Words: bs be bs be b bs be bs be bs be bs be bs be bs be
b b
+Sentences: bs
e 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/valid-24.expected b/tests/markups/valid-24.expected
new file mode 100644
index 00000000..73420aad
--- /dev/null
+++ b/tests/markups/valid-24.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-24.markup b/tests/markups/valid-24.markup
new file mode 100644
index 00000000..08d6a040
--- /dev/null
+++ b/tests/markups/valid-24.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 52f4cda2..06c89e81 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:
g_string_append_printf (string, "%d", ((PangoAttrInt *)attr)->value);
diff --git a/tests/testattributes.c b/tests/testattributes.c
index 5149766f..423e4c31 100644
--- a/tests/testattributes.c
+++ b/tests/testattributes.c
@@ -70,6 +70,7 @@ test_attributes_basic (void)
test_copy (pango_attr_show_new (PANGO_SHOW_SPACES));
test_copy (pango_attr_insert_hyphens_new (FALSE));
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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]