summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-11-23 15:45:58 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-11-23 15:45:58 +0000
commit55efd092b0319f2a2697c510eafc2b0b23597d26 (patch)
treef8d8664f1f4652c0ca777b78f90581891f8e7361
parenta31741faf6e59737c561574c3a7679ea185f4154 (diff)
parent0a1218ebb121a829b2a63ac98f36c28e594e124f (diff)
downloadpango-55efd092b0319f2a2697c510eafc2b0b23597d26.tar.gz
Merge branch 'line-breaking-fixes4' into 'main'
Fix a case of unintended hyphenation See merge request GNOME/pango!519
-rw-r--r--pango/break.c9
-rw-r--r--pango/pango-attributes.h4
-rw-r--r--pango/pango-coverage.h2
-rw-r--r--pango/pango-font.h1
-rw-r--r--pango/pango-layout.c31
-rw-r--r--pango/pango-layout.h4
-rw-r--r--pango/pango-tabs.h3
-rw-r--r--tests/breaks/eight.expected2
-rw-r--r--tests/breaks/eleven.expected14
-rw-r--r--tests/breaks/fifteen.expected4
-rw-r--r--tests/breaks/one.expected4
-rw-r--r--tests/breaks/seventeen.expected2
-rw-r--r--tests/breaks/sixteen.expected4
-rw-r--r--tests/breaks/thirteen.expected4
-rw-r--r--tests/breaks/two.break2
-rw-r--r--tests/breaks/two.expected14
-rw-r--r--tests/layouts/bratwurst.expected32
-rw-r--r--tests/layouts/bratwurst.layout21
18 files changed, 124 insertions, 33 deletions
diff --git a/pango/break.c b/pango/break.c
index 3af083ce..5622ca21 100644
--- a/pango/break.c
+++ b/pango/break.c
@@ -170,6 +170,8 @@ default_break (const char *text,
GUnicodeBreakType prev_break_type;
GUnicodeBreakType prev_prev_break_type;
+ PangoScript prev_script;
+
/* See Grapheme_Cluster_Break Property Values table of UAX#29 */
typedef enum
{
@@ -262,6 +264,7 @@ default_break (const char *text,
prev_break_type = G_UNICODE_BREAK_UNKNOWN;
prev_prev_break_type = G_UNICODE_BREAK_UNKNOWN;
prev_wc = 0;
+ prev_script = PANGO_SCRIPT_COMMON;
prev_jamo = NO_JAMO;
prev_space_or_hyphen = FALSE;
@@ -539,7 +542,6 @@ default_break (const char *text,
}
script = (PangoScript)g_unichar_get_script (wc);
-
/* ---- UAX#29 Word Boundaries ---- */
{
is_word_boundary = FALSE;
@@ -1571,9 +1573,11 @@ default_break (const char *text,
attrs[i].break_inserts_hyphen = FALSE;
attrs[i].break_removes_preceding = FALSE;
- switch ((int)script)
+ switch ((int)prev_script)
{
case PANGO_SCRIPT_COMMON:
+ insert_hyphens = prev_wc == 0x00ad;
+ break;
case PANGO_SCRIPT_HAN:
case PANGO_SCRIPT_HANGUL:
case PANGO_SCRIPT_HIRAGANA:
@@ -1634,6 +1638,7 @@ default_break (const char *text,
}
prev_wc = wc;
+ prev_script = script;
/* wc might not be a valid Unicode base character, but really all we
* need to know is the last non-combining character */
diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h
index 5ea6bd9e..f1bd5635 100644
--- a/pango/pango-attributes.h
+++ b/pango/pango-attributes.h
@@ -739,6 +739,10 @@ void pango_attr_iterator_get_font (PangoAttrIterator *
PANGO_AVAILABLE_IN_1_2
GSList * pango_attr_iterator_get_attrs (PangoAttrIterator *iterator);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoAttribute, pango_attribute_destroy)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoAttrList, pango_attr_list_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoAttrIterator, pango_attr_iterator_destroy)
+
G_END_DECLS
#endif /* __PANGO_ATTRIBUTES_H__ */
diff --git a/pango/pango-coverage.h b/pango/pango-coverage.h
index dbee7e9f..b24d73d5 100644
--- a/pango/pango-coverage.h
+++ b/pango/pango-coverage.h
@@ -101,6 +101,8 @@ PANGO_DEPRECATED_IN_1_44
PangoCoverage *pango_coverage_from_bytes (guchar *bytes,
int n_bytes);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoCoverage, pango_coverage_unref)
+
G_END_DECLS
#endif /* __PANGO_COVERAGE_H__ */
diff --git a/pango/pango-font.h b/pango/pango-font.h
index 6f3284fa..c56fb792 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -689,6 +689,7 @@ PangoLanguage ** pango_font_get_languages (PangoFont *font);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoFontFamily, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoFontFace, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoFont, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoFontDescription, pango_font_description_free)
G_END_DECLS
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 050138df..a5806774 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -3930,15 +3930,29 @@ process_item (PangoLayout *layout,
width += state->log_widths[state->log_widths_offset + i];
}
- if ((width <= state->remaining_width || (item->num_chars == 1 && !line->runs)) &&
+ if (!no_break_at_end &&
+ can_break_at (layout, state->start_offset + item->num_chars, wrap))
+ {
+ if (processing_new_item)
+ {
+ compute_log_widths (layout, state);
+ processing_new_item = FALSE;
+ }
+
+ extra_width = find_break_extra_width (layout, state, item->num_chars);
+ }
+ else
+ extra_width = 0;
+
+ if ((width + extra_width <= state->remaining_width || (item->num_chars == 1 && !line->runs)) &&
!no_break_at_end)
{
- DEBUG1 ("%d <= %d", width, state->remaining_width);
+ DEBUG1 ("%d + %d <= %d", width, extra_width, state->remaining_width);
insert_run (line, state, item, NULL, FALSE);
width = pango_glyph_string_get_width (((PangoGlyphItem *)(line->runs->data))->glyphs);
- if (width <= state->remaining_width || (item->num_chars == 1 && !line->runs))
+ if (width + extra_width <= state->remaining_width || (item->num_chars == 1 && !line->runs))
{
state->remaining_width -= width;
state->remaining_width = MAX (state->remaining_width, 0);
@@ -4007,7 +4021,7 @@ retry_break:
if (can_break_at (layout, state->start_offset + num_chars, wrap) &&
(num_chars > 0 || line->runs))
{
- DEBUG1 ("possible breakpoint: %d", num_chars);
+ DEBUG1 ("possible breakpoint: %d, extra_width %d", num_chars, extra_width);
if (num_chars == 0 ||
width + extra_width < state->remaining_width - safe_distance)
{
@@ -4044,10 +4058,13 @@ retry_break:
if (num_chars > 0 &&
layout->log_attrs[state->start_offset + num_chars - 1].is_white)
extra_width = - state->log_widths[state->log_widths_offset + num_chars - 1];
+ else if (item == new_item &&
+ break_needs_hyphen (layout, state, num_chars))
+ extra_width = state->hyphen_width;
else
extra_width = 0;
- DEBUG1 ("measured breakpoint %d: %d", num_chars, new_break_width);
+ DEBUG1 ("measured breakpoint %d: %d, extra %d", num_chars, new_break_width, extra_width);
if (new_item != item)
{
@@ -4107,7 +4124,8 @@ retry_break:
if (break_num_chars == item->num_chars)
{
- if (break_needs_hyphen (layout, state, break_num_chars))
+ if (can_break_at (layout, state->start_offset + break_num_chars, wrap) &&
+ break_needs_hyphen (layout, state, break_num_chars))
item->analysis.flags |= PANGO_ANALYSIS_FLAG_NEED_HYPHEN;
insert_run (line, state, item, NULL, TRUE);
@@ -5946,6 +5964,7 @@ add_missing_hyphen (PangoLayoutLine *line,
int width;
int start_offset;
+ DEBUG1("add a missing hyphen");
/* The last run fit onto the line without breaking it, but it still needs a hyphen */
width = pango_glyph_string_get_width (run->glyphs);
diff --git a/pango/pango-layout.h b/pango/pango-layout.h
index 502f5e29..3b725adc 100644
--- a/pango/pango-layout.h
+++ b/pango/pango-layout.h
@@ -494,6 +494,10 @@ int pango_layout_iter_get_baseline (PangoLayoutIter *iter);
PANGO_AVAILABLE_IN_1_50
int pango_layout_iter_get_run_baseline (PangoLayoutIter *iter);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoLayout, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoLayoutIter, pango_layout_iter_free)
+
G_END_DECLS
#endif /* __PANGO_LAYOUT_H__ */
diff --git a/pango/pango-tabs.h b/pango/pango-tabs.h
index e8ce1b97..d2a68d5a 100644
--- a/pango/pango-tabs.h
+++ b/pango/pango-tabs.h
@@ -92,6 +92,9 @@ char * pango_tab_array_to_string (PangoTabArray *tab_array);
PANGO_AVAILABLE_IN_1_50
PangoTabArray * pango_tab_array_from_string (const char *text);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoTabArray, pango_tab_array_free)
+
G_END_DECLS
#endif /* __PANGO_TABS_H__ */
diff --git a/tests/breaks/eight.expected b/tests/breaks/eight.expected
index 39794d22..d71bb02f 100644
--- a/tests/breaks/eight.expected
+++ b/tests/breaks/eight.expected
@@ -4,4 +4,4 @@ Whitespace: x x x x
Sentences: bs e b
Words: bs be bs e s be bs be b bs be bs be bs be bs be bs be 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 b b b b b b b b
-Hyphens: i i i i i i i i i i i i i i i i
+Hyphens: i i i i i i i i i i i i i i i i
diff --git a/tests/breaks/eleven.expected b/tests/breaks/eleven.expected
index 8df89869..b4a33897 100644
--- a/tests/breaks/eleven.expected
+++ b/tests/breaks/eleven.expected
@@ -1,7 +1,7 @@
-Text: ⁦❤⁩ ⁦️⁩ ⁦︎⁩ ⁦︎⁩ ⁦👨⁩ [0x200d]⁦🦰⁩ ⁦👨⁩⁦🏿⁩ [0x200d]⁦🦱⁩ ⁦0⁩ ⁦️⁩ ⁦⃣⁩ ⁦🏴⁩[0xe0075][0xe0073][0xe0063][0xe0061][0xe007f] ⁦🇩⁩⁦🇪⁩ ⁦️⁩ [0x0a]
-Breaks: c lc lc lc lc lc c lc
-Whitespace: w w
-Sentences: bs e b
-Words: b b b bs be b b b
-Graphemes: b b b b b b b b
-Hyphens: i i i i i i i i
+Text: ⁦❤⁩⁦️⁩ ⁦︎⁩ ⁦︎⁩ ⁦👨⁩[0x200d] ⁦🦰⁩ ⁦👨⁩⁦🏿⁩[0x200d] ⁦🦱⁩ ⁦0⁩⁦️⁩ ⁦⃣⁩ ⁦🏴⁩[0xe0075][0xe0073][0xe0063][0xe0061][0xe007f] ⁦🇩⁩⁦🇪⁩⁦️⁩ [0x0a]
+Breaks: c lc lc lc lc lc c Lc
+Whitespace: w w
+Sentences: bs e b
+Words: b b b bs be b b b
+Graphemes: b b b b b b b b
+Hyphens: i i i i i
diff --git a/tests/breaks/fifteen.expected b/tests/breaks/fifteen.expected
index 93b37c39..3521a70b 100644
--- a/tests/breaks/fifteen.expected
+++ b/tests/breaks/fifteen.expected
@@ -1,7 +1,7 @@
Text: ⁦o⁩ ⁦n⁩ ⁦e⁩ [ ] ⁦t⁩ ⁦w⁩ ⁦o⁩ ⁦-⁩ ⁦t⁩ ⁦h⁩ ⁦r⁩ ⁦e⁩ ⁦e⁩ [ ] ⁦f⁩ ⁦o⁩ [0xad] ⁦u⁩ ⁦r⁩ [0x0a]
-Breaks: c c c c lc c c c lc c c c c c lc c c lc c c lc
+Breaks: c c c c lc c c c lc c c c c c lc c c lc c c Lc
Whitespace: x x w w
Sentences: bs e b
Words: bs be bs be bs be bs be b
Graphemes: b b b b b b b b b b b b b b b b b b b b b
-Hyphens: i i i i i i i i i
+Hyphens: i i i i i i i i i i
diff --git a/tests/breaks/one.expected b/tests/breaks/one.expected
index 44fee3ef..6c811256 100644
--- a/tests/breaks/one.expected
+++ b/tests/breaks/one.expected
@@ -1,7 +1,7 @@
Text: ⁦a⁩ ⁦b⁩ ⁦c⁩ ⁦/⁩ ⁦d⁩ ⁦e⁩ ⁦f⁩ [ ] ⁦g⁩ ⁦h⁩ ⁦i⁩ [0xad] ⁦j⁩ ⁦k⁩ ⁦l⁩ ⁦.⁩ [ ] ⁦B⁩ ⁦l⁩ ⁦a⁩ [0x0a]
-Breaks: c c c c lc c c c lc c c c lc c c c c lc c c c lc
+Breaks: c c c c lc c c c lc c c c lc c c c c lc c c c Lc
Whitespace: x x w w
Sentences: bs e bs e b
Words: bs be bs be bs be b bs be b
Graphemes: b b b b b b b b b b b b b b b b b b b b b b
-Hyphens: i i i i i i i i i i i
+Hyphens: i i i i i i i i i i i i
diff --git a/tests/breaks/seventeen.expected b/tests/breaks/seventeen.expected
index 8f5f2749..35fb5120 100644
--- a/tests/breaks/seventeen.expected
+++ b/tests/breaks/seventeen.expected
@@ -4,4 +4,4 @@ Whitespace: x x x w
Sentences: bs e bs e bs e b
Words: bs be bs be bs be bs e s be bs be bs be bs be bs e s be bs be bs be bs be bs e s e s be 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 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 b b b b b b b b b
-Hyphens: i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i
+Hyphens: i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i
diff --git a/tests/breaks/sixteen.expected b/tests/breaks/sixteen.expected
index 0fd06fb2..2868b8e4 100644
--- a/tests/breaks/sixteen.expected
+++ b/tests/breaks/sixteen.expected
@@ -1,7 +1,7 @@
Text: ⁦h⁩ ⁦y⁩ ⁦‧⁩ ⁦p⁩ ⁦h⁩ ⁦e⁩ ⁦n⁩ ⁦|⁩ ⁦a⁩ ⁦t⁩ ⁦i⁩ ⁦o⁩ ⁦n⁩ [ ] ⁦o⁩ ⁦v⁩ ⁦e⁩ ⁦r⁩ [0xad] ⁦l⁩ ⁦o⁩ ⁦a⁩ ⁦d⁩ [0x0a]
-Breaks: c c c lc c c c c lc c c c c c lc c c c c lc c c c c lc
+Breaks: c c c lc c c c c lc c c c c c lc c c c c lc c c c c Lc
Whitespace: x w w
Sentences: bs e b
Words: bs e s be bs be bs be 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
-Hyphens: i ri i i i i i i i i i i i i i i
+Hyphens: i ri i i i i i i i i i i i i i i i
diff --git a/tests/breaks/thirteen.expected b/tests/breaks/thirteen.expected
index e6b1787d..25a38150 100644
--- a/tests/breaks/thirteen.expected
+++ b/tests/breaks/thirteen.expected
@@ -1,7 +1,7 @@
Text: ⁦a⁩ [ ] ⁦a⁩ ⁦b⁩ [0x200b] ⁦s⁩ ⁦p⁩ [0x200b] [ ] [ ] ⁦d⁩ ⁦e⁩ [0xad] ⁦f⁩ ⁦g⁩ [ ] ⁦b⁩ [0x0a]
-Breaks: c c lc c c lc c c c c lc c c lc c c lc c lc
+Breaks: c c lc c c lc c c c c lc c c lc c c lc c Lc
Whitespace: x x x x w w
Sentences: bs e b
Words: bs be bs be bs be b
Graphemes: b b b b b b b b b b b b b b b b b b b
-Hyphens: i i i i i i
+Hyphens: i i i i i i i i
diff --git a/tests/breaks/two.break b/tests/breaks/two.break
index 6ff0a36e..53c39c5c 100644
--- a/tests/breaks/two.break
+++ b/tests/breaks/two.break
@@ -1,3 +1,3 @@
# Example from https://gitlab.gnome.org/GNOME/pango/issues/218
# This shows difference between word start/end and boundary
-goril·les
+goril‧les
diff --git a/tests/breaks/two.expected b/tests/breaks/two.expected
index 2921d224..58d15186 100644
--- a/tests/breaks/two.expected
+++ b/tests/breaks/two.expected
@@ -1,7 +1,7 @@
-Text: ⁦g⁩ ⁦o⁩ ⁦r⁩ ⁦i⁩ ⁦l⁩ ⁦·⁩ ⁦l⁩ ⁦e⁩ ⁦s⁩ [0x0a]
-Breaks: c c c c c c c c c c lc
-Whitespace: w w
-Sentences: bs e b
-Words: bs e s be b
-Graphemes: b b b b b b b b b b b
-Hyphens: i i i i i i i
+Text: ⁦g⁩ ⁦o⁩ ⁦r⁩ ⁦i⁩ ⁦l⁩ ⁦‧⁩ ⁦l⁩ ⁦e⁩ ⁦s⁩ [0x0a]
+Breaks: c c c c c c lc c c c Lc
+Whitespace: w w
+Sentences: bs e b
+Words: bs e s be b
+Graphemes: b b b b b b b b b b b
+Hyphens: i i i i ri i i
diff --git a/tests/layouts/bratwurst.expected b/tests/layouts/bratwurst.expected
new file mode 100644
index 00000000..f81dbaeb
--- /dev/null
+++ b/tests/layouts/bratwurst.expected
@@ -0,0 +1,32 @@
+Bratwurst
+--- parameters
+
+wrapped: 0
+ellipsized: 0
+lines: 1
+width: 102400
+
+--- attributes
+
+range 0 4
+range 4 2147483647
+4 4294967295 style italic
+range 2147483647 2147483647
+
+--- directions
+
+0 0 0 0 0 0 0 0 0
+
+--- cursor positions
+
+0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 8(1)
+
+--- lines
+
+i=1, index=0, paragraph-start=1, dir=ltr 'Bratwurst'
+
+--- runs
+
+i=1, index=0, chars=4, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'Brat'
+i=2, index=4, chars=5, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'wurst'
+i=3, index=9, no run, line end
diff --git a/tests/layouts/bratwurst.layout b/tests/layouts/bratwurst.layout
new file mode 100644
index 00000000..65104276
--- /dev/null
+++ b/tests/layouts/bratwurst.layout
@@ -0,0 +1,21 @@
+{
+ "text" : "Bratwurst",
+ "attributes" : [
+ {
+ "start" : 4,
+ "type" : "style",
+ "value" : "italic"
+ }
+ ],
+ "font" : "Sans Bold 32",
+ "tabs" : {
+ "positions-in-pixels" : true,
+ "positions" : [
+ 0,
+ 50,
+ 100
+ ]
+ },
+ "width" : 102400,
+ "line-spacing" : 1.2999999523162842
+} \ No newline at end of file