diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-19 19:33:18 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-19 19:33:18 +0100 |
commit | 65883cc73b0bedb14760e97f59a2c58b83b2470c (patch) | |
tree | 2656e3735f4a1f33ddb8b8b6a18528946b5a5a55 /modules | |
parent | ab5c75b9ad9134cfca3952203042a9b5d87851b2 (diff) | |
parent | 5361ec9f43e454d0869c3ce0984fda34a95472a1 (diff) |
Merge pull request #71598 from bruvzg/gdscript_bidi_override
Implement BiDi override mode for GDScript source.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 44 | ||||
-rw-r--r-- | modules/text_server_adv/text_server_adv.h | 2 | ||||
-rw-r--r-- | modules/text_server_fb/text_server_fb.cpp | 2 |
3 files changed, 39 insertions, 9 deletions
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 8e9ff61ad0..79ca4a7024 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -3654,6 +3654,7 @@ void TextServerAdvanced::full_copy(ShapedTextDataAdvanced *p_shaped) { RID TextServerAdvanced::_create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) { _THREAD_SAFE_METHOD_ + ERR_FAIL_COND_V_MSG(p_direction == DIRECTION_INHERITED, RID(), "Invalid text direction."); ShapedTextDataAdvanced *sd = memnew(ShapedTextDataAdvanced); sd->hb_buffer = hb_buffer_create(); @@ -3679,6 +3680,7 @@ void TextServerAdvanced::_shaped_text_clear(const RID &p_shaped) { void TextServerAdvanced::_shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) { ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped); + ERR_FAIL_COND_MSG(p_direction == DIRECTION_INHERITED, "Invalid text direction."); ERR_FAIL_COND(!sd); MutexLock lock(sd->mutex); @@ -3738,8 +3740,12 @@ void TextServerAdvanced::_shaped_text_set_bidi_override(const RID &p_shaped, con } sd->bidi_override.clear(); for (int i = 0; i < p_override.size(); i++) { - if (p_override[i].get_type() == Variant::VECTOR2I) { - sd->bidi_override.push_back(p_override[i]); + if (p_override[i].get_type() == Variant::VECTOR3I) { + const Vector3i &r = p_override[i]; + sd->bidi_override.push_back(r); + } else if (p_override[i].get_type() == Variant::VECTOR2I) { + const Vector2i &r = p_override[i]; + sd->bidi_override.push_back(Vector3i(r.x, r.y, DIRECTION_INHERITED)); } } invalidate(sd, false); @@ -5544,8 +5550,31 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) { sd->script_iter = memnew(ScriptIterator(sd->text, 0, sd->text.length())); } + int base_para_direction = UBIDI_DEFAULT_LTR; + switch (sd->direction) { + case DIRECTION_LTR: { + sd->para_direction = DIRECTION_LTR; + base_para_direction = UBIDI_LTR; + } break; + case DIRECTION_RTL: { + sd->para_direction = DIRECTION_RTL; + base_para_direction = UBIDI_RTL; + } break; + case DIRECTION_INHERITED: + case DIRECTION_AUTO: { + UBiDiDirection direction = ubidi_getBaseDirection(data, sd->utf16.length()); + if (direction != UBIDI_NEUTRAL) { + sd->para_direction = (direction == UBIDI_RTL) ? DIRECTION_RTL : DIRECTION_LTR; + base_para_direction = direction; + } else { + sd->para_direction = DIRECTION_LTR; + base_para_direction = UBIDI_DEFAULT_LTR; + } + } break; + } + if (sd->bidi_override.is_empty()) { - sd->bidi_override.push_back(Vector2i(sd->start, sd->end)); + sd->bidi_override.push_back(Vector3i(sd->start, sd->end, DIRECTION_INHERITED)); } for (int ov = 0; ov < sd->bidi_override.size(); ov++) { @@ -5561,23 +5590,22 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) { UBiDi *bidi_iter = ubidi_openSized(end, 0, &err); ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); - switch (sd->direction) { + switch (static_cast<TextServer::Direction>(sd->bidi_override[ov].z)) { case DIRECTION_LTR: { ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_LTR, nullptr, &err); - sd->para_direction = DIRECTION_LTR; } break; case DIRECTION_RTL: { ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_RTL, nullptr, &err); - sd->para_direction = DIRECTION_RTL; + } break; + case DIRECTION_INHERITED: { + ubidi_setPara(bidi_iter, data + start, end - start, base_para_direction, nullptr, &err); } break; case DIRECTION_AUTO: { UBiDiDirection direction = ubidi_getBaseDirection(data + start, end - start); if (direction != UBIDI_NEUTRAL) { ubidi_setPara(bidi_iter, data + start, end - start, direction, nullptr, &err); - sd->para_direction = (direction == UBIDI_RTL) ? DIRECTION_RTL : DIRECTION_LTR; } else { ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_DEFAULT_LTR, nullptr, &err); - sd->para_direction = DIRECTION_LTR; } } break; } diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 5920ddaa50..c7fe46d554 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -499,7 +499,7 @@ class TextServerAdvanced : public TextServerExtension { /* Intermediate data */ Char16String utf16; Vector<UBiDi *> bidi_iter; - Vector<Vector2i> bidi_override; + Vector<Vector3i> bidi_override; ScriptIterator *script_iter = nullptr; hb_buffer_t *hb_buffer = nullptr; diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index d08666482d..b5d7d3a3cf 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -2664,6 +2664,7 @@ void TextServerFallback::full_copy(ShapedTextDataFallback *p_shaped) { RID TextServerFallback::_create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) { _THREAD_SAFE_METHOD_ + ERR_FAIL_COND_V_MSG(p_direction == DIRECTION_INHERITED, RID(), "Invalid text direction."); ShapedTextDataFallback *sd = memnew(ShapedTextDataFallback); sd->direction = p_direction; @@ -2687,6 +2688,7 @@ void TextServerFallback::_shaped_text_clear(const RID &p_shaped) { } void TextServerFallback::_shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) { + ERR_FAIL_COND_MSG(p_direction == DIRECTION_INHERITED, "Invalid text direction."); if (p_direction == DIRECTION_RTL) { ERR_PRINT_ONCE("Right-to-left layout is not supported by this text server."); } |