summaryrefslogtreecommitdiffstats
path: root/servers/text_server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/text_server.cpp')
-rw-r--r--servers/text_server.cpp105
1 files changed, 98 insertions, 7 deletions
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index b67a698615..562f2df411 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -29,6 +29,8 @@
/**************************************************************************/
#include "servers/text_server.h"
+#include "text_server.compat.inc"
+
#include "core/variant/typed_array.h"
#include "servers/rendering_server.h"
@@ -234,6 +236,9 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_set_antialiasing", "font_rid", "antialiasing"), &TextServer::font_set_antialiasing);
ClassDB::bind_method(D_METHOD("font_get_antialiasing", "font_rid"), &TextServer::font_get_antialiasing);
+ ClassDB::bind_method(D_METHOD("font_set_disable_embedded_bitmaps", "font_rid", "disable_embedded_bitmaps"), &TextServer::font_set_disable_embedded_bitmaps);
+ ClassDB::bind_method(D_METHOD("font_get_disable_embedded_bitmaps", "font_rid"), &TextServer::font_get_disable_embedded_bitmaps);
+
ClassDB::bind_method(D_METHOD("font_set_generate_mipmaps", "font_rid", "generate_mipmaps"), &TextServer::font_set_generate_mipmaps);
ClassDB::bind_method(D_METHOD("font_get_generate_mipmaps", "font_rid"), &TextServer::font_get_generate_mipmaps);
@@ -432,7 +437,7 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_get_range", "shaped"), &TextServer::shaped_text_get_range);
ClassDB::bind_method(D_METHOD("shaped_text_get_line_breaks_adv", "shaped", "width", "start", "once", "break_flags"), &TextServer::shaped_text_get_line_breaks_adv, DEFVAL(0), DEFVAL(true), DEFVAL(BREAK_MANDATORY | BREAK_WORD_BOUND));
ClassDB::bind_method(D_METHOD("shaped_text_get_line_breaks", "shaped", "width", "start", "break_flags"), &TextServer::shaped_text_get_line_breaks, DEFVAL(0), DEFVAL(BREAK_MANDATORY | BREAK_WORD_BOUND));
- ClassDB::bind_method(D_METHOD("shaped_text_get_word_breaks", "shaped", "grapheme_flags"), &TextServer::shaped_text_get_word_breaks, DEFVAL(GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION));
+ ClassDB::bind_method(D_METHOD("shaped_text_get_word_breaks", "shaped", "grapheme_flags", "skip_grapheme_flags"), &TextServer::shaped_text_get_word_breaks, DEFVAL(GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION), DEFVAL(GRAPHEME_IS_VIRTUAL));
ClassDB::bind_method(D_METHOD("shaped_text_get_trim_pos", "shaped"), &TextServer::shaped_text_get_trim_pos);
ClassDB::bind_method(D_METHOD("shaped_text_get_ellipsis_pos", "shaped"), &TextServer::shaped_text_get_ellipsis_pos);
@@ -443,6 +448,8 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_get_objects", "shaped"), &TextServer::shaped_text_get_objects);
ClassDB::bind_method(D_METHOD("shaped_text_get_object_rect", "shaped", "key"), &TextServer::shaped_text_get_object_rect);
+ ClassDB::bind_method(D_METHOD("shaped_text_get_object_range", "shaped", "key"), &TextServer::shaped_text_get_object_range);
+ ClassDB::bind_method(D_METHOD("shaped_text_get_object_glyph", "shaped", "key"), &TextServer::shaped_text_get_object_glyph);
ClassDB::bind_method(D_METHOD("shaped_text_get_size", "shaped"), &TextServer::shaped_text_get_size);
ClassDB::bind_method(D_METHOD("shaped_text_get_ascent", "shaped"), &TextServer::shaped_text_get_ascent);
@@ -486,6 +493,7 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("string_to_upper", "string", "language"), &TextServer::string_to_upper, DEFVAL(""));
ClassDB::bind_method(D_METHOD("string_to_lower", "string", "language"), &TextServer::string_to_lower, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("string_to_title", "string", "language"), &TextServer::string_to_title, DEFVAL(""));
ClassDB::bind_method(D_METHOD("parse_structured_text", "parser_type", "args", "text"), &TextServer::parse_structured_text);
@@ -535,6 +543,7 @@ void TextServer::_bind_methods() {
BIND_BITFIELD_FLAG(BREAK_GRAPHEME_BOUND);
BIND_BITFIELD_FLAG(BREAK_ADAPTIVE);
BIND_BITFIELD_FLAG(BREAK_TRIM_EDGE_SPACES);
+ BIND_BITFIELD_FLAG(BREAK_TRIM_INDENT);
/* VisibleCharactersBehavior */
BIND_ENUM_CONSTANT(VC_CHARS_BEFORE_SHAPING);
@@ -636,6 +645,48 @@ void TextServer::_bind_methods() {
BIND_ENUM_CONSTANT(FIXED_SIZE_SCALE_ENABLED);
}
+_FORCE_INLINE_ int32_t ot_tag_from_string(const char *p_str, int p_len) {
+ char tag[4];
+ uint32_t i;
+
+ if (!p_str || !p_len || !*p_str) {
+ return OT_TAG(0, 0, 0, 0);
+ }
+
+ if (p_len < 0 || p_len > 4) {
+ p_len = 4;
+ }
+ for (i = 0; i < (uint32_t)p_len && p_str[i]; i++) {
+ tag[i] = p_str[i];
+ }
+
+ for (; i < 4; i++) {
+ tag[i] = ' ';
+ }
+
+ return OT_TAG(tag[0], tag[1], tag[2], tag[3]);
+}
+
+int64_t TextServer::name_to_tag(const String &p_name) const {
+ // No readable name, use tag string.
+ return ot_tag_from_string(p_name.replace("custom_", "").ascii().get_data(), -1);
+}
+
+_FORCE_INLINE_ void ot_tag_to_string(int32_t p_tag, char *p_buf) {
+ p_buf[0] = (char)(uint8_t)(p_tag >> 24);
+ p_buf[1] = (char)(uint8_t)(p_tag >> 16);
+ p_buf[2] = (char)(uint8_t)(p_tag >> 8);
+ p_buf[3] = (char)(uint8_t)(p_tag >> 0);
+}
+
+String TextServer::tag_to_name(int64_t p_tag) const {
+ // No readable name, use tag string.
+ char name[5];
+ memset(name, 0, 5);
+ ot_tag_to_string(p_tag, name);
+ return String("custom_") + String(name);
+}
+
Vector2 TextServer::get_hex_code_box_size(int64_t p_size, int64_t p_index) const {
int w = ((p_index <= 0xFF) ? 1 : ((p_index <= 0xFFFF) ? 2 : 3));
int sp = MAX(0, w - 1);
@@ -750,13 +801,28 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped
int l_size = shaped_text_get_glyph_count(p_shaped);
const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped);
+ double indent = 0.0;
+ if (p_break_flags.has_flag(BREAK_TRIM_INDENT)) {
+ for (int i = 0; i < l_size; i++) {
+ if ((l_gl[i].flags & GRAPHEME_IS_TAB) == GRAPHEME_IS_TAB || (l_gl[i].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE) {
+ indent += l_gl[i].advance * l_gl[i].repeat;
+ } else {
+ break;
+ }
+ }
+ }
+
for (int i = 0; i < l_size; i++) {
+ double l_width = p_width[chunk];
+ if (l_width > indent) {
+ l_width -= indent;
+ }
if (l_gl[i].start < p_start) {
prev_safe_break = i + 1;
continue;
}
if (l_gl[i].count > 0) {
- if ((p_width[chunk] > 0) && (width + l_gl[i].advance > p_width[chunk]) && (last_safe_break >= 0)) {
+ if ((l_width > 0) && (width + l_gl[i].advance > l_width) && (last_safe_break >= 0)) {
if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) {
int start_pos = prev_safe_break;
int end_pos = last_safe_break;
@@ -891,13 +957,25 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
int l_size = shaped_text_get_glyph_count(p_shaped);
const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped);
+ double indent = 0.0;
+ if (p_break_flags.has_flag(BREAK_TRIM_INDENT)) {
+ for (int i = 0; i < l_size; i++) {
+ if ((l_gl[i].flags & GRAPHEME_IS_TAB) == GRAPHEME_IS_TAB || (l_gl[i].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE) {
+ indent += l_gl[i].advance * l_gl[i].repeat;
+ } else {
+ break;
+ }
+ }
+ }
+
+ double l_width = p_width;
for (int i = 0; i < l_size; i++) {
if (l_gl[i].start < p_start) {
prev_safe_break = i + 1;
continue;
}
if (l_gl[i].count > 0) {
- if ((p_width > 0) && (width + l_gl[i].advance * l_gl[i].repeat > p_width) && (last_safe_break >= 0)) {
+ if ((l_width > 0) && (width + l_gl[i].advance * l_gl[i].repeat > l_width) && (last_safe_break >= 0)) {
if (p_break_flags.has_flag(BREAK_TRIM_EDGE_SPACES)) {
int start_pos = prev_safe_break;
int end_pos = last_safe_break;
@@ -910,6 +988,9 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
if (last_end <= l_gl[start_pos].start) {
lines.push_back(l_gl[start_pos].start);
lines.push_back(l_gl[end_pos].end);
+ if (p_width > indent) {
+ l_width = p_width - indent;
+ }
last_end = l_gl[end_pos].end;
}
trim_next = true;
@@ -917,6 +998,9 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
if (last_end <= line_start) {
lines.push_back(line_start);
lines.push_back(l_gl[last_safe_break].end);
+ if (p_width > indent) {
+ l_width = p_width - indent;
+ }
last_end = l_gl[last_safe_break].end;
}
}
@@ -943,12 +1027,18 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
if (last_end <= l_gl[start_pos].start) {
lines.push_back(l_gl[start_pos].start);
lines.push_back(l_gl[end_pos].end);
+ if (p_width > indent) {
+ l_width = p_width - indent;
+ }
last_end = l_gl[end_pos].end;
}
} else {
if (last_end <= line_start) {
lines.push_back(line_start);
lines.push_back(l_gl[i].end);
+ if (p_width > indent) {
+ l_width = p_width - indent;
+ }
last_end = l_gl[i].end;
}
}
@@ -1006,7 +1096,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
return lines;
}
-PackedInt32Array TextServer::shaped_text_get_word_breaks(const RID &p_shaped, BitField<TextServer::GraphemeFlag> p_grapheme_flags) const {
+PackedInt32Array TextServer::shaped_text_get_word_breaks(const RID &p_shaped, BitField<TextServer::GraphemeFlag> p_grapheme_flags, BitField<TextServer::GraphemeFlag> p_skip_grapheme_flags) const {
PackedInt32Array words;
const_cast<TextServer *>(this)->shaped_text_update_justification_ops(p_shaped);
@@ -1019,10 +1109,11 @@ PackedInt32Array TextServer::shaped_text_get_word_breaks(const RID &p_shaped, Bi
for (int i = 0; i < l_size; i++) {
if (l_gl[i].count > 0) {
- if ((l_gl[i].flags & p_grapheme_flags) != 0) {
- if (word_start != l_gl[i].start) {
+ if ((l_gl[i].flags & p_grapheme_flags) != 0 && (l_gl[i].flags & p_skip_grapheme_flags) == 0) {
+ int next = (i == 0) ? l_gl[i].start : l_gl[i - 1].end;
+ if (word_start < next) {
words.push_back(word_start);
- words.push_back(l_gl[i].start);
+ words.push_back(next);
}
word_start = l_gl[i].end;
}