diff options
author | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2023-12-08 12:30:56 +0200 |
---|---|---|
committer | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2024-02-23 12:40:13 +0200 |
commit | ad017a20eac1e58eaeca18b0ee6a5e89e7ee7ab9 (patch) | |
tree | ac405da5edc7ace680d3ba22e2eb2d20f93cf698 /modules/text_server_adv | |
parent | 60b927b4cf0e3fb34a0b14ce9b6f9157e69dd549 (diff) | |
download | redot-engine-ad017a20eac1e58eaeca18b0ee6a5e89e7ee7ab9.tar.gz |
[TextServer] Implement soft hyphen handling.
Diffstat (limited to 'modules/text_server_adv')
-rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index c06202ed19..ea88278a17 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -4588,6 +4588,12 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S if ((sd_glyphs[j].start >= bidi_run_start) && (sd_glyphs[j].end <= bidi_run_end)) { // Copy glyphs. Glyph gl = sd_glyphs[j]; + if (gl.end == p_start + p_length && ((gl.flags & GRAPHEME_IS_SOFT_HYPHEN) == GRAPHEME_IS_SOFT_HYPHEN)) { + uint32_t index = font_get_glyph_index(gl.font_rid, gl.font_size, 0x00ad, 0); + float w = font_get_glyph_advance(gl.font_rid, gl.font_size, index)[(p_new_sd->orientation == ORIENTATION_HORIZONTAL) ? 0 : 1]; + gl.index = index; + gl.advance = w; + } Variant key; bool find_embedded = false; if (gl.count == 1) { @@ -4708,22 +4714,22 @@ double TextServerAdvanced::_shaped_text_fit_to_width(const RID &p_shaped, double if (p_jst_flags.has_flag(JUSTIFICATION_TRIM_EDGE_SPACES)) { // Trim spaces. - while ((start_pos < end_pos) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while ((start_pos < end_pos) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { justification_width -= sd->glyphs[start_pos].advance * sd->glyphs[start_pos].repeat; sd->glyphs.write[start_pos].advance = 0; start_pos += sd->glyphs[start_pos].count; } - while ((start_pos < end_pos) && ((sd->glyphs[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while ((start_pos < end_pos) && ((sd->glyphs[end_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((sd->glyphs[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { justification_width -= sd->glyphs[end_pos].advance * sd->glyphs[end_pos].repeat; sd->glyphs.write[end_pos].advance = 0; end_pos -= sd->glyphs[end_pos].count; } } else { // Skip breaks, but do not reset size. - while ((start_pos < end_pos) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while ((start_pos < end_pos) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { start_pos += sd->glyphs[start_pos].count; } - while ((start_pos < end_pos) && ((sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while ((start_pos < end_pos) && ((sd->glyphs[end_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (sd->glyphs[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { end_pos -= sd->glyphs[end_pos].count; } } @@ -4739,7 +4745,7 @@ double TextServerAdvanced::_shaped_text_fit_to_width(const RID &p_shaped, double elongation_count++; } } - if ((gl.flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE && (gl.flags & GRAPHEME_IS_PUNCTUATION) != GRAPHEME_IS_PUNCTUATION) { + if ((gl.flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN && (gl.flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE && (gl.flags & GRAPHEME_IS_PUNCTUATION) != GRAPHEME_IS_PUNCTUATION) { space_count++; } } @@ -4772,7 +4778,7 @@ double TextServerAdvanced::_shaped_text_fit_to_width(const RID &p_shaped, double for (int i = start_pos; i <= end_pos; i++) { Glyph &gl = sd->glyphs.write[i]; if (gl.count > 0) { - if ((gl.flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE && (gl.flags & GRAPHEME_IS_PUNCTUATION) != GRAPHEME_IS_PUNCTUATION) { + if ((gl.flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN && (gl.flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE && (gl.flags & GRAPHEME_IS_PUNCTUATION) != GRAPHEME_IS_PUNCTUATION) { double old_adv = gl.advance; double new_advance; if ((gl.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) { @@ -5420,6 +5426,9 @@ bool TextServerAdvanced::_shaped_text_update_breaks(const RID &p_shaped) { if (c == 0x0009 || c == 0x000b) { sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_TAB; } + if (c == 0x00ad) { + sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_SOFT_HYPHEN; + } if (is_whitespace(c)) { sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_SPACE; } @@ -5441,7 +5450,7 @@ bool TextServerAdvanced::_shaped_text_update_breaks(const RID &p_shaped) { if (sd->breaks.has(sd_glyphs[i].end)) { if (sd->breaks[sd_glyphs[i].end] && (is_linebreak(c))) { sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_BREAK_HARD; - } else if (is_whitespace(c)) { + } else if (is_whitespace(c) || c == 0x00ad) { sd_glyphs_new[sd_shift + i].flags |= GRAPHEME_IS_BREAK_SOFT; } else { int count = sd_glyphs[i].count; @@ -5660,7 +5669,7 @@ bool TextServerAdvanced::_shaped_text_update_justification_ops(const RID &p_shap sd_glyphs[i].flags |= GRAPHEME_IS_ELONGATION; } if (sd->jstops.has(sd_glyphs[i].start)) { - if (c == 0xfffc) { + if (c == 0xfffc || c == 0x00ad) { continue; } if (sd->jstops[sd_glyphs[i].start]) { |