Perform population UTF16Mapping only once
Bug: skia: https://bugs.chromium.org/p/skia/issues/detail?id=13396 Change-Id: I043ecfa175f18cde666a034af8290fe98a701855 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/547776 Reviewed-by: Julia Lavrova <jlavrova@google.com> Commit-Queue: Julia Lavrova <jlavrova@google.com>
This commit is contained in:
parent
26282a522c
commit
a9aac9d677
@ -1091,34 +1091,33 @@ TextIndex ParagraphImpl::findNextGraphemeBoundary(TextIndex utf8) {
|
||||
}
|
||||
|
||||
void ParagraphImpl::ensureUTF16Mapping() {
|
||||
if (!fUTF16IndexForUTF8Index.empty()) {
|
||||
return;
|
||||
}
|
||||
// Fill out code points 16
|
||||
auto ptr = fText.c_str();
|
||||
auto end = fText.c_str() + fText.size();
|
||||
while (ptr < end) {
|
||||
fillUTF16MappingOnce([&] {
|
||||
// Fill out code points 16
|
||||
auto ptr = fText.c_str();
|
||||
auto end = fText.c_str() + fText.size();
|
||||
while (ptr < end) {
|
||||
|
||||
size_t index = ptr - fText.c_str();
|
||||
SkUnichar u = SkUTF::NextUTF8(&ptr, end);
|
||||
size_t index = ptr - fText.c_str();
|
||||
SkUnichar u = SkUTF::NextUTF8(&ptr, end);
|
||||
|
||||
// All utf8 units refer to the same codepoint
|
||||
size_t next = ptr - fText.c_str();
|
||||
for (auto i = index; i < next; ++i) {
|
||||
fUTF16IndexForUTF8Index.emplace_back(fUTF8IndexForUTF16Index.size());
|
||||
}
|
||||
SkASSERT(fUTF16IndexForUTF8Index.size() == next);
|
||||
// All utf8 units refer to the same codepoint
|
||||
size_t next = ptr - fText.c_str();
|
||||
for (auto i = index; i < next; ++i) {
|
||||
fUTF16IndexForUTF8Index.emplace_back(fUTF8IndexForUTF16Index.size());
|
||||
}
|
||||
SkASSERT(fUTF16IndexForUTF8Index.size() == next);
|
||||
|
||||
// One or two codepoints refer to the same text index
|
||||
uint16_t buffer[2];
|
||||
size_t count = SkUTF::ToUTF16(u, buffer);
|
||||
fUTF8IndexForUTF16Index.emplace_back(index);
|
||||
if (count > 1) {
|
||||
// One or two codepoints refer to the same text index
|
||||
uint16_t buffer[2];
|
||||
size_t count = SkUTF::ToUTF16(u, buffer);
|
||||
fUTF8IndexForUTF16Index.emplace_back(index);
|
||||
if (count > 1) {
|
||||
fUTF8IndexForUTF16Index.emplace_back(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
fUTF16IndexForUTF8Index.emplace_back(fUTF8IndexForUTF16Index.size());
|
||||
fUTF8IndexForUTF16Index.emplace_back(fText.size());
|
||||
fUTF16IndexForUTF8Index.emplace_back(fUTF8IndexForUTF16Index.size());
|
||||
fUTF8IndexForUTF16Index.emplace_back(fText.size());
|
||||
});
|
||||
}
|
||||
|
||||
void ParagraphImpl::visit(const Visitor& visitor) {
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "include/core/SkString.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/private/SkBitmaskEnum.h"
|
||||
#include "include/private/SkOnce.h"
|
||||
#include "include/private/SkTArray.h"
|
||||
#include "include/private/SkTHash.h"
|
||||
#include "include/private/SkTemplates.h"
|
||||
@ -255,6 +256,7 @@ private:
|
||||
// They are filled lazily whenever they need and cached
|
||||
SkTArray<TextIndex, true> fUTF8IndexForUTF16Index;
|
||||
SkTArray<size_t, true> fUTF16IndexForUTF8Index;
|
||||
SkOnce fillUTF16MappingOnce;
|
||||
size_t fUnresolvedGlyphs;
|
||||
|
||||
SkTArray<TextLine, false> fLines; // kFormatted (cached: width, max lines, ellipsis, text align)
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
|
||||
struct GrContextOptions;
|
||||
|
||||
@ -6924,3 +6925,51 @@ UNIX_ONLY_TEST(SkParagraph_NonMonotonicGlyphsRTL, reporter) {
|
||||
REPORTER_ASSERT(reporter, impl->lineNumber() == 1); // But it's still one line
|
||||
paragraph->paint(canvas.get(), 0, 0);
|
||||
}
|
||||
|
||||
void performGetRectsForRangeConcurrently(skiatest::Reporter* reporter) {
|
||||
sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
|
||||
if (!fontCollection->fontsFound()) {
|
||||
INFOF(reporter, "No fonts found\n");
|
||||
return;
|
||||
}
|
||||
auto const text = std::u16string(42000, 'x');
|
||||
ParagraphStyle paragraphStyle;
|
||||
TextStyle textStyle;
|
||||
textStyle.setFontFamilies({SkString("Roboto")});
|
||||
textStyle.setFontSize(14);
|
||||
textStyle.setColor(SK_ColorBLACK);
|
||||
textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
|
||||
SkFontStyle::kUpright_Slant));
|
||||
|
||||
ParagraphBuilderImpl builder(paragraphStyle, fontCollection);
|
||||
builder.pushStyle(textStyle);
|
||||
builder.addText(text);
|
||||
builder.pop();
|
||||
|
||||
auto paragraph = builder.Build();
|
||||
paragraph->layout(std::numeric_limits<float>::max());
|
||||
|
||||
RectHeightStyle heightStyle = RectHeightStyle::kMax;
|
||||
RectWidthStyle widthStyle = RectWidthStyle::kMax;
|
||||
auto t1 = std::thread([&] {
|
||||
auto result = paragraph->getRectsForRange(0, 2, heightStyle, widthStyle);
|
||||
REPORTER_ASSERT(reporter, !result.empty());
|
||||
});
|
||||
auto t2 = std::thread([&] {
|
||||
auto result = paragraph->getRectsForRange(5, 10, heightStyle, widthStyle);
|
||||
REPORTER_ASSERT(reporter, !result.empty());
|
||||
});
|
||||
t1.join();
|
||||
t2.join();
|
||||
}
|
||||
|
||||
UNIX_ONLY_TEST(SkParagraph_GetRectsForRangeConcurrently, reporter) {
|
||||
auto const threads_count = 100;
|
||||
std::thread threads[threads_count];
|
||||
for (auto& thread : threads) {
|
||||
thread = std::thread(performGetRectsForRangeConcurrently, reporter);
|
||||
}
|
||||
for (auto& thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user