From 0b84e14251445de349038eca15d2559dfe25ae26 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 20 Nov 2021 22:54:27 -0500 Subject: Add more autoptr definitions --- pango/pango-attributes.h | 4 ++++ pango/pango-coverage.h | 2 ++ pango/pango-font.h | 1 + pango/pango-layout.h | 4 ++++ pango/pango-tabs.h | 3 +++ 5 files changed, 14 insertions(+) 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.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__ */ -- cgit v1.2.1 From 9d114095bd4c4fb5ab64fff0ed5c1f6680ed2609 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 21 Nov 2021 11:02:07 -0500 Subject: Fix a case of unintended hyphenation When we take a complete item because there are no breakpoints, we were inserting a hyphen at the end even though there may not be a breakpoint there, and ending up with a hyphen in the middle of an (overlong) line: Brat-wurst. Test included. This but was discovered with the help of http://gitlab.gnome.org/matthiasc/layout-editor --- pango/pango-layout.c | 3 ++- tests/layouts/bratwurst.expected | 32 ++++++++++++++++++++++++++++++++ tests/layouts/bratwurst.layout | 21 +++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 tests/layouts/bratwurst.expected create mode 100644 tests/layouts/bratwurst.layout diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 050138df..3cdb677a 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -4107,7 +4107,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); 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 -- cgit v1.2.1 From 6655ceabff26f7830335833ace8e59e78251c296 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 21 Nov 2021 16:17:37 -0500 Subject: break: Fix hyphen condition When looking at scripts, we want to look at the script of the *previous* character. And then we need to exclude SHY from the common script. --- pango/break.c | 9 +++++++-- tests/breaks/eight.expected | 2 +- tests/breaks/eleven.expected | 14 +++++++------- tests/breaks/fifteen.expected | 4 ++-- tests/breaks/one.expected | 4 ++-- tests/breaks/seventeen.expected | 2 +- tests/breaks/sixteen.expected | 4 ++-- tests/breaks/thirteen.expected | 4 ++-- tests/breaks/two.break | 2 +- tests/breaks/two.expected | 14 +++++++------- 10 files changed, 32 insertions(+), 27 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/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 -- cgit v1.2.1 From 0a1218ebb121a829b2a63ac98f36c28e594e124f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 21 Nov 2021 16:20:25 -0500 Subject: Fix handling of extra width When handling items that fix completely, we were not consistently taking extra width into account, leading to hyphens sticking out in some cases. --- pango/pango-layout.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 3cdb677a..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) { @@ -5947,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); -- cgit v1.2.1