Skip to content

Commit

Permalink
libtxt: Clone an ICU line break iterator for each Paragraph/WordBreak…
Browse files Browse the repository at this point in the history
  • Loading branch information
jason-simmons committed Nov 20, 2020
1 parent c0b08e8 commit 6c26217
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 10 deletions.
2 changes: 1 addition & 1 deletion third_party/txt/benchmarks/paragraph_benchmarks.cc
Expand Up @@ -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();
Expand Down
8 changes: 4 additions & 4 deletions third_party/txt/src/minikin/LineBreaker.cpp
Expand Up @@ -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() {
Expand Down
5 changes: 4 additions & 1 deletion third_party/txt/src/minikin/LineBreaker.h
Expand Up @@ -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);
Expand Down
14 changes: 12 additions & 2 deletions third_party/txt/src/minikin/WordBreaker.cpp
Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion third_party/txt/src/minikin/WordBreaker.h
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion third_party/txt/src/txt/paragraph_txt.cc
Expand Up @@ -229,7 +229,7 @@ void ParagraphTxt::CodeUnitRun::Shift(double delta) {
}

ParagraphTxt::ParagraphTxt() {
breaker_.setLocale(icu::Locale(), nullptr);
breaker_.setLocale();
}

ParagraphTxt::~ParagraphTxt() = default;
Expand Down

0 comments on commit 6c26217

Please sign in to comment.