You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-07 12:30:27 +00:00
[TextServer] Implement soft hyphen handling.
This commit is contained in:
@@ -3367,6 +3367,10 @@ RID TextServerFallback::_shaped_text_substr(const RID &p_shaped, int64_t p_start
|
||||
for (int i = 0; i < sd_size; i++) {
|
||||
if ((sd_glyphs[i].start >= new_sd->start) && (sd_glyphs[i].end <= new_sd->end)) {
|
||||
Glyph gl = sd_glyphs[i];
|
||||
if (gl.end == p_start + p_length && ((gl.flags & GRAPHEME_IS_SOFT_HYPHEN) == GRAPHEME_IS_SOFT_HYPHEN)) {
|
||||
gl.index = 0x00ad;
|
||||
gl.advance = font_get_glyph_advance(gl.font_rid, gl.font_size, 0x00ad).x;
|
||||
}
|
||||
Variant key;
|
||||
bool find_embedded = false;
|
||||
if (gl.count == 1) {
|
||||
@@ -3480,22 +3484,22 @@ double TextServerFallback::_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)) {
|
||||
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)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -3504,7 +3508,7 @@ double TextServerFallback::_shaped_text_fit_to_width(const RID &p_shaped, double
|
||||
for (int i = start_pos; i <= end_pos; i++) {
|
||||
const Glyph &gl = sd->glyphs[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) {
|
||||
space_count++;
|
||||
}
|
||||
}
|
||||
@@ -3515,7 +3519,7 @@ double TextServerFallback::_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;
|
||||
gl.advance = MAX(gl.advance + delta_width_per_space, Math::round(0.1 * gl.font_size));
|
||||
justification_width += (gl.advance - old_adv);
|
||||
@@ -3641,6 +3645,9 @@ bool TextServerFallback::_shaped_text_update_breaks(const RID &p_shaped) {
|
||||
if (c == 0x0009 || c == 0x000b) {
|
||||
sd_glyphs[i].flags |= GRAPHEME_IS_TAB;
|
||||
}
|
||||
if (c == 0x00ad) {
|
||||
sd_glyphs[i].flags |= GRAPHEME_IS_SOFT_HYPHEN;
|
||||
}
|
||||
|
||||
i += (sd_glyphs[i].count - 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user