Skip to content

Commit 6c82cf0

Browse files
committed
Optimize text rendering by caching UBreakIterator instances.
1 parent e549802 commit 6c82cf0

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

modules/text_server_adv/text_server_adv.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5632,8 +5632,12 @@ bool TextServerAdvanced::_shaped_text_update_breaks(const RID &p_shaped) {
56325632
i++;
56335633
}
56345634
int r_end = sd->spans[i].end;
5635-
UBreakIterator *bi = ubrk_open(UBRK_LINE, (language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale().ascii().get_data() : language.ascii().get_data(), data + _convert_pos_inv(sd, r_start), _convert_pos_inv(sd, r_end - r_start), &err);
5636-
if (U_FAILURE(err)) {
5635+
UBreakIterator *bi = sd->_get_break_iterator_for_locale(language, &err);
5636+
if (!U_FAILURE(err) && bi) {
5637+
ubrk_setText(bi, data + _convert_pos_inv(sd, r_start), _convert_pos_inv(sd, r_end - r_start), &err);
5638+
}
5639+
5640+
if (U_FAILURE(err) || !bi) {
56375641
// No data loaded - use fallback.
56385642
for (int j = r_start; j < r_end; j++) {
56395643
char32_t c = sd->text[j - sd->start];
@@ -5662,7 +5666,6 @@ bool TextServerAdvanced::_shaped_text_update_breaks(const RID &p_shaped) {
56625666
}
56635667
}
56645668
}
5665-
ubrk_close(bi);
56665669
i++;
56675670
}
56685671
sd->break_ops_valid = true;
@@ -6110,6 +6113,15 @@ _FORCE_INLINE_ void TextServerAdvanced::_add_featuers(const Dictionary &p_source
61106113
}
61116114
}
61126115

6116+
UBreakIterator *TextServerAdvanced::ShapedTextDataAdvanced::_get_break_iterator_for_locale(const String &p_language, UErrorCode *r_err) {
6117+
HashMap<String, UBreakIterator *>::Iterator key_value = line_break_iterators_per_language.find(p_language);
6118+
if (key_value) {
6119+
return key_value->value;
6120+
}
6121+
UBreakIterator *brk = ubrk_open(UBRK_LINE, p_language.is_empty() ? TranslationServer::get_singleton()->get_tool_locale().ascii().get_data() : p_language.ascii().get_data(), nullptr, 0, r_err);
6122+
return line_break_iterators_per_language.insert(p_language, brk)->value;
6123+
}
6124+
61136125
void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_end, hb_script_t p_script, hb_direction_t p_direction, TypedArray<RID> p_fonts, int64_t p_span, int64_t p_fb_index, int64_t p_prev_start, int64_t p_prev_end, RID p_prev_font) {
61146126
RID f;
61156127
int fs = p_sd->spans[p_span].font_size;

modules/text_server_adv/text_server_adv.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,11 @@ class TextServerAdvanced : public TextServerExtension {
544544
bool js_ops_valid = false;
545545
bool chars_valid = false;
546546

547+
HashMap<String, UBreakIterator *> line_break_iterators_per_language;
548+
549+
// Creating UBreakIterator is surprisingly costly. To improve efficiency, we cache them.
550+
UBreakIterator *_get_break_iterator_for_locale(const String &p_language, UErrorCode *r_err);
551+
547552
~ShapedTextDataAdvanced() {
548553
for (int i = 0; i < bidi_iter.size(); i++) {
549554
if (bidi_iter[i]) {
@@ -556,6 +561,9 @@ class TextServerAdvanced : public TextServerExtension {
556561
if (hb_buffer) {
557562
hb_buffer_destroy(hb_buffer);
558563
}
564+
for (const KeyValue<String, UBreakIterator *> &bi : line_break_iterators_per_language) {
565+
ubrk_close(bi.value);
566+
}
559567
}
560568
};
561569

0 commit comments

Comments
 (0)