From ad017a20eac1e58eaeca18b0ee6a5e89e7ee7ab9 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Fri, 8 Dec 2023 12:30:56 +0200 Subject: [TextServer] Implement soft hyphen handling. --- servers/text_server.cpp | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'servers/text_server.cpp') diff --git a/servers/text_server.cpp b/servers/text_server.cpp index cd06027f9f..b67a698615 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -572,6 +572,7 @@ void TextServer::_bind_methods() { BIND_BITFIELD_FLAG(GRAPHEME_IS_CONNECTED); BIND_BITFIELD_FLAG(GRAPHEME_IS_SAFE_TO_INSERT_TATWEEL); BIND_BITFIELD_FLAG(GRAPHEME_IS_EMBEDDED_OBJECT); + BIND_BITFIELD_FLAG(GRAPHEME_IS_SOFT_HYPHEN); /* Hinting */ BIND_ENUM_CONSTANT(HINTING_NONE); @@ -733,6 +734,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped ERR_FAIL_COND_V(p_width.is_empty(), lines); + TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped); const_cast(this)->shaped_text_update_breaks(p_shaped); const Vector2i &range = shaped_text_get_range(p_shaped); @@ -758,10 +760,10 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) { int start_pos = prev_safe_break; int end_pos = last_safe_break; - while (trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while (trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { start_pos += l_gl[start_pos].count; } - while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { end_pos -= l_gl[end_pos].count; } if (last_end <= l_gl[start_pos].start) { @@ -829,8 +831,17 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped } if (p_break_flags.has_flag(BREAK_WORD_BOUND)) { if ((l_gl[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) { - last_safe_break = i; - word_count++; + if ((l_gl[i].flags & GRAPHEME_IS_SOFT_HYPHEN) == GRAPHEME_IS_SOFT_HYPHEN) { + uint32_t gl = font_get_glyph_index(l_gl[i].font_rid, l_gl[i].font_size, 0x00ad, 0); + float w = font_get_glyph_advance(l_gl[i].font_rid, l_gl[i].font_size, gl)[(orientation == ORIENTATION_HORIZONTAL) ? 0 : 1]; + if (width + l_gl[i].advance + w <= p_width[chunk]) { + last_safe_break = i; + word_count++; + } + } else { + last_safe_break = i; + word_count++; + } } } if (p_break_flags.has_flag(BREAK_GRAPHEME_BOUND) && word_count == 0) { @@ -876,6 +887,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do int word_count = 0; bool trim_next = false; + TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped); int l_size = shaped_text_get_glyph_count(p_shaped); const Glyph *l_gl = const_cast(this)->shaped_text_sort_logical(p_shaped); @@ -889,10 +901,10 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) { int start_pos = prev_safe_break; int end_pos = last_safe_break; - while (trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while (trim_next && (start_pos < end_pos) && ((l_gl[start_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[start_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[start_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { start_pos += l_gl[start_pos].count; } - while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { + while ((start_pos < end_pos) && ((l_gl[end_pos].flags & GRAPHEME_IS_SOFT_HYPHEN) != GRAPHEME_IS_SOFT_HYPHEN) && ((l_gl[end_pos].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD || (l_gl[end_pos].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT)) { end_pos -= l_gl[end_pos].count; } if (last_end <= l_gl[start_pos].start) { @@ -949,8 +961,17 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do } if (p_break_flags.has_flag(BREAK_WORD_BOUND)) { if ((l_gl[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) { - last_safe_break = i; - word_count++; + if ((l_gl[i].flags & GRAPHEME_IS_SOFT_HYPHEN) == GRAPHEME_IS_SOFT_HYPHEN) { + uint32_t gl = font_get_glyph_index(l_gl[i].font_rid, l_gl[i].font_size, 0x00AD, 0); + float w = font_get_glyph_advance(l_gl[i].font_rid, l_gl[i].font_size, gl)[(orientation == ORIENTATION_HORIZONTAL) ? 0 : 1]; + if (width + l_gl[i].advance + w <= p_width) { + last_safe_break = i; + word_count++; + } + } else { + last_safe_break = i; + word_count++; + } } if (p_break_flags.has_flag(BREAK_ADAPTIVE) && word_count == 0) { last_safe_break = i; -- cgit v1.2.3