Skip to content

Commit c80eb95

Browse files
committed
Merge pull request #103224 from bruvzg/lbl_rounding_errors
[Label] Fix rounding errors with fractional scale.
2 parents 0b1a7af + 8016c53 commit c80eb95

File tree

1 file changed

+61
-10
lines changed

1 file changed

+61
-10
lines changed

scene/gui/label.cpp

+61-10
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,15 @@ int Label::get_line_height(int p_line) const {
9191
int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size;
9292
int font_h = font->get_height(font_size);
9393
if (p_line >= 0 && p_line < total_line_count) {
94-
return MAX(font_h, TS->shaped_text_get_size(get_line_rid(p_line)).y);
94+
RID rid = get_line_rid(p_line);
95+
double asc = TS->shaped_text_get_ascent(rid);
96+
double dsc = TS->shaped_text_get_descent(rid);
97+
if (asc + dsc < font_h) {
98+
double diff = font_h - (asc + dsc);
99+
asc += diff / 2;
100+
dsc += diff - (diff / 2);
101+
}
102+
return asc + dsc;
95103
} else if (total_line_count > 0) {
96104
int h = font_h;
97105
for (const Paragraph &para : paragraphs) {
@@ -357,7 +365,14 @@ void Label::_update_visible() const {
357365
break;
358366
}
359367
for (int i = start; i < end; i++) {
360-
minsize.height += MAX(font_h, TS->shaped_text_get_size(para.lines_rid[i]).y) + line_spacing;
368+
double asc = TS->shaped_text_get_ascent(para.lines_rid[i]);
369+
double dsc = TS->shaped_text_get_descent(para.lines_rid[i]);
370+
if (asc + dsc < font_h) {
371+
double diff = font_h - (asc + dsc);
372+
asc += diff / 2;
373+
dsc += diff - (diff / 2);
374+
}
375+
minsize.height += asc + dsc + line_spacing;
361376
}
362377
minsize.height += paragraph_spacing;
363378
line_index += para.lines_rid.size();
@@ -454,8 +469,16 @@ Rect2 Label::_get_line_rect(int p_para, int p_line) const {
454469
int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size;
455470
int font_h = font->get_height(font_size);
456471
Size2 size = get_size();
457-
Size2 line_size = TS->shaped_text_get_size(paragraphs[p_para].lines_rid[p_line]);
458-
line_size.y = MAX(font_h, line_size.y);
472+
RID rid = paragraphs[p_para].lines_rid[p_line];
473+
Size2 line_size = TS->shaped_text_get_size(rid);
474+
double asc = TS->shaped_text_get_ascent(rid);
475+
double dsc = TS->shaped_text_get_descent(rid);
476+
if (asc + dsc < font_h) {
477+
double diff = font_h - (asc + dsc);
478+
asc += diff / 2;
479+
dsc += diff - (diff / 2);
480+
}
481+
line_size.y = asc + dsc;
459482
Vector2 offset;
460483
switch (horizontal_alignment) {
461484
case HORIZONTAL_ALIGNMENT_FILL:
@@ -508,8 +531,15 @@ int Label::get_layout_data(Vector2 &r_offset, int &r_last_line, int &r_line_spac
508531
} else {
509532
int start = (line_index < lines_skipped) ? lines_skipped - line_index : 0;
510533
for (int i = start; i < para.lines_rid.size(); i++) {
511-
total_h += MAX(font_h, TS->shaped_text_get_size(para.lines_rid[i]).y) + line_spacing;
512-
if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) {
534+
double asc = TS->shaped_text_get_ascent(para.lines_rid[i]);
535+
double dsc = TS->shaped_text_get_descent(para.lines_rid[i]);
536+
if (asc + dsc < font_h) {
537+
double diff = font_h - (asc + dsc);
538+
asc += diff / 2;
539+
dsc += diff - (diff / 2);
540+
}
541+
total_h += asc + dsc + line_spacing;
542+
if (total_h > Math::ceil(get_size().height - style->get_minimum_size().height + line_spacing)) {
513543
break;
514544
}
515545
lines_visible++;
@@ -539,7 +569,14 @@ int Label::get_layout_data(Vector2 &r_offset, int &r_last_line, int &r_line_spac
539569
break;
540570
}
541571
for (int i = start; i < end; i++) {
542-
total_h += MAX(font_h, TS->shaped_text_get_size(para.lines_rid[i]).y) + line_spacing;
572+
double asc = TS->shaped_text_get_ascent(para.lines_rid[i]);
573+
double dsc = TS->shaped_text_get_descent(para.lines_rid[i]);
574+
if (asc + dsc < font_h) {
575+
double diff = font_h - (asc + dsc);
576+
asc += diff / 2;
577+
dsc += diff - (diff / 2);
578+
}
579+
total_h += asc + dsc + line_spacing;
543580
total_glyphs += TS->shaped_text_get_glyph_count(para.lines_rid[i]) + TS->shaped_text_get_ellipsis_glyph_count(para.lines_rid[i]);
544581
}
545582
total_h += paragraph_spacing;
@@ -879,7 +916,14 @@ Rect2 Label::get_character_bounds(int p_pos) const {
879916
}
880917
gl_off += glyphs[j].advance * glyphs[j].repeat;
881918
}
882-
ofs.y += MAX(font_h, TS->shaped_text_get_ascent(line_rid) + TS->shaped_text_get_descent(line_rid)) + line_spacing;
919+
double asc = TS->shaped_text_get_ascent(line_rid);
920+
double dsc = TS->shaped_text_get_descent(line_rid);
921+
if (asc + dsc < font_h) {
922+
double diff = font_h - (asc + dsc);
923+
asc += diff / 2;
924+
dsc += diff - (diff / 2);
925+
}
926+
ofs.y += asc + dsc + line_spacing;
883927
}
884928
ofs.y += paragraph_spacing;
885929
line_index += para.lines_rid.size();
@@ -948,8 +992,15 @@ int Label::get_visible_line_count() const {
948992
} else {
949993
int start = (line_index < lines_skipped) ? lines_skipped - line_index : 0;
950994
for (int i = start; i < para.lines_rid.size(); i++) {
951-
total_h += MAX(font_h, TS->shaped_text_get_size(para.lines_rid[i]).y) + line_spacing;
952-
if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) {
995+
double asc = TS->shaped_text_get_ascent(para.lines_rid[i]);
996+
double dsc = TS->shaped_text_get_descent(para.lines_rid[i]);
997+
if (asc + dsc < font_h) {
998+
double diff = font_h - (asc + dsc);
999+
asc += diff / 2;
1000+
dsc += diff - (diff / 2);
1001+
}
1002+
total_h += asc + dsc + line_spacing;
1003+
if (total_h > Math::ceil(get_size().height - style->get_minimum_size().height + line_spacing)) {
9531004
break;
9541005
}
9551006
lines_visible++;

0 commit comments

Comments
 (0)