未验证 提交 6c262173 编写于 作者: J Jason Simmons 提交者: GitHub

libtxt: Clone an ICU line break iterator for each Paragraph/WordBreaker (#22594)

上级 c0b08e8e
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册