summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorbruvzg <7645683+bruvzg@users.noreply.github.com>2023-04-11 10:07:00 +0300
committerYuri Sizov <yuris@humnom.net>2023-04-24 17:03:54 +0200
commit3a1af9393f0accfed8d05a257e2ff8af6b2e7050 (patch)
tree8bb13f967f80354c0ed7c4311b745643215b9650 /modules
parent2c773e12b8122edd58a32c67febeb470434f89dd (diff)
[TextServer] Improve BiDi error handling.
(cherry picked from commit d8d88e15300de05119a6d782067578e6e05d52e5)
Diffstat (limited to 'modules')
-rw-r--r--modules/text_server_adv/text_server_adv.cpp98
-rw-r--r--modules/text_server_adv/text_server_adv.h4
2 files changed, 67 insertions, 35 deletions
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index c1a1d8e048..ae32a08c58 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -4149,22 +4149,37 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
ERR_FAIL_COND_V_MSG((start < 0 || end - start > p_new_sd->utf16.length()), false, "Invalid BiDi override range.");
// Create temporary line bidi & shape.
- UBiDi *bidi_iter = ubidi_openSized(end - start, 0, &err);
- ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err));
- ubidi_setLine(p_sd->bidi_iter[ov], start, end, bidi_iter, &err);
- if (U_FAILURE(err)) {
- ubidi_close(bidi_iter);
- ERR_FAIL_V_MSG(false, u_errorName(err));
+ UBiDi *bidi_iter = nullptr;
+ if (p_sd->bidi_iter[ov]) {
+ bidi_iter = ubidi_openSized(end - start, 0, &err);
+ 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)));
+ }
+ } else {
+ bidi_iter = nullptr;
+ ERR_PRINT(vformat("BiDi iterator allocation for the line failed: %s", u_errorName(err)));
+ }
}
p_new_sd->bidi_iter.push_back(bidi_iter);
err = U_ZERO_ERROR;
- int bidi_run_count = ubidi_countRuns(bidi_iter, &err);
- ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err));
+ int bidi_run_count = 1;
+ if (bidi_iter) {
+ bidi_run_count = ubidi_countRuns(bidi_iter, &err);
+ if (U_FAILURE(err)) {
+ ERR_PRINT(u_errorName(err));
+ }
+ }
for (int i = 0; i < bidi_run_count; i++) {
int32_t _bidi_run_start = 0;
- int32_t _bidi_run_length = 0;
- ubidi_getVisualRun(bidi_iter, i, &_bidi_run_start, &_bidi_run_length);
+ int32_t _bidi_run_length = end - start;
+ if (bidi_iter) {
+ ubidi_getVisualRun(bidi_iter, i, &_bidi_run_start, &_bidi_run_length);
+ }
int32_t bidi_run_start = _convert_pos(p_sd, ov_start + start + _bidi_run_start);
int32_t bidi_run_end = _convert_pos(p_sd, ov_start + start + _bidi_run_start + _bidi_run_length);
@@ -5609,38 +5624,53 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
UErrorCode err = U_ZERO_ERROR;
UBiDi *bidi_iter = ubidi_openSized(end - start, 0, &err);
- ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err));
-
- 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);
- } 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, 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 {
+ if (U_SUCCESS(err)) {
+ 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);
+ } 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, base_para_direction, nullptr, &err);
- }
- } break;
+ } 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);
+ }
+ } break;
+ }
+ if (U_FAILURE(err)) {
+ ubidi_close(bidi_iter);
+ bidi_iter = nullptr;
+ ERR_PRINT(vformat("BiDi reordering for the paragraph failed: %s", u_errorName(err)));
+ }
+ } else {
+ bidi_iter = nullptr;
+ ERR_PRINT(vformat("BiDi iterator allocation for the paragraph failed: %s", u_errorName(err)));
}
- ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err));
sd->bidi_iter.push_back(bidi_iter);
err = U_ZERO_ERROR;
- int bidi_run_count = ubidi_countRuns(bidi_iter, &err);
- ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err));
+ int bidi_run_count = 1;
+ if (bidi_iter) {
+ bidi_run_count = ubidi_countRuns(bidi_iter, &err);
+ if (U_FAILURE(err)) {
+ ERR_PRINT(u_errorName(err));
+ }
+ }
for (int i = 0; i < bidi_run_count; i++) {
int32_t _bidi_run_start = 0;
- int32_t _bidi_run_length = 0;
+ int32_t _bidi_run_length = end - start;
+ bool is_rtl = false;
hb_direction_t bidi_run_direction = HB_DIRECTION_INVALID;
- bool is_rtl = (ubidi_getVisualRun(bidi_iter, i, &_bidi_run_start, &_bidi_run_length) == UBIDI_LTR);
+ if (bidi_iter) {
+ is_rtl = (ubidi_getVisualRun(bidi_iter, i, &_bidi_run_start, &_bidi_run_length) == UBIDI_LTR);
+ }
switch (sd->orientation) {
case ORIENTATION_HORIZONTAL: {
if (is_rtl) {
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index ce08cf7694..046a85d2f7 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -514,7 +514,9 @@ class TextServerAdvanced : public TextServerExtension {
~ShapedTextDataAdvanced() {
for (int i = 0; i < bidi_iter.size(); i++) {
- ubidi_close(bidi_iter[i]);
+ if (bidi_iter[i]) {
+ ubidi_close(bidi_iter[i]);
+ }
}
if (script_iter) {
memdelete(script_iter);