Skip to content

Commit c11863c

Browse files
committed
Merge pull request #101626 from bruvzg/ts_fix_inv
[TextServer] Fix text buffer not processing strings added after `shape`.
2 parents d6adc77 + 43bc44e commit c11863c

File tree

2 files changed

+62
-11
lines changed

2 files changed

+62
-11
lines changed

modules/text_server_adv/text_server_adv.cpp

+20-10
Original file line numberDiff line numberDiff line change
@@ -4773,17 +4773,24 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
47734773
}
47744774
}
47754775

4776+
Vector<Vector3i> bidi_ranges;
4777+
if (p_sd->bidi_override.is_empty()) {
4778+
bidi_ranges.push_back(Vector3i(p_sd->start, p_sd->end, DIRECTION_INHERITED));
4779+
} else {
4780+
bidi_ranges = p_sd->bidi_override;
4781+
}
4782+
47764783
int sd_size = p_sd->glyphs.size();
47774784
const Glyph *sd_glyphs = p_sd->glyphs.ptr();
4778-
for (int ov = 0; ov < p_sd->bidi_override.size(); ov++) {
4785+
for (int ov = 0; ov < bidi_ranges.size(); ov++) {
47794786
UErrorCode err = U_ZERO_ERROR;
47804787

4781-
if (p_sd->bidi_override[ov].x >= p_start + p_length || p_sd->bidi_override[ov].y <= p_start) {
4788+
if (bidi_ranges[ov].x >= p_start + p_length || bidi_ranges[ov].y <= p_start) {
47824789
continue;
47834790
}
4784-
int ov_start = _convert_pos_inv(p_sd, p_sd->bidi_override[ov].x);
4791+
int ov_start = _convert_pos_inv(p_sd, bidi_ranges[ov].x);
47854792
int start = MAX(0, _convert_pos_inv(p_sd, p_start) - ov_start);
4786-
int end = MIN(_convert_pos_inv(p_sd, p_start + p_length), _convert_pos_inv(p_sd, p_sd->bidi_override[ov].y)) - ov_start;
4793+
int end = MIN(_convert_pos_inv(p_sd, p_start + p_length), _convert_pos_inv(p_sd, bidi_ranges[ov].y)) - ov_start;
47874794

47884795
ERR_FAIL_COND_V_MSG((start < 0 || end - start > p_new_sd->utf16.length()), false, "Invalid BiDi override range.");
47894796

@@ -4797,7 +4804,7 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
47974804
// Line BiDi failed (string contains incompatible control characters), try full paragraph BiDi instead.
47984805
err = U_ZERO_ERROR;
47994806
const UChar *data = p_sd->utf16.get_data();
4800-
switch (static_cast<TextServer::Direction>(p_sd->bidi_override[ov].z)) {
4807+
switch (static_cast<TextServer::Direction>(bidi_ranges[ov].z)) {
48014808
case DIRECTION_LTR: {
48024809
ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_LTR, nullptr, &err);
48034810
} break;
@@ -6490,14 +6497,17 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
64906497
} break;
64916498
}
64926499

6500+
Vector<Vector3i> bidi_ranges;
64936501
if (sd->bidi_override.is_empty()) {
6494-
sd->bidi_override.push_back(Vector3i(sd->start, sd->end, DIRECTION_INHERITED));
6502+
bidi_ranges.push_back(Vector3i(sd->start, sd->end, DIRECTION_INHERITED));
6503+
} else {
6504+
bidi_ranges = sd->bidi_override;
64956505
}
64966506

6497-
for (int ov = 0; ov < sd->bidi_override.size(); ov++) {
6507+
for (int ov = 0; ov < bidi_ranges.size(); ov++) {
64986508
// Create BiDi iterator.
6499-
int start = _convert_pos_inv(sd, sd->bidi_override[ov].x - sd->start);
6500-
int end = _convert_pos_inv(sd, sd->bidi_override[ov].y - sd->start);
6509+
int start = _convert_pos_inv(sd, bidi_ranges[ov].x - sd->start);
6510+
int end = _convert_pos_inv(sd, bidi_ranges[ov].y - sd->start);
65016511

65026512
if (start < 0 || end - start > sd->utf16.length()) {
65036513
continue;
@@ -6506,7 +6516,7 @@ bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
65066516
UErrorCode err = U_ZERO_ERROR;
65076517
UBiDi *bidi_iter = ubidi_openSized(end - start, 0, &err);
65086518
if (U_SUCCESS(err)) {
6509-
switch (static_cast<TextServer::Direction>(sd->bidi_override[ov].z)) {
6519+
switch (static_cast<TextServer::Direction>(bidi_ranges[ov].z)) {
65106520
case DIRECTION_LTR: {
65116521
ubidi_setPara(bidi_iter, data + start, end - start, UBIDI_LTR, nullptr, &err);
65126522
} break;

tests/servers/test_text_server.h

+42-1
Original file line numberDiff line numberDiff line change
@@ -815,12 +815,12 @@ TEST_SUITE("[TextServer]") {
815815
SUBCASE("[TextServer] Word break") {
816816
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
817817
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
818+
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
818819

819820
if (!ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
820821
continue;
821822
}
822823

823-
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
824824
{
825825
String text1 = U"linguistically similar and effectively form";
826826
// 14^ 22^ 26^ 38^
@@ -918,6 +918,47 @@ TEST_SUITE("[TextServer]") {
918918
}
919919
}
920920
}
921+
922+
SUBCASE("[TextServer] Buffer invalidation") {
923+
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
924+
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
925+
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
926+
927+
if (!ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
928+
continue;
929+
}
930+
931+
RID font1 = ts->create_font();
932+
ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
933+
934+
Array font;
935+
font.push_back(font1);
936+
937+
RID ctx = ts->create_shaped_text();
938+
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
939+
bool ok = ts->shaped_text_add_string(ctx, "T", font, 16);
940+
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
941+
int gl_size = ts->shaped_text_get_glyph_count(ctx);
942+
CHECK_MESSAGE(gl_size == 1, "Shaping failed, invalid glyph count");
943+
944+
ok = ts->shaped_text_add_object(ctx, "key", Size2(20, 20), INLINE_ALIGNMENT_CENTER, 1, 0.0);
945+
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
946+
gl_size = ts->shaped_text_get_glyph_count(ctx);
947+
CHECK_MESSAGE(gl_size == 2, "Shaping failed, invalid glyph count");
948+
949+
ok = ts->shaped_text_add_string(ctx, "B", font, 16);
950+
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
951+
gl_size = ts->shaped_text_get_glyph_count(ctx);
952+
CHECK_MESSAGE(gl_size == 3, "Shaping failed, invalid glyph count");
953+
954+
ts->free_rid(ctx);
955+
956+
for (int j = 0; j < font.size(); j++) {
957+
ts->free_rid(font[j]);
958+
}
959+
font.clear();
960+
}
961+
}
921962
}
922963
}
923964
}; // namespace TestTextServer

0 commit comments

Comments
 (0)