mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
libtxt: Clone an ICU line break iterator for each Paragraph/WordBreaker (flutter/engine#22594)
This commit is contained in:
parent
b29a73b5dc
commit
dcbace3a9d
@ -405,7 +405,7 @@ BENCHMARK_DEFINE_F(ParagraphFixture, AddStyleRun)(benchmark::State& state) {
|
||||
paint.wordSpacing = text_style.word_spacing;
|
||||
|
||||
minikin::LineBreaker breaker;
|
||||
breaker.setLocale(icu::Locale(), nullptr);
|
||||
breaker.setLocale();
|
||||
breaker.resize(text.size());
|
||||
memcpy(breaker.buffer(), text.data(), text.size() * sizeof(text[0]));
|
||||
breaker.setText();
|
||||
|
||||
@ -68,10 +68,10 @@ const float SHRINKABILITY = 1.0 / 3.0;
|
||||
// not precisely match the postBreak width.
|
||||
const float LIBTXT_WIDTH_ADJUST = 0.00001;
|
||||
|
||||
void LineBreaker::setLocale(const icu::Locale& locale, Hyphenator* hyphenator) {
|
||||
mWordBreaker.setLocale(locale);
|
||||
mLocale = locale;
|
||||
mHyphenator = hyphenator;
|
||||
void LineBreaker::setLocale() {
|
||||
mWordBreaker.setLocale();
|
||||
mLocale = icu::Locale();
|
||||
mHyphenator = nullptr;
|
||||
}
|
||||
|
||||
void LineBreaker::setText() {
|
||||
|
||||
@ -97,7 +97,10 @@ class LineBreaker {
|
||||
// could be here but it's better for performance that it's upstream because of
|
||||
// the cost of constructing and comparing the ICU Locale object.
|
||||
// Note: caller is responsible for managing lifetime of hyphenator
|
||||
void setLocale(const icu::Locale& locale, Hyphenator* hyphenator);
|
||||
//
|
||||
// libtxt extension: always use the default locale so that a cached instance
|
||||
// of the ICU break iterator can be reused.
|
||||
void setLocale();
|
||||
|
||||
void resize(size_t size) {
|
||||
mTextBuf.resize(size);
|
||||
|
||||
@ -31,9 +31,19 @@ namespace minikin {
|
||||
const uint32_t CHAR_SOFT_HYPHEN = 0x00AD;
|
||||
const uint32_t CHAR_ZWJ = 0x200D;
|
||||
|
||||
void WordBreaker::setLocale(const icu::Locale& locale) {
|
||||
// libtxt extension: avoid the cost of initializing new ICU break iterators
|
||||
// by constructing a global iterator using the default locale and then
|
||||
// creating a clone for each WordBreaker instance.
|
||||
static std::once_flag gLibtxtBreakIteratorInitFlag;
|
||||
static icu::BreakIterator* gLibtxtDefaultBreakIterator = nullptr;
|
||||
|
||||
void WordBreaker::setLocale() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
mBreakIterator.reset(icu::BreakIterator::createLineInstance(locale, status));
|
||||
std::call_once(gLibtxtBreakIteratorInitFlag, [&status] {
|
||||
gLibtxtDefaultBreakIterator =
|
||||
icu::BreakIterator::createLineInstance(icu::Locale(), status);
|
||||
});
|
||||
mBreakIterator.reset(gLibtxtDefaultBreakIterator->clone());
|
||||
// TODO: handle failure status
|
||||
if (mText != nullptr) {
|
||||
mBreakIterator->setText(&mUText, status);
|
||||
|
||||
@ -33,7 +33,9 @@ class WordBreaker {
|
||||
public:
|
||||
~WordBreaker() { finish(); }
|
||||
|
||||
void setLocale(const icu::Locale& locale);
|
||||
// libtxt extension: always use the default locale so that a cached instance
|
||||
// of the ICU break iterator can be reused.
|
||||
void setLocale();
|
||||
|
||||
void setText(const uint16_t* data, size_t size);
|
||||
|
||||
|
||||
@ -229,7 +229,7 @@ void ParagraphTxt::CodeUnitRun::Shift(double delta) {
|
||||
}
|
||||
|
||||
ParagraphTxt::ParagraphTxt() {
|
||||
breaker_.setLocale(icu::Locale(), nullptr);
|
||||
breaker_.setLocale();
|
||||
}
|
||||
|
||||
ParagraphTxt::~ParagraphTxt() = default;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user