diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-11-23 15:45:58 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-11-23 15:45:58 +0000 |
commit | 55efd092b0319f2a2697c510eafc2b0b23597d26 (patch) | |
tree | f8d8664f1f4652c0ca777b78f90581891f8e7361 | |
parent | a31741faf6e59737c561574c3a7679ea185f4154 (diff) | |
parent | 0a1218ebb121a829b2a63ac98f36c28e594e124f (diff) | |
download | pango-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.c | 9 | ||||
-rw-r--r-- | pango/pango-attributes.h | 4 | ||||
-rw-r--r-- | pango/pango-coverage.h | 2 | ||||
-rw-r--r-- | pango/pango-font.h | 1 | ||||
-rw-r--r-- | pango/pango-layout.c | 31 | ||||
-rw-r--r-- | pango/pango-layout.h | 4 | ||||
-rw-r--r-- | pango/pango-tabs.h | 3 | ||||
-rw-r--r-- | tests/breaks/eight.expected | 2 | ||||
-rw-r--r-- | tests/breaks/eleven.expected | 14 | ||||
-rw-r--r-- | tests/breaks/fifteen.expected | 4 | ||||
-rw-r--r-- | tests/breaks/one.expected | 4 | ||||
-rw-r--r-- | tests/breaks/seventeen.expected | 2 | ||||
-rw-r--r-- | tests/breaks/sixteen.expected | 4 | ||||
-rw-r--r-- | tests/breaks/thirteen.expected | 4 | ||||
-rw-r--r-- | tests/breaks/two.break | 2 | ||||
-rw-r--r-- | tests/breaks/two.expected | 14 | ||||
-rw-r--r-- | tests/layouts/bratwurst.expected | 32 | ||||
-rw-r--r-- | tests/layouts/bratwurst.layout | 21 |
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 |