diff options
author | Marvin W <git@larma.de> | 2025-01-02 14:22:41 +0100 |
---|---|---|
committer | Marvin W <git@larma.de> | 2025-01-03 17:44:43 +0100 |
commit | 398c52e1b9a5c91cd99277463080819ebdedfe1d (patch) | |
tree | dc8aef72d3bdd27a75b14608af4f174a0548c670 /main/src/ui/util/helper.vala | |
parent | b490eb662fb8fb9ddbc8bbaea2b5608e7a511158 (diff) | |
download | dino-398c52e1b9a5c91cd99277463080819ebdedfe1d.tar.gz dino-398c52e1b9a5c91cd99277463080819ebdedfe1d.zip |
Work around pango bug
See https://gitlab.gnome.org/GNOME/pango/-/issues/798 and https://gitlab.gnome.org/GNOME/pango/-/issues/832
Diffstat (limited to 'main/src/ui/util/helper.vala')
-rw-r--r-- | main/src/ui/util/helper.vala | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/main/src/ui/util/helper.vala b/main/src/ui/util/helper.vala index e12dfe20..578e313a 100644 --- a/main/src/ui/util/helper.vala +++ b/main/src/ui/util/helper.vala @@ -170,6 +170,41 @@ public static Map<unichar, unichar> get_matching_chars() { return MATCHING_CHARS; } +/** + * This replaces spaces with non-breaking spaces when they are adjacent to a non-spacing mark. + * + * We do this to work-around a bug in Pango. See https://gitlab.gnome.org/GNOME/pango/-/issues/798 and + * https://gitlab.gnome.org/GNOME/pango/-/issues/832 + * + * This is zero-copy iff no space is adjacent to a non-spacing mark, otherwise the provided string will be destroyed + * and the returned string should be used instead. + */ +public static string unbreak_space_around_non_spacing_mark(owned string s) { + int current_index = 0; + unichar current_char = 0; + int prev_index = 0; + unichar prev_char = 0; + bool is_non_spacing_mark = false; + while (s.get_next_char(ref current_index, out current_char)) { + int replace_index = -1; + if (is_non_spacing_mark && current_char == ' ') { + replace_index = prev_index; + current_char = ' '; + } + is_non_spacing_mark = ICU.get_int_property_value(current_char, ICU.Property.BIDI_CLASS) == ICU.CharDirection.DIR_NON_SPACING_MARK; + if (prev_char == ' ' && is_non_spacing_mark) { + replace_index = prev_index - 1; + } + if (replace_index != -1) { + s = s[0:replace_index] + " " + s[(replace_index + 1):s.length]; + current_index += 1; + } + prev_index = current_index; + prev_char = current_char; + } + return (owned) s; +} + public static string parse_add_markup(string s_, string? highlight_word, bool parse_links, bool parse_text_markup) { bool ignore_out_var = false; return parse_add_markup_theme(s_, highlight_word, parse_links, parse_text_markup, parse_text_markup, false, ref ignore_out_var); |