|
@@ -4138,6 +4138,7 @@ RID TextServerAdvanced::_shaped_text_substr(const RID &p_shaped, int64_t p_start
|
|
|
new_sd->direction = sd->direction;
|
|
|
new_sd->custom_punct = sd->custom_punct;
|
|
|
new_sd->para_direction = sd->para_direction;
|
|
|
+ new_sd->base_para_direction = sd->base_para_direction;
|
|
|
for (int i = 0; i < TextServer::SPACING_MAX; i++) {
|
|
|
new_sd->extra_spacing[i] = sd->extra_spacing[i];
|
|
|
}
|
|
@@ -4188,9 +4189,33 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
|
|
|
if (U_SUCCESS(err)) {
|
|
|
ubidi_setLine(p_sd->bidi_iter[ov], start, end, bidi_iter, &err);
|
|
|
if (U_FAILURE(err)) {
|
|
|
- ubidi_close(bidi_iter);
|
|
|
- bidi_iter = nullptr;
|
|
|
- ERR_PRINT(vformat("BiDi reordering for the line failed: %s", u_errorName(err)));
|
|
|
+ // Line BiDi failed (string contains incompatible control characters), try full paragraph BiDi instead.
|
|
|
+ err = U_ZERO_ERROR;
|
|
|
+ const UChar *data = p_sd->utf16.get_data();
|
|
|
+ switch (static_cast<TextServer::Direction>(p_sd->bidi_override[ov].z)) {
|
|
|
+ case DIRECTION_LTR: {
|
|
|
+ ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_LTR, nullptr, &err);
|
|
|
+ } break;
|
|
|
+ case DIRECTION_RTL: {
|
|
|
+ ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_RTL, nullptr, &err);
|
|
|
+ } break;
|
|
|
+ case DIRECTION_INHERITED: {
|
|
|
+ ubidi_setPara(bidi_iter, data + start, end - start, p_sd->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);
|
|
|
+ } else {
|
|
|
+ ubidi_setPara(bidi_iter, data + start, end - start, p_sd->base_para_direction, nullptr, &err);
|
|
|
+ }
|
|
|
+ } break;
|
|
|
+ }
|
|
|
+ if (U_FAILURE(err)) {
|
|
|
+ ubidi_close(bidi_iter);
|
|
|
+ bidi_iter = nullptr;
|
|
|
+ ERR_PRINT(vformat("BiDi reordering for the line failed: %s", u_errorName(err)));
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
bidi_iter = nullptr;
|
|
@@ -5619,25 +5644,25 @@ 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;
|
|
|
+ sd->base_para_direction = UBIDI_DEFAULT_LTR;
|
|
|
switch (sd->direction) {
|
|
|
case DIRECTION_LTR: {
|
|
|
sd->para_direction = DIRECTION_LTR;
|
|
|
- base_para_direction = UBIDI_LTR;
|
|
|
+ sd->base_para_direction = UBIDI_LTR;
|
|
|
} break;
|
|
|
case DIRECTION_RTL: {
|
|
|
sd->para_direction = DIRECTION_RTL;
|
|
|
- base_para_direction = UBIDI_RTL;
|
|
|
+ sd->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;
|
|
|
+ sd->base_para_direction = direction;
|
|
|
} else {
|
|
|
sd->para_direction = DIRECTION_LTR;
|
|
|
- base_para_direction = UBIDI_DEFAULT_LTR;
|
|
|
+ sd->base_para_direction = UBIDI_DEFAULT_LTR;
|
|
|
}
|
|
|
} break;
|
|
|
}
|
|
@@ -5666,14 +5691,14 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
|
|
|
ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_RTL, nullptr, &err);
|
|
|
} break;
|
|
|
case DIRECTION_INHERITED: {
|
|
|
- ubidi_setPara(bidi_iter, data + start, end - start, base_para_direction, nullptr, &err);
|
|
|
+ ubidi_setPara(bidi_iter, data + start, end - start, sd->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);
|
|
|
} else {
|
|
|
- ubidi_setPara(bidi_iter, data + start, end - start, base_para_direction, nullptr, &err);
|
|
|
+ ubidi_setPara(bidi_iter, data + start, end - start, sd->base_para_direction, nullptr, &err);
|
|
|
}
|
|
|
} break;
|
|
|
}
|