[Complex Text Layouts] Adds missing Font::SPACING_* to the Label, LineEdit, TextEdit, TextLine and TextParagraph.
Fixes oversized editor control height (default editor spacing is negative) and control size changing when text is set.
This commit is contained in:
parent
d834789f47
commit
a458e90179
9 changed files with 85 additions and 52 deletions
|
@ -1874,7 +1874,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star
|
|||
}
|
||||
|
||||
if (fd == nullptr) {
|
||||
// Add fallback glyohs
|
||||
// Add fallback glyphs
|
||||
for (int i = p_start; i < p_end; i++) {
|
||||
if (p_sd->preserve_invalid || (p_sd->preserve_control && is_control(p_sd->text[i]))) {
|
||||
TextServer::Glyph gl;
|
||||
|
@ -2026,7 +2026,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star
|
|||
}
|
||||
for (int j = 0; j < w[i].count; j++) {
|
||||
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
|
||||
p_sd->ascent = MAX(p_sd->ascent, MAX(fd->get_ascent(w[i + j].font_size), w[i + j].y_off));
|
||||
p_sd->ascent = MAX(p_sd->ascent, MAX(fd->get_ascent(w[i + j].font_size), -w[i + j].y_off));
|
||||
p_sd->descent = MAX(p_sd->descent, MAX(fd->get_descent(w[i + j].font_size), w[i + j].y_off));
|
||||
} else {
|
||||
p_sd->ascent = MAX(p_sd->ascent, fd->get_advance(w[i + j].index, w[i + j].font_size).x * 0.5);
|
||||
|
|
|
@ -64,16 +64,17 @@ bool Label::is_uppercase() const {
|
|||
}
|
||||
|
||||
int Label::get_line_height(int p_line) const {
|
||||
Ref<Font> font = get_theme_font("font");
|
||||
if (p_line >= 0 && p_line < lines_rid.size()) {
|
||||
return TS->shaped_text_get_size(lines_rid[p_line]).y;
|
||||
return TS->shaped_text_get_size(lines_rid[p_line]).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM);
|
||||
} else if (lines_rid.size() > 0) {
|
||||
int h = 0;
|
||||
for (int i = 0; i < lines_rid.size(); i++) {
|
||||
h = MAX(h, TS->shaped_text_get_size(lines_rid[i]).y);
|
||||
h = MAX(h, TS->shaped_text_get_size(lines_rid[i]).y) + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM);
|
||||
}
|
||||
return h;
|
||||
} else {
|
||||
return get_theme_font("font")->get_height(get_theme_font_size("font_size"));
|
||||
return font->get_height(get_theme_font_size("font_size"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,6 +139,7 @@ void Label::_shape() {
|
|||
void Label::_update_visible() {
|
||||
int line_spacing = get_theme_constant("line_spacing", "Label");
|
||||
Ref<StyleBox> style = get_theme_stylebox("normal", "Label");
|
||||
Ref<Font> font = get_theme_font("font");
|
||||
int lines_visible = lines_rid.size();
|
||||
|
||||
if (max_lines_visible >= 0 && lines_visible > max_lines_visible) {
|
||||
|
@ -147,7 +149,7 @@ void Label::_update_visible() {
|
|||
minsize.height = 0;
|
||||
int last_line = MIN(lines_rid.size(), lines_visible + lines_skipped);
|
||||
for (int64_t i = lines_skipped; i < last_line; i++) {
|
||||
minsize.height += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
|
||||
minsize.height += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM) + line_spacing;
|
||||
if (minsize.height > (get_size().height - style->get_minimum_size().height + line_spacing)) {
|
||||
break;
|
||||
}
|
||||
|
@ -197,7 +199,7 @@ void Label::_notification(int p_what) {
|
|||
|
||||
// Get number of lines to fit to the height.
|
||||
for (int64_t i = lines_skipped; i < lines_rid.size(); i++) {
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM) + line_spacing;
|
||||
if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) {
|
||||
break;
|
||||
}
|
||||
|
@ -213,7 +215,7 @@ void Label::_notification(int p_what) {
|
|||
// Get real total height.
|
||||
total_h = 0;
|
||||
for (int64_t i = lines_skipped; i < last_line; i++) {
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM) + line_spacing;
|
||||
}
|
||||
|
||||
int vbegin = 0, vsep = 0;
|
||||
|
@ -263,7 +265,7 @@ void Label::_notification(int p_what) {
|
|||
ofs.y = style->get_offset().y + vbegin;
|
||||
for (int i = lines_skipped; i < last_line; i++) {
|
||||
ofs.x = 0;
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[i]);
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + font->get_spacing(Font::SPACING_TOP);
|
||||
switch (align) {
|
||||
case ALIGN_FILL:
|
||||
case ALIGN_LEFT: {
|
||||
|
@ -337,7 +339,7 @@ void Label::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing;
|
||||
ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing + font->get_spacing(Font::SPACING_BOTTOM);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,12 +383,13 @@ int Label::get_line_count() const {
|
|||
}
|
||||
|
||||
int Label::get_visible_line_count() const {
|
||||
Ref<Font> font = get_theme_font("font");
|
||||
Ref<StyleBox> style = get_theme_stylebox("normal");
|
||||
int line_spacing = get_theme_constant("line_spacing");
|
||||
int lines_visible = 0;
|
||||
float total_h = 0;
|
||||
for (int64_t i = lines_skipped; i < lines_rid.size(); i++) {
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM) + line_spacing;
|
||||
if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -732,6 +732,7 @@ void LineEdit::_notification(int p_what) {
|
|||
style = get_theme_stylebox("read_only");
|
||||
draw_caret = false;
|
||||
}
|
||||
Ref<Font> font = get_theme_font("font");
|
||||
|
||||
style->draw(ci, Rect2(Point2(), size));
|
||||
|
||||
|
@ -742,7 +743,7 @@ void LineEdit::_notification(int p_what) {
|
|||
int x_ofs = 0;
|
||||
bool using_placeholder = text.empty() && ime_text.empty();
|
||||
float text_width = TS->shaped_text_get_size(text_rid).x;
|
||||
float text_height = TS->shaped_text_get_size(text_rid).y;
|
||||
float text_height = TS->shaped_text_get_size(text_rid).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM);
|
||||
|
||||
switch (align) {
|
||||
case ALIGN_FILL:
|
||||
|
@ -1570,7 +1571,7 @@ Size2 LineEdit::get_minimum_size() const {
|
|||
min_size.width = MAX(min_size.width, full_width + space_size);
|
||||
}
|
||||
|
||||
min_size.height = MAX(TS->shaped_text_get_size(text_rid).y, font->get_height(font_size));
|
||||
min_size.height = MAX(TS->shaped_text_get_size(text_rid).y + font->get_spacing(Font::SPACING_TOP) + font->get_spacing(Font::SPACING_BOTTOM), font->get_height(font_size));
|
||||
|
||||
// Take icons into account.
|
||||
bool using_placeholder = text.empty() && ime_text.empty();
|
||||
|
|
|
@ -1141,7 +1141,7 @@ void TextEdit::_notification(int p_what) {
|
|||
|
||||
// Draw line.
|
||||
RID rid = ldata->get_line_rid(line_wrap_index);
|
||||
float text_height = TS->shaped_text_get_size(rid).y;
|
||||
float text_height = TS->shaped_text_get_size(rid).y + cache.font->get_spacing(Font::SPACING_TOP) + cache.font->get_spacing(Font::SPACING_BOTTOM);
|
||||
|
||||
if (rtl) {
|
||||
char_margin = size.width - char_margin - TS->shaped_text_get_size(rid).x;
|
||||
|
|
|
@ -595,41 +595,41 @@ Dictionary Font::get_feature_list() const {
|
|||
float Font::get_height(int p_size) const {
|
||||
float ret = 0.f;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
ret += data[i]->get_height(p_size);
|
||||
ret = MAX(ret, data[i]->get_height(p_size));
|
||||
}
|
||||
return (ret / data.size()) + spacing_top + spacing_bottom;
|
||||
return ret + spacing_top + spacing_bottom;
|
||||
}
|
||||
|
||||
float Font::get_ascent(int p_size) const {
|
||||
float ret = 0.f;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
ret += data[i]->get_ascent(p_size);
|
||||
ret = MAX(ret, data[i]->get_ascent(p_size));
|
||||
}
|
||||
return (ret / data.size()) + spacing_top;
|
||||
return ret + spacing_top;
|
||||
}
|
||||
|
||||
float Font::get_descent(int p_size) const {
|
||||
float ret = 0.f;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
ret += data[i]->get_descent(p_size);
|
||||
ret = MAX(ret, data[i]->get_descent(p_size));
|
||||
}
|
||||
return (ret / data.size()) + spacing_bottom;
|
||||
return ret + spacing_bottom;
|
||||
}
|
||||
|
||||
float Font::get_underline_position(int p_size) const {
|
||||
float ret = 0.f;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
ret += data[i]->get_underline_position(p_size);
|
||||
ret = MAX(ret, data[i]->get_underline_position(p_size));
|
||||
}
|
||||
return (ret / data.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
float Font::get_underline_thickness(int p_size) const {
|
||||
float ret = 0.f;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
ret += data[i]->get_underline_thickness(p_size);
|
||||
ret = MAX(ret, data[i]->get_underline_thickness(p_size));
|
||||
}
|
||||
return (ret / data.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Font::get_spacing(int p_type) const {
|
||||
|
|
|
@ -113,6 +113,8 @@ RID TextLine::get_rid() const {
|
|||
|
||||
void TextLine::clear() {
|
||||
TS->shaped_text_clear(rid);
|
||||
spacing_top = 0;
|
||||
spacing_bottom = 0;
|
||||
}
|
||||
|
||||
void TextLine::set_preserve_invalid(bool p_enabled) {
|
||||
|
@ -166,6 +168,8 @@ void TextLine::set_bidi_override(const Vector<Vector2i> &p_override) {
|
|||
|
||||
bool TextLine::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) {
|
||||
bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
|
||||
spacing_top = p_fonts->get_spacing(Font::SPACING_TOP);
|
||||
spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM);
|
||||
dirty = true;
|
||||
return res;
|
||||
}
|
||||
|
@ -233,17 +237,21 @@ float TextLine::get_width() const {
|
|||
|
||||
Size2 TextLine::get_size() const {
|
||||
const_cast<TextLine *>(this)->_shape();
|
||||
return TS->shaped_text_get_size(rid);
|
||||
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y + spacing_top + spacing_bottom);
|
||||
} else {
|
||||
return Size2(TS->shaped_text_get_size(rid).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(rid).y);
|
||||
}
|
||||
}
|
||||
|
||||
float TextLine::get_line_ascent() const {
|
||||
const_cast<TextLine *>(this)->_shape();
|
||||
return TS->shaped_text_get_ascent(rid);
|
||||
return TS->shaped_text_get_ascent(rid) + spacing_top;
|
||||
}
|
||||
|
||||
float TextLine::get_line_descent() const {
|
||||
const_cast<TextLine *>(this)->_shape();
|
||||
return TS->shaped_text_get_descent(rid);
|
||||
return TS->shaped_text_get_descent(rid) + spacing_bottom;
|
||||
}
|
||||
|
||||
float TextLine::get_line_width() const {
|
||||
|
@ -291,10 +299,10 @@ void TextLine::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color) co
|
|||
|
||||
float clip_l;
|
||||
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.y += TS->shaped_text_get_ascent(rid);
|
||||
ofs.y += TS->shaped_text_get_ascent(rid) + spacing_top;
|
||||
clip_l = MAX(0, p_pos.x - ofs.x);
|
||||
} else {
|
||||
ofs.x += TS->shaped_text_get_ascent(rid);
|
||||
ofs.x += TS->shaped_text_get_ascent(rid) + spacing_top;
|
||||
clip_l = MAX(0, p_pos.y - ofs.y);
|
||||
}
|
||||
return TS->shaped_text_draw(rid, p_canvas, ofs, clip_l, clip_l + width, p_color);
|
||||
|
@ -330,10 +338,10 @@ void TextLine::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_si
|
|||
|
||||
float clip_l;
|
||||
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.y += TS->shaped_text_get_ascent(rid);
|
||||
ofs.y += TS->shaped_text_get_ascent(rid) + spacing_top;
|
||||
clip_l = MAX(0, p_pos.x - ofs.x);
|
||||
} else {
|
||||
ofs.x += TS->shaped_text_get_ascent(rid);
|
||||
ofs.x += TS->shaped_text_get_ascent(rid) + spacing_top;
|
||||
clip_l = MAX(0, p_pos.y - ofs.y);
|
||||
}
|
||||
return TS->shaped_text_draw_outline(rid, p_canvas, ofs, clip_l, clip_l + width, p_outline_size, p_color);
|
||||
|
@ -347,6 +355,8 @@ int TextLine::hit_test(float p_coords) const {
|
|||
|
||||
TextLine::TextLine(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
|
||||
rid = TS->create_shaped_text(p_direction, p_orientation);
|
||||
spacing_top = p_fonts->get_spacing(Font::SPACING_TOP);
|
||||
spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM);
|
||||
TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ class TextLine : public Reference {
|
|||
GDCLASS(TextLine, Reference);
|
||||
|
||||
RID rid;
|
||||
int spacing_top = 0;
|
||||
int spacing_bottom = 0;
|
||||
|
||||
bool dirty = true;
|
||||
|
||||
|
|
|
@ -140,6 +140,8 @@ RID TextParagraph::get_line_rid(int p_line) const {
|
|||
}
|
||||
|
||||
void TextParagraph::clear() {
|
||||
spacing_top = 0;
|
||||
spacing_bottom = 0;
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
TS->free(lines[i]);
|
||||
}
|
||||
|
@ -187,6 +189,8 @@ TextServer::Orientation TextParagraph::get_orientation() const {
|
|||
|
||||
bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) {
|
||||
bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
|
||||
spacing_top = p_fonts->get_spacing(Font::SPACING_TOP);
|
||||
spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM);
|
||||
dirty_lines = true;
|
||||
return res;
|
||||
}
|
||||
|
@ -260,7 +264,11 @@ float TextParagraph::get_width() const {
|
|||
|
||||
Size2 TextParagraph::get_non_wraped_size() const {
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
return TS->shaped_text_get_size(rid);
|
||||
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y + spacing_top + spacing_bottom);
|
||||
} else {
|
||||
return Size2(TS->shaped_text_get_size(rid).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(rid).y);
|
||||
}
|
||||
}
|
||||
|
||||
Size2 TextParagraph::get_size() const {
|
||||
|
@ -270,9 +278,9 @@ Size2 TextParagraph::get_size() const {
|
|||
Size2 lsize = TS->shaped_text_get_size(lines[i]);
|
||||
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
size.x = MAX(size.x, lsize.x);
|
||||
size.y += lsize.y;
|
||||
size.y += lsize.y + spacing_top + spacing_bottom;
|
||||
} else {
|
||||
size.x += lsize.x;
|
||||
size.x += lsize.x + spacing_top + spacing_bottom;
|
||||
size.y = MAX(size.y, lsize.y);
|
||||
}
|
||||
}
|
||||
|
@ -297,9 +305,9 @@ Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const {
|
|||
for (int i = 0; i < p_line; i++) {
|
||||
Size2 lsize = TS->shaped_text_get_size(lines[i]);
|
||||
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
xrect.position.y += lsize.y;
|
||||
xrect.position.y += lsize.y + spacing_top + spacing_bottom;
|
||||
} else {
|
||||
xrect.position.x += lsize.x;
|
||||
xrect.position.x += lsize.x + spacing_top + spacing_bottom;
|
||||
}
|
||||
}
|
||||
return xrect;
|
||||
|
@ -308,7 +316,11 @@ Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const {
|
|||
Size2 TextParagraph::get_line_size(int p_line) const {
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines.size(), Size2());
|
||||
return TS->shaped_text_get_size(lines[p_line]);
|
||||
if (TS->shaped_text_get_orientation(lines[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
return Size2(TS->shaped_text_get_size(lines[p_line]).x, TS->shaped_text_get_size(lines[p_line]).y + spacing_top + spacing_bottom);
|
||||
} else {
|
||||
return Size2(TS->shaped_text_get_size(lines[p_line]).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(lines[p_line]).y);
|
||||
}
|
||||
}
|
||||
|
||||
Vector2i TextParagraph::get_line_range(int p_line) const {
|
||||
|
@ -320,13 +332,13 @@ Vector2i TextParagraph::get_line_range(int p_line) const {
|
|||
float TextParagraph::get_line_ascent(int p_line) const {
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines.size(), 0.f);
|
||||
return TS->shaped_text_get_ascent(lines[p_line]);
|
||||
return TS->shaped_text_get_ascent(lines[p_line]) + spacing_top;
|
||||
}
|
||||
|
||||
float TextParagraph::get_line_descent(int p_line) const {
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= lines.size(), 0.f);
|
||||
return TS->shaped_text_get_descent(lines[p_line]);
|
||||
return TS->shaped_text_get_descent(lines[p_line]) + spacing_bottom;
|
||||
}
|
||||
|
||||
float TextParagraph::get_line_width(int p_line) const {
|
||||
|
@ -353,10 +365,10 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
|
|||
for (int i = 0; i < lines.size(); i++) {
|
||||
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.x = p_pos.x;
|
||||
ofs.y += TS->shaped_text_get_ascent(lines[i]);
|
||||
ofs.y += TS->shaped_text_get_ascent(lines[i]) + spacing_top;
|
||||
} else {
|
||||
ofs.y = p_pos.y;
|
||||
ofs.x += TS->shaped_text_get_ascent(lines[i]);
|
||||
ofs.x += TS->shaped_text_get_ascent(lines[i]) + spacing_top;
|
||||
}
|
||||
float length = TS->shaped_text_get_width(lines[i]);
|
||||
if (width > 0) {
|
||||
|
@ -389,10 +401,10 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
|
|||
TS->shaped_text_draw(lines[i], p_canvas, ofs, clip_l, clip_l + width, p_color);
|
||||
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.x = p_pos.x;
|
||||
ofs.y += TS->shaped_text_get_descent(lines[i]);
|
||||
ofs.y += TS->shaped_text_get_descent(lines[i]) + spacing_bottom;
|
||||
} else {
|
||||
ofs.y = p_pos.y;
|
||||
ofs.x += TS->shaped_text_get_descent(lines[i]);
|
||||
ofs.x += TS->shaped_text_get_descent(lines[i]) + spacing_bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -403,10 +415,10 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
|
|||
for (int i = 0; i < lines.size(); i++) {
|
||||
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.x = p_pos.x;
|
||||
ofs.y += TS->shaped_text_get_ascent(lines[i]);
|
||||
ofs.y += TS->shaped_text_get_ascent(lines[i]) + spacing_top;
|
||||
} else {
|
||||
ofs.y = p_pos.y;
|
||||
ofs.x += TS->shaped_text_get_ascent(lines[i]);
|
||||
ofs.x += TS->shaped_text_get_ascent(lines[i]) + spacing_top;
|
||||
}
|
||||
float length = TS->shaped_text_get_width(lines[i]);
|
||||
if (width > 0) {
|
||||
|
@ -439,10 +451,10 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
|
|||
TS->shaped_text_draw_outline(lines[i], p_canvas, ofs, clip_l, clip_l + width, p_outline_size, p_color);
|
||||
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.x = p_pos.x;
|
||||
ofs.y += TS->shaped_text_get_descent(lines[i]);
|
||||
ofs.y += TS->shaped_text_get_descent(lines[i]) + spacing_bottom;
|
||||
} else {
|
||||
ofs.y = p_pos.y;
|
||||
ofs.x += TS->shaped_text_get_descent(lines[i]);
|
||||
ofs.x += TS->shaped_text_get_descent(lines[i]) + spacing_bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -462,10 +474,12 @@ int TextParagraph::hit_test(const Point2 &p_coords) const {
|
|||
if ((p_coords.y >= ofs.y) && (p_coords.y <= ofs.y + TS->shaped_text_get_size(lines[i]).y)) {
|
||||
return TS->shaped_text_hit_test_position(lines[i], p_coords.x);
|
||||
}
|
||||
ofs.y += TS->shaped_text_get_size(lines[i]).y + spacing_bottom + spacing_top;
|
||||
} else {
|
||||
if ((p_coords.x >= ofs.x) && (p_coords.x <= ofs.x + TS->shaped_text_get_size(lines[i]).x)) {
|
||||
return TS->shaped_text_hit_test_position(lines[i], p_coords.y);
|
||||
}
|
||||
ofs.y += TS->shaped_text_get_size(lines[i]).x + spacing_bottom + spacing_top;
|
||||
}
|
||||
}
|
||||
return TS->shaped_text_get_range(rid).y;
|
||||
|
@ -477,9 +491,9 @@ void TextParagraph::draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, co
|
|||
|
||||
Vector2 ofs = p_pos;
|
||||
if (TS->shaped_text_get_orientation(lines[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.y += TS->shaped_text_get_ascent(lines[p_line]);
|
||||
ofs.y += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top;
|
||||
} else {
|
||||
ofs.x += TS->shaped_text_get_ascent(lines[p_line]);
|
||||
ofs.x += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top;
|
||||
}
|
||||
return TS->shaped_text_draw(lines[p_line], p_canvas, ofs, -1, -1, p_color);
|
||||
}
|
||||
|
@ -490,9 +504,9 @@ void TextParagraph::draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_
|
|||
|
||||
Vector2 ofs = p_pos;
|
||||
if (TS->shaped_text_get_orientation(lines[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.y += TS->shaped_text_get_ascent(lines[p_line]);
|
||||
ofs.y += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top;
|
||||
} else {
|
||||
ofs.x += TS->shaped_text_get_ascent(lines[p_line]);
|
||||
ofs.x += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top;
|
||||
}
|
||||
return TS->shaped_text_draw_outline(lines[p_line], p_canvas, ofs, -1, -1, p_outline_size, p_color);
|
||||
}
|
||||
|
@ -500,8 +514,9 @@ void TextParagraph::draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_
|
|||
TextParagraph::TextParagraph(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, float p_width, TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
|
||||
rid = TS->create_shaped_text(p_direction, p_orientation);
|
||||
TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
|
||||
spacing_top = p_fonts->get_spacing(Font::SPACING_TOP);
|
||||
spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM);
|
||||
width = p_width;
|
||||
dirty_lines = true;
|
||||
}
|
||||
|
||||
TextParagraph::TextParagraph() {
|
||||
|
|
|
@ -41,6 +41,8 @@ class TextParagraph : public Reference {
|
|||
|
||||
RID rid;
|
||||
Vector<RID> lines;
|
||||
int spacing_top = 0;
|
||||
int spacing_bottom = 0;
|
||||
|
||||
bool dirty_lines = true;
|
||||
|
||||
|
|
Loading…
Reference in a new issue