summaryrefslogtreecommitdiff
path: root/pango/break.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-07-20 10:36:48 -0700
committerMatthias Clasen <mclasen@redhat.com>2019-07-20 11:56:18 -0700
commitc7c8d8120925f83c638cc496b3f4de07aed442d0 (patch)
tree591d9a38e03130c9e10f91b00ad3babbed7aebd3 /pango/break.c
parent62580f2fa5e46d51bb2377d4028471926108bab3 (diff)
downloadpango-c7c8d8120925f83c638cc496b3f4de07aed442d0.tar.gz
break: Implement allow-breaks
We implement this in pango_tailor_break(), after the script-specific breaking. When line breaks are forbidden in a range, we remove line and char break opportunities inside the range.
Diffstat (limited to 'pango/break.c')
-rw-r--r--pango/break.c96
1 files changed, 87 insertions, 9 deletions
diff --git a/pango/break.c b/pango/break.c
index d25d2616..cde43fcb 100644
--- a/pango/break.c
+++ b/pango/break.c
@@ -1578,18 +1578,34 @@ break_script (const char *item_text,
int attrs_len);
static gboolean
-tailor_break (const gchar *text,
- gint length,
- PangoAnalysis *analysis,
- PangoLogAttr *attrs,
- int attrs_len)
+break_attrs (const char *text,
+ int length,
+ GSList *attributes,
+ int item_offset,
+ PangoLogAttr *attrs,
+ int attrs_len);
+
+static gboolean
+tailor_break (const char *text,
+ int length,
+ PangoAnalysis *analysis,
+ int item_offset,
+ PangoLogAttr *attrs,
+ int attrs_len)
{
+ gboolean res;
+
if (length < 0)
length = strlen (text);
else if (text == NULL)
text = "";
- return break_script (text, length, analysis, attrs, attrs_len);
+ res = break_script (text, length, analysis, attrs, attrs_len);
+
+ if (item_offset >= 0)
+ res |= break_attrs (text, length, analysis->extra_attrs, item_offset, attrs, attrs_len);
+
+ return res;
}
/**
@@ -1618,7 +1634,7 @@ pango_break (const gchar *text,
g_return_if_fail (attrs != NULL);
pango_default_break (text, length, analysis, attrs, attrs_len);
- tailor_break (text, length, analysis, attrs, attrs_len);
+ tailor_break (text, length, analysis, -1, attrs, attrs_len);
}
/**
@@ -1726,7 +1742,8 @@ pango_find_paragraph_boundary (const gchar *text,
* @text: text to process. Must be valid UTF-8
* @length: length in bytes of @text
* @analysis: #PangoAnalysis structure from pango_itemize() for @text
- * @offset: byte offset of @text in paragraph, or -1
+ * @offset: Byte offset of @text from the beginning of the
+ * paragraph, or -1 to ignore attributes from @analysis
* @log_attrs: (array length=attrs_len): array with one #PangoLogAttr
* per character in @text, plus one extra, to be filled in
* @attrs_len: length of @log_attrs array
@@ -1734,6 +1751,9 @@ pango_find_paragraph_boundary (const gchar *text,
* Apply language-specific tailoring to the breaks in
* @log_attrs, which are assumed to have been produced
* by pango_default_break().
+ *
+ * If @offset is not -1, it is used to apply attributes
+ * from @analysis that are relevant to line breaking.
*/
void
pango_tailor_break (const char *text,
@@ -1746,7 +1766,7 @@ pango_tailor_break (const char *text,
PangoLogAttr *start = log_attrs;
PangoLogAttr attr_before = *start;
- if (tailor_break (text, length, analysis, log_attrs, log_attrs_len))
+ if (tailor_break (text, length, analysis, offset, log_attrs, log_attrs_len))
{
/* if tailored, we enforce some of the attrs from before
* tailoring at the boundary
@@ -1775,6 +1795,7 @@ tailor_segment (const char *range_start,
pango_tailor_break (range_start,
range_end - range_start,
analysis,
+ -1,
start,
chars_in_range + 1);
@@ -1879,3 +1900,60 @@ break_script (const char *item_text,
return TRUE;
}
+
+static gboolean
+break_attrs (const char *text,
+ int length,
+ GSList *attributes,
+ int offset,
+ PangoLogAttr *log_attrs,
+ int log_attrs_len)
+{
+ PangoAttrList *list;
+ PangoAttrIterator *iter;
+ GSList *l;
+
+ list = pango_attr_list_new ();
+ for (l = attributes; l; l = l->next)
+ {
+ PangoAttribute *attr = l->data;
+
+ if (attr->klass->type == PANGO_ATTR_ALLOW_BREAKS)
+ pango_attr_list_insert (list, (PangoAttribute*)l->data);
+ }
+
+ iter = pango_attr_list_get_iterator (list);
+ do {
+ PangoAttribute *attr;
+
+ attr = pango_attr_iterator_get (iter, PANGO_ATTR_ALLOW_BREAKS);
+ if (attr && ((PangoAttrInt*)attr)->value == 0)
+ {
+ int start, end;
+ int start_pos, end_pos;
+ int pos;
+
+ pango_attr_iterator_range (iter, &start, &end);
+ if (start < offset)
+ start_pos = 0;
+ else
+ start_pos = g_utf8_pointer_to_offset (text, text + start - offset);
+ if (end >= offset + length)
+ end_pos = log_attrs_len;
+ else
+ end_pos = g_utf8_pointer_to_offset (text, text + end - offset);
+
+ 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;
+ }
+ }
+ } while (pango_attr_iterator_next (iter));
+
+ pango_attr_iterator_destroy (iter);
+ pango_attr_list_unref (list);
+
+ return TRUE;
+}