diff options
author | Matthias Clasen <mclasen@redhat.com> | 2019-07-20 10:36:48 -0700 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-07-20 11:56:18 -0700 |
commit | c7c8d8120925f83c638cc496b3f4de07aed442d0 (patch) | |
tree | 591d9a38e03130c9e10f91b00ad3babbed7aebd3 /pango/break.c | |
parent | 62580f2fa5e46d51bb2377d4028471926108bab3 (diff) | |
download | pango-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.c | 96 |
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; +} |