Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Label] Fix rounding errors with fractional scale. #103224

Merged
merged 1 commit into from
Feb 24, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 61 additions & 10 deletions scene/gui/label.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,15 @@ int Label::get_line_height(int p_line) const {
int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size;
int font_h = font->get_height(font_size);
if (p_line >= 0 && p_line < total_line_count) {
return MAX(font_h, TS->shaped_text_get_size(get_line_rid(p_line)).y);
RID rid = get_line_rid(p_line);
double asc = TS->shaped_text_get_ascent(rid);
double dsc = TS->shaped_text_get_descent(rid);
if (asc + dsc < font_h) {
double diff = font_h - (asc + dsc);
asc += diff / 2;
dsc += diff - (diff / 2);
}
return asc + dsc;
} else if (total_line_count > 0) {
int h = font_h;
for (const Paragraph &para : paragraphs) {
Expand Down Expand Up @@ -357,7 +365,14 @@ void Label::_update_visible() const {
break;
}
for (int i = start; i < end; i++) {
minsize.height += MAX(font_h, TS->shaped_text_get_size(para.lines_rid[i]).y) + line_spacing;
double asc = TS->shaped_text_get_ascent(para.lines_rid[i]);
double dsc = TS->shaped_text_get_descent(para.lines_rid[i]);
if (asc + dsc < font_h) {
double diff = font_h - (asc + dsc);
asc += diff / 2;
dsc += diff - (diff / 2);
}
minsize.height += asc + dsc + line_spacing;
}
minsize.height += paragraph_spacing;
line_index += para.lines_rid.size();
Expand Down Expand Up @@ -454,8 +469,16 @@ Rect2 Label::_get_line_rect(int p_para, int p_line) const {
int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size;
int font_h = font->get_height(font_size);
Size2 size = get_size();
Size2 line_size = TS->shaped_text_get_size(paragraphs[p_para].lines_rid[p_line]);
line_size.y = MAX(font_h, line_size.y);
RID rid = paragraphs[p_para].lines_rid[p_line];
Size2 line_size = TS->shaped_text_get_size(rid);
double asc = TS->shaped_text_get_ascent(rid);
double dsc = TS->shaped_text_get_descent(rid);
if (asc + dsc < font_h) {
double diff = font_h - (asc + dsc);
asc += diff / 2;
dsc += diff - (diff / 2);
}
line_size.y = asc + dsc;
Vector2 offset;
switch (horizontal_alignment) {
case HORIZONTAL_ALIGNMENT_FILL:
Expand Down Expand Up @@ -508,8 +531,15 @@ int Label::get_layout_data(Vector2 &r_offset, int &r_last_line, int &r_line_spac
} else {
int start = (line_index < lines_skipped) ? lines_skipped - line_index : 0;
for (int i = start; i < para.lines_rid.size(); i++) {
total_h += MAX(font_h, TS->shaped_text_get_size(para.lines_rid[i]).y) + line_spacing;
if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) {
double asc = TS->shaped_text_get_ascent(para.lines_rid[i]);
double dsc = TS->shaped_text_get_descent(para.lines_rid[i]);
if (asc + dsc < font_h) {
double diff = font_h - (asc + dsc);
asc += diff / 2;
dsc += diff - (diff / 2);
}
total_h += asc + dsc + line_spacing;
if (total_h > Math::ceil(get_size().height - style->get_minimum_size().height + line_spacing)) {
break;
}
lines_visible++;
Expand Down Expand Up @@ -539,7 +569,14 @@ int Label::get_layout_data(Vector2 &r_offset, int &r_last_line, int &r_line_spac
break;
}
for (int i = start; i < end; i++) {
total_h += MAX(font_h, TS->shaped_text_get_size(para.lines_rid[i]).y) + line_spacing;
double asc = TS->shaped_text_get_ascent(para.lines_rid[i]);
double dsc = TS->shaped_text_get_descent(para.lines_rid[i]);
if (asc + dsc < font_h) {
double diff = font_h - (asc + dsc);
asc += diff / 2;
dsc += diff - (diff / 2);
}
total_h += asc + dsc + line_spacing;
total_glyphs += TS->shaped_text_get_glyph_count(para.lines_rid[i]) + TS->shaped_text_get_ellipsis_glyph_count(para.lines_rid[i]);
}
total_h += paragraph_spacing;
Expand Down Expand Up @@ -879,7 +916,14 @@ Rect2 Label::get_character_bounds(int p_pos) const {
}
gl_off += glyphs[j].advance * glyphs[j].repeat;
}
ofs.y += MAX(font_h, TS->shaped_text_get_ascent(line_rid) + TS->shaped_text_get_descent(line_rid)) + line_spacing;
double asc = TS->shaped_text_get_ascent(line_rid);
double dsc = TS->shaped_text_get_descent(line_rid);
if (asc + dsc < font_h) {
double diff = font_h - (asc + dsc);
asc += diff / 2;
dsc += diff - (diff / 2);
}
ofs.y += asc + dsc + line_spacing;
}
ofs.y += paragraph_spacing;
line_index += para.lines_rid.size();
Expand Down Expand Up @@ -948,8 +992,15 @@ int Label::get_visible_line_count() const {
} else {
int start = (line_index < lines_skipped) ? lines_skipped - line_index : 0;
for (int i = start; i < para.lines_rid.size(); i++) {
total_h += MAX(font_h, TS->shaped_text_get_size(para.lines_rid[i]).y) + line_spacing;
if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) {
double asc = TS->shaped_text_get_ascent(para.lines_rid[i]);
double dsc = TS->shaped_text_get_descent(para.lines_rid[i]);
if (asc + dsc < font_h) {
double diff = font_h - (asc + dsc);
asc += diff / 2;
dsc += diff - (diff / 2);
}
total_h += asc + dsc + line_spacing;
if (total_h > Math::ceil(get_size().height - style->get_minimum_size().height + line_spacing)) {
break;
}
lines_visible++;
Expand Down