diff --git a/third_party/txt/benchmarks/paragraph_benchmarks.cc b/third_party/txt/benchmarks/paragraph_benchmarks.cc index 70e01cb4ca282e..c0a6573dd739fd 100644 --- a/third_party/txt/benchmarks/paragraph_benchmarks.cc +++ b/third_party/txt/benchmarks/paragraph_benchmarks.cc @@ -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(); diff --git a/third_party/txt/src/minikin/LineBreaker.cpp b/third_party/txt/src/minikin/LineBreaker.cpp index c0da19137ff8e1..6a67f87e30a163 100644 --- a/third_party/txt/src/minikin/LineBreaker.cpp +++ b/third_party/txt/src/minikin/LineBreaker.cpp @@ -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() { diff --git a/third_party/txt/src/minikin/LineBreaker.h b/third_party/txt/src/minikin/LineBreaker.h index 12dd439d40ace5..a00f3b97ccdefa 100644 --- a/third_party/txt/src/minikin/LineBreaker.h +++ b/third_party/txt/src/minikin/LineBreaker.h @@ -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); diff --git a/third_party/txt/src/minikin/WordBreaker.cpp b/third_party/txt/src/minikin/WordBreaker.cpp index 3e1dec1c95f185..107674d9b8643c 100644 --- a/third_party/txt/src/minikin/WordBreaker.cpp +++ b/third_party/txt/src/minikin/WordBreaker.cpp @@ -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); diff --git a/third_party/txt/src/minikin/WordBreaker.h b/third_party/txt/src/minikin/WordBreaker.h index 27072517ce2581..f318a956603076 100644 --- a/third_party/txt/src/minikin/WordBreaker.h +++ b/third_party/txt/src/minikin/WordBreaker.h @@ -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); diff --git a/third_party/txt/src/txt/paragraph_txt.cc b/third_party/txt/src/txt/paragraph_txt.cc index 45d3e7f5c271e7..f395ba8160cc10 100644 --- a/third_party/txt/src/txt/paragraph_txt.cc +++ b/third_party/txt/src/txt/paragraph_txt.cc @@ -229,7 +229,7 @@ void ParagraphTxt::CodeUnitRun::Shift(double delta) { } ParagraphTxt::ParagraphTxt() { - breaker_.setLocale(icu::Locale(), nullptr); + breaker_.setLocale(); } ParagraphTxt::~ParagraphTxt() = default;