Merge pull request #75922 from bruvzg/bidi_error_handling

[TextServer] Improve BiDi error handling.
This commit is contained in:
Rémi Verschelde 2023-04-11 19:40:56 +02:00
commit fa2fdefc17
No known key found for this signature in database
GPG key ID: C3336907360768E1
2 changed files with 67 additions and 35 deletions

View file

@ -4182,22 +4182,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."); ERR_FAIL_COND_V_MSG((start < 0 || end - start > p_new_sd->utf16.length()), false, "Invalid BiDi override range.");
// Create temporary line bidi & shape. // Create temporary line bidi & shape.
UBiDi *bidi_iter = ubidi_openSized(end - start, 0, &err); UBiDi *bidi_iter = nullptr;
ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); 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); ubidi_setLine(p_sd->bidi_iter[ov], start, end, bidi_iter, &err);
if (U_FAILURE(err)) { if (U_FAILURE(err)) {
ubidi_close(bidi_iter); ubidi_close(bidi_iter);
ERR_FAIL_V_MSG(false, u_errorName(err)); 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); p_new_sd->bidi_iter.push_back(bidi_iter);
err = U_ZERO_ERROR; err = U_ZERO_ERROR;
int bidi_run_count = ubidi_countRuns(bidi_iter, &err); int bidi_run_count = 1;
ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); 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++) { for (int i = 0; i < bidi_run_count; i++) {
int32_t _bidi_run_start = 0; int32_t _bidi_run_start = 0;
int32_t _bidi_run_length = 0; int32_t _bidi_run_length = end - start;
if (bidi_iter) {
ubidi_getVisualRun(bidi_iter, i, &_bidi_run_start, &_bidi_run_length); 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_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); int32_t bidi_run_end = _convert_pos(p_sd, ov_start + start + _bidi_run_start + _bidi_run_length);
@ -5642,8 +5657,7 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
UErrorCode err = U_ZERO_ERROR; UErrorCode err = U_ZERO_ERROR;
UBiDi *bidi_iter = ubidi_openSized(end - start, 0, &err); UBiDi *bidi_iter = ubidi_openSized(end - start, 0, &err);
ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); if (U_SUCCESS(err)) {
switch (static_cast<TextServer::Direction>(sd->bidi_override[ov].z)) { switch (static_cast<TextServer::Direction>(sd->bidi_override[ov].z)) {
case DIRECTION_LTR: { case DIRECTION_LTR: {
ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_LTR, nullptr, &err); ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_LTR, nullptr, &err);
@ -5663,17 +5677,33 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
} }
} break; } break;
} }
ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); 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)));
}
sd->bidi_iter.push_back(bidi_iter); sd->bidi_iter.push_back(bidi_iter);
err = U_ZERO_ERROR; err = U_ZERO_ERROR;
int bidi_run_count = ubidi_countRuns(bidi_iter, &err); int bidi_run_count = 1;
ERR_FAIL_COND_V_MSG(U_FAILURE(err), false, u_errorName(err)); 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++) { for (int i = 0; i < bidi_run_count; i++) {
int32_t _bidi_run_start = 0; 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; 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) { switch (sd->orientation) {
case ORIENTATION_HORIZONTAL: { case ORIENTATION_HORIZONTAL: {
if (is_rtl) { if (is_rtl) {

View file

@ -515,8 +515,10 @@ class TextServerAdvanced : public TextServerExtension {
~ShapedTextDataAdvanced() { ~ShapedTextDataAdvanced() {
for (int i = 0; i < bidi_iter.size(); i++) { for (int i = 0; i < bidi_iter.size(); i++) {
if (bidi_iter[i]) {
ubidi_close(bidi_iter[i]); ubidi_close(bidi_iter[i]);
} }
}
if (script_iter) { if (script_iter) {
memdelete(script_iter); memdelete(script_iter);
} }