Refactor Font configuration and import UI, and Font resources.
This commit is contained in:
parent
cf19484746
commit
344ba0ffaf
113 changed files with 5041 additions and 6485 deletions
|
|
@ -53,10 +53,6 @@ void Label3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Label3D::set_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_text_direction"), &Label3D::get_text_direction);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &Label3D::set_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &Label3D::get_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_opentype_features"), &Label3D::clear_opentype_features);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_language", "language"), &Label3D::set_language);
|
||||
ClassDB::bind_method(D_METHOD("get_language"), &Label3D::get_language);
|
||||
|
||||
|
|
@ -140,7 +136,7 @@ void Label3D::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_modulate"), "set_outline_modulate", "get_outline_modulate");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, ""), "set_text", "get_text");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_font", "get_font");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,127,1,suffix:px"), "set_font_size", "get_font_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px"), "set_font_size", "get_font_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,127,1,suffix:px"), "set_outline_size", "get_outline_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom"), "set_vertical_alignment", "get_vertical_alignment");
|
||||
|
|
@ -148,12 +144,12 @@ void Label3D::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "line_spacing", PROPERTY_HINT_NONE, "suffix:px"), "set_line_spacing", "get_line_spacing");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width", PROPERTY_HINT_NONE, "suffix:px"), "set_width", "get_width");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
|
||||
|
||||
ADD_GROUP("Locale", "");
|
||||
ADD_GROUP("BiDi", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
|
||||
|
||||
BIND_ENUM_CONSTANT(FLAG_SHADED);
|
||||
BIND_ENUM_CONSTANT(FLAG_DOUBLE_SIDED);
|
||||
|
|
@ -166,56 +162,6 @@ void Label3D::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS);
|
||||
}
|
||||
|
||||
bool Label3D::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
int value = p_value;
|
||||
if (value == -1) {
|
||||
if (opentype_features.has(tag)) {
|
||||
opentype_features.erase(tag);
|
||||
dirty_font = true;
|
||||
_queue_update();
|
||||
}
|
||||
} else {
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
|
||||
opentype_features[tag] = value;
|
||||
dirty_font = true;
|
||||
_queue_update();
|
||||
}
|
||||
}
|
||||
notify_property_list_changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Label3D::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
if (opentype_features.has(tag)) {
|
||||
r_ret = opentype_features[tag];
|
||||
return true;
|
||||
} else {
|
||||
r_ret = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Label3D::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
|
||||
String name = TS->tag_to_name(*ftr);
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
|
||||
}
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
}
|
||||
|
||||
void Label3D::_validate_property(PropertyInfo &property) const {
|
||||
if (property.name == "material_override" || property.name == "material_overlay") {
|
||||
property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
|
|
@ -280,7 +226,7 @@ Ref<TriangleMesh> Label3D::generate_triangle_mesh() const {
|
|||
float total_h = 0.0;
|
||||
float max_line_w = 0.0;
|
||||
for (int i = 0; i < lines_rid.size(); i++) {
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing;
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
|
||||
max_line_w = MAX(max_line_w, TS->shaped_text_get_width(lines_rid[i]));
|
||||
}
|
||||
|
||||
|
|
@ -471,7 +417,10 @@ void Label3D::_shape() {
|
|||
TS->shaped_text_set_direction(text_rid, text_direction);
|
||||
|
||||
String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
|
||||
TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, language);
|
||||
TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, font->get_opentype_features(), language);
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
|
||||
Array stt;
|
||||
if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) {
|
||||
|
|
@ -487,7 +436,10 @@ void Label3D::_shape() {
|
|||
} else if (dirty_font) {
|
||||
int spans = TS->shaped_get_span_count(text_rid);
|
||||
for (int i = 0; i < spans; i++) {
|
||||
TS->shaped_set_span_update_font(text_rid, i, font->get_rids(), font_size, opentype_features);
|
||||
TS->shaped_set_span_update_font(text_rid, i, font->get_rids(), font_size, font->get_opentype_features());
|
||||
}
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
|
||||
dirty_font = false;
|
||||
|
|
@ -534,7 +486,7 @@ void Label3D::_shape() {
|
|||
// Generate surfaces and materials.
|
||||
float total_h = 0.0;
|
||||
for (int i = 0; i < lines_rid.size(); i++) {
|
||||
total_h += (TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing) * pixel_size;
|
||||
total_h += (TS->shaped_text_get_size(lines_rid[i]).y + line_spacing) * pixel_size;
|
||||
}
|
||||
|
||||
float vbegin = 0.0;
|
||||
|
|
@ -570,7 +522,7 @@ void Label3D::_shape() {
|
|||
} break;
|
||||
}
|
||||
offset.x += lbl_offset.x * pixel_size;
|
||||
offset.y -= (TS->shaped_text_get_ascent(lines_rid[i]) + font->get_spacing(TextServer::SPACING_TOP)) * pixel_size;
|
||||
offset.y -= TS->shaped_text_get_ascent(lines_rid[i]) * pixel_size;
|
||||
|
||||
if (outline_modulate.a != 0.0 && outline_size > 0) {
|
||||
// Outline surfaces.
|
||||
|
|
@ -584,7 +536,7 @@ void Label3D::_shape() {
|
|||
for (int j = 0; j < gl_size; j++) {
|
||||
_generate_glyph_surfaces(glyphs[j], offset, modulate, render_priority);
|
||||
}
|
||||
offset.y -= (TS->shaped_text_get_descent(lines_rid[i]) + line_spacing + font->get_spacing(TextServer::SPACING_BOTTOM)) * pixel_size;
|
||||
offset.y -= (TS->shaped_text_get_descent(lines_rid[i]) + line_spacing) * pixel_size;
|
||||
}
|
||||
|
||||
for (const KeyValue<SurfaceKey, SurfaceData> &E : surfaces) {
|
||||
|
|
@ -657,29 +609,6 @@ TextServer::Direction Label3D::get_text_direction() const {
|
|||
return text_direction;
|
||||
}
|
||||
|
||||
void Label3D::clear_opentype_features() {
|
||||
opentype_features.clear();
|
||||
dirty_font = true;
|
||||
_queue_update();
|
||||
}
|
||||
|
||||
void Label3D::set_opentype_feature(const String &p_name, int p_value) {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
|
||||
opentype_features[tag] = p_value;
|
||||
dirty_font = true;
|
||||
_queue_update();
|
||||
}
|
||||
}
|
||||
|
||||
int Label3D::get_opentype_feature(const String &p_name) const {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return opentype_features[tag];
|
||||
}
|
||||
|
||||
void Label3D::set_language(const String &p_language) {
|
||||
if (language != p_language) {
|
||||
language = p_language;
|
||||
|
|
@ -781,7 +710,7 @@ Ref<Font> Label3D::_get_font_or_default() const {
|
|||
theme_font.unref();
|
||||
}
|
||||
|
||||
if (font_override.is_valid() && font_override->get_data_count() > 0) {
|
||||
if (font_override.is_valid()) {
|
||||
return font_override;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,7 +122,6 @@ private:
|
|||
|
||||
float line_spacing = 0.f;
|
||||
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
TextServer::Direction text_direction = TextServer::DIRECTION_AUTO;
|
||||
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
|
||||
|
|
@ -150,9 +149,6 @@ protected:
|
|||
|
||||
static void _bind_methods();
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
void _validate_property(PropertyInfo &property) const override;
|
||||
|
||||
void _im_update();
|
||||
|
|
@ -180,10 +176,6 @@ public:
|
|||
void set_text_direction(TextServer::Direction p_text_direction);
|
||||
TextServer::Direction get_text_direction() const;
|
||||
|
||||
void set_opentype_feature(const String &p_name, int p_value);
|
||||
int get_opentype_feature(const String &p_name) const;
|
||||
void clear_opentype_features();
|
||||
|
||||
void set_language(const String &p_language);
|
||||
String get_language() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -342,12 +342,7 @@ void Button::_notification(int p_what) {
|
|||
} break;
|
||||
}
|
||||
|
||||
Color font_outline_color = get_theme_color(SNAME("font_outline_color"));
|
||||
int outline_size = get_theme_constant(SNAME("outline_size"));
|
||||
if (outline_size > 0 && font_outline_color.a > 0) {
|
||||
text_buf->draw_outline(ci, text_ofs, outline_size, font_outline_color);
|
||||
}
|
||||
|
||||
text_buf->draw_outline(ci, text_ofs, get_theme_constant(SNAME("outline_size")), get_theme_color(SNAME("font_outline_color")));
|
||||
text_buf->draw(ci, text_ofs, color);
|
||||
} break;
|
||||
}
|
||||
|
|
@ -363,7 +358,7 @@ void Button::_shape() {
|
|||
} else {
|
||||
text_buf->set_direction((TextServer::Direction)text_direction);
|
||||
}
|
||||
text_buf->add_string(xl_text, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
text_buf->add_string(xl_text, font, font_size, language);
|
||||
text_buf->set_text_overrun_behavior(overrun_behavior);
|
||||
}
|
||||
|
||||
|
|
@ -409,29 +404,6 @@ Control::TextDirection Button::get_text_direction() const {
|
|||
return text_direction;
|
||||
}
|
||||
|
||||
void Button::clear_opentype_features() {
|
||||
opentype_features.clear();
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
|
||||
void Button::set_opentype_feature(const String &p_name, int p_value) {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
|
||||
opentype_features[tag] = p_value;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int Button::get_opentype_feature(const String &p_name) const {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return opentype_features[tag];
|
||||
}
|
||||
|
||||
void Button::set_language(const String &p_language) {
|
||||
if (language != p_language) {
|
||||
language = p_language;
|
||||
|
|
@ -512,56 +484,6 @@ HorizontalAlignment Button::get_icon_alignment() const {
|
|||
return icon_alignment;
|
||||
}
|
||||
|
||||
bool Button::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
int value = p_value;
|
||||
if (value == -1) {
|
||||
if (opentype_features.has(tag)) {
|
||||
opentype_features.erase(tag);
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
|
||||
opentype_features[tag] = value;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
notify_property_list_changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Button::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
if (opentype_features.has(tag)) {
|
||||
r_ret = opentype_features[tag];
|
||||
return true;
|
||||
} else {
|
||||
r_ret = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Button::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
|
||||
String name = TS->tag_to_name(*ftr);
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
|
||||
}
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
}
|
||||
|
||||
void Button::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_text", "text"), &Button::set_text);
|
||||
ClassDB::bind_method(D_METHOD("get_text"), &Button::get_text);
|
||||
|
|
@ -569,9 +491,6 @@ void Button::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &Button::get_text_overrun_behavior);
|
||||
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Button::set_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_text_direction"), &Button::get_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &Button::set_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &Button::get_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_opentype_features"), &Button::clear_opentype_features);
|
||||
ClassDB::bind_method(D_METHOD("set_language", "language"), &Button::set_language);
|
||||
ClassDB::bind_method(D_METHOD("get_language"), &Button::get_language);
|
||||
ClassDB::bind_method(D_METHOD("set_button_icon", "texture"), &Button::set_icon);
|
||||
|
|
@ -588,8 +507,6 @@ void Button::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("is_expand_icon"), &Button::is_expand_icon);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_button_icon", "get_button_icon");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text");
|
||||
|
|
@ -597,6 +514,10 @@ void Button::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "icon_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_icon_alignment", "get_icon_alignment");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand_icon"), "set_expand_icon", "is_expand_icon");
|
||||
|
||||
ADD_GROUP("BiDi", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
}
|
||||
|
||||
Button::Button(const String &p_text) {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ private:
|
|||
String xl_text;
|
||||
Ref<TextParagraph> text_buf;
|
||||
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
TextDirection text_direction = TEXT_DIRECTION_AUTO;
|
||||
TextServer::OverrunBehavior overrun_behavior = TextServer::OVERRUN_NO_TRIMMING;
|
||||
|
|
@ -62,10 +61,6 @@ protected:
|
|||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
public:
|
||||
virtual Size2 get_minimum_size() const override;
|
||||
|
||||
|
|
@ -78,10 +73,6 @@ public:
|
|||
void set_text_direction(TextDirection p_text_direction);
|
||||
TextDirection get_text_direction() const;
|
||||
|
||||
void set_opentype_feature(const String &p_name, int p_value);
|
||||
int get_opentype_feature(const String &p_name) const;
|
||||
void clear_opentype_features();
|
||||
|
||||
void set_language(const String &p_language);
|
||||
String get_language() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ void CodeEdit::_notification(int p_what) {
|
|||
line_spacing = get_theme_constant(SNAME("line_spacing"));
|
||||
|
||||
set_gutter_width(main_gutter, get_line_height());
|
||||
set_gutter_width(line_number_gutter, (line_number_digits + 1) * font->get_char_size('0', 0, font_size).width);
|
||||
set_gutter_width(line_number_gutter, (line_number_digits + 1) * font->get_char_size('0', font_size).width);
|
||||
set_gutter_width(fold_gutter, get_line_height() / 1.2);
|
||||
|
||||
breakpoint_color = get_theme_color(SNAME("breakpoint_color"));
|
||||
|
|
@ -86,7 +86,7 @@ void CodeEdit::_notification(int p_what) {
|
|||
if (line_length_guideline_columns.size() > 0) {
|
||||
const int xmargin_beg = style_normal->get_margin(SIDE_LEFT) + get_total_gutter_width();
|
||||
const int xmargin_end = size.width - style_normal->get_margin(SIDE_RIGHT) - (is_drawing_minimap() ? get_minimap_width() : 0);
|
||||
const float char_size = font->get_char_size('0', 0, font_size).width;
|
||||
const float char_size = font->get_char_size('0', font_size).width;
|
||||
|
||||
for (int i = 0; i < line_length_guideline_columns.size(); i++) {
|
||||
const int xoffset = xmargin_beg + char_size * (int)line_length_guideline_columns[i] - get_h_scroll();
|
||||
|
|
@ -123,7 +123,7 @@ void CodeEdit::_notification(int p_what) {
|
|||
}
|
||||
|
||||
const int scroll_width = code_completion_options_count > code_completion_max_lines ? code_completion_scroll_width : 0;
|
||||
const int code_completion_base_width = font->get_string_size(code_completion_base, font_size).width;
|
||||
const int code_completion_base_width = font->get_string_size(code_completion_base, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
|
||||
if (caret_pos.x - code_completion_base_width + code_completion_rect.size.width + scroll_width > get_size().width) {
|
||||
code_completion_rect.position.x = get_size().width - code_completion_rect.size.width - scroll_width;
|
||||
} else {
|
||||
|
|
@ -178,8 +178,8 @@ void CodeEdit::_notification(int p_what) {
|
|||
|
||||
for (int j = 0; j < code_completion_options[l].matches.size(); j++) {
|
||||
Pair<int, int> match = code_completion_options[l].matches[j];
|
||||
int match_offset = font->get_string_size(code_completion_options[l].display.substr(0, match.first), font_size).width;
|
||||
int match_len = font->get_string_size(code_completion_options[l].display.substr(match.first, match.second), font_size).width;
|
||||
int match_offset = font->get_string_size(code_completion_options[l].display.substr(0, match.first), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
|
||||
int match_len = font->get_string_size(code_completion_options[l].display.substr(match.first, match.second), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width;
|
||||
|
||||
draw_rect(Rect2(match_pos + Point2(match_offset, 0), Size2(match_len, row_height)), code_completion_existing_color);
|
||||
}
|
||||
|
|
@ -208,11 +208,11 @@ void CodeEdit::_notification(int p_what) {
|
|||
|
||||
int max_width = 0;
|
||||
for (int i = 0; i < line_count; i++) {
|
||||
max_width = MAX(max_width, font->get_string_size(code_hint_lines[i], font_size).x);
|
||||
max_width = MAX(max_width, font->get_string_size(code_hint_lines[i], HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x);
|
||||
}
|
||||
Size2 minsize = sb->get_minimum_size() + Size2(max_width, line_count * font_height + (line_spacing * line_count - 1));
|
||||
|
||||
int offset = font->get_string_size(code_hint_lines[0].substr(0, code_hint_lines[0].find(String::chr(0xFFFF))), font_size).x;
|
||||
int offset = font->get_string_size(code_hint_lines[0].substr(0, code_hint_lines[0].find(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x;
|
||||
if (code_hint_xpos == -0xFFFF) {
|
||||
code_hint_xpos = get_caret_draw_pos().x - offset;
|
||||
}
|
||||
|
|
@ -232,8 +232,8 @@ void CodeEdit::_notification(int p_what) {
|
|||
int begin = 0;
|
||||
int end = 0;
|
||||
if (line.contains(String::chr(0xFFFF))) {
|
||||
begin = font->get_string_size(line.substr(0, line.find(String::chr(0xFFFF))), font_size).x;
|
||||
end = font->get_string_size(line.substr(0, line.rfind(String::chr(0xFFFF))), font_size).x;
|
||||
begin = font->get_string_size(line.substr(0, line.find(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x;
|
||||
end = font->get_string_size(line.substr(0, line.rfind(String::chr(0xFFFF))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x;
|
||||
}
|
||||
|
||||
Point2 round_ofs = hint_ofs + sb->get_offset() + Vector2(0, font->get_ascent(font_size) + font_height * i + yofs);
|
||||
|
|
@ -2795,7 +2795,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
|
|||
offset = line_height;
|
||||
}
|
||||
|
||||
max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
|
||||
max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
|
||||
code_completion_options.push_back(option);
|
||||
}
|
||||
|
||||
|
|
@ -2906,7 +2906,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
|
|||
|
||||
if (string_to_complete.length() == 0) {
|
||||
code_completion_options.push_back(option);
|
||||
max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
|
||||
max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -3012,7 +3012,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
|
|||
option.matches.append_array(ssq_matches);
|
||||
completion_options_subseq.push_back(option);
|
||||
}
|
||||
max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
|
||||
max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
|
||||
} else if (!*ssq_lower) { // Matched the whole subsequence in s_lower.
|
||||
option.matches.clear();
|
||||
|
||||
|
|
@ -3029,7 +3029,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
|
|||
option.matches.append_array(ssq_lower_matches);
|
||||
completion_options_subseq_casei.push_back(option);
|
||||
}
|
||||
max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
|
||||
max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3085,7 +3085,7 @@ void CodeEdit::_text_changed() {
|
|||
}
|
||||
|
||||
if (font.is_valid()) {
|
||||
set_gutter_width(line_number_gutter, (line_number_digits + 1) * font->get_char_size('0', 0, font_size).width);
|
||||
set_gutter_width(line_number_gutter, (line_number_digits + 1) * font->get_char_size('0', font_size).width);
|
||||
}
|
||||
|
||||
lc = get_line_count();
|
||||
|
|
|
|||
|
|
@ -1115,7 +1115,7 @@ Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const String
|
|||
Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
|
||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||
const Ref<Font> *font = data.font_override.getptr(p_name);
|
||||
if (font && (*font)->get_data_count() > 0) {
|
||||
if (font) {
|
||||
return *font;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,26 +44,6 @@ struct _MinSizeCache {
|
|||
|
||||
bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
int value = p_value;
|
||||
if (value == -1) {
|
||||
if (opentype_features.has(tag)) {
|
||||
opentype_features.erase(tag);
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
|
||||
opentype_features[tag] = value;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
notify_property_list_changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!str.begins_with("slot/")) {
|
||||
return false;
|
||||
|
|
@ -106,18 +86,6 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
|
|||
|
||||
bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
if (opentype_features.has(tag)) {
|
||||
r_ret = opentype_features[tag];
|
||||
return true;
|
||||
} else {
|
||||
r_ret = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!str.begins_with("slot/")) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -156,12 +124,6 @@ bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
|
|||
}
|
||||
|
||||
void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
|
||||
String name = TS->tag_to_name(*ftr);
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
|
||||
}
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
|
||||
int idx = 0;
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
Control *c = Object::cast_to<Control>(get_child(i));
|
||||
|
|
@ -471,7 +433,7 @@ void GraphNode::_shape() {
|
|||
} else {
|
||||
title_buf->set_direction((TextServer::Direction)text_direction);
|
||||
}
|
||||
title_buf->add_string(title, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
title_buf->add_string(title, font, font_size, language);
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
|
@ -726,29 +688,6 @@ Control::TextDirection GraphNode::get_text_direction() const {
|
|||
return text_direction;
|
||||
}
|
||||
|
||||
void GraphNode::clear_opentype_features() {
|
||||
opentype_features.clear();
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
|
||||
void GraphNode::set_opentype_feature(const String &p_name, int p_value) {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
|
||||
opentype_features[tag] = p_value;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int GraphNode::get_opentype_feature(const String &p_name) const {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return opentype_features[tag];
|
||||
}
|
||||
|
||||
void GraphNode::set_language(const String &p_language) {
|
||||
if (language != p_language) {
|
||||
language = p_language;
|
||||
|
|
@ -1043,9 +982,6 @@ void GraphNode::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_title"), &GraphNode::get_title);
|
||||
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &GraphNode::set_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_text_direction"), &GraphNode::get_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &GraphNode::set_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &GraphNode::get_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_opentype_features"), &GraphNode::clear_opentype_features);
|
||||
ClassDB::bind_method(D_METHOD("set_language", "language"), &GraphNode::set_language);
|
||||
ClassDB::bind_method(D_METHOD("get_language"), &GraphNode::get_language);
|
||||
|
||||
|
|
@ -1105,8 +1041,6 @@ void GraphNode::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_overlay"), &GraphNode::get_overlay);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_position_offset", "get_position_offset");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_close"), "set_show_close_button", "is_close_button_visible");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resizable"), "set_resizable", "is_resizable");
|
||||
|
|
@ -1114,6 +1048,10 @@ void GraphNode::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "comment"), "set_comment", "is_comment");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "overlay", PROPERTY_HINT_ENUM, "Disabled,Breakpoint,Position"), "set_overlay", "get_overlay");
|
||||
|
||||
ADD_GROUP("BiDi", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
|
||||
ADD_SIGNAL(MethodInfo("position_offset_changed"));
|
||||
ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "idx")));
|
||||
ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to")));
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ private:
|
|||
String title;
|
||||
Ref<TextLine> title_buf;
|
||||
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
TextDirection text_direction = TEXT_DIRECTION_AUTO;
|
||||
|
||||
|
|
@ -148,10 +147,6 @@ public:
|
|||
void set_text_direction(TextDirection p_text_direction);
|
||||
TextDirection get_text_direction() const;
|
||||
|
||||
void set_opentype_feature(const String &p_name, int p_value);
|
||||
int get_opentype_feature(const String &p_name) const;
|
||||
void clear_opentype_features();
|
||||
|
||||
void set_language(const String &p_language);
|
||||
String get_language() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ void ItemList::_shape(int p_idx) {
|
|||
} else {
|
||||
item.text_buf->set_direction((TextServer::Direction)item.text_direction);
|
||||
}
|
||||
item.text_buf->add_string(item.text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), item.opentype_features, (!item.language.is_empty()) ? item.language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
item.text_buf->add_string(item.text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), item.language);
|
||||
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
|
||||
item.text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
|
||||
} else {
|
||||
|
|
@ -117,35 +117,6 @@ Control::TextDirection ItemList::get_item_text_direction(int p_idx) const {
|
|||
return items[p_idx].text_direction;
|
||||
}
|
||||
|
||||
void ItemList::clear_item_opentype_features(int p_idx) {
|
||||
ERR_FAIL_INDEX(p_idx, items.size());
|
||||
items.write[p_idx].opentype_features.clear();
|
||||
_shape(p_idx);
|
||||
update();
|
||||
}
|
||||
|
||||
void ItemList::set_item_opentype_feature(int p_idx, const String &p_name, int p_value) {
|
||||
if (p_idx < 0) {
|
||||
p_idx += get_item_count();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_idx, items.size());
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!items[p_idx].opentype_features.has(tag) || (int)items[p_idx].opentype_features[tag] != p_value) {
|
||||
items.write[p_idx].opentype_features[tag] = p_value;
|
||||
_shape(p_idx);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int ItemList::get_item_opentype_feature(int p_idx, const String &p_name) const {
|
||||
ERR_FAIL_INDEX_V(p_idx, items.size(), -1);
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!items[p_idx].opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return items[p_idx].opentype_features[tag];
|
||||
}
|
||||
|
||||
void ItemList::set_item_language(int p_idx, const String &p_language) {
|
||||
if (p_idx < 0) {
|
||||
p_idx += get_item_count();
|
||||
|
|
@ -1656,10 +1627,6 @@ void ItemList::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_item_text_direction", "idx", "direction"), &ItemList::set_item_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_item_text_direction", "idx"), &ItemList::get_item_text_direction);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_item_opentype_feature", "idx", "tag", "value"), &ItemList::set_item_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_item_opentype_feature", "idx", "tag"), &ItemList::get_item_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_item_opentype_features", "idx"), &ItemList::clear_item_opentype_features);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_item_language", "idx", "language"), &ItemList::set_item_language);
|
||||
ClassDB::bind_method(D_METHOD("get_item_language", "idx"), &ItemList::get_item_language);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ private:
|
|||
Ref<Texture2D> tag_icon;
|
||||
String text;
|
||||
Ref<TextParagraph> text_buf;
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
TextDirection text_direction = TEXT_DIRECTION_AUTO;
|
||||
|
||||
|
|
@ -145,10 +144,6 @@ public:
|
|||
void set_item_text_direction(int p_idx, TextDirection p_text_direction);
|
||||
TextDirection get_item_text_direction(int p_idx) const;
|
||||
|
||||
void set_item_opentype_feature(int p_idx, const String &p_name, int p_value);
|
||||
int get_item_opentype_feature(int p_idx, const String &p_name) const;
|
||||
void clear_item_opentype_features(int p_idx);
|
||||
|
||||
void set_item_language(int p_idx, const String &p_language);
|
||||
String get_item_language(int p_idx) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -66,11 +66,11 @@ bool Label::is_uppercase() const {
|
|||
int Label::get_line_height(int p_line) const {
|
||||
Ref<Font> font = get_theme_font(SNAME("font"));
|
||||
if (p_line >= 0 && p_line < lines_rid.size()) {
|
||||
return TS->shaped_text_get_size(lines_rid[p_line]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM);
|
||||
return TS->shaped_text_get_size(lines_rid[p_line]).y;
|
||||
} 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) + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM);
|
||||
h = MAX(h, TS->shaped_text_get_size(lines_rid[i]).y);
|
||||
}
|
||||
return h;
|
||||
} else {
|
||||
|
|
@ -83,7 +83,6 @@ void Label::_shape() {
|
|||
int width = (get_size().width - style->get_minimum_size().width);
|
||||
|
||||
if (dirty || font_dirty) {
|
||||
String lang = (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale();
|
||||
if (dirty) {
|
||||
TS->shaped_text_clear(text_rid);
|
||||
}
|
||||
|
|
@ -95,18 +94,21 @@ void Label::_shape() {
|
|||
const Ref<Font> &font = get_theme_font(SNAME("font"));
|
||||
int font_size = get_theme_font_size(SNAME("font_size"));
|
||||
ERR_FAIL_COND(font.is_null());
|
||||
String text = (uppercase) ? TS->string_to_upper(xl_text, lang) : xl_text;
|
||||
String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
|
||||
if (visible_chars >= 0 && visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) {
|
||||
text = text.substr(0, visible_chars);
|
||||
}
|
||||
if (dirty) {
|
||||
TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, lang);
|
||||
TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, font->get_opentype_features(), language);
|
||||
} else {
|
||||
int spans = TS->shaped_get_span_count(text_rid);
|
||||
for (int i = 0; i < spans; i++) {
|
||||
TS->shaped_set_span_update_font(text_rid, i, font->get_rids(), font_size, opentype_features);
|
||||
TS->shaped_set_span_update_font(text_rid, i, font->get_rids(), font_size, font->get_opentype_features());
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, text));
|
||||
dirty = false;
|
||||
font_dirty = false;
|
||||
|
|
@ -233,7 +235,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 + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing;
|
||||
minsize.height += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
|
||||
if (minsize.height > (get_size().height - style->get_minimum_size().height + line_spacing)) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -314,7 +316,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 + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing;
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
|
||||
if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -334,7 +336,7 @@ void Label::_notification(int p_what) {
|
|||
int total_glyphs = 0;
|
||||
total_h = 0;
|
||||
for (int64_t i = lines_skipped; i < last_line; i++) {
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing;
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
|
||||
total_glyphs += TS->shaped_text_get_glyph_count(lines_rid[i]) + TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]);
|
||||
}
|
||||
int visible_glyphs = total_glyphs * percent_visible;
|
||||
|
|
@ -374,7 +376,7 @@ void Label::_notification(int p_what) {
|
|||
for (int i = lines_skipped; i < last_line; i++) {
|
||||
Size2 line_size = TS->shaped_text_get_size(lines_rid[i]);
|
||||
ofs.x = 0;
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + font->get_spacing(TextServer::SPACING_TOP);
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[i]);
|
||||
switch (horizontal_alignment) {
|
||||
case HORIZONTAL_ALIGNMENT_FILL:
|
||||
if (rtl && autowrap_mode != TextServer::AUTOWRAP_OFF) {
|
||||
|
|
@ -527,7 +529,7 @@ void Label::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
}
|
||||
ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing + font->get_spacing(TextServer::SPACING_BOTTOM);
|
||||
ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing;
|
||||
}
|
||||
} break;
|
||||
|
||||
|
|
@ -551,7 +553,7 @@ Size2 Label::get_minimum_size() const {
|
|||
Size2 min_size = minsize;
|
||||
|
||||
Ref<Font> font = get_theme_font(SNAME("font"));
|
||||
min_size.height = MAX(min_size.height, font->get_height(get_theme_font_size(SNAME("font_size"))) + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM));
|
||||
min_size.height = MAX(min_size.height, font->get_height(get_theme_font_size(SNAME("font_size"))));
|
||||
|
||||
Size2 min_style = get_theme_stylebox(SNAME("normal"))->get_minimum_size();
|
||||
if (autowrap_mode != TextServer::AUTOWRAP_OFF) {
|
||||
|
|
@ -582,7 +584,7 @@ int Label::get_visible_line_count() const {
|
|||
int lines_visible = 0;
|
||||
float total_h = 0.0;
|
||||
for (int64_t i = lines_skipped; i < lines_rid.size(); i++) {
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing;
|
||||
total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
|
||||
if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -674,29 +676,6 @@ Control::TextDirection Label::get_text_direction() const {
|
|||
return text_direction;
|
||||
}
|
||||
|
||||
void Label::clear_opentype_features() {
|
||||
opentype_features.clear();
|
||||
font_dirty = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void Label::set_opentype_feature(const String &p_name, int p_value) {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
|
||||
opentype_features[tag] = p_value;
|
||||
font_dirty = true;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int Label::get_opentype_feature(const String &p_name) const {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return opentype_features[tag];
|
||||
}
|
||||
|
||||
void Label::set_language(const String &p_language) {
|
||||
if (language != p_language) {
|
||||
language = p_language;
|
||||
|
|
@ -818,56 +797,6 @@ int Label::get_total_character_count() const {
|
|||
return xl_text.length();
|
||||
}
|
||||
|
||||
bool Label::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
int value = p_value;
|
||||
if (value == -1) {
|
||||
if (opentype_features.has(tag)) {
|
||||
opentype_features.erase(tag);
|
||||
font_dirty = true;
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
|
||||
opentype_features[tag] = value;
|
||||
font_dirty = true;
|
||||
update();
|
||||
}
|
||||
}
|
||||
notify_property_list_changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Label::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
if (opentype_features.has(tag)) {
|
||||
r_ret = opentype_features[tag];
|
||||
return true;
|
||||
} else {
|
||||
r_ret = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Label::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
|
||||
String name = TS->tag_to_name(*ftr);
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
|
||||
}
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
}
|
||||
|
||||
void Label::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &Label::set_horizontal_alignment);
|
||||
ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &Label::get_horizontal_alignment);
|
||||
|
|
@ -877,9 +806,6 @@ void Label::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_text"), &Label::get_text);
|
||||
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Label::set_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_text_direction"), &Label::get_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &Label::set_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &Label::get_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_opentype_features"), &Label::clear_opentype_features);
|
||||
ClassDB::bind_method(D_METHOD("set_language", "language"), &Label::set_language);
|
||||
ClassDB::bind_method(D_METHOD("get_language"), &Label::get_language);
|
||||
ClassDB::bind_method(D_METHOD("set_autowrap_mode", "autowrap_mode"), &Label::set_autowrap_mode);
|
||||
|
|
@ -924,11 +850,9 @@ void Label::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters_behavior", PROPERTY_HINT_ENUM, "Characters Before Shaping,Characters After Shaping,Glyphs (Layout Direction),Glyphs (Left-to-Right),Glyphs (Right-to-Left)"), "set_visible_characters_behavior", "get_visible_characters_behavior");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible");
|
||||
|
||||
ADD_GROUP("Locale", "");
|
||||
ADD_GROUP("BiDi", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
|
||||
ADD_GROUP("Structured Text", "structured_text_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ private:
|
|||
RID text_rid;
|
||||
Vector<RID> lines_rid;
|
||||
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
TextDirection text_direction = TEXT_DIRECTION_AUTO;
|
||||
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
|
||||
|
|
@ -74,10 +73,6 @@ protected:
|
|||
|
||||
static void _bind_methods();
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
public:
|
||||
virtual Size2 get_minimum_size() const override;
|
||||
|
||||
|
|
@ -93,10 +88,6 @@ public:
|
|||
void set_text_direction(TextDirection p_text_direction);
|
||||
TextDirection get_text_direction() const;
|
||||
|
||||
void set_opentype_feature(const String &p_name, int p_value);
|
||||
int get_opentype_feature(const String &p_name) const;
|
||||
void clear_opentype_features();
|
||||
|
||||
void set_language(const String &p_language);
|
||||
String get_language() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -787,7 +787,7 @@ void LineEdit::_notification(int p_what) {
|
|||
int x_ofs = 0;
|
||||
bool using_placeholder = text.is_empty() && ime_text.is_empty();
|
||||
float text_width = TS->shaped_text_get_size(text_rid).x;
|
||||
float text_height = TS->shaped_text_get_size(text_rid).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM);
|
||||
float text_height = TS->shaped_text_get_size(text_rid).y;
|
||||
|
||||
switch (alignment) {
|
||||
case HORIZONTAL_ALIGNMENT_FILL:
|
||||
|
|
@ -1451,29 +1451,6 @@ Control::TextDirection LineEdit::get_text_direction() const {
|
|||
return text_direction;
|
||||
}
|
||||
|
||||
void LineEdit::clear_opentype_features() {
|
||||
opentype_features.clear();
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
|
||||
void LineEdit::set_opentype_feature(const String &p_name, int p_value) {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
|
||||
opentype_features[tag] = p_value;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int LineEdit::get_opentype_feature(const String &p_name) const {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return opentype_features[tag];
|
||||
}
|
||||
|
||||
void LineEdit::set_language(const String &p_language) {
|
||||
if (language != p_language) {
|
||||
language = p_language;
|
||||
|
|
@ -1688,7 +1665,7 @@ Size2 LineEdit::get_minimum_size() const {
|
|||
Size2 min_size;
|
||||
|
||||
// Minimum size of text.
|
||||
float em_space_size = font->get_char_size('M', 0, font_size).x;
|
||||
float em_space_size = font->get_char_size('M', font_size).x;
|
||||
min_size.width = get_theme_constant(SNAME("minimum_character_width")) * em_space_size;
|
||||
|
||||
if (expand_to_text_length) {
|
||||
|
|
@ -1696,7 +1673,7 @@ Size2 LineEdit::get_minimum_size() const {
|
|||
min_size.width = MAX(min_size.width, full_width + em_space_size);
|
||||
}
|
||||
|
||||
min_size.height = MAX(TS->shaped_text_get_size(text_rid).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM), font->get_height(font_size));
|
||||
min_size.height = MAX(TS->shaped_text_get_size(text_rid).y, font->get_height(font_size));
|
||||
|
||||
// Take icons into account.
|
||||
int icon_max_width = 0;
|
||||
|
|
@ -2155,7 +2132,10 @@ void LineEdit::_shape() {
|
|||
const Ref<Font> &font = get_theme_font(SNAME("font"));
|
||||
int font_size = get_theme_font_size(SNAME("font_size"));
|
||||
ERR_FAIL_COND(font.is_null());
|
||||
TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
TS->shaped_text_add_string(text_rid, t, font->get_rids(), font_size, font->get_opentype_features(), language);
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, t));
|
||||
|
||||
full_width = TS->shaped_text_get_size(text_rid).x;
|
||||
|
|
@ -2236,56 +2216,6 @@ Key LineEdit::_get_menu_action_accelerator(const String &p_action) {
|
|||
}
|
||||
}
|
||||
|
||||
bool LineEdit::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
int value = p_value;
|
||||
if (value == -1) {
|
||||
if (opentype_features.has(tag)) {
|
||||
opentype_features.erase(tag);
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
|
||||
opentype_features[tag] = value;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
notify_property_list_changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LineEdit::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
if (opentype_features.has(tag)) {
|
||||
r_ret = opentype_features[tag];
|
||||
return true;
|
||||
} else {
|
||||
r_ret = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LineEdit::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
|
||||
String name = TS->tag_to_name(*ftr);
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
|
||||
}
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
}
|
||||
|
||||
void LineEdit::_validate_property(PropertyInfo &property) const {
|
||||
if (!caret_blink_enabled && property.name == "caret_blink_speed") {
|
||||
property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
|
|
@ -2311,9 +2241,6 @@ void LineEdit::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_draw_control_chars", "enable"), &LineEdit::set_draw_control_chars);
|
||||
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &LineEdit::set_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_text_direction"), &LineEdit::get_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &LineEdit::set_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &LineEdit::get_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_opentype_features"), &LineEdit::clear_opentype_features);
|
||||
ClassDB::bind_method(D_METHOD("set_language", "language"), &LineEdit::set_language);
|
||||
ClassDB::bind_method(D_METHOD("get_language"), &LineEdit::get_language);
|
||||
ClassDB::bind_method(D_METHOD("set_structured_text_bidi_override", "parser"), &LineEdit::set_structured_text_bidi_override);
|
||||
|
|
@ -2419,18 +2346,20 @@ void LineEdit::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars");
|
||||
ADD_GROUP("Structured Text", "structured_text_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
|
||||
|
||||
ADD_GROUP("Caret", "caret_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "set_caret_blink_enabled", "is_caret_blink_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "set_caret_blink_speed", "get_caret_blink_speed");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_column", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_caret_column", "get_caret_column");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_force_displayed"), "set_caret_force_displayed", "is_caret_force_displayed");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled");
|
||||
|
||||
ADD_GROUP("BiDi", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
|
||||
}
|
||||
|
||||
void LineEdit::_ensure_menu() {
|
||||
|
|
|
|||
|
|
@ -105,7 +105,6 @@ private:
|
|||
int scroll_offset = 0;
|
||||
int max_length = 0; // 0 for no maximum.
|
||||
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
TextDirection text_direction = TEXT_DIRECTION_AUTO;
|
||||
TextDirection input_direction = TEXT_DIRECTION_LTR;
|
||||
|
|
@ -210,9 +209,6 @@ protected:
|
|||
virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;
|
||||
virtual void gui_input(const Ref<InputEvent> &p_event) override;
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
void _validate_property(PropertyInfo &property) const override;
|
||||
|
||||
public:
|
||||
|
|
@ -248,10 +244,6 @@ public:
|
|||
void set_text_direction(TextDirection p_text_direction);
|
||||
TextDirection get_text_direction() const;
|
||||
|
||||
void set_opentype_feature(const String &p_name, int p_value);
|
||||
int get_opentype_feature(const String &p_name) const;
|
||||
void clear_opentype_features();
|
||||
|
||||
void set_language(const String &p_language);
|
||||
String get_language() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ void LinkButton::_shape() {
|
|||
text_buf->set_direction((TextServer::Direction)text_direction);
|
||||
}
|
||||
TS->shaped_text_set_bidi_override(text_buf->get_rid(), structured_text_parser(st_parser, st_args, xl_text));
|
||||
text_buf->add_string(xl_text, font, font_size, opentype_features, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
text_buf->add_string(xl_text, font, font_size, language);
|
||||
}
|
||||
|
||||
void LinkButton::set_text(const String &p_text) {
|
||||
|
|
@ -96,29 +96,6 @@ Control::TextDirection LinkButton::get_text_direction() const {
|
|||
return text_direction;
|
||||
}
|
||||
|
||||
void LinkButton::clear_opentype_features() {
|
||||
opentype_features.clear();
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
|
||||
void LinkButton::set_opentype_feature(const String &p_name, int p_value) {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
|
||||
opentype_features[tag] = p_value;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int LinkButton::get_opentype_feature(const String &p_name) const {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return opentype_features[tag];
|
||||
}
|
||||
|
||||
void LinkButton::set_language(const String &p_language) {
|
||||
if (language != p_language) {
|
||||
language = p_language;
|
||||
|
|
@ -237,64 +214,11 @@ void LinkButton::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
bool LinkButton::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
int value = p_value;
|
||||
if (value == -1) {
|
||||
if (opentype_features.has(tag)) {
|
||||
opentype_features.erase(tag);
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
|
||||
opentype_features[tag] = value;
|
||||
_shape();
|
||||
update();
|
||||
}
|
||||
}
|
||||
notify_property_list_changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LinkButton::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
if (opentype_features.has(tag)) {
|
||||
r_ret = opentype_features[tag];
|
||||
return true;
|
||||
} else {
|
||||
r_ret = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LinkButton::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
|
||||
String name = TS->tag_to_name(*ftr);
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
|
||||
}
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
}
|
||||
|
||||
void LinkButton::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_text", "text"), &LinkButton::set_text);
|
||||
ClassDB::bind_method(D_METHOD("get_text"), &LinkButton::get_text);
|
||||
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &LinkButton::set_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_text_direction"), &LinkButton::get_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &LinkButton::set_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &LinkButton::get_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_opentype_features"), &LinkButton::clear_opentype_features);
|
||||
ClassDB::bind_method(D_METHOD("set_language", "language"), &LinkButton::set_language);
|
||||
ClassDB::bind_method(D_METHOD("get_language"), &LinkButton::get_language);
|
||||
ClassDB::bind_method(D_METHOD("set_underline_mode", "underline_mode"), &LinkButton::set_underline_mode);
|
||||
|
|
@ -309,10 +233,11 @@ void LinkButton::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(UNDERLINE_MODE_NEVER);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "underline", PROPERTY_HINT_ENUM, "Always,On Hover,Never"), "set_underline_mode", "get_underline_mode");
|
||||
|
||||
ADD_GROUP("BiDi", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "underline", PROPERTY_HINT_ENUM, "Always,On Hover,Never"), "set_underline_mode", "get_underline_mode");
|
||||
ADD_GROUP("Structured Text", "structured_text_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ private:
|
|||
Ref<TextLine> text_buf;
|
||||
UnderlineMode underline_mode = UNDERLINE_MODE_ALWAYS;
|
||||
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
TextDirection text_direction = TEXT_DIRECTION_AUTO;
|
||||
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
|
||||
|
|
@ -63,10 +62,6 @@ protected:
|
|||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
public:
|
||||
void set_text(const String &p_text);
|
||||
String get_text() const;
|
||||
|
|
@ -80,10 +75,6 @@ public:
|
|||
void set_text_direction(TextDirection p_text_direction);
|
||||
TextDirection get_text_direction() const;
|
||||
|
||||
void set_opentype_feature(const String &p_name, int p_value);
|
||||
int get_opentype_feature(const String &p_name) const;
|
||||
void clear_opentype_features();
|
||||
|
||||
void set_language(const String &p_language);
|
||||
String get_language() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -760,11 +760,11 @@ void PopupMenu::_shape_item(int p_item) {
|
|||
} else {
|
||||
items.write[p_item].text_buf->set_direction((TextServer::Direction)items[p_item].text_direction);
|
||||
}
|
||||
items.write[p_item].text_buf->add_string(items.write[p_item].xl_text, font, font_size, items[p_item].opentype_features, !items[p_item].language.is_empty() ? items[p_item].language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
items.write[p_item].text_buf->add_string(items.write[p_item].xl_text, font, font_size, items[p_item].language);
|
||||
|
||||
items.write[p_item].accel_text_buf->clear();
|
||||
items.write[p_item].accel_text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
|
||||
items.write[p_item].accel_text_buf->add_string(_get_accel_text(items.write[p_item]), font, font_size, Dictionary(), TranslationServer::get_singleton()->get_tool_locale());
|
||||
items.write[p_item].accel_text_buf->add_string(_get_accel_text(items.write[p_item]), font, font_size);
|
||||
items.write[p_item].dirty = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1067,29 +1067,6 @@ void PopupMenu::set_item_text_direction(int p_item, Control::TextDirection p_tex
|
|||
}
|
||||
}
|
||||
|
||||
void PopupMenu::clear_item_opentype_features(int p_item) {
|
||||
if (p_item < 0) {
|
||||
p_item += get_item_count();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_item, items.size());
|
||||
items.write[p_item].opentype_features.clear();
|
||||
items.write[p_item].dirty = true;
|
||||
control->update();
|
||||
}
|
||||
|
||||
void PopupMenu::set_item_opentype_feature(int p_item, const String &p_name, int p_value) {
|
||||
if (p_item < 0) {
|
||||
p_item += get_item_count();
|
||||
}
|
||||
ERR_FAIL_INDEX(p_item, items.size());
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!items[p_item].opentype_features.has(tag) || (int)items[p_item].opentype_features[tag] != p_value) {
|
||||
items.write[p_item].opentype_features[tag] = p_value;
|
||||
items.write[p_item].dirty = true;
|
||||
control->update();
|
||||
}
|
||||
}
|
||||
|
||||
void PopupMenu::set_item_language(int p_item, const String &p_language) {
|
||||
if (p_item < 0) {
|
||||
p_item += get_item_count();
|
||||
|
|
@ -1195,15 +1172,6 @@ Control::TextDirection PopupMenu::get_item_text_direction(int p_item) const {
|
|||
return items[p_item].text_direction;
|
||||
}
|
||||
|
||||
int PopupMenu::get_item_opentype_feature(int p_item, const String &p_name) const {
|
||||
ERR_FAIL_INDEX_V(p_item, items.size(), -1);
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!items[p_item].opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return items[p_item].opentype_features[tag];
|
||||
}
|
||||
|
||||
String PopupMenu::get_item_language(int p_item) const {
|
||||
ERR_FAIL_INDEX_V(p_item, items.size(), "");
|
||||
return items[p_item].language;
|
||||
|
|
@ -1853,7 +1821,6 @@ void PopupMenu::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("set_item_text", "index", "text"), &PopupMenu::set_item_text);
|
||||
ClassDB::bind_method(D_METHOD("set_item_text_direction", "index", "direction"), &PopupMenu::set_item_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("set_item_opentype_feature", "index", "tag", "value"), &PopupMenu::set_item_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("set_item_language", "index", "language"), &PopupMenu::set_item_language);
|
||||
ClassDB::bind_method(D_METHOD("set_item_icon", "index", "icon"), &PopupMenu::set_item_icon);
|
||||
ClassDB::bind_method(D_METHOD("set_item_checked", "index", "checked"), &PopupMenu::set_item_checked);
|
||||
|
|
@ -1876,8 +1843,6 @@ void PopupMenu::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("get_item_text", "index"), &PopupMenu::get_item_text);
|
||||
ClassDB::bind_method(D_METHOD("get_item_text_direction", "index"), &PopupMenu::get_item_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_item_opentype_feature", "index", "tag"), &PopupMenu::get_item_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_item_opentype_features", "index"), &PopupMenu::clear_item_opentype_features);
|
||||
ClassDB::bind_method(D_METHOD("get_item_language", "index"), &PopupMenu::get_item_language);
|
||||
ClassDB::bind_method(D_METHOD("get_item_icon", "index"), &PopupMenu::get_item_icon);
|
||||
ClassDB::bind_method(D_METHOD("is_item_checked", "index"), &PopupMenu::is_item_checked);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ class PopupMenu : public Popup {
|
|||
Ref<TextLine> text_buf;
|
||||
Ref<TextLine> accel_text_buf;
|
||||
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
Control::TextDirection text_direction = Control::TEXT_DIRECTION_AUTO;
|
||||
|
||||
|
|
@ -171,8 +170,6 @@ public:
|
|||
void set_item_text(int p_idx, const String &p_text);
|
||||
|
||||
void set_item_text_direction(int p_idx, Control::TextDirection p_text_direction);
|
||||
void set_item_opentype_feature(int p_idx, const String &p_name, int p_value);
|
||||
void clear_item_opentype_features(int p_idx);
|
||||
void set_item_language(int p_idx, const String &p_language);
|
||||
void set_item_icon(int p_idx, const Ref<Texture2D> &p_icon);
|
||||
void set_item_checked(int p_idx, bool p_checked);
|
||||
|
|
@ -195,7 +192,6 @@ public:
|
|||
|
||||
String get_item_text(int p_idx) const;
|
||||
Control::TextDirection get_item_text_direction(int p_idx) const;
|
||||
int get_item_opentype_feature(int p_idx, const String &p_name) const;
|
||||
String get_item_language(int p_idx) const;
|
||||
int get_item_idx_from_text(const String &text) const;
|
||||
Ref<Texture2D> get_item_icon(int p_idx) const;
|
||||
|
|
|
|||
|
|
@ -227,8 +227,10 @@ void RichTextLabel::_update_line_font(ItemFrame *p_frame, int p_line, const Ref<
|
|||
if (font_size == -1) {
|
||||
font_size = p_base_font_size;
|
||||
}
|
||||
Dictionary font_ftr = _find_font_features(it);
|
||||
TS->shaped_set_span_update_font(t, i, font->get_rids(), font_size, font_ftr);
|
||||
TS->shaped_set_span_update_font(t, i, font->get_rids(), font_size, font->get_opentype_features());
|
||||
for (int j = 0; j < TextServer::SPACING_MAX; j++) {
|
||||
TS->shaped_text_set_spacing(t, TextServer::SpacingType(j), font->get_spacing(TextServer::SpacingType(j)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +265,7 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font
|
|||
|
||||
if (tab_size > 0) { // Align inline tabs.
|
||||
Vector<float> tabs;
|
||||
tabs.push_back(tab_size * p_base_font->get_char_size(' ', 0, p_base_font_size).width);
|
||||
tabs.push_back(tab_size * p_base_font->get_char_size(' ', p_base_font_size).width);
|
||||
l.text_buf->tab_align(tabs);
|
||||
}
|
||||
|
||||
|
|
@ -453,7 +455,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
|
|||
|
||||
if (tab_size > 0) { // Align inline tabs.
|
||||
Vector<float> tabs;
|
||||
tabs.push_back(tab_size * p_base_font->get_char_size(' ', 0, p_base_font_size).width);
|
||||
tabs.push_back(tab_size * p_base_font->get_char_size(' ', p_base_font_size).width);
|
||||
l.text_buf->tab_align(tabs);
|
||||
}
|
||||
|
||||
|
|
@ -483,7 +485,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
|
|||
if (font_size == -1) {
|
||||
font_size = p_base_font_size;
|
||||
}
|
||||
l.text_buf->add_string("\n", font, font_size, Dictionary(), "");
|
||||
l.text_buf->add_string("\n", font, font_size);
|
||||
text += "\n";
|
||||
l.char_count++;
|
||||
remaining_characters--;
|
||||
|
|
@ -498,7 +500,6 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
|
|||
if (font_size == -1) {
|
||||
font_size = p_base_font_size;
|
||||
}
|
||||
Dictionary font_ftr = _find_font_features(it);
|
||||
String lang = _find_language(it);
|
||||
String tx = t->text;
|
||||
if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING && visible_characters >= 0 && remaining_characters >= 0) {
|
||||
|
|
@ -506,7 +507,7 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
|
|||
}
|
||||
remaining_characters -= tx.length();
|
||||
|
||||
l.text_buf->add_string(tx, font, font_size, font_ftr, lang, (uint64_t)it);
|
||||
l.text_buf->add_string(tx, font, font_size, lang, (uint64_t)it);
|
||||
text += tx;
|
||||
l.char_count += tx.length();
|
||||
} break;
|
||||
|
|
@ -837,7 +838,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
|
|||
|
||||
//draw_rect(Rect2(p_ofs + off, TS->shaped_text_get_size(rid)), Color(1,0,0), false, 2); //DEBUG_RECTS
|
||||
|
||||
off.y += TS->shaped_text_get_ascent(rid) + l.text_buf->get_spacing_top();
|
||||
off.y += TS->shaped_text_get_ascent(rid);
|
||||
// Draw inlined objects.
|
||||
Array objects = TS->shaped_text_get_objects(rid);
|
||||
for (int i = 0; i < objects.size(); i++) {
|
||||
|
|
@ -1299,7 +1300,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
|
|||
// Draw foreground color box
|
||||
_draw_fbg_boxes(ci, rid, fbg_line_off, it_from, it_to, chr_range.x, chr_range.y, 1);
|
||||
|
||||
off.y += TS->shaped_text_get_descent(rid) + l.text_buf->get_spacing_bottom();
|
||||
off.y += TS->shaped_text_get_descent(rid);
|
||||
}
|
||||
|
||||
return line_count;
|
||||
|
|
@ -1394,7 +1395,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
|
|||
} break;
|
||||
}
|
||||
|
||||
off.y += TS->shaped_text_get_ascent(rid) + l.text_buf->get_spacing_top();
|
||||
off.y += TS->shaped_text_get_ascent(rid);
|
||||
|
||||
Array objects = TS->shaped_text_get_objects(rid);
|
||||
for (int i = 0; i < objects.size(); i++) {
|
||||
|
|
@ -1491,7 +1492,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
|
|||
return table_offy;
|
||||
}
|
||||
|
||||
off.y += TS->shaped_text_get_descent(rid) + l.text_buf->get_spacing_bottom() + get_theme_constant(SNAME("line_separation"));
|
||||
off.y += TS->shaped_text_get_descent(rid) + get_theme_constant(SNAME("line_separation"));
|
||||
}
|
||||
|
||||
// Text line hit.
|
||||
|
|
@ -2080,7 +2081,7 @@ Ref<Font> RichTextLabel::_find_font(Item *p_item) {
|
|||
fontitem = fontitem->parent;
|
||||
}
|
||||
|
||||
return Ref<Font>();
|
||||
return Ref<FontFile>();
|
||||
}
|
||||
|
||||
int RichTextLabel::_find_font_size(Item *p_item) {
|
||||
|
|
@ -2113,21 +2114,6 @@ int RichTextLabel::_find_outline_size(Item *p_item, int p_default) {
|
|||
return p_default;
|
||||
}
|
||||
|
||||
Dictionary RichTextLabel::_find_font_features(Item *p_item) {
|
||||
Item *ffitem = p_item;
|
||||
|
||||
while (ffitem) {
|
||||
if (ffitem->type == ITEM_FONT_FEATURES) {
|
||||
ItemFontFeatures *fi = static_cast<ItemFontFeatures *>(ffitem);
|
||||
return fi->opentype_features;
|
||||
}
|
||||
|
||||
ffitem = ffitem->parent;
|
||||
}
|
||||
|
||||
return Dictionary();
|
||||
}
|
||||
|
||||
RichTextLabel::ItemDropcap *RichTextLabel::_find_dc_item(Item *p_item) {
|
||||
Item *item = p_item;
|
||||
|
||||
|
|
@ -2204,7 +2190,7 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int
|
|||
if (font_size == -1) {
|
||||
font_size = p_base_font_size;
|
||||
}
|
||||
margin += tab_size * font->get_char_size(' ', 0, font_size).width;
|
||||
margin += tab_size * font->get_char_size(' ', font_size).width;
|
||||
|
||||
} else if (item->type == ITEM_LIST) {
|
||||
Ref<Font> font = _find_font(item);
|
||||
|
|
@ -2215,7 +2201,7 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int
|
|||
if (font_size == -1) {
|
||||
font_size = p_base_font_size;
|
||||
}
|
||||
margin += tab_size * font->get_char_size(' ', 0, font_size).width;
|
||||
margin += tab_size * font->get_char_size(' ', font_size).width;
|
||||
}
|
||||
|
||||
item = item->parent;
|
||||
|
|
@ -2584,8 +2570,8 @@ void RichTextLabel::_process_line_caches() {
|
|||
MutexLock data_lock(data_mutex);
|
||||
Rect2 text_rect = _get_text_rect();
|
||||
|
||||
Ref<Font> base_font = get_theme_font(SNAME("normal_font"));
|
||||
int base_font_size = get_theme_font_size(SNAME("normal_font_size"));
|
||||
Ref<Font> base_font = get_theme_font(SNAME("normal_font"));
|
||||
int ctrl_height = get_size().height;
|
||||
int fi = main->first_invalid_line.load();
|
||||
int total_chars = (fi == 0) ? 0 : (main->lines[fi].char_offset + main->lines[fi].char_count);
|
||||
|
|
@ -2950,25 +2936,14 @@ void RichTextLabel::push_font_size(int p_font_size) {
|
|||
_add_item(item, true);
|
||||
}
|
||||
|
||||
void RichTextLabel::push_font_features(const Dictionary &p_features) {
|
||||
_stop_thread();
|
||||
MutexLock data_lock(data_mutex);
|
||||
|
||||
ERR_FAIL_COND(current->type == ITEM_TABLE);
|
||||
ItemFontFeatures *item = memnew(ItemFontFeatures);
|
||||
|
||||
item->opentype_features = p_features;
|
||||
_add_item(item, true);
|
||||
}
|
||||
|
||||
void RichTextLabel::push_outline_size(int p_font_size) {
|
||||
void RichTextLabel::push_outline_size(int p_ol_size) {
|
||||
_stop_thread();
|
||||
MutexLock data_lock(data_mutex);
|
||||
|
||||
ERR_FAIL_COND(current->type == ITEM_TABLE);
|
||||
ItemOutlineSize *item = memnew(ItemOutlineSize);
|
||||
|
||||
item->outline_size = p_font_size;
|
||||
item->outline_size = p_ol_size;
|
||||
_add_item(item, true);
|
||||
}
|
||||
|
||||
|
|
@ -3840,8 +3815,8 @@ void RichTextLabel::append_text(const String &p_bbcode) {
|
|||
tag_stack.push_front("hint");
|
||||
} else if (tag.begins_with("dropcap")) {
|
||||
Vector<String> subtag = tag.substr(5, tag.length()).split(" ");
|
||||
Ref<Font> f = get_theme_font(SNAME("normal_font"));
|
||||
int fs = get_theme_font_size(SNAME("normal_font_size")) * 3;
|
||||
Ref<Font> f = get_theme_font(SNAME("normal_font"));
|
||||
Color color = get_theme_color(SNAME("default_color"));
|
||||
Color outline_color = get_theme_color(SNAME("outline_color"));
|
||||
int outline_size = get_theme_constant(SNAME("outline_size"));
|
||||
|
|
@ -3974,64 +3949,127 @@ void RichTextLabel::append_text(const String &p_bbcode) {
|
|||
pos = brk_end + 1;
|
||||
tag_stack.push_front("outline_color");
|
||||
|
||||
} else if (tag.begins_with("font=")) {
|
||||
String fnt = tag.substr(5, tag.length());
|
||||
|
||||
Ref<Font> font = ResourceLoader::load(fnt, "Font");
|
||||
if (font.is_valid()) {
|
||||
push_font(font);
|
||||
} else {
|
||||
push_font(normal_font);
|
||||
}
|
||||
|
||||
pos = brk_end + 1;
|
||||
tag_stack.push_front("font");
|
||||
} else if (tag.begins_with("font_size=")) {
|
||||
int fnt_size = tag.substr(10, tag.length()).to_int();
|
||||
push_font_size(fnt_size);
|
||||
pos = brk_end + 1;
|
||||
tag_stack.push_front("font_size");
|
||||
|
||||
} else if (tag.begins_with("opentype_features=")) {
|
||||
String fnt_ftr = tag.substr(18, tag.length());
|
||||
Vector<String> subtag = fnt_ftr.split(",");
|
||||
Dictionary ftrs;
|
||||
for (int i = 0; i < subtag.size(); i++) {
|
||||
Vector<String> subtag_a = subtag[i].split("=");
|
||||
if (subtag_a.size() == 2) {
|
||||
ftrs[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int();
|
||||
} else if (subtag_a.size() == 1) {
|
||||
ftrs[TS->name_to_tag(subtag_a[0])] = 1;
|
||||
if (subtag.size() > 0) {
|
||||
Ref<Font> font = _find_font(current);
|
||||
if (font.is_null()) {
|
||||
font = normal_font;
|
||||
}
|
||||
Ref<FontVariation> fc;
|
||||
fc.instantiate();
|
||||
fc->set_base_font(font);
|
||||
Dictionary features;
|
||||
for (int i = 0; i < subtag.size(); i++) {
|
||||
Vector<String> subtag_a = subtag[i].split("=");
|
||||
if (subtag_a.size() == 2) {
|
||||
features[TS->name_to_tag(subtag_a[0])] = subtag_a[1].to_int();
|
||||
} else if (subtag_a.size() == 1) {
|
||||
features[TS->name_to_tag(subtag_a[0])] = 1;
|
||||
}
|
||||
}
|
||||
fc->set_opentype_features(features);
|
||||
push_font(fc);
|
||||
}
|
||||
push_font_features(ftrs);
|
||||
pos = brk_end + 1;
|
||||
tag_stack.push_front("opentype_features");
|
||||
|
||||
} else if (tag.begins_with("font=")) {
|
||||
String fnt = tag.substr(5, tag.length());
|
||||
|
||||
Ref<Font> fc = ResourceLoader::load(fnt, "Font");
|
||||
if (fc.is_valid()) {
|
||||
push_font(fc);
|
||||
}
|
||||
|
||||
pos = brk_end + 1;
|
||||
tag_stack.push_front("font");
|
||||
|
||||
} else if (tag.begins_with("font ")) {
|
||||
Vector<String> subtag = tag.substr(2, tag.length()).split(" ");
|
||||
|
||||
Ref<FontVariation> fc;
|
||||
fc.instantiate();
|
||||
for (int i = 1; i < subtag.size(); i++) {
|
||||
Vector<String> subtag_a = subtag[i].split("=", true, 2);
|
||||
if (subtag_a.size() == 2) {
|
||||
if (subtag_a[0] == "name" || subtag_a[0] == "n") {
|
||||
String fnt = subtag_a[1];
|
||||
Ref<Font> font = ResourceLoader::load(fnt, "Font");
|
||||
if (font.is_valid()) {
|
||||
push_font(font);
|
||||
} else {
|
||||
push_font(normal_font);
|
||||
Ref<Font> font_data = ResourceLoader::load(fnt, "FontFile");
|
||||
if (font_data.is_valid()) {
|
||||
fc->set_base_font(font_data);
|
||||
}
|
||||
} else if (subtag_a[0] == "size" || subtag_a[0] == "s") {
|
||||
int fnt_size = subtag_a[1].to_int();
|
||||
push_font_size(fnt_size);
|
||||
if (fnt_size > 0) {
|
||||
push_font_size(fnt_size);
|
||||
}
|
||||
} else if (subtag_a[0] == "glyph_spacing" || subtag_a[0] == "gl") {
|
||||
int spacing = subtag_a[1].to_int();
|
||||
fc->set_spacing(TextServer::SPACING_GLYPH, spacing);
|
||||
} else if (subtag_a[0] == "space_spacing" || subtag_a[0] == "sp") {
|
||||
int spacing = subtag_a[1].to_int();
|
||||
fc->set_spacing(TextServer::SPACING_SPACE, spacing);
|
||||
} else if (subtag_a[0] == "top_spacing" || subtag_a[0] == "top") {
|
||||
int spacing = subtag_a[1].to_int();
|
||||
fc->set_spacing(TextServer::SPACING_TOP, spacing);
|
||||
} else if (subtag_a[0] == "bottom_spacing" || subtag_a[0] == "bt") {
|
||||
int spacing = subtag_a[1].to_int();
|
||||
fc->set_spacing(TextServer::SPACING_BOTTOM, spacing);
|
||||
} else if (subtag_a[0] == "embolden" || subtag_a[0] == "emb") {
|
||||
float emb = subtag_a[1].to_float();
|
||||
fc->set_variation_embolden(emb);
|
||||
} else if (subtag_a[0] == "face_index" || subtag_a[0] == "fi") {
|
||||
int fi = subtag_a[1].to_int();
|
||||
fc->set_variation_face_index(fi);
|
||||
} else if (subtag_a[0] == "slant" || subtag_a[0] == "sln") {
|
||||
float slant = subtag_a[1].to_float();
|
||||
fc->set_variation_transform(Transform2D(1.0, slant, 0.0, 1.0, 0.0, 0.0));
|
||||
} else if (subtag_a[0] == "opentype_variation" || subtag_a[0] == "otv") {
|
||||
Dictionary variations;
|
||||
if (!subtag_a[1].is_empty()) {
|
||||
Vector<String> variation_tags = subtag_a[1].split(",");
|
||||
for (int j = 0; j < variation_tags.size(); j++) {
|
||||
Vector<String> subtag_b = variation_tags[j].split("=");
|
||||
if (subtag_b.size() == 2) {
|
||||
variations[TS->name_to_tag(subtag_b[0])] = subtag_b[1].to_float();
|
||||
}
|
||||
}
|
||||
fc->set_variation_opentype(variations);
|
||||
}
|
||||
} else if (subtag_a[0] == "opentype_features" || subtag_a[0] == "otf") {
|
||||
Dictionary features;
|
||||
if (!subtag_a[1].is_empty()) {
|
||||
Vector<String> feature_tags = subtag_a[1].split(",");
|
||||
for (int j = 0; j < feature_tags.size(); j++) {
|
||||
Vector<String> subtag_b = feature_tags[j].split("=");
|
||||
if (subtag_b.size() == 2) {
|
||||
features[TS->name_to_tag(subtag_b[0])] = subtag_b[1].to_float();
|
||||
} else if (subtag_b.size() == 1) {
|
||||
features[TS->name_to_tag(subtag_b[0])] = 1;
|
||||
}
|
||||
}
|
||||
fc->set_opentype_features(features);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
push_font(fc);
|
||||
pos = brk_end + 1;
|
||||
tag_stack.push_front("font");
|
||||
|
||||
} else if (tag.begins_with("outline_size=")) {
|
||||
int fnt_size = tag.substr(13, tag.length()).to_int();
|
||||
push_outline_size(fnt_size);
|
||||
if (fnt_size > 0) {
|
||||
push_outline_size(fnt_size);
|
||||
}
|
||||
pos = brk_end + 1;
|
||||
tag_stack.push_front("outline_size");
|
||||
|
||||
|
|
@ -4854,7 +4892,6 @@ void RichTextLabel::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line);
|
||||
ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font);
|
||||
ClassDB::bind_method(D_METHOD("push_font_size", "font_size"), &RichTextLabel::push_font_size);
|
||||
ClassDB::bind_method(D_METHOD("push_font_features", "opentype_features"), &RichTextLabel::push_font_features);
|
||||
ClassDB::bind_method(D_METHOD("push_normal"), &RichTextLabel::push_normal);
|
||||
ClassDB::bind_method(D_METHOD("push_bold"), &RichTextLabel::push_bold);
|
||||
ClassDB::bind_method(D_METHOD("push_bold_italics"), &RichTextLabel::push_bold_italics);
|
||||
|
|
@ -5018,11 +5055,9 @@ void RichTextLabel::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled");
|
||||
|
||||
ADD_GROUP("Locale", "");
|
||||
ADD_GROUP("BiDi", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
|
||||
ADD_GROUP("Structured Text", "structured_text_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
|
||||
|
||||
|
|
|
|||
|
|
@ -186,11 +186,6 @@ private:
|
|||
ItemFontSize() { type = ITEM_FONT_SIZE; }
|
||||
};
|
||||
|
||||
struct ItemFontFeatures : public Item {
|
||||
Dictionary opentype_features;
|
||||
ItemFontFeatures() { type = ITEM_FONT_FEATURES; }
|
||||
};
|
||||
|
||||
struct ItemColor : public Item {
|
||||
Color color;
|
||||
ItemColor() { type = ITEM_COLOR; }
|
||||
|
|
@ -466,9 +461,8 @@ private:
|
|||
|
||||
Item *_get_item_at_pos(Item *p_item_from, Item *p_item_to, int p_position);
|
||||
void _find_frame(Item *p_item, ItemFrame **r_frame, int *r_line);
|
||||
Ref<Font> _find_font(Item *p_item);
|
||||
int _find_font_size(Item *p_item);
|
||||
Dictionary _find_font_features(Item *p_item);
|
||||
Ref<Font> _find_font(Item *p_item);
|
||||
int _find_outline_size(Item *p_item, int p_default);
|
||||
ItemList *_find_list_item(Item *p_item);
|
||||
ItemDropcap *_find_dc_item(Item *p_item);
|
||||
|
|
@ -525,7 +519,6 @@ public:
|
|||
void push_dropcap(const String &p_string, const Ref<Font> &p_font, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Color &p_color = Color(1, 1, 1), int p_ol_size = 0, const Color &p_ol_color = Color(0, 0, 0, 0));
|
||||
void push_font(const Ref<Font> &p_font);
|
||||
void push_font_size(int p_font_size);
|
||||
void push_font_features(const Dictionary &p_features);
|
||||
void push_outline_size(int p_font_size);
|
||||
void push_normal();
|
||||
void push_bold();
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ void TabBar::_shape(int p_tab) {
|
|||
tabs.write[p_tab].text_buf->set_direction((TextServer::Direction)tabs[p_tab].text_direction);
|
||||
}
|
||||
|
||||
tabs.write[p_tab].text_buf->add_string(tabs[p_tab].xl_text, font, font_size, tabs[p_tab].opentype_features, !tabs[p_tab].language.is_empty() ? tabs[p_tab].language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
tabs.write[p_tab].text_buf->add_string(tabs[p_tab].xl_text, font, font_size, tabs[p_tab].language);
|
||||
}
|
||||
|
||||
void TabBar::_notification(int p_what) {
|
||||
|
|
@ -667,48 +667,6 @@ Control::TextDirection TabBar::get_tab_text_direction(int p_tab) const {
|
|||
return tabs[p_tab].text_direction;
|
||||
}
|
||||
|
||||
void TabBar::clear_tab_opentype_features(int p_tab) {
|
||||
ERR_FAIL_INDEX(p_tab, tabs.size());
|
||||
tabs.write[p_tab].opentype_features.clear();
|
||||
|
||||
_shape(p_tab);
|
||||
_update_cache();
|
||||
_ensure_no_over_offset();
|
||||
if (scroll_to_selected) {
|
||||
ensure_tab_visible(current);
|
||||
}
|
||||
update();
|
||||
update_minimum_size();
|
||||
}
|
||||
|
||||
void TabBar::set_tab_opentype_feature(int p_tab, const String &p_name, int p_value) {
|
||||
ERR_FAIL_INDEX(p_tab, tabs.size());
|
||||
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!tabs[p_tab].opentype_features.has(tag) || (int)tabs[p_tab].opentype_features[tag] != p_value) {
|
||||
tabs.write[p_tab].opentype_features[tag] = p_value;
|
||||
|
||||
_shape(p_tab);
|
||||
_update_cache();
|
||||
_ensure_no_over_offset();
|
||||
if (scroll_to_selected) {
|
||||
ensure_tab_visible(current);
|
||||
}
|
||||
update();
|
||||
update_minimum_size();
|
||||
}
|
||||
}
|
||||
|
||||
int TabBar::get_tab_opentype_feature(int p_tab, const String &p_name) const {
|
||||
ERR_FAIL_INDEX_V(p_tab, tabs.size(), -1);
|
||||
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!tabs[p_tab].opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return tabs[p_tab].opentype_features[tag];
|
||||
}
|
||||
|
||||
void TabBar::set_tab_language(int p_tab, const String &p_language) {
|
||||
ERR_FAIL_INDEX(p_tab, tabs.size());
|
||||
|
||||
|
|
@ -1553,9 +1511,6 @@ void TabBar::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_tab_title", "tab_idx"), &TabBar::get_tab_title);
|
||||
ClassDB::bind_method(D_METHOD("set_tab_text_direction", "tab_idx", "direction"), &TabBar::set_tab_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_tab_text_direction", "tab_idx"), &TabBar::get_tab_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("set_tab_opentype_feature", "tab_idx", "tag", "values"), &TabBar::set_tab_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_tab_opentype_feature", "tab_idx", "tag"), &TabBar::get_tab_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_tab_opentype_features", "tab_idx"), &TabBar::clear_tab_opentype_features);
|
||||
ClassDB::bind_method(D_METHOD("set_tab_language", "tab_idx", "language"), &TabBar::set_tab_language);
|
||||
ClassDB::bind_method(D_METHOD("get_tab_language", "tab_idx"), &TabBar::get_tab_language);
|
||||
ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &TabBar::set_tab_icon);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ private:
|
|||
String text;
|
||||
String xl_text;
|
||||
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
Control::TextDirection text_direction = Control::TEXT_DIRECTION_INHERITED;
|
||||
|
||||
|
|
@ -137,10 +136,6 @@ public:
|
|||
void set_tab_text_direction(int p_tab, TextDirection p_text_direction);
|
||||
TextDirection get_tab_text_direction(int p_tab) const;
|
||||
|
||||
void set_tab_opentype_feature(int p_tab, const String &p_name, int p_value);
|
||||
int get_tab_opentype_feature(int p_tab, const String &p_name) const;
|
||||
void clear_tab_opentype_features(int p_tab);
|
||||
|
||||
void set_tab_language(int p_tab, const String &p_language);
|
||||
String get_tab_language(int p_tab) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -75,14 +75,6 @@ int TextEdit::Text::get_tab_size() const {
|
|||
return tab_size;
|
||||
}
|
||||
|
||||
void TextEdit::Text::set_font_features(const Dictionary &p_features) {
|
||||
if (opentype_features.hash() == p_features.hash()) {
|
||||
return;
|
||||
}
|
||||
opentype_features = p_features;
|
||||
is_dirty = true;
|
||||
}
|
||||
|
||||
void TextEdit::Text::set_direction_and_language(TextServer::Direction p_direction, const String &p_language) {
|
||||
if (direction == p_direction && language == p_language) {
|
||||
return;
|
||||
|
|
@ -178,7 +170,7 @@ void TextEdit::Text::_calculate_max_line_width() {
|
|||
void TextEdit::Text::invalidate_cache(int p_line, int p_column, bool p_text_changed, const String &p_ime_text, const Array &p_bidi_override) {
|
||||
ERR_FAIL_INDEX(p_line, text.size());
|
||||
|
||||
if (font.is_null() || font_size <= 0) {
|
||||
if (font.is_null()) {
|
||||
return; // Not in tree?
|
||||
}
|
||||
|
||||
|
|
@ -191,14 +183,14 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, bool p_text_chan
|
|||
text.write[p_line].data_buf->set_preserve_control(draw_control_chars);
|
||||
if (p_ime_text.length() > 0) {
|
||||
if (p_text_changed) {
|
||||
text.write[p_line].data_buf->add_string(p_ime_text, font, font_size, opentype_features, language);
|
||||
text.write[p_line].data_buf->add_string(p_ime_text, font, font_size, language);
|
||||
}
|
||||
if (!p_bidi_override.is_empty()) {
|
||||
TS->shaped_text_set_bidi_override(text.write[p_line].data_buf->get_rid(), p_bidi_override);
|
||||
}
|
||||
} else {
|
||||
if (p_text_changed) {
|
||||
text.write[p_line].data_buf->add_string(text[p_line].data, font, font_size, opentype_features, language);
|
||||
text.write[p_line].data_buf->add_string(text[p_line].data, font, font_size, language);
|
||||
}
|
||||
if (!text[p_line].bidi_override.is_empty()) {
|
||||
TS->shaped_text_set_bidi_override(text.write[p_line].data_buf->get_rid(), text[p_line].bidi_override);
|
||||
|
|
@ -209,14 +201,17 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, bool p_text_chan
|
|||
RID r = text.write[p_line].data_buf->get_rid();
|
||||
int spans = TS->shaped_get_span_count(r);
|
||||
for (int i = 0; i < spans; i++) {
|
||||
TS->shaped_set_span_update_font(r, i, font->get_rids(), font_size, opentype_features);
|
||||
TS->shaped_set_span_update_font(r, i, font->get_rids(), font_size, font->get_opentype_features());
|
||||
}
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(r, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
}
|
||||
|
||||
// Apply tab align.
|
||||
if (tab_size > 0) {
|
||||
Vector<float> tabs;
|
||||
tabs.push_back(font->get_char_size(' ', 0, font_size).width * tab_size);
|
||||
tabs.push_back(font->get_char_size(' ', font_size).width * tab_size);
|
||||
text.write[p_line].data_buf->tab_align(tabs);
|
||||
}
|
||||
|
||||
|
|
@ -255,7 +250,7 @@ void TextEdit::Text::invalidate_all_lines() {
|
|||
if (tab_size_dirty) {
|
||||
if (tab_size > 0) {
|
||||
Vector<float> tabs;
|
||||
tabs.push_back(font->get_char_size(' ', 0, font_size).width * tab_size);
|
||||
tabs.push_back(font->get_char_size(' ', font_size).width * tab_size);
|
||||
text.write[i].data_buf->tab_align(tabs);
|
||||
}
|
||||
// Tabs have changes, force width update.
|
||||
|
|
@ -277,7 +272,7 @@ void TextEdit::Text::invalidate_font() {
|
|||
max_width = -1;
|
||||
line_height = -1;
|
||||
|
||||
if (!font.is_null() && font_size > 0) {
|
||||
if (font.is_valid() && font_size > 0) {
|
||||
font_height = font->get_height(font_size);
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +290,7 @@ void TextEdit::Text::invalidate_all() {
|
|||
max_width = -1;
|
||||
line_height = -1;
|
||||
|
||||
if (!font.is_null() && font_size > 0) {
|
||||
if (font.is_valid() && font_size > 0) {
|
||||
font_height = font->get_height(font_size);
|
||||
}
|
||||
|
||||
|
|
@ -973,7 +968,7 @@ void TextEdit::_notification(int p_what) {
|
|||
|
||||
// Give visual indication of empty selected line.
|
||||
if (selection.active && line >= selection.from_line && line <= selection.to_line && char_margin >= xmargin_beg) {
|
||||
float char_w = font->get_char_size(' ', 0, font_size).width;
|
||||
float char_w = font->get_char_size(' ', font_size).width;
|
||||
if (rtl) {
|
||||
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - xmargin_beg - ofs_x - char_w, ofs_y, char_w, row_height), selection_color);
|
||||
} else {
|
||||
|
|
@ -1071,7 +1066,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 + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM);
|
||||
float text_height = TS->shaped_text_get_size(rid).y;
|
||||
|
||||
if (rtl) {
|
||||
char_margin = size.width - char_margin - TS->shaped_text_get_size(rid).x;
|
||||
|
|
@ -1355,7 +1350,7 @@ void TextEdit::_notification(int p_what) {
|
|||
ts_caret.l_caret.size.y = caret_width;
|
||||
}
|
||||
if (ts_caret.l_caret.position.x >= TS->shaped_text_get_size(rid).x) {
|
||||
ts_caret.l_caret.size.x = font->get_char_size('m', 0, font_size).x;
|
||||
ts_caret.l_caret.size.x = font->get_char_size('m', font_size).x;
|
||||
} else {
|
||||
ts_caret.l_caret.size.x = 3 * caret_width;
|
||||
}
|
||||
|
|
@ -2573,7 +2568,7 @@ void TextEdit::_update_placeholder() {
|
|||
placeholder_data_buf->set_width(text.get_width());
|
||||
placeholder_data_buf->set_direction((TextServer::Direction)text_direction);
|
||||
placeholder_data_buf->set_preserve_control(draw_control_chars);
|
||||
placeholder_data_buf->add_string(placeholder_text, font, font_size, opentype_features, language);
|
||||
placeholder_data_buf->add_string(placeholder_text, font, font_size, language);
|
||||
|
||||
placeholder_bidi_override = structured_text_parser(st_parser, st_args, placeholder_text);
|
||||
if (placeholder_bidi_override.is_empty()) {
|
||||
|
|
@ -2582,7 +2577,7 @@ void TextEdit::_update_placeholder() {
|
|||
|
||||
if (get_tab_size() > 0) {
|
||||
Vector<float> tabs;
|
||||
tabs.push_back(font->get_char_size(' ', 0, font_size).width * get_tab_size());
|
||||
tabs.push_back(font->get_char_size(' ', font_size).width * get_tab_size());
|
||||
placeholder_data_buf->tab_align(tabs);
|
||||
}
|
||||
|
||||
|
|
@ -2653,7 +2648,6 @@ void TextEdit::_update_caches() {
|
|||
dir = (TextServer::Direction)text_direction;
|
||||
}
|
||||
text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
text.set_font_features(opentype_features);
|
||||
text.set_draw_control_chars(draw_control_chars);
|
||||
text.set_font(font);
|
||||
text.set_font_size(font_size);
|
||||
|
|
@ -2858,33 +2852,6 @@ Control::TextDirection TextEdit::get_text_direction() const {
|
|||
return text_direction;
|
||||
}
|
||||
|
||||
void TextEdit::set_opentype_feature(const String &p_name, int p_value) {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
|
||||
opentype_features[tag] = p_value;
|
||||
text.set_font_features(opentype_features);
|
||||
text.invalidate_font();
|
||||
_update_placeholder();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int TextEdit::get_opentype_feature(const String &p_name) const {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return opentype_features[tag];
|
||||
}
|
||||
|
||||
void TextEdit::clear_opentype_features() {
|
||||
opentype_features.clear();
|
||||
text.set_font_features(opentype_features);
|
||||
text.invalidate_font();
|
||||
_update_placeholder();
|
||||
update();
|
||||
}
|
||||
|
||||
void TextEdit::set_language(const String &p_language) {
|
||||
if (language != p_language) {
|
||||
language = p_language;
|
||||
|
|
@ -5071,10 +5038,6 @@ void TextEdit::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &TextEdit::set_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_text_direction"), &TextEdit::get_text_direction);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &TextEdit::set_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &TextEdit::get_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_opentype_features"), &TextEdit::clear_opentype_features);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_language", "language"), &TextEdit::set_language);
|
||||
ClassDB::bind_method(D_METHOD("get_language"), &TextEdit::get_language);
|
||||
|
||||
|
|
@ -5107,6 +5070,7 @@ void TextEdit::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("set_text", "text"), &TextEdit::set_text);
|
||||
ClassDB::bind_method(D_METHOD("get_text"), &TextEdit::get_text);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_line_count"), &TextEdit::get_line_count);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_placeholder", "text"), &TextEdit::set_placeholder);
|
||||
|
|
@ -5427,8 +5391,6 @@ void TextEdit::_bind_methods() {
|
|||
/* Inspector */
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text", PROPERTY_HINT_MULTILINE_TEXT), "set_placeholder", "get_placeholder");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
|
||||
|
|
@ -5468,7 +5430,9 @@ void TextEdit::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_move_on_right_click"), "set_move_caret_on_right_click_enabled", "is_move_caret_on_right_click_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled");
|
||||
|
||||
ADD_GROUP("Structured Text", "structured_text_");
|
||||
ADD_GROUP("BiDi", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
|
||||
|
||||
|
|
@ -5493,60 +5457,6 @@ void TextEdit::_bind_methods() {
|
|||
ProjectSettings::get_singleton()->set_custom_property_info("gui/common/text_edit_undo_stack_max_size", PropertyInfo(Variant::INT, "gui/common/text_edit_undo_stack_max_size", PROPERTY_HINT_RANGE, "0,10000,1,or_greater")); // No negative numbers.
|
||||
}
|
||||
|
||||
bool TextEdit::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
int value = p_value;
|
||||
if (value == -1) {
|
||||
if (opentype_features.has(tag)) {
|
||||
opentype_features.erase(tag);
|
||||
text.set_font_features(opentype_features);
|
||||
text.invalidate_font();
|
||||
_update_placeholder();
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
|
||||
opentype_features[tag] = value;
|
||||
text.set_font_features(opentype_features);
|
||||
text.invalidate_font();
|
||||
_update_placeholder();
|
||||
update();
|
||||
}
|
||||
}
|
||||
notify_property_list_changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TextEdit::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
if (opentype_features.has(tag)) {
|
||||
r_ret = opentype_features[tag];
|
||||
return true;
|
||||
} else {
|
||||
r_ret = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TextEdit::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
|
||||
String name = TS->tag_to_name(*ftr);
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
|
||||
}
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
}
|
||||
|
||||
/* Internal API for CodeEdit. */
|
||||
// Line hiding.
|
||||
void TextEdit::_set_hiding_enabled(bool p_enabled) {
|
||||
|
|
|
|||
|
|
@ -160,7 +160,6 @@ private:
|
|||
int font_size = -1;
|
||||
int font_height = 0;
|
||||
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
TextServer::Direction direction = TextServer::DIRECTION_AUTO;
|
||||
bool draw_control_chars = false;
|
||||
|
|
@ -180,7 +179,6 @@ private:
|
|||
int get_tab_size() const;
|
||||
void set_font(const Ref<Font> &p_font);
|
||||
void set_font_size(int p_font_size);
|
||||
void set_font_features(const Dictionary &p_features);
|
||||
void set_direction_and_language(TextServer::Direction p_direction, const String &p_language);
|
||||
void set_draw_control_chars(bool p_enabled);
|
||||
|
||||
|
|
@ -271,7 +269,6 @@ private:
|
|||
TextDirection text_direction = TEXT_DIRECTION_AUTO;
|
||||
TextDirection input_direction = TEXT_DIRECTION_LTR;
|
||||
|
||||
Dictionary opentype_features;
|
||||
String language = "";
|
||||
|
||||
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
|
||||
|
|
@ -581,10 +578,6 @@ protected:
|
|||
|
||||
static void _bind_methods();
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
/* Internal API for CodeEdit, pending public API. */
|
||||
// brace matching
|
||||
bool highlight_matching_braces_enabled = false;
|
||||
|
|
@ -650,10 +643,6 @@ public:
|
|||
void set_text_direction(TextDirection p_text_direction);
|
||||
TextDirection get_text_direction() const;
|
||||
|
||||
void set_opentype_feature(const String &p_name, int p_value);
|
||||
int get_opentype_feature(const String &p_name) const;
|
||||
void clear_opentype_features();
|
||||
|
||||
void set_language(const String &p_language);
|
||||
String get_language() const;
|
||||
|
||||
|
|
@ -686,6 +675,7 @@ public:
|
|||
|
||||
void set_text(const String &p_text);
|
||||
String get_text() const;
|
||||
|
||||
int get_line_count() const;
|
||||
|
||||
void set_placeholder(const String &p_text);
|
||||
|
|
|
|||
|
|
@ -303,37 +303,6 @@ Control::TextDirection TreeItem::get_text_direction(int p_column) const {
|
|||
return cells[p_column].text_direction;
|
||||
}
|
||||
|
||||
void TreeItem::clear_opentype_features(int p_column) {
|
||||
ERR_FAIL_INDEX(p_column, cells.size());
|
||||
|
||||
cells.write[p_column].opentype_features.clear();
|
||||
cells.write[p_column].dirty = true;
|
||||
cells.write[p_column].cached_minimum_size_dirty = true;
|
||||
|
||||
_changed_notify(p_column);
|
||||
}
|
||||
|
||||
void TreeItem::set_opentype_feature(int p_column, const String &p_name, int p_value) {
|
||||
ERR_FAIL_INDEX(p_column, cells.size());
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!cells[p_column].opentype_features.has(tag) || (int)cells[p_column].opentype_features[tag] != p_value) {
|
||||
cells.write[p_column].opentype_features[tag] = p_value;
|
||||
cells.write[p_column].dirty = true;
|
||||
cells.write[p_column].cached_minimum_size_dirty = true;
|
||||
|
||||
_changed_notify(p_column);
|
||||
}
|
||||
}
|
||||
|
||||
int TreeItem::get_opentype_feature(int p_column, const String &p_name) const {
|
||||
ERR_FAIL_INDEX_V(p_column, cells.size(), -1);
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!cells[p_column].opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return cells[p_column].opentype_features[tag];
|
||||
}
|
||||
|
||||
void TreeItem::set_structured_text_bidi_override(int p_column, TextServer::StructuredTextParser p_parser) {
|
||||
ERR_FAIL_INDEX(p_column, cells.size());
|
||||
|
||||
|
|
@ -1269,10 +1238,6 @@ void TreeItem::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_text_direction", "column", "direction"), &TreeItem::set_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_text_direction", "column"), &TreeItem::get_text_direction);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_opentype_feature", "column", "tag", "value"), &TreeItem::set_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_opentype_feature", "column", "tag"), &TreeItem::get_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_opentype_features", "column"), &TreeItem::clear_opentype_features);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_structured_text_bidi_override", "column", "parser"), &TreeItem::set_structured_text_bidi_override);
|
||||
ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override", "column"), &TreeItem::get_structured_text_bidi_override);
|
||||
|
||||
|
|
@ -1667,7 +1632,7 @@ void Tree::update_column(int p_col) {
|
|||
columns.write[p_col].text_buf->set_direction((TextServer::Direction)columns[p_col].text_direction);
|
||||
}
|
||||
|
||||
columns.write[p_col].text_buf->add_string(columns[p_col].title, cache.font, cache.font_size, columns[p_col].opentype_features, !columns[p_col].language.is_empty() ? columns[p_col].language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
columns.write[p_col].text_buf->add_string(columns[p_col].title, cache.font, cache.font_size, columns[p_col].language);
|
||||
}
|
||||
|
||||
void Tree::update_item_cell(TreeItem *p_item, int p_col) {
|
||||
|
|
@ -1725,7 +1690,7 @@ void Tree::update_item_cell(TreeItem *p_item, int p_col) {
|
|||
} else {
|
||||
font_size = cache.font_size;
|
||||
}
|
||||
p_item->cells.write[p_col].text_buf->add_string(valtext, font, font_size, p_item->cells[p_col].opentype_features, !p_item->cells[p_col].language.is_empty() ? p_item->cells[p_col].language : TranslationServer::get_singleton()->get_tool_locale());
|
||||
p_item->cells.write[p_col].text_buf->add_string(valtext, font, font_size, p_item->cells[p_col].language);
|
||||
TS->shaped_text_set_bidi_override(p_item->cells[p_col].text_buf->get_rid(), structured_text_parser(p_item->cells[p_col].st_parser, p_item->cells[p_col].st_args, valtext));
|
||||
p_item->cells.write[p_col].dirty = false;
|
||||
}
|
||||
|
|
@ -4192,7 +4157,7 @@ int Tree::get_column_minimum_width(int p_column) const {
|
|||
|
||||
// Check if the visible title of the column is wider.
|
||||
if (show_column_titles) {
|
||||
min_width = MAX(cache.font->get_string_size(columns[p_column].title, cache.font_size).width + cache.bg->get_margin(SIDE_LEFT) + cache.bg->get_margin(SIDE_RIGHT), min_width);
|
||||
min_width = MAX(cache.font->get_string_size(columns[p_column].title, HORIZONTAL_ALIGNMENT_LEFT, -1, cache.font_size).width + cache.bg->get_margin(SIDE_LEFT) + cache.bg->get_margin(SIDE_RIGHT), min_width);
|
||||
}
|
||||
|
||||
if (!columns[p_column].clip_content) {
|
||||
|
|
@ -4471,32 +4436,6 @@ Control::TextDirection Tree::get_column_title_direction(int p_column) const {
|
|||
return columns[p_column].text_direction;
|
||||
}
|
||||
|
||||
void Tree::clear_column_title_opentype_features(int p_column) {
|
||||
ERR_FAIL_INDEX(p_column, columns.size());
|
||||
columns.write[p_column].opentype_features.clear();
|
||||
update_column(p_column);
|
||||
update();
|
||||
}
|
||||
|
||||
void Tree::set_column_title_opentype_feature(int p_column, const String &p_name, int p_value) {
|
||||
ERR_FAIL_INDEX(p_column, columns.size());
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!columns[p_column].opentype_features.has(tag) || (int)columns[p_column].opentype_features[tag] != p_value) {
|
||||
columns.write[p_column].opentype_features[tag] = p_value;
|
||||
update_column(p_column);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int Tree::get_column_title_opentype_feature(int p_column, const String &p_name) const {
|
||||
ERR_FAIL_INDEX_V(p_column, columns.size(), -1);
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!columns[p_column].opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return columns[p_column].opentype_features[tag];
|
||||
}
|
||||
|
||||
void Tree::set_column_title_language(int p_column, const String &p_language) {
|
||||
ERR_FAIL_INDEX(p_column, columns.size());
|
||||
if (columns[p_column].language != p_language) {
|
||||
|
|
@ -4983,10 +4922,6 @@ void Tree::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_column_title_direction", "column", "direction"), &Tree::set_column_title_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_column_title_direction", "column"), &Tree::get_column_title_direction);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_column_title_opentype_feature", "column", "tag", "value"), &Tree::set_column_title_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_column_title_opentype_feature", "column", "tag"), &Tree::get_column_title_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_column_title_opentype_features", "column"), &Tree::clear_column_title_opentype_features);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_column_title_language", "column", "language"), &Tree::set_column_title_language);
|
||||
ClassDB::bind_method(D_METHOD("get_column_title_language", "column"), &Tree::get_column_title_language);
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ private:
|
|||
String text;
|
||||
String suffix;
|
||||
Ref<TextLine> text_buf;
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
|
||||
Array st_args;
|
||||
|
|
@ -220,10 +219,6 @@ public:
|
|||
void set_text_direction(int p_column, Control::TextDirection p_text_direction);
|
||||
Control::TextDirection get_text_direction(int p_column) const;
|
||||
|
||||
void set_opentype_feature(int p_column, const String &p_name, int p_value);
|
||||
int get_opentype_feature(int p_column, const String &p_name) const;
|
||||
void clear_opentype_features(int p_column);
|
||||
|
||||
void set_structured_text_bidi_override(int p_column, TextServer::StructuredTextParser p_parser);
|
||||
TextServer::StructuredTextParser get_structured_text_bidi_override(int p_column) const;
|
||||
|
||||
|
|
@ -429,7 +424,6 @@ private:
|
|||
bool clip_content = false;
|
||||
String title;
|
||||
Ref<TextLine> text_buf;
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
Control::TextDirection text_direction = Control::TEXT_DIRECTION_INHERITED;
|
||||
ColumnInfo() {
|
||||
|
|
@ -666,10 +660,6 @@ public:
|
|||
void set_column_title_direction(int p_column, Control::TextDirection p_text_direction);
|
||||
Control::TextDirection get_column_title_direction(int p_column) const;
|
||||
|
||||
void set_column_title_opentype_feature(int p_column, const String &p_name, int p_value);
|
||||
int get_column_title_opentype_feature(int p_column, const String &p_name) const;
|
||||
void clear_column_title_opentype_features(int p_column);
|
||||
|
||||
void set_column_title_language(int p_column, const String &p_language);
|
||||
String get_column_title_language(int p_column) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -658,24 +658,48 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex
|
|||
RenderingServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, real_t p_width, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
|
||||
void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, uint16_t p_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
|
||||
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
ERR_FAIL_COND(p_font.is_null());
|
||||
p_font->draw_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);
|
||||
|
||||
p_font->draw_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_modulate, p_flags, p_direction, p_orientation);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, real_t p_width, int p_max_lines, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate, uint16_t p_flags) const {
|
||||
void CanvasItem::draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, const Color &p_modulate, uint16_t p_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
|
||||
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
ERR_FAIL_COND(p_font.is_null());
|
||||
p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_max_lines, p_size, p_modulate, p_outline_size, p_outline_modulate, p_flags);
|
||||
|
||||
p_font->draw_multiline_string(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_modulate, p_flags, p_direction, p_orientation);
|
||||
}
|
||||
|
||||
real_t CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next, int p_size, const Color &p_modulate, int p_outline_size, const Color &p_outline_modulate) const {
|
||||
ERR_FAIL_COND_V_MSG(!drawing, 0.f, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
ERR_FAIL_COND_V(p_font.is_null(), 0.f);
|
||||
ERR_FAIL_COND_V(p_char.length() != 1, 0.f);
|
||||
void CanvasItem::draw_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, uint16_t p_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
|
||||
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
ERR_FAIL_COND(p_font.is_null());
|
||||
|
||||
return p_font->draw_char(canvas_item, p_pos, p_char[0], p_next.get_data()[0], p_size, p_modulate, p_outline_size, p_outline_modulate);
|
||||
p_font->draw_string_outline(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_size, p_modulate, p_flags, p_direction, p_orientation);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_multiline_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_max_lines, int p_size, const Color &p_modulate, uint16_t p_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
|
||||
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
ERR_FAIL_COND(p_font.is_null());
|
||||
|
||||
p_font->draw_multiline_string_outline(canvas_item, p_pos, p_text, p_alignment, p_width, p_font_size, p_max_lines, p_size, p_modulate, p_flags, p_direction, p_orientation);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size, const Color &p_modulate) const {
|
||||
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
ERR_FAIL_COND(p_char.length() != 1);
|
||||
ERR_FAIL_COND(p_font.is_null());
|
||||
|
||||
p_font->draw_char(canvas_item, p_pos, p_char[0], p_font_size, p_modulate);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_char_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size, int p_size, const Color &p_modulate) const {
|
||||
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
ERR_FAIL_COND(p_char.length() != 1);
|
||||
ERR_FAIL_COND(p_font.is_null());
|
||||
|
||||
p_font->draw_char_outline(canvas_item, p_pos, p_char[0], p_font_size, p_size, p_modulate);
|
||||
}
|
||||
|
||||
void CanvasItem::_notify_transform(CanvasItem *p_node) {
|
||||
|
|
@ -900,9 +924,12 @@ void CanvasItem::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture", "width"), &CanvasItem::draw_primitive, DEFVAL(Ref<Texture2D>()), DEFVAL(1.0));
|
||||
ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture"), &CanvasItem::draw_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>()));
|
||||
ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture"), &CanvasItem::draw_colored_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>()));
|
||||
ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "alignment", "width", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
|
||||
ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "alignment", "width", "max_lines", "size", "modulate", "outline_size", "outline_modulate", "flags"), &CanvasItem::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND));
|
||||
ClassDB::bind_method(D_METHOD("draw_char", "font", "pos", "char", "next", "size", "modulate", "outline_size", "outline_modulate"), &CanvasItem::draw_char, DEFVAL(""), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(Color(1, 1, 1, 0)));
|
||||
ClassDB::bind_method(D_METHOD("draw_string", "font", "pos", "text", "alignment", "width", "font_size", "modulate", "flags", "direction", "orientation"), &CanvasItem::draw_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
|
||||
ClassDB::bind_method(D_METHOD("draw_multiline_string", "font", "pos", "text", "alignment", "width", "font_size", "max_lines", "modulate", "flags", "direction", "orientation"), &CanvasItem::draw_multiline_string, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
|
||||
ClassDB::bind_method(D_METHOD("draw_string_outline", "font", "pos", "text", "alignment", "width", "font_size", "size", "modulate", "flags", "direction", "orientation"), &CanvasItem::draw_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
|
||||
ClassDB::bind_method(D_METHOD("draw_multiline_string_outline", "font", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "flags", "direction", "orientation"), &CanvasItem::draw_multiline_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL));
|
||||
ClassDB::bind_method(D_METHOD("draw_char", "font", "pos", "char", "font_size", "modulate"), &CanvasItem::draw_char, DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(Color(1.0, 1.0, 1.0)));
|
||||
ClassDB::bind_method(D_METHOD("draw_char_outline", "font", "pos", "char", "font_size", "size", "modulate"), &CanvasItem::draw_char_outline, DEFVAL(Font::DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0)));
|
||||
ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "transform", "modulate"), &CanvasItem::draw_mesh, DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1, 1)));
|
||||
ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture"), &CanvasItem::draw_multimesh);
|
||||
ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform, DEFVAL(0.0), DEFVAL(Size2(1.0, 1.0)));
|
||||
|
|
|
|||
|
|
@ -235,9 +235,14 @@ public:
|
|||
void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1));
|
||||
void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture);
|
||||
|
||||
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, real_t p_width = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
|
||||
void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, real_t p_width = -1, int p_max_lines = -1, int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
|
||||
real_t draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", int p_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const;
|
||||
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
|
||||
void draw_multiline_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_max_lines = -1, const Color &p_modulate = Color(1.0, 1.0, 1.0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
|
||||
|
||||
void draw_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_size = 1, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
|
||||
void draw_multiline_string_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_max_lines = -1, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
|
||||
|
||||
void draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size = Font::DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
|
||||
void draw_char_outline(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, int p_font_size = Font::DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
|
||||
|
||||
void draw_set_transform(const Point2 &p_offset, real_t p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0));
|
||||
void draw_set_transform_matrix(const Transform2D &p_matrix);
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ void Viewport::_sub_window_update(Window *p_window) {
|
|||
int close_h_ofs = p_window->get_theme_constant(SNAME("close_h_offset"));
|
||||
int close_v_ofs = p_window->get_theme_constant(SNAME("close_v_offset"));
|
||||
|
||||
TextLine title_text = TextLine(p_window->atr(p_window->get_title()), title_font, font_size, Dictionary(), TranslationServer::get_singleton()->get_tool_locale());
|
||||
TextLine title_text = TextLine(p_window->atr(p_window->get_title()), title_font, font_size);
|
||||
title_text.set_width(r.size.width - panel->get_minimum_size().x - close_h_ofs);
|
||||
title_text.set_direction(p_window->is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
|
||||
int x = (r.size.width - title_text.get_size().x) / 2;
|
||||
|
|
|
|||
|
|
@ -853,8 +853,11 @@ void register_scene_types() {
|
|||
|
||||
GDREGISTER_CLASS(Animation);
|
||||
GDREGISTER_CLASS(AnimationLibrary);
|
||||
GDREGISTER_CLASS(FontData);
|
||||
GDREGISTER_CLASS(Font);
|
||||
|
||||
GDREGISTER_ABSTRACT_CLASS(Font);
|
||||
GDREGISTER_CLASS(FontFile);
|
||||
GDREGISTER_CLASS(FontVariation);
|
||||
|
||||
GDREGISTER_CLASS(Curve);
|
||||
|
||||
GDREGISTER_CLASS(SceneReplicationConfig);
|
||||
|
|
@ -921,9 +924,9 @@ void register_scene_types() {
|
|||
ClassDB::add_compatibility_class("AnimationTreePlayer", "AnimationTree");
|
||||
ClassDB::add_compatibility_class("BakedLightmap", "LightmapGI");
|
||||
ClassDB::add_compatibility_class("BakedLightmapData", "LightmapGIData");
|
||||
ClassDB::add_compatibility_class("BitmapFont", "Font");
|
||||
ClassDB::add_compatibility_class("DynamicFont", "Font");
|
||||
ClassDB::add_compatibility_class("DynamicFontData", "FontData");
|
||||
ClassDB::add_compatibility_class("BitmapFont", "FontFile");
|
||||
ClassDB::add_compatibility_class("DynamicFont", "FontFile");
|
||||
ClassDB::add_compatibility_class("DynamicFontData", "FontFile");
|
||||
ClassDB::add_compatibility_class("Navigation3D", "Node3D");
|
||||
ClassDB::add_compatibility_class("Navigation2D", "Node2D");
|
||||
ClassDB::add_compatibility_class("OpenSimplexNoise", "FastNoiseLite");
|
||||
|
|
@ -1113,7 +1116,7 @@ void initialize_theme() {
|
|||
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom", PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
|
||||
|
||||
String font_path = GLOBAL_DEF_RST("gui/theme/custom_font", "");
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res,*.font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
|
||||
|
||||
bool font_antialiased = (bool)GLOBAL_DEF_RST("gui/theme/default_font_antialiased", true);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_antialiased", PropertyInfo(Variant::BOOL, "gui/theme/default_font_antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
|
||||
|
|
|
|||
|
|
@ -918,8 +918,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
|||
theme->set_stylebox("panel", "TooltipPanel",
|
||||
make_flat_stylebox(Color(0, 0, 0, 0.5), 2 * default_margin, 0.5 * default_margin, 2 * default_margin, 0.5 * default_margin));
|
||||
|
||||
theme->set_font("font", "TooltipLabel", Ref<Font>());
|
||||
theme->set_font_size("font_size", "TooltipLabel", -1);
|
||||
theme->set_font("font", "TooltipLabel", Ref<Font>());
|
||||
|
||||
theme->set_color("font_color", "TooltipLabel", control_font_color);
|
||||
theme->set_color("font_shadow_color", "TooltipLabel", Color(0, 0, 0, 0));
|
||||
|
|
@ -939,7 +939,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
|
|||
theme->set_font("italics_font", "RichTextLabel", italics_font);
|
||||
theme->set_font("bold_italics_font", "RichTextLabel", bold_italics_font);
|
||||
theme->set_font("mono_font", "RichTextLabel", Ref<Font>());
|
||||
|
||||
theme->set_font_size("normal_font_size", "RichTextLabel", -1);
|
||||
theme->set_font_size("bold_font_size", "RichTextLabel", -1);
|
||||
theme->set_font_size("italics_font_size", "RichTextLabel", -1);
|
||||
|
|
@ -1034,9 +1033,9 @@ void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPos
|
|||
Ref<StyleBox> default_style;
|
||||
Ref<Texture2D> default_icon;
|
||||
Ref<Font> default_font;
|
||||
Ref<Font> bold_font;
|
||||
Ref<Font> bold_italics_font;
|
||||
Ref<Font> italics_font;
|
||||
Ref<FontVariation> bold_font;
|
||||
Ref<FontVariation> bold_italics_font;
|
||||
Ref<FontVariation> italics_font;
|
||||
float default_scale = CLAMP(p_scale, 0.5, 8.0);
|
||||
|
||||
if (p_font.is_valid()) {
|
||||
|
|
@ -1046,48 +1045,31 @@ void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPos
|
|||
// Use the default DynamicFont (separate from the editor font).
|
||||
// The default DynamicFont is chosen to have a small file size since it's
|
||||
// embedded in both editor and export template binaries.
|
||||
Ref<Font> dynamic_font;
|
||||
Ref<FontFile> dynamic_font;
|
||||
dynamic_font.instantiate();
|
||||
|
||||
Ref<FontData> dynamic_font_data;
|
||||
dynamic_font_data.instantiate();
|
||||
dynamic_font_data->set_data_ptr(_font_OpenSans_SemiBold, _font_OpenSans_SemiBold_size);
|
||||
dynamic_font_data->set_subpixel_positioning(p_font_subpixel);
|
||||
dynamic_font_data->set_hinting(p_font_hinting);
|
||||
dynamic_font_data->set_antialiased(p_font_antialiased);
|
||||
dynamic_font_data->set_multichannel_signed_distance_field(p_font_msdf);
|
||||
dynamic_font_data->set_generate_mipmaps(p_font_generate_mipmaps);
|
||||
|
||||
dynamic_font->add_data(dynamic_font_data);
|
||||
dynamic_font->set_data_ptr(_font_OpenSans_SemiBold, _font_OpenSans_SemiBold_size);
|
||||
dynamic_font->set_subpixel_positioning(p_font_subpixel);
|
||||
dynamic_font->set_hinting(p_font_hinting);
|
||||
dynamic_font->set_antialiased(p_font_antialiased);
|
||||
dynamic_font->set_multichannel_signed_distance_field(p_font_msdf);
|
||||
dynamic_font->set_generate_mipmaps(p_font_generate_mipmaps);
|
||||
|
||||
default_font = dynamic_font;
|
||||
}
|
||||
|
||||
if (default_font.is_valid()) {
|
||||
bold_font.instantiate();
|
||||
for (int i = 0; i < default_font->get_data_count(); i++) {
|
||||
Ref<FontData> data = default_font->get_data(i)->duplicate();
|
||||
// Try to match OpenSans ExtraBold.
|
||||
data->set_embolden(1.2);
|
||||
bold_font->add_data(data);
|
||||
}
|
||||
bold_font->set_base_font(default_font);
|
||||
bold_font->set_variation_embolden(1.2);
|
||||
|
||||
bold_italics_font.instantiate();
|
||||
for (int i = 0; i < default_font->get_data_count(); i++) {
|
||||
Ref<FontData> data = default_font->get_data(i)->duplicate();
|
||||
// Try to match OpenSans ExtraBold Italic.
|
||||
data->set_embolden(1.2);
|
||||
data->set_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
|
||||
bold_italics_font->add_data(data);
|
||||
}
|
||||
bold_italics_font->set_base_font(default_font);
|
||||
bold_italics_font->set_variation_embolden(1.2);
|
||||
bold_italics_font->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
|
||||
|
||||
italics_font.instantiate();
|
||||
for (int i = 0; i < default_font->get_data_count(); i++) {
|
||||
Ref<FontData> data = default_font->get_data(i)->duplicate();
|
||||
// Try to match OpenSans Italic.
|
||||
data->set_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
|
||||
italics_font->add_data(data);
|
||||
}
|
||||
italics_font->set_base_font(default_font);
|
||||
italics_font->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
fill_default_theme(t, default_font, bold_font, bold_italics_font, italics_font, default_icon, default_style, default_scale);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -37,16 +37,108 @@
|
|||
#include "scene/resources/texture.h"
|
||||
#include "servers/text_server.h"
|
||||
|
||||
class TextLine;
|
||||
class TextParagraph;
|
||||
|
||||
/*************************************************************************/
|
||||
/* Font */
|
||||
/*************************************************************************/
|
||||
|
||||
class FontData : public Resource {
|
||||
GDCLASS(FontData, Resource);
|
||||
class Font : public Resource {
|
||||
GDCLASS(Font, Resource);
|
||||
|
||||
// Shaped string cache.
|
||||
mutable LRUCache<uint64_t, Ref<TextLine>> cache;
|
||||
mutable LRUCache<uint64_t, Ref<TextParagraph>> cache_wrap;
|
||||
|
||||
protected:
|
||||
// Output.
|
||||
mutable TypedArray<RID> rids;
|
||||
mutable bool dirty_rids = true;
|
||||
|
||||
// Fallbacks.
|
||||
static constexpr int MAX_FALLBACK_DEPTH = 64;
|
||||
TypedArray<Font> fallbacks;
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
virtual void _update_rids_fb(const Ref<Font> &p_f, int p_depth) const;
|
||||
virtual void _update_rids() const;
|
||||
virtual bool _is_cyclic(const Ref<Font> &p_f, int p_depth) const;
|
||||
|
||||
virtual void reset_state() override;
|
||||
|
||||
public:
|
||||
virtual void _invalidate_rids();
|
||||
|
||||
static constexpr int DEFAULT_FONT_SIZE = 16;
|
||||
|
||||
// Fallbacks.
|
||||
virtual void set_fallbacks(const TypedArray<Font> &p_fallbacks);
|
||||
virtual TypedArray<Font> get_fallbacks() const;
|
||||
|
||||
// Output.
|
||||
virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const { return RID(); };
|
||||
virtual RID _get_rid() const { return RID(); };
|
||||
virtual TypedArray<RID> get_rids() const;
|
||||
|
||||
// Font metrics.
|
||||
virtual real_t get_height(int p_font_size) const;
|
||||
virtual real_t get_ascent(int p_font_size) const;
|
||||
virtual real_t get_descent(int p_font_size) const;
|
||||
virtual real_t get_underline_position(int p_font_size) const;
|
||||
virtual real_t get_underline_thickness(int p_font_size) const;
|
||||
|
||||
virtual String get_font_name() const;
|
||||
virtual String get_font_style_name() const;
|
||||
virtual uint32_t get_font_style() const;
|
||||
|
||||
virtual int get_spacing(TextServer::SpacingType p_spacing) const { return 0; };
|
||||
virtual Dictionary get_opentype_features() const;
|
||||
|
||||
// Drawing string.
|
||||
virtual void set_cache_capacity(int p_single_line, int p_multi_line);
|
||||
|
||||
virtual Size2 get_string_size(const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
|
||||
virtual Size2 get_multiline_string_size(const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
|
||||
|
||||
virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
|
||||
virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, const Color &p_modulate = Color(1.0, 1.0, 1.0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
|
||||
|
||||
virtual void draw_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
|
||||
virtual void draw_multiline_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_font_size = DEFAULT_FONT_SIZE, int p_max_lines = -1, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL) const;
|
||||
|
||||
// Drawing char.
|
||||
virtual Size2 get_char_size(char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE) const;
|
||||
virtual real_t draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
|
||||
virtual real_t draw_char_outline(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, int p_font_size = DEFAULT_FONT_SIZE, int p_size = 1, const Color &p_modulate = Color(1.0, 1.0, 1.0)) const;
|
||||
|
||||
// Helper functions.
|
||||
virtual bool has_char(char32_t p_char) const;
|
||||
virtual String get_supported_chars() const;
|
||||
|
||||
virtual bool is_language_supported(const String &p_language) const;
|
||||
virtual bool is_script_supported(const String &p_script) const;
|
||||
|
||||
virtual Dictionary get_supported_feature_list() const;
|
||||
virtual Dictionary get_supported_variation_list() const;
|
||||
virtual int64_t get_face_count() const;
|
||||
|
||||
Font();
|
||||
~Font();
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
/* FontFile */
|
||||
/*************************************************************************/
|
||||
|
||||
class FontFile : public Font {
|
||||
GDCLASS(FontFile, Font);
|
||||
RES_BASE_EXTENSION("fontdata");
|
||||
|
||||
// Font source data.
|
||||
const uint8_t *data_ptr = nullptr;
|
||||
size_t data_size = 0;
|
||||
int face_index = 0;
|
||||
PackedByteArray data;
|
||||
|
||||
bool antialiased = true;
|
||||
|
|
@ -59,8 +151,11 @@ class FontData : public Resource {
|
|||
TextServer::Hinting hinting = TextServer::HINTING_LIGHT;
|
||||
TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
|
||||
real_t oversampling = 0.f;
|
||||
real_t embolden = 0.f;
|
||||
Transform2D transform;
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
real_t bmp_height = 0.0;
|
||||
real_t bmp_ascent = 0.0;
|
||||
#endif
|
||||
|
||||
// Cache.
|
||||
mutable Vector<RID> cache;
|
||||
|
|
@ -92,20 +187,10 @@ public:
|
|||
virtual void set_data(const PackedByteArray &p_data);
|
||||
virtual PackedByteArray get_data() const;
|
||||
|
||||
virtual void set_face_index(int64_t p_index);
|
||||
virtual int64_t get_face_index() const;
|
||||
|
||||
virtual int64_t get_face_count() const;
|
||||
|
||||
// Common properties.
|
||||
virtual void set_font_name(const String &p_name);
|
||||
virtual String get_font_name() const;
|
||||
|
||||
virtual void set_font_style_name(const String &p_name);
|
||||
virtual String get_font_style_name() const;
|
||||
|
||||
virtual void set_font_style(uint32_t p_style);
|
||||
virtual uint32_t get_font_style() const;
|
||||
|
||||
virtual void set_antialiased(bool p_antialiased);
|
||||
virtual bool is_antialiased() const;
|
||||
|
|
@ -134,17 +219,12 @@ public:
|
|||
virtual void set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel);
|
||||
virtual TextServer::SubpixelPositioning get_subpixel_positioning() const;
|
||||
|
||||
virtual void set_embolden(float p_strength);
|
||||
virtual float get_embolden() const;
|
||||
|
||||
virtual void set_transform(Transform2D p_transform);
|
||||
virtual Transform2D get_transform() const;
|
||||
|
||||
virtual void set_oversampling(real_t p_oversampling);
|
||||
virtual real_t get_oversampling() const;
|
||||
|
||||
// Cache.
|
||||
virtual RID find_cache(const Dictionary &p_variation_coordinates) const;
|
||||
virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const override;
|
||||
virtual RID _get_rid() const override;
|
||||
|
||||
virtual int get_cache_count() const;
|
||||
virtual void clear_cache();
|
||||
|
|
@ -157,23 +237,29 @@ public:
|
|||
virtual void set_variation_coordinates(int p_cache_index, const Dictionary &p_variation_coordinates);
|
||||
virtual Dictionary get_variation_coordinates(int p_cache_index) const;
|
||||
|
||||
virtual void set_ascent(int p_cache_index, int p_size, real_t p_ascent);
|
||||
virtual real_t get_ascent(int p_cache_index, int p_size) const;
|
||||
virtual void set_embolden(int p_cache_index, float p_strength);
|
||||
virtual float get_embolden(int p_cache_index) const;
|
||||
|
||||
virtual void set_descent(int p_cache_index, int p_size, real_t p_descent);
|
||||
virtual real_t get_descent(int p_cache_index, int p_size) const;
|
||||
virtual void set_transform(int p_cache_index, Transform2D p_transform);
|
||||
virtual Transform2D get_transform(int p_cache_index) const;
|
||||
|
||||
virtual void set_underline_position(int p_cache_index, int p_size, real_t p_underline_position);
|
||||
virtual real_t get_underline_position(int p_cache_index, int p_size) const;
|
||||
virtual void set_face_index(int p_cache_index, int64_t p_index);
|
||||
virtual int64_t get_face_index(int p_cache_index) const;
|
||||
|
||||
virtual void set_underline_thickness(int p_cache_index, int p_size, real_t p_underline_thickness);
|
||||
virtual real_t get_underline_thickness(int p_cache_index, int p_size) const;
|
||||
virtual void set_cache_ascent(int p_cache_index, int p_size, real_t p_ascent);
|
||||
virtual real_t get_cache_ascent(int p_cache_index, int p_size) const;
|
||||
|
||||
virtual void set_scale(int p_cache_index, int p_size, real_t p_scale); // Rendering scale for bitmap fonts (e.g. emoji fonts).
|
||||
virtual real_t get_scale(int p_cache_index, int p_size) const;
|
||||
virtual void set_cache_descent(int p_cache_index, int p_size, real_t p_descent);
|
||||
virtual real_t get_cache_descent(int p_cache_index, int p_size) const;
|
||||
|
||||
virtual void set_spacing(int p_cache_index, int p_size, TextServer::SpacingType p_spacing, int p_value);
|
||||
virtual int get_spacing(int p_cache_index, int p_size, TextServer::SpacingType p_spacing) const;
|
||||
virtual void set_cache_underline_position(int p_cache_index, int p_size, real_t p_underline_position);
|
||||
virtual real_t get_cache_underline_position(int p_cache_index, int p_size) const;
|
||||
|
||||
virtual void set_cache_underline_thickness(int p_cache_index, int p_size, real_t p_underline_thickness);
|
||||
virtual real_t get_cache_underline_thickness(int p_cache_index, int p_size) const;
|
||||
|
||||
virtual void set_cache_scale(int p_cache_index, int p_size, real_t p_scale); // Rendering scale for bitmap fonts (e.g. emoji fonts).
|
||||
virtual real_t get_cache_scale(int p_cache_index, int p_size) const;
|
||||
|
||||
virtual int get_texture_count(int p_cache_index, const Vector2i &p_size) const;
|
||||
virtual void clear_textures(int p_cache_index, const Vector2i &p_size);
|
||||
|
|
@ -214,16 +300,12 @@ public:
|
|||
virtual void render_range(int p_cache_index, const Vector2i &p_size, char32_t p_start, char32_t p_end);
|
||||
virtual void render_glyph(int p_cache_index, const Vector2i &p_size, int32_t p_index);
|
||||
|
||||
virtual RID get_cache_rid(int p_cache_index) const;
|
||||
|
||||
// Language/script support override.
|
||||
virtual bool is_language_supported(const String &p_language) const;
|
||||
virtual void set_language_support_override(const String &p_language, bool p_supported);
|
||||
virtual bool get_language_support_override(const String &p_language) const;
|
||||
virtual void remove_language_support_override(const String &p_language);
|
||||
virtual Vector<String> get_language_support_overrides() const;
|
||||
|
||||
virtual bool is_script_supported(const String &p_script) const;
|
||||
virtual void set_script_support_override(const String &p_script, bool p_supported);
|
||||
virtual bool get_script_support_override(const String &p_script) const;
|
||||
virtual void remove_script_support_override(const String &p_script);
|
||||
|
|
@ -233,100 +315,70 @@ public:
|
|||
virtual Dictionary get_opentype_feature_overrides() const;
|
||||
|
||||
// Base font properties.
|
||||
virtual bool has_char(char32_t p_char) const;
|
||||
virtual String get_supported_chars() const;
|
||||
|
||||
virtual int32_t get_glyph_index(int p_size, char32_t p_char, char32_t p_variation_selector = 0x0000) const;
|
||||
|
||||
virtual Dictionary get_supported_feature_list() const;
|
||||
virtual Dictionary get_supported_variation_list() const;
|
||||
|
||||
FontData();
|
||||
~FontData();
|
||||
FontFile();
|
||||
~FontFile();
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
/* FontVariation */
|
||||
/*************************************************************************/
|
||||
|
||||
class TextLine;
|
||||
class TextParagraph;
|
||||
class FontVariation : public Font {
|
||||
GDCLASS(FontVariation, Font);
|
||||
|
||||
class Font : public Resource {
|
||||
GDCLASS(Font, Resource);
|
||||
struct Variation {
|
||||
Dictionary opentype;
|
||||
real_t embolden = 0.f;
|
||||
int face_index = 0;
|
||||
Transform2D transform;
|
||||
};
|
||||
|
||||
// Shaped string cache.
|
||||
mutable LRUCache<uint64_t, Ref<TextLine>> cache;
|
||||
mutable LRUCache<uint64_t, Ref<TextParagraph>> cache_wrap;
|
||||
mutable Ref<Font> theme_font;
|
||||
|
||||
// Font data cache.
|
||||
Vector<Ref<FontData>> data;
|
||||
mutable Vector<RID> rids;
|
||||
Ref<Font> base_font;
|
||||
|
||||
// Font config.
|
||||
Dictionary variation_coordinates;
|
||||
int spacing_bottom = 0;
|
||||
int spacing_top = 0;
|
||||
|
||||
_FORCE_INLINE_ void _data_changed();
|
||||
_FORCE_INLINE_ void _ensure_rid(int p_index) const; // Find or create cache record.
|
||||
Variation variation;
|
||||
Dictionary opentype_features;
|
||||
int extra_spacing[TextServer::SPACING_MAX];
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
virtual void _update_rids() const override;
|
||||
|
||||
virtual void reset_state() override;
|
||||
|
||||
public:
|
||||
static const int DEFAULT_FONT_SIZE = 16;
|
||||
virtual void set_base_font(const Ref<Font> &p_font);
|
||||
virtual Ref<Font> get_base_font() const;
|
||||
virtual Ref<Font> _get_base_font_or_default() const;
|
||||
|
||||
Dictionary get_feature_list() const;
|
||||
virtual void set_variation_opentype(const Dictionary &p_coords);
|
||||
virtual Dictionary get_variation_opentype() const;
|
||||
|
||||
// Font data.
|
||||
virtual void add_data(const Ref<FontData> &p_data);
|
||||
virtual void set_data(int p_idx, const Ref<FontData> &p_data);
|
||||
virtual int get_data_count() const;
|
||||
virtual Ref<FontData> get_data(int p_idx) const;
|
||||
virtual RID get_data_rid(int p_idx) const;
|
||||
virtual void clear_data();
|
||||
virtual void remove_data(int p_idx);
|
||||
virtual void set_variation_embolden(float p_strength);
|
||||
virtual float get_variation_embolden() const;
|
||||
|
||||
// Font configuration.
|
||||
virtual void set_variation_coordinates(const Dictionary &p_variation_coordinates);
|
||||
virtual Dictionary get_variation_coordinates() const;
|
||||
virtual void set_variation_transform(Transform2D p_transform);
|
||||
virtual Transform2D get_variation_transform() const;
|
||||
|
||||
virtual void set_variation_face_index(int p_face_index);
|
||||
virtual int get_variation_face_index() const;
|
||||
|
||||
virtual void set_opentype_features(const Dictionary &p_features);
|
||||
virtual Dictionary get_opentype_features() const override;
|
||||
|
||||
virtual void set_spacing(TextServer::SpacingType p_spacing, int p_value);
|
||||
virtual int get_spacing(TextServer::SpacingType p_spacing) const;
|
||||
virtual int get_spacing(TextServer::SpacingType p_spacing) const override;
|
||||
|
||||
// Font metrics.
|
||||
virtual real_t get_height(int p_size = DEFAULT_FONT_SIZE) const;
|
||||
virtual real_t get_ascent(int p_size = DEFAULT_FONT_SIZE) const;
|
||||
virtual real_t get_descent(int p_size = DEFAULT_FONT_SIZE) const;
|
||||
virtual real_t get_underline_position(int p_size = DEFAULT_FONT_SIZE) const;
|
||||
virtual real_t get_underline_thickness(int p_size = DEFAULT_FONT_SIZE) const;
|
||||
// Output.
|
||||
virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const override;
|
||||
virtual RID _get_rid() const override;
|
||||
|
||||
// Drawing string.
|
||||
virtual Size2 get_string_size(const String &p_text, int p_size = DEFAULT_FONT_SIZE, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
|
||||
virtual Size2 get_multiline_string_size(const String &p_text, float p_width = -1, int p_size = DEFAULT_FONT_SIZE, uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND) const;
|
||||
|
||||
virtual void draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
|
||||
virtual void draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment = HORIZONTAL_ALIGNMENT_LEFT, float p_width = -1, int p_max_lines = -1, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0), uint16_t p_flags = TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND) const;
|
||||
|
||||
// Helper functions.
|
||||
virtual bool has_char(char32_t p_char) const;
|
||||
virtual String get_supported_chars() const;
|
||||
|
||||
// Drawing char.
|
||||
virtual Size2 get_char_size(char32_t p_char, char32_t p_next = 0, int p_size = DEFAULT_FONT_SIZE) const;
|
||||
virtual real_t draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const;
|
||||
|
||||
Array get_rids() const;
|
||||
|
||||
void update_changes();
|
||||
|
||||
Font();
|
||||
~Font();
|
||||
FontVariation();
|
||||
~FontVariation();
|
||||
};
|
||||
|
||||
#endif /* FONT_H */
|
||||
|
|
|
|||
|
|
@ -2376,7 +2376,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
|
|||
TS->shaped_text_set_direction(text_rid, text_direction);
|
||||
|
||||
String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
|
||||
TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, language);
|
||||
TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, font->get_opentype_features(), language);
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
|
||||
Array stt;
|
||||
if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) {
|
||||
|
|
@ -2394,7 +2397,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
|
|||
} else if (dirty_font) {
|
||||
int spans = TS->shaped_get_span_count(text_rid);
|
||||
for (int i = 0; i < spans; i++) {
|
||||
TS->shaped_set_span_update_font(text_rid, i, font->get_rids(), font_size, opentype_features);
|
||||
TS->shaped_set_span_update_font(text_rid, i, font->get_rids(), font_size, font->get_opentype_features());
|
||||
}
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
|
||||
dirty_font = false;
|
||||
|
|
@ -2679,10 +2685,6 @@ void TextMesh::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &TextMesh::set_text_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_text_direction"), &TextMesh::get_text_direction);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &TextMesh::set_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &TextMesh::get_opentype_feature);
|
||||
ClassDB::bind_method(D_METHOD("clear_opentype_features"), &TextMesh::clear_opentype_features);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_language", "language"), &TextMesh::set_language);
|
||||
ClassDB::bind_method(D_METHOD("get_language"), &TextMesh::get_language);
|
||||
|
||||
|
|
@ -2701,11 +2703,9 @@ void TextMesh::_bind_methods() {
|
|||
ADD_GROUP("Text", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_font", "get_font");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,127,1,suffix:px"), "set_font_size", "get_font_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px"), "set_font_size", "get_font_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
|
||||
|
||||
ADD_GROUP("Mesh", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pixel_size", PROPERTY_HINT_RANGE, "0.0001,128,0.0001,suffix:m"), "set_pixel_size", "get_pixel_size");
|
||||
|
|
@ -2713,9 +2713,11 @@ void TextMesh::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_RANGE, "0.0,100.0,0.001,or_greater,suffix:m"), "set_depth", "get_depth");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width", PROPERTY_HINT_NONE, "suffix:m"), "set_width", "get_width");
|
||||
|
||||
ADD_GROUP("Locale", "");
|
||||
ADD_GROUP("BiDi", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left"), "set_text_direction", "get_text_direction");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
|
||||
}
|
||||
|
||||
void TextMesh::_notification(int p_what) {
|
||||
|
|
@ -2732,56 +2734,6 @@ void TextMesh::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
bool TextMesh::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
int value = p_value;
|
||||
if (value == -1) {
|
||||
if (opentype_features.has(tag)) {
|
||||
opentype_features.erase(tag);
|
||||
dirty_font = true;
|
||||
_request_update();
|
||||
}
|
||||
} else {
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
|
||||
opentype_features[tag] = value;
|
||||
dirty_font = true;
|
||||
_request_update();
|
||||
}
|
||||
}
|
||||
notify_property_list_changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TextMesh::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
String str = p_name;
|
||||
if (str.begins_with("opentype_features/")) {
|
||||
String name = str.get_slicec('/', 1);
|
||||
int32_t tag = TS->name_to_tag(name);
|
||||
if (opentype_features.has(tag)) {
|
||||
r_ret = opentype_features[tag];
|
||||
return true;
|
||||
} else {
|
||||
r_ret = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TextMesh::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
|
||||
String name = TS->tag_to_name(*ftr);
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
|
||||
}
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
|
||||
}
|
||||
|
||||
TextMesh::TextMesh() {
|
||||
primitive_type = PRIMITIVE_TRIANGLES;
|
||||
text_rid = TS->create_shaped_text();
|
||||
|
|
@ -2845,7 +2797,7 @@ Ref<Font> TextMesh::get_font() const {
|
|||
}
|
||||
|
||||
Ref<Font> TextMesh::_get_font_or_default() const {
|
||||
if (font_override.is_valid() && font_override->get_data_count() > 0) {
|
||||
if (font_override.is_valid()) {
|
||||
return font_override;
|
||||
}
|
||||
|
||||
|
|
@ -2952,29 +2904,6 @@ TextServer::Direction TextMesh::get_text_direction() const {
|
|||
return text_direction;
|
||||
}
|
||||
|
||||
void TextMesh::clear_opentype_features() {
|
||||
opentype_features.clear();
|
||||
dirty_font = true;
|
||||
_request_update();
|
||||
}
|
||||
|
||||
void TextMesh::set_opentype_feature(const String &p_name, int p_value) {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
|
||||
opentype_features[tag] = p_value;
|
||||
dirty_font = true;
|
||||
_request_update();
|
||||
}
|
||||
}
|
||||
|
||||
int TextMesh::get_opentype_feature(const String &p_name) const {
|
||||
int32_t tag = TS->name_to_tag(p_name);
|
||||
if (!opentype_features.has(tag)) {
|
||||
return -1;
|
||||
}
|
||||
return opentype_features[tag];
|
||||
}
|
||||
|
||||
void TextMesh::set_language(const String &p_language) {
|
||||
if (language != p_language) {
|
||||
language = p_language;
|
||||
|
|
|
|||
|
|
@ -525,7 +525,6 @@ private:
|
|||
|
||||
HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER;
|
||||
bool uppercase = false;
|
||||
Dictionary opentype_features;
|
||||
String language;
|
||||
TextServer::Direction text_direction = TextServer::DIRECTION_AUTO;
|
||||
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
|
||||
|
|
@ -548,10 +547,6 @@ protected:
|
|||
|
||||
virtual void _create_mesh_array(Array &p_arr) const override;
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
public:
|
||||
GDVIRTUAL2RC(Array, _structured_text_parser, Array, String)
|
||||
|
||||
|
|
@ -574,10 +569,6 @@ public:
|
|||
void set_text_direction(TextServer::Direction p_text_direction);
|
||||
TextServer::Direction get_text_direction() const;
|
||||
|
||||
void set_opentype_feature(const String &p_name, int p_value);
|
||||
int get_opentype_feature(const String &p_name) const;
|
||||
void clear_opentype_features();
|
||||
|
||||
void set_language(const String &p_language);
|
||||
String get_language() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ void TextLine::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextLine::set_bidi_override);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language", "meta"), &TextLine::add_string, DEFVAL(Dictionary()), DEFVAL(""), DEFVAL(Variant()));
|
||||
ClassDB::bind_method(D_METHOD("add_string", "text", "font", "font_size", "language", "meta"), &TextLine::add_string, DEFVAL(""), DEFVAL(Variant()));
|
||||
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextLine::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1));
|
||||
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextLine::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER));
|
||||
|
||||
|
|
@ -149,8 +149,6 @@ 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) {
|
||||
|
|
@ -194,11 +192,12 @@ void TextLine::set_bidi_override(const Array &p_override) {
|
|||
dirty = true;
|
||||
}
|
||||
|
||||
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, const Variant &p_meta) {
|
||||
ERR_FAIL_COND_V(p_fonts.is_null(), false);
|
||||
bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language, p_meta);
|
||||
spacing_top = p_fonts->get_spacing(TextServer::SPACING_TOP);
|
||||
spacing_bottom = p_fonts->get_spacing(TextServer::SPACING_BOTTOM);
|
||||
bool TextLine::add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language, const Variant &p_meta) {
|
||||
ERR_FAIL_COND_V(p_font.is_null(), false);
|
||||
bool res = TS->shaped_text_add_string(rid, p_text, p_font->get_rids(), p_font_size, p_font->get_opentype_features(), p_language, p_meta);
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(rid, TextServer::SpacingType(i), p_font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
dirty = true;
|
||||
return res;
|
||||
}
|
||||
|
|
@ -278,20 +277,20 @@ float TextLine::get_width() const {
|
|||
Size2 TextLine::get_size() const {
|
||||
const_cast<TextLine *>(this)->_shape();
|
||||
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);
|
||||
return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y);
|
||||
} else {
|
||||
return Size2(TS->shaped_text_get_size(rid).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(rid).y);
|
||||
return Size2(TS->shaped_text_get_size(rid).x, 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) + spacing_top;
|
||||
return TS->shaped_text_get_ascent(rid);
|
||||
}
|
||||
|
||||
float TextLine::get_line_descent() const {
|
||||
const_cast<TextLine *>(this)->_shape();
|
||||
return TS->shaped_text_get_descent(rid) + spacing_bottom;
|
||||
return TS->shaped_text_get_descent(rid);
|
||||
}
|
||||
|
||||
float TextLine::get_line_width() const {
|
||||
|
|
@ -347,10 +346,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) + spacing_top;
|
||||
ofs.y += TS->shaped_text_get_ascent(rid);
|
||||
clip_l = MAX(0, p_pos.x - ofs.x);
|
||||
} else {
|
||||
ofs.x += TS->shaped_text_get_ascent(rid) + spacing_top;
|
||||
ofs.x += TS->shaped_text_get_ascent(rid);
|
||||
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);
|
||||
|
|
@ -394,10 +393,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) + spacing_top;
|
||||
ofs.y += TS->shaped_text_get_ascent(rid);
|
||||
clip_l = MAX(0, p_pos.x - ofs.x);
|
||||
} else {
|
||||
ofs.x += TS->shaped_text_get_ascent(rid) + spacing_top;
|
||||
ofs.x += TS->shaped_text_get_ascent(rid);
|
||||
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);
|
||||
|
|
@ -409,11 +408,14 @@ int TextLine::hit_test(float p_coords) const {
|
|||
return TS->shaped_text_hit_test_position(rid, p_coords);
|
||||
}
|
||||
|
||||
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) {
|
||||
TextLine::TextLine(const String &p_text, const Ref<Font> &p_font, int p_font_size, 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(TextServer::SPACING_TOP);
|
||||
spacing_bottom = p_fonts->get_spacing(TextServer::SPACING_BOTTOM);
|
||||
TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
|
||||
if (p_font.is_valid()) {
|
||||
TS->shaped_text_add_string(rid, p_text, p_font->get_rids(), p_font_size, p_font->get_opentype_features(), p_language);
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(rid, TextServer::SpacingType(i), p_font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextLine::TextLine() {
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ class TextLine : public RefCounted {
|
|||
|
||||
private:
|
||||
RID rid;
|
||||
int spacing_top = 0;
|
||||
int spacing_bottom = 0;
|
||||
|
||||
bool dirty = true;
|
||||
|
||||
|
|
@ -77,7 +75,7 @@ public:
|
|||
void set_preserve_control(bool p_enabled);
|
||||
bool get_preserve_control() const;
|
||||
|
||||
bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant());
|
||||
bool add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", const Variant &p_meta = Variant());
|
||||
bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1);
|
||||
bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER);
|
||||
|
||||
|
|
@ -111,7 +109,7 @@ public:
|
|||
|
||||
int hit_test(float p_coords) const;
|
||||
|
||||
TextLine(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
|
||||
TextLine(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
|
||||
TextLine();
|
||||
~TextLine();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -60,10 +60,10 @@ void TextParagraph::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextParagraph::set_bidi_override);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_dropcap", "text", "fonts", "size", "dropcap_margins", "opentype_features", "language"), &TextParagraph::set_dropcap, DEFVAL(Rect2()), DEFVAL(Dictionary()), DEFVAL(""));
|
||||
ClassDB::bind_method(D_METHOD("set_dropcap", "text", "font", "font_size", "dropcap_margins", "language"), &TextParagraph::set_dropcap, DEFVAL(Rect2()), DEFVAL(""));
|
||||
ClassDB::bind_method(D_METHOD("clear_dropcap"), &TextParagraph::clear_dropcap);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language", "meta"), &TextParagraph::add_string, DEFVAL(Dictionary()), DEFVAL(""), DEFVAL(Variant()));
|
||||
ClassDB::bind_method(D_METHOD("add_string", "text", "font", "font_size", "language", "meta"), &TextParagraph::add_string, DEFVAL(""), DEFVAL(Variant()));
|
||||
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextParagraph::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1));
|
||||
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextParagraph::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER));
|
||||
|
||||
|
|
@ -113,9 +113,6 @@ void TextParagraph::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_line_underline_position", "line"), &TextParagraph::get_line_underline_position);
|
||||
ClassDB::bind_method(D_METHOD("get_line_underline_thickness", "line"), &TextParagraph::get_line_underline_thickness);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_spacing_top"), &TextParagraph::get_spacing_top);
|
||||
ClassDB::bind_method(D_METHOD("get_spacing_bottom"), &TextParagraph::get_spacing_bottom);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_dropcap_size"), &TextParagraph::get_dropcap_size);
|
||||
ClassDB::bind_method(D_METHOD("get_dropcap_lines"), &TextParagraph::get_dropcap_lines);
|
||||
|
||||
|
|
@ -266,8 +263,6 @@ RID TextParagraph::get_dropcap_rid() const {
|
|||
void TextParagraph::clear() {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
spacing_top = 0;
|
||||
spacing_bottom = 0;
|
||||
for (int i = 0; i < (int)lines_rid.size(); i++) {
|
||||
TS->free_rid(lines_rid[i]);
|
||||
}
|
||||
|
|
@ -347,44 +342,37 @@ TextServer::Orientation TextParagraph::get_orientation() const {
|
|||
return TS->shaped_text_get_orientation(rid);
|
||||
}
|
||||
|
||||
bool TextParagraph::set_dropcap(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Rect2 &p_dropcap_margins, const Dictionary &p_opentype_features, const String &p_language) {
|
||||
bool TextParagraph::set_dropcap(const String &p_text, const Ref<Font> &p_font, int p_font_size, const Rect2 &p_dropcap_margins, const String &p_language) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
ERR_FAIL_COND_V(p_fonts.is_null(), false);
|
||||
ERR_FAIL_COND_V(p_font.is_null(), false);
|
||||
TS->shaped_text_clear(dropcap_rid);
|
||||
dropcap_margins = p_dropcap_margins;
|
||||
bool res = TS->shaped_text_add_string(dropcap_rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
|
||||
bool res = TS->shaped_text_add_string(dropcap_rid, p_text, p_font->get_rids(), p_font_size, p_font->get_opentype_features(), p_language);
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(dropcap_rid, TextServer::SpacingType(i), p_font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
lines_dirty = true;
|
||||
return res;
|
||||
}
|
||||
|
||||
void TextParagraph::clear_dropcap() {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
dropcap_margins = Rect2();
|
||||
TS->shaped_text_clear(dropcap_rid);
|
||||
lines_dirty = true;
|
||||
}
|
||||
|
||||
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, const Variant &p_meta) {
|
||||
bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language, const Variant &p_meta) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
ERR_FAIL_COND_V(p_fonts.is_null(), false);
|
||||
bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language, p_meta);
|
||||
spacing_top = p_fonts->get_spacing(TextServer::SPACING_TOP);
|
||||
spacing_bottom = p_fonts->get_spacing(TextServer::SPACING_BOTTOM);
|
||||
ERR_FAIL_COND_V(p_font.is_null(), false);
|
||||
bool res = TS->shaped_text_add_string(rid, p_text, p_font->get_rids(), p_font_size, p_font->get_opentype_features(), p_language, p_meta);
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(rid, TextServer::SpacingType(i), p_font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
lines_dirty = true;
|
||||
return res;
|
||||
}
|
||||
|
||||
int TextParagraph::get_spacing_top() const {
|
||||
return spacing_top;
|
||||
}
|
||||
|
||||
int TextParagraph::get_spacing_bottom() const {
|
||||
return spacing_bottom;
|
||||
}
|
||||
|
||||
void TextParagraph::set_bidi_override(const Array &p_override) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
|
@ -476,9 +464,9 @@ Size2 TextParagraph::get_non_wrapped_size() const {
|
|||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
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);
|
||||
return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y);
|
||||
} else {
|
||||
return Size2(TS->shaped_text_get_size(rid).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(rid).y);
|
||||
return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -492,9 +480,9 @@ Size2 TextParagraph::get_size() const {
|
|||
Size2 lsize = TS->shaped_text_get_size(lines_rid[i]);
|
||||
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
size.x = MAX(size.x, lsize.x);
|
||||
size.y += lsize.y + spacing_top + spacing_bottom;
|
||||
size.y += lsize.y;
|
||||
} else {
|
||||
size.x += lsize.x + spacing_top + spacing_bottom;
|
||||
size.x += lsize.x;
|
||||
size.y = MAX(size.y, lsize.y);
|
||||
}
|
||||
}
|
||||
|
|
@ -538,9 +526,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_rid[i]);
|
||||
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
xrect.position.y += lsize.y + spacing_top + spacing_bottom;
|
||||
xrect.position.y += lsize.y;
|
||||
} else {
|
||||
xrect.position.x += lsize.x + spacing_top + spacing_bottom;
|
||||
xrect.position.x += lsize.x;
|
||||
}
|
||||
}
|
||||
return xrect;
|
||||
|
|
@ -552,9 +540,9 @@ Size2 TextParagraph::get_line_size(int p_line) const {
|
|||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), Size2());
|
||||
if (TS->shaped_text_get_orientation(lines_rid[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
return Size2(TS->shaped_text_get_size(lines_rid[p_line]).x, TS->shaped_text_get_size(lines_rid[p_line]).y + spacing_top + spacing_bottom);
|
||||
return Size2(TS->shaped_text_get_size(lines_rid[p_line]).x, TS->shaped_text_get_size(lines_rid[p_line]).y);
|
||||
} else {
|
||||
return Size2(TS->shaped_text_get_size(lines_rid[p_line]).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(lines_rid[p_line]).y);
|
||||
return Size2(TS->shaped_text_get_size(lines_rid[p_line]).x, TS->shaped_text_get_size(lines_rid[p_line]).y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -571,7 +559,7 @@ float TextParagraph::get_line_ascent(int p_line) const {
|
|||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), 0.f);
|
||||
return TS->shaped_text_get_ascent(lines_rid[p_line]) + spacing_top;
|
||||
return TS->shaped_text_get_ascent(lines_rid[p_line]);
|
||||
}
|
||||
|
||||
float TextParagraph::get_line_descent(int p_line) const {
|
||||
|
|
@ -579,7 +567,7 @@ float TextParagraph::get_line_descent(int p_line) const {
|
|||
|
||||
const_cast<TextParagraph *>(this)->_shape_lines();
|
||||
ERR_FAIL_COND_V(p_line < 0 || p_line >= (int)lines_rid.size(), 0.f);
|
||||
return TS->shaped_text_get_descent(lines_rid[p_line]) + spacing_bottom;
|
||||
return TS->shaped_text_get_descent(lines_rid[p_line]);
|
||||
}
|
||||
|
||||
float TextParagraph::get_line_width(int p_line) const {
|
||||
|
|
@ -647,7 +635,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
|
|||
float l_width = width;
|
||||
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.x = p_pos.x;
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[i]);
|
||||
if (i <= dropcap_lines) {
|
||||
if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
|
||||
ofs.x -= h_offset;
|
||||
|
|
@ -656,7 +644,7 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
|
|||
}
|
||||
} else {
|
||||
ofs.y = p_pos.y;
|
||||
ofs.x += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
|
||||
ofs.x += TS->shaped_text_get_ascent(lines_rid[i]);
|
||||
if (i <= dropcap_lines) {
|
||||
if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
|
||||
ofs.x -= h_offset;
|
||||
|
|
@ -711,10 +699,10 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
|
|||
TS->shaped_text_draw(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_color);
|
||||
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.x = p_pos.x;
|
||||
ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + spacing_bottom;
|
||||
ofs.y += TS->shaped_text_get_descent(lines_rid[i]);
|
||||
} else {
|
||||
ofs.y = p_pos.y;
|
||||
ofs.x += TS->shaped_text_get_descent(lines_rid[i]) + spacing_bottom;
|
||||
ofs.x += TS->shaped_text_get_descent(lines_rid[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -749,7 +737,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
|
|||
float l_width = width;
|
||||
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.x = p_pos.x;
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[i]);
|
||||
if (i <= dropcap_lines) {
|
||||
if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
|
||||
ofs.x -= h_offset;
|
||||
|
|
@ -758,7 +746,7 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
|
|||
}
|
||||
} else {
|
||||
ofs.y = p_pos.y;
|
||||
ofs.x += TS->shaped_text_get_ascent(lines_rid[i]) + spacing_top;
|
||||
ofs.x += TS->shaped_text_get_ascent(lines_rid[i]);
|
||||
if (i <= dropcap_lines) {
|
||||
if (TS->shaped_text_get_inferred_direction(dropcap_rid) == TextServer::DIRECTION_LTR) {
|
||||
ofs.x -= h_offset;
|
||||
|
|
@ -813,10 +801,10 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli
|
|||
TS->shaped_text_draw_outline(lines_rid[i], p_canvas, ofs, clip_l, clip_l + l_width, p_outline_size, p_color);
|
||||
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.x = p_pos.x;
|
||||
ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + spacing_bottom;
|
||||
ofs.y += TS->shaped_text_get_descent(lines_rid[i]);
|
||||
} else {
|
||||
ofs.y = p_pos.y;
|
||||
ofs.x += TS->shaped_text_get_descent(lines_rid[i]) + spacing_bottom;
|
||||
ofs.x += TS->shaped_text_get_descent(lines_rid[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -840,12 +828,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_rid[i]).y)) {
|
||||
return TS->shaped_text_hit_test_position(lines_rid[i], p_coords.x);
|
||||
}
|
||||
ofs.y += TS->shaped_text_get_size(lines_rid[i]).y + spacing_bottom + spacing_top;
|
||||
ofs.y += TS->shaped_text_get_size(lines_rid[i]).y;
|
||||
} else {
|
||||
if ((p_coords.x >= ofs.x) && (p_coords.x <= ofs.x + TS->shaped_text_get_size(lines_rid[i]).x)) {
|
||||
return TS->shaped_text_hit_test_position(lines_rid[i], p_coords.y);
|
||||
}
|
||||
ofs.y += TS->shaped_text_get_size(lines_rid[i]).x + spacing_bottom + spacing_top;
|
||||
ofs.y += TS->shaped_text_get_size(lines_rid[i]).x;
|
||||
}
|
||||
}
|
||||
return TS->shaped_text_get_range(rid).y;
|
||||
|
|
@ -908,9 +896,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_rid[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[p_line]) + spacing_top;
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[p_line]);
|
||||
} else {
|
||||
ofs.x += TS->shaped_text_get_ascent(lines_rid[p_line]) + spacing_top;
|
||||
ofs.x += TS->shaped_text_get_ascent(lines_rid[p_line]);
|
||||
}
|
||||
return TS->shaped_text_draw(lines_rid[p_line], p_canvas, ofs, -1, -1, p_color);
|
||||
}
|
||||
|
|
@ -923,18 +911,21 @@ 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_rid[p_line]) == TextServer::ORIENTATION_HORIZONTAL) {
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[p_line]) + spacing_top;
|
||||
ofs.y += TS->shaped_text_get_ascent(lines_rid[p_line]);
|
||||
} else {
|
||||
ofs.x += TS->shaped_text_get_ascent(lines_rid[p_line]) + spacing_top;
|
||||
ofs.x += TS->shaped_text_get_ascent(lines_rid[p_line]);
|
||||
}
|
||||
return TS->shaped_text_draw_outline(lines_rid[p_line], p_canvas, ofs, -1, -1, p_outline_size, p_color);
|
||||
}
|
||||
|
||||
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) {
|
||||
TextParagraph::TextParagraph(const String &p_text, const Ref<Font> &p_font, int p_font_size, 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(TextServer::SPACING_TOP);
|
||||
spacing_bottom = p_fonts->get_spacing(TextServer::SPACING_BOTTOM);
|
||||
if (p_font.is_valid()) {
|
||||
TS->shaped_text_add_string(rid, p_text, p_font->get_rids(), p_font_size, p_font->get_opentype_features(), p_language);
|
||||
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
||||
TS->shaped_text_set_spacing(rid, TextServer::SpacingType(i), p_font->get_spacing(TextServer::SpacingType(i)));
|
||||
}
|
||||
}
|
||||
width = p_width;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,6 @@ private:
|
|||
|
||||
RID rid;
|
||||
LocalVector<RID> lines_rid;
|
||||
int spacing_top = 0;
|
||||
int spacing_bottom = 0;
|
||||
|
||||
bool lines_dirty = true;
|
||||
|
||||
|
|
@ -92,10 +90,10 @@ public:
|
|||
void set_custom_punctuation(const String &p_punct);
|
||||
String get_custom_punctuation() const;
|
||||
|
||||
bool set_dropcap(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "");
|
||||
bool set_dropcap(const String &p_text, const Ref<Font> &p_font, int p_font_size, const Rect2 &p_dropcap_margins = Rect2(), const String &p_language = "");
|
||||
void clear_dropcap();
|
||||
|
||||
bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant());
|
||||
bool add_string(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", const Variant &p_meta = Variant());
|
||||
bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1);
|
||||
bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER);
|
||||
|
||||
|
|
@ -151,7 +149,7 @@ public:
|
|||
|
||||
Mutex &get_mutex() const { return _thread_safe_; };
|
||||
|
||||
TextParagraph(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", float p_width = -1.f, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
|
||||
TextParagraph(const String &p_text, const Ref<Font> &p_font, int p_font_size, const String &p_language = "", float p_width = -1.f, TextServer::Direction p_direction = TextServer::DIRECTION_AUTO, TextServer::Orientation p_orientation = TextServer::ORIENTATION_HORIZONTAL);
|
||||
TextParagraph();
|
||||
~TextParagraph();
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue