mirror of
https://github.com/Redot-Engine/redot-engine.git
synced 2025-12-06 07:17:42 -05:00
Implement BiDi override mode for GDScript source.
This commit is contained in:
@@ -483,6 +483,7 @@ void TextServer::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(DIRECTION_AUTO);
|
||||
BIND_ENUM_CONSTANT(DIRECTION_LTR);
|
||||
BIND_ENUM_CONSTANT(DIRECTION_RTL);
|
||||
BIND_ENUM_CONSTANT(DIRECTION_INHERITED);
|
||||
|
||||
/* Orientation */
|
||||
BIND_ENUM_CONSTANT(ORIENTATION_HORIZONTAL);
|
||||
@@ -599,7 +600,7 @@ void TextServer::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(STRUCTURED_TEXT_FILE);
|
||||
BIND_ENUM_CONSTANT(STRUCTURED_TEXT_EMAIL);
|
||||
BIND_ENUM_CONSTANT(STRUCTURED_TEXT_LIST);
|
||||
BIND_ENUM_CONSTANT(STRUCTURED_TEXT_NONE);
|
||||
BIND_ENUM_CONSTANT(STRUCTURED_TEXT_GDSCRIPT);
|
||||
BIND_ENUM_CONSTANT(STRUCTURED_TEXT_CUSTOM);
|
||||
}
|
||||
|
||||
@@ -1692,22 +1693,22 @@ String TextServer::strip_diacritics(const String &p_string) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
TypedArray<Vector2i> TextServer::parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const {
|
||||
TypedArray<Vector2i> ret;
|
||||
TypedArray<Vector3i> TextServer::parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const {
|
||||
TypedArray<Vector3i> ret;
|
||||
switch (p_parser_type) {
|
||||
case STRUCTURED_TEXT_URI: {
|
||||
int prev = 0;
|
||||
for (int i = 0; i < p_text.length(); i++) {
|
||||
if ((p_text[i] == '\\') || (p_text[i] == '/') || (p_text[i] == '.') || (p_text[i] == ':') || (p_text[i] == '&') || (p_text[i] == '=') || (p_text[i] == '@') || (p_text[i] == '?') || (p_text[i] == '#')) {
|
||||
if (prev != i) {
|
||||
ret.push_back(Vector2i(prev, i));
|
||||
ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
ret.push_back(Vector2i(i, i + 1));
|
||||
ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
||||
prev = i + 1;
|
||||
}
|
||||
}
|
||||
if (prev != p_text.length()) {
|
||||
ret.push_back(Vector2i(prev, p_text.length()));
|
||||
ret.push_back(Vector3i(prev, p_text.length(), TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
} break;
|
||||
case STRUCTURED_TEXT_FILE: {
|
||||
@@ -1715,14 +1716,14 @@ TypedArray<Vector2i> TextServer::parse_structured_text(StructuredTextParser p_pa
|
||||
for (int i = 0; i < p_text.length(); i++) {
|
||||
if ((p_text[i] == '\\') || (p_text[i] == '/') || (p_text[i] == ':')) {
|
||||
if (prev != i) {
|
||||
ret.push_back(Vector2i(prev, i));
|
||||
ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
ret.push_back(Vector2i(i, i + 1));
|
||||
ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
||||
prev = i + 1;
|
||||
}
|
||||
}
|
||||
if (prev != p_text.length()) {
|
||||
ret.push_back(Vector2i(prev, p_text.length()));
|
||||
ret.push_back(Vector3i(prev, p_text.length(), TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
} break;
|
||||
case STRUCTURED_TEXT_EMAIL: {
|
||||
@@ -1731,19 +1732,19 @@ TypedArray<Vector2i> TextServer::parse_structured_text(StructuredTextParser p_pa
|
||||
for (int i = 0; i < p_text.length(); i++) {
|
||||
if ((p_text[i] == '@') && local) { // Add full "local" as single context.
|
||||
local = false;
|
||||
ret.push_back(Vector2i(prev, i));
|
||||
ret.push_back(Vector2i(i, i + 1));
|
||||
ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
||||
ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
||||
prev = i + 1;
|
||||
} else if (!local && (p_text[i] == '.')) { // Add each dot separated "domain" part as context.
|
||||
if (prev != i) {
|
||||
ret.push_back(Vector2i(prev, i));
|
||||
ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
ret.push_back(Vector2i(i, i + 1));
|
||||
ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
||||
prev = i + 1;
|
||||
}
|
||||
}
|
||||
if (prev != p_text.length()) {
|
||||
ret.push_back(Vector2i(prev, p_text.length()));
|
||||
ret.push_back(Vector3i(prev, p_text.length(), TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
} break;
|
||||
case STRUCTURED_TEXT_LIST: {
|
||||
@@ -1752,18 +1753,97 @@ TypedArray<Vector2i> TextServer::parse_structured_text(StructuredTextParser p_pa
|
||||
int prev = 0;
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
if (prev != i) {
|
||||
ret.push_back(Vector2i(prev, prev + tags[i].length()));
|
||||
ret.push_back(Vector3i(prev, prev + tags[i].length(), TextServer::DIRECTION_INHERITED));
|
||||
}
|
||||
ret.push_back(Vector2i(prev + tags[i].length(), prev + tags[i].length() + 1));
|
||||
ret.push_back(Vector3i(prev + tags[i].length(), prev + tags[i].length() + 1, TextServer::DIRECTION_INHERITED));
|
||||
prev = prev + tags[i].length() + 1;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case STRUCTURED_TEXT_GDSCRIPT: {
|
||||
bool in_string_literal = false;
|
||||
bool in_string_literal_single = false;
|
||||
bool in_id = false;
|
||||
|
||||
int prev = 0;
|
||||
for (int i = 0; i < p_text.length(); i++) {
|
||||
char32_t c = p_text[i];
|
||||
if (in_string_literal) {
|
||||
if (c == '\\') {
|
||||
i++;
|
||||
continue; // Skip escaped chars.
|
||||
} else if (c == '\"') {
|
||||
// String literal end, push string and ".
|
||||
if (prev != i) {
|
||||
ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
prev = i + 1;
|
||||
ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
||||
in_string_literal = false;
|
||||
}
|
||||
} else if (in_string_literal_single) {
|
||||
if (c == '\\') {
|
||||
i++;
|
||||
continue; // Skip escaped chars.
|
||||
} else if (c == '\'') {
|
||||
// String literal end, push string and '.
|
||||
if (prev != i) {
|
||||
ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
prev = i + 1;
|
||||
ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
||||
in_string_literal_single = false;
|
||||
}
|
||||
} else if (in_id) {
|
||||
if (!is_unicode_identifier_continue(c)) {
|
||||
// End of id, push id.
|
||||
if (prev != i) {
|
||||
ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
prev = i;
|
||||
in_id = false;
|
||||
}
|
||||
} else if (is_unicode_identifier_start(c)) {
|
||||
// Start of new id, push prev element.
|
||||
if (prev != i) {
|
||||
ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
prev = i;
|
||||
in_id = true;
|
||||
} else if (c == '\"') {
|
||||
// String literal start, push prev element and ".
|
||||
if (prev != i) {
|
||||
ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
prev = i + 1;
|
||||
ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
||||
in_string_literal = true;
|
||||
} else if (c == '\'') {
|
||||
// String literal start, push prev element and '.
|
||||
if (prev != i) {
|
||||
ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
prev = i + 1;
|
||||
ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
||||
in_string_literal_single = true;
|
||||
} else if (c == '#') {
|
||||
// Start of comment, push prev element and #, skip the rest of the text.
|
||||
if (prev != i) {
|
||||
ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
prev = i + 1;
|
||||
ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (prev < p_text.length()) {
|
||||
ret.push_back(Vector3i(prev, p_text.length(), TextServer::DIRECTION_AUTO));
|
||||
}
|
||||
} break;
|
||||
case STRUCTURED_TEXT_CUSTOM:
|
||||
case STRUCTURED_TEXT_NONE:
|
||||
case STRUCTURED_TEXT_DEFAULT:
|
||||
default: {
|
||||
ret.push_back(Vector2i(0, p_text.length()));
|
||||
ret.push_back(Vector3i(0, p_text.length(), TextServer::DIRECTION_INHERITED));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user