Reland "Add setters for providing client info to SkParagraphBuilder"
This reverts commit b1398c9c64a878e4d3e5d8268b0a01bbda060857.
Reason for revert: Fixing the build
Original change's description:
> Revert "Add setters for providing client info to SkParagraphBuilder"
>
> This reverts commit d840c9bc3ef36ee79f991c35488d14013c8b06bb.
>
> Reason for revert: breaking g3 and Android rolls, e.g.
>
> ld.lld: error: undefined symbol: SkUnicode::MakeClientBasedUnicode(SkSpan<char>, std::__1::vector<SkUnicode::BidiRegion, std::__1::allocator<SkUnicode::BidiRegion>>, std::__1::vector<unsigned int, std::__1::allocator<unsigned int>>, std::__1::vector<unsigned int, std::__1::allocator<unsigned int>>, std::__1::vector<SkUnicode::LineBreakBefore, std::__1::allocator<SkUnicode::LineBreakBefore>>)
> >>> referenced by ParagraphBuilderImpl.cpp:161 (external/skia/modules/skparagraph/src/ParagraphBuilderImpl.cpp:161)
> >>> out/soong/.intermediates/external/skia/skia_nanobench/android_arm_armv8-a/obj/external/skia/modules/skparagraph/src/ParagraphBuilderImpl.o:(skia::textlayout::ParagraphBuilderImpl::Build())
> clang-16: error: linker command failed with exit code 1 (use -v to see invocation)
>
> Original change's description:
> > Add setters for providing client info to SkParagraphBuilder
> >
> > We need to have UTF8 and UTF16 setters for client info. The reason is that ICU4X produces UTF8 indices, but browser APIs produce UTF16 indices. So SkParagraphBuilder needs to accept both.
> >
> > Change-Id: Ie26e1d728a35c2b2e0d971918c6c079ddbed25ed
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/611560
> > Reviewed-by: Kevin Lubick <kjlubick@google.com>
> > Reviewed-by: Julia Lavrova <jlavrova@google.com>
> > Commit-Queue: Julia Lavrova <jlavrova@google.com>
>
> Change-Id: I4f3cb667f992b86f0ed3a121a156fa7716e6a99d
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/631756
> Auto-Submit: Florin Malita <fmalita@google.com>
> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
> Commit-Queue: Julia Lavrova <jlavrova@google.com>
> Reviewed-by: Kevin Lubick <kjlubick@google.com>
Change-Id: Ie6bfc5cb99d4ca60773e734450c79b06ae49693d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/631837
Reviewed-by: Julia Lavrova <jlavrova@google.com>
Commit-Queue: Julia Lavrova <jlavrova@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
diff --git a/modules/canvaskit/externs.js b/modules/canvaskit/externs.js
index e10fd33..89c177a 100644
--- a/modules/canvaskit/externs.js
+++ b/modules/canvaskit/externs.js
@@ -170,7 +170,16 @@
ShapeText: function() {},
addText: function() {},
build: function() {},
- buildWithClientInfo: function() {},
+
+ setBidiRegionsUtf8: function() {},
+ setBidiRegionsUtf16: function() {},
+ setWordsUtf8: function() {},
+ setWordsUtf16: function() {},
+ setGraphemeBreaksUtf8: function() {},
+ setGraphemeBreaksUtf16: function() {},
+ setLineBreaksUtf8: function() {},
+ setLineBreaksUtf16: function() {},
+
getText: function() {},
pop: function() {},
reset: function() {},
@@ -188,7 +197,15 @@
_pushStyle: function() {},
_pushPaintStyle: function() {},
_addPlaceholder: function() {},
- _buildWithClientInfo: function() {},
+
+ _setBidiRegionsUtf8: function() {},
+ _setBidiRegionsUtf16: function() {},
+ _setWordsUtf8: function() {},
+ _setWordsUtf16: function() {},
+ _setGraphemeBreaksUtf8: function() {},
+ _setGraphemeBreaksUtf16: function() {},
+ _setLineBreaksUtf8: function() {},
+ _setLineBreaksUtf16: function() {},
},
RuntimeEffect: {
diff --git a/modules/canvaskit/npm_build/extra.html b/modules/canvaskit/npm_build/extra.html
index b8d210e..e01f2b6 100644
--- a/modules/canvaskit/npm_build/extra.html
+++ b/modules/canvaskit/npm_build/extra.html
@@ -450,12 +450,11 @@
const mallocedLineBreaks = CanvasKit.Malloc(Uint32Array, lineBreaks.length);
mallocedLineBreaks.toTypedArray().set(lineBreaks);
- const paragraph = builder.buildWithClientInfo(
- mallocedBidis,
- mallocedWords,
- graphemesArr,
- mallocedLineBreaks
- );
+ builder.setBidiRegionsUtf16(mallocedBidis);
+ builder.setWordsUtf16(mallocedWords);
+ builder.setGraphemeBreaksUtf16(mallocedGraphemes);
+ builder.setLineBreaksUtf16(mallocedLineBreaks);
+ const paragraph = builder.build();
paragraph.layout(600);
diff --git a/modules/canvaskit/npm_build/paragraphs.html b/modules/canvaskit/npm_build/paragraphs.html
index 8c14eaa..9fe043a 100644
--- a/modules/canvaskit/npm_build/paragraphs.html
+++ b/modules/canvaskit/npm_build/paragraphs.html
@@ -150,12 +150,11 @@
const mallocedLineBreaks = CanvasKit.Malloc(Uint32Array, lineBreaks.length);
mallocedLineBreaks.toTypedArray().set(lineBreaks);
- const paragraph = builder.buildWithClientInfo(
- mallocedBidis,
- mallocedWords,
- mallocedGraphemes,
- mallocedLineBreaks
- );
+ builder.setBidiRegionsUtf16(mallocedBidis);
+ builder.setWordsUtf16(mallocedWords);
+ builder.setGraphemeBreaksUtf16(mallocedGraphemes);
+ builder.setLineBreaksUtf16(mallocedLineBreaks);
+ const paragraph = builder.build();
fontMgr.delete();
@@ -207,7 +206,6 @@
breaks.push(iterator.current(), getBreakType(iterator.breakType()));
}
- console.log(breaks);
return breaks;
}
diff --git a/modules/canvaskit/npm_build/types/canvaskit-wasm-tests.ts b/modules/canvaskit/npm_build/types/canvaskit-wasm-tests.ts
index 374a52b..c770fa8 100644
--- a/modules/canvaskit/npm_build/types/canvaskit-wasm-tests.ts
+++ b/modules/canvaskit/npm_build/types/canvaskit-wasm-tests.ts
@@ -614,16 +614,11 @@
builder2.reset();
const text = builder.getText(); // $ExpectType string
- const mallocedBidis = CK.Malloc(Uint32Array, 3);
- const mallocedWords = new Uint32Array(10);
- const mallocedGraphemes = new Uint32Array(10);
- const mallocedLineBreaks = new Uint32Array(10);
- const paragraph3 = builder.buildWithClientInfo(// $ExpectType Paragraph
- mallocedBidis,
- mallocedWords,
- mallocedGraphemes,
- mallocedLineBreaks
- );
+ builder.setBidiRegionsUtf16(CK.Malloc(Uint32Array, 3));
+ builder.setWordsUtf16(new Uint32Array(10));
+ builder.setGraphemeBreaksUtf16(new Uint32Array(10));
+ builder.setLineBreaksUtf16(new Uint32Array(10));
+ const paragraph3 = builder.build(); // $ExpectType Paragraph
}
function particlesTests(CK: CanvasKit, canvas?: Canvas) {
diff --git a/modules/canvaskit/npm_build/types/index.d.ts b/modules/canvaskit/npm_build/types/index.d.ts
index 29149c7..7bfb841 100644
--- a/modules/canvaskit/npm_build/types/index.d.ts
+++ b/modules/canvaskit/npm_build/types/index.d.ts
@@ -987,25 +987,52 @@
build(): Paragraph;
/**
- * Returns a Paragraph object that can be used to be layout and
- * paint the text to an Canvas.
* @param bidiRegions is an array of unsigned integers that should be
- * treated as triples (starting index, ending index, direction).
- * Direction == 1 means left-to-right, direction == 0 is right-to-left. It's
- * recommended to use `CanvasKit.TextDirection.RTL.value` or
- * `CanvasKit.TextDirection.LTR.value` instead of hardcoding 0 or 1.
+ * treated as triples (starting index, ending index, bidi level).
+ *
+ * The indices are expected to be relative to the UTF-8 representation of
+ * the text.
+ */
+ setBidiRegionsUtf8(bidiRegions: InputBidiRegions): void;
+ /**
+ * @param bidiRegions is an array of unsigned integers that should be
+ * treated as triples (starting index, ending index, bidi level).
*
* The indices are expected to be relative to the UTF-16 representation of
* the text.
+ */
+ setBidiRegionsUtf16(bidiRegions: InputBidiRegions): void;
+
+ /**
* @param words is an array of word edges (starting or ending). You can
* pass 2 elements (0 as a start of the entire text and text.size as the
- * end). This information only needed for a specific API method getWords.
+ * end). This information is only needed for a specific API method getWords.
+ *
+ * The indices are expected to be relative to the UTF-8 representation of
+ * the text.
+ */
+ setWordsUtf8(words: InputWords): void;
+ /**
+ * @param words is an array of word edges (starting or ending). You can
+ * pass 2 elements (0 as a start of the entire text and text.size as the
+ * end). This information is only needed for a specific API method getWords.
*
* The indices are expected to be relative to the UTF-16 representation of
* the text.
*
* The `Intl.Segmenter` API can be used as a source for this data.
+ */
+ setWordsUtf16(words: InputWords): void;
+
+ /**
+ * @param graphemes is an array of indexes in the input text that point
+ * to the start of each grapheme.
*
+ * The indices are expected to be relative to the UTF-8 representation of
+ * the text.
+ */
+ setGraphemeBreaksUtf8(graphemes: InputGraphemes): void;
+ /**
* @param graphemes is an array of indexes in the input text that point
* to the start of each grapheme.
*
@@ -1013,7 +1040,20 @@
* the text.
*
* The `Intl.Segmenter` API can be used as a source for this data.
+ */
+ setGraphemeBreaksUtf16(graphemes: InputGraphemes): void;
+
+ /**
+ * @param lineBreaks is an array of unsigned integers that should be
+ * treated as pairs (index, break type) that point to the places of possible
+ * line breaking if needed. It should include 0 as the first element.
+ * Break type == 0 means soft break, break type == 1 is a hard break.
*
+ * The indices are expected to be relative to the UTF-8 representation of
+ * the text.
+ */
+ setLineBreaksUtf8(lineBreaks: InputLineBreaks): void;
+ /**
* @param lineBreaks is an array of unsigned integers that should be
* treated as pairs (index, break type) that point to the places of possible
* line breaking if needed. It should include 0 as the first element.
@@ -1024,10 +1064,7 @@
*
* Chrome's `v8BreakIterator` API can be used as a source for this data.
*/
- buildWithClientInfo(bidiRegions?: InputBidiRegions | null,
- words?: InputWords | null,
- graphemes?: InputGraphemes | null,
- lineBreaks?: InputLineBreaks | null): Paragraph;
+ setLineBreaksUtf16(lineBreaks: InputLineBreaks): void;
/**
* Returns the entire Paragraph text (which is useful in case that text
diff --git a/modules/canvaskit/paragraph.js b/modules/canvaskit/paragraph.js
index c16c8eb..cc43ab6 100644
--- a/modules/canvaskit/paragraph.js
+++ b/modules/canvaskit/paragraph.js
@@ -329,23 +329,48 @@
this._addPlaceholder(width, height, alignment, baseline, offset);
};
- CanvasKit.ParagraphBuilder.prototype.buildWithClientInfo =
- function(bidiRegions, words, graphemeBreaks, lineBreaks) {
-
+ CanvasKit.ParagraphBuilder.prototype.setBidiRegionsUtf8 = function(bidiRegions) {
var bPtr = copy1dArray(bidiRegions, 'HEAPU32');
- var wPtr = copy1dArray(words, 'HEAPU32');
- var gPtr = copy1dArray(graphemeBreaks, 'HEAPU32');
- var lPtr = copy1dArray(lineBreaks, 'HEAPU32');
- var para = this._buildWithClientInfo(
- bPtr, bidiRegions && bidiRegions.length || 0,
- wPtr, words && words.length || 0,
- gPtr, graphemeBreaks && graphemeBreaks.length || 0,
- lPtr, lineBreaks && lineBreaks.length || 0);
+ this._setBidiRegionsUtf8(bPtr, bidiRegions && bidiRegions.length || 0);
freeArraysThatAreNotMallocedByUsers(bPtr, bidiRegions);
- freeArraysThatAreNotMallocedByUsers(wPtr, words);
- freeArraysThatAreNotMallocedByUsers(gPtr, graphemeBreaks);
- freeArraysThatAreNotMallocedByUsers(lPtr, lineBreaks);
- return para;
+ };
+ CanvasKit.ParagraphBuilder.prototype.setBidiRegionsUtf16 = function(bidiRegions) {
+ var bPtr = copy1dArray(bidiRegions, 'HEAPU32');
+ this._setBidiRegionsUtf16(bPtr, bidiRegions && bidiRegions.length || 0);
+ freeArraysThatAreNotMallocedByUsers(bPtr, bidiRegions);
+ };
+
+ CanvasKit.ParagraphBuilder.prototype.setWordsUtf8 = function(words) {
+ var bPtr = copy1dArray(words, 'HEAPU32');
+ this._setWordsUtf8(bPtr, words && words.length || 0);
+ freeArraysThatAreNotMallocedByUsers(bPtr, words);
+ };
+ CanvasKit.ParagraphBuilder.prototype.setWordsUtf16 = function(words) {
+ var bPtr = copy1dArray(words, 'HEAPU32');
+ this._setWordsUtf16(bPtr, words && words.length || 0);
+ freeArraysThatAreNotMallocedByUsers(bPtr, words);
+ };
+
+ CanvasKit.ParagraphBuilder.prototype.setGraphemeBreaksUtf8 = function(graphemeBreaks) {
+ var bPtr = copy1dArray(graphemeBreaks, 'HEAPU32');
+ this._setGraphemeBreaksUtf8(bPtr, graphemeBreaks && graphemeBreaks.length || 0);
+ freeArraysThatAreNotMallocedByUsers(bPtr, graphemeBreaks);
+ };
+ CanvasKit.ParagraphBuilder.prototype.setGraphemeBreaksUtf16 = function(graphemeBreaks) {
+ var bPtr = copy1dArray(graphemeBreaks, 'HEAPU32');
+ this._setGraphemeBreaksUtf16(bPtr, graphemeBreaks && graphemeBreaks.length || 0);
+ freeArraysThatAreNotMallocedByUsers(bPtr, graphemeBreaks);
+ };
+
+ CanvasKit.ParagraphBuilder.prototype.setLineBreaksUtf8 = function(lineBreaks) {
+ var bPtr = copy1dArray(lineBreaks, 'HEAPU32');
+ this._setLineBreaksUtf8(bPtr, lineBreaks && lineBreaks.length || 0);
+ freeArraysThatAreNotMallocedByUsers(bPtr, lineBreaks);
+ };
+ CanvasKit.ParagraphBuilder.prototype.setLineBreaksUtf16 = function(lineBreaks) {
+ var bPtr = copy1dArray(lineBreaks, 'HEAPU32');
+ this._setLineBreaksUtf16(bPtr, lineBreaks && lineBreaks.length || 0);
+ freeArraysThatAreNotMallocedByUsers(bPtr, lineBreaks);
};
});
}(Module)); // When this file is loaded in, the high level object is "Module";
diff --git a/modules/canvaskit/paragraph_bindings.cpp b/modules/canvaskit/paragraph_bindings.cpp
index 637b0f7..6c1e95b 100644
--- a/modules/canvaskit/paragraph_bindings.cpp
+++ b/modules/canvaskit/paragraph_bindings.cpp
@@ -592,24 +592,57 @@
auto text = self.getText();
return emscripten::val(std::string(text.data(), text.size()).c_str());
}))
- .function("_buildWithClientInfo",
+ .function("_setBidiRegionsUtf8",
optional_override([](para::ParagraphBuilderImpl& self,
- WASMPointerU32 clientBidis, size_t bidisNum,
- WASMPointerU32 clientWords, size_t wordsNum,
- WASMPointerU32 clientGraphemes, size_t graphemesNum,
- WASMPointerU32 clientLineBreaks, size_t lineBreaksNum) {
+ WASMPointerU32 clientBidis, size_t bidisNum) {
SkUnicode::Position* bidiData = reinterpret_cast<SkUnicode::Position*>(clientBidis);
std::vector<SkUnicode::BidiRegion> bidiRegions;
for (size_t i = 0; i < bidisNum; i += 3) {
auto start = bidiData[i];
auto end = bidiData[i+1];
- auto direction = SkToU8(bidiData[i+2]);
+ auto level = SkToU8(bidiData[i+2]);
- SkUnicode::BidiLevel level = direction == static_cast<int>(para::TextDirection::kLtr)
- ? static_cast<SkUnicode::BidiLevel>(SkUnicode::TextDirection::kLTR)
- : static_cast<SkUnicode::BidiLevel>(SkUnicode::TextDirection::kRTL);
bidiRegions.emplace_back(start, end, level);
}
+ self.setBidiRegionsUtf8(std::move(bidiRegions));
+ }))
+ .function("_setBidiRegionsUtf16",
+ optional_override([](para::ParagraphBuilderImpl& self,
+ WASMPointerU32 clientBidis, size_t bidisNum) {
+ SkUnicode::Position* bidiData = reinterpret_cast<SkUnicode::Position*>(clientBidis);
+ std::vector<SkUnicode::BidiRegion> bidiRegions;
+ for (size_t i = 0; i < bidisNum; i += 3) {
+ auto start = bidiData[i];
+ auto end = bidiData[i+1];
+ auto level = SkToU8(bidiData[i+2]);
+
+ bidiRegions.emplace_back(start, end, level);
+ }
+ self.setBidiRegionsUtf16(std::move(bidiRegions));
+ }))
+ .function("_setWordsUtf8",
+ optional_override([](para::ParagraphBuilderImpl& self,
+ WASMPointerU32 clientWords, size_t wordsNum) {
+ self.setWordsUtf8(convertArrayU32(clientWords, wordsNum));
+ }))
+ .function("_setWordsUtf16",
+ optional_override([](para::ParagraphBuilderImpl& self,
+ WASMPointerU32 clientWords, size_t wordsNum) {
+ self.setWordsUtf16(convertArrayU32(clientWords, wordsNum));
+ }))
+ .function("_setGraphemeBreaksUtf8",
+ optional_override([](para::ParagraphBuilderImpl& self,
+ WASMPointerU32 clientGraphemes, size_t graphemesNum) {
+ self.setGraphemeBreaksUtf8(convertArrayU32(clientGraphemes, graphemesNum));
+ }))
+ .function("_setGraphemeBreaksUtf16",
+ optional_override([](para::ParagraphBuilderImpl& self,
+ WASMPointerU32 clientGraphemes, size_t graphemesNum) {
+ self.setGraphemeBreaksUtf16(convertArrayU32(clientGraphemes, graphemesNum));
+ }))
+ .function("_setLineBreaksUtf8",
+ optional_override([](para::ParagraphBuilderImpl& self,
+ WASMPointerU32 clientLineBreaks, size_t lineBreaksNum) {
SkUnicode::Position* lineBreakData = reinterpret_cast<SkUnicode::Position*>(clientLineBreaks);
std::vector<SkUnicode::LineBreakBefore> lineBreaks;
for (size_t i = 0; i < lineBreaksNum; i += 2) {
@@ -621,11 +654,23 @@
lineBreaks.emplace_back(pos, SkUnicode::LineBreakType::kHardLineBreak);
}
}
- return self.BuildWithClientInfo(
- std::move(bidiRegions),
- convertArrayU32(clientWords, wordsNum),
- convertArrayU32(clientGraphemes, graphemesNum),
- std::move(lineBreaks));
+ self.setLineBreaksUtf8(std::move(lineBreaks));
+ }))
+ .function("_setLineBreaksUtf16",
+ optional_override([](para::ParagraphBuilderImpl& self,
+ WASMPointerU32 clientLineBreaks, size_t lineBreaksNum) {
+ SkUnicode::Position* lineBreakData = reinterpret_cast<SkUnicode::Position*>(clientLineBreaks);
+ std::vector<SkUnicode::LineBreakBefore> lineBreaks;
+ for (size_t i = 0; i < lineBreaksNum; i += 2) {
+ auto pos = lineBreakData[i];
+ auto breakType = lineBreakData[i+1];
+ if (breakType == 0) {
+ lineBreaks.emplace_back(pos, SkUnicode::LineBreakType::kSoftLineBreak);
+ } else {
+ lineBreaks.emplace_back(pos, SkUnicode::LineBreakType::kHardLineBreak);
+ }
+ }
+ self.setLineBreaksUtf16(std::move(lineBreaks));
}));
class_<para::TypefaceFontProvider, base<SkFontMgr>>("TypefaceFontProvider")
diff --git a/modules/skparagraph/src/ParagraphBuilderImpl.cpp b/modules/skparagraph/src/ParagraphBuilderImpl.cpp
index 96c56ba..8a5d268 100644
--- a/modules/skparagraph/src/ParagraphBuilderImpl.cpp
+++ b/modules/skparagraph/src/ParagraphBuilderImpl.cpp
@@ -40,7 +40,11 @@
, fUtf8()
, fFontCollection(std::move(fontCollection))
, fParagraphStyle(style)
- , fUnicode(std::move(unicode)) {
+ , fUnicode(std::move(unicode))
+#if !defined(SK_UNICODE_ICU_IMPLEMENTATION) && defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
+ , fUsingClientInfo(false)
+#endif
+{
startStyledBlock();
}
@@ -148,6 +152,19 @@
// Add one fake placeholder with the rest of the text
addPlaceholder(PlaceholderStyle(), true);
+
+#if !defined(SK_UNICODE_ICU_IMPLEMENTATION) && defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
+ SkASSERT(fUsingClientInfo);
+ fUTF8IndexForUTF16Index.clear();
+
+ // This is the place where SkUnicode is paired with SkParagraph
+ fUnicode = SkUnicode::MakeClientBasedUnicode(this->getText(),
+ std::move(fBidiRegionsUtf8),
+ std::move(fWordsUtf8),
+ std::move(fGraphemeBreaksUtf8),
+ std::move(fLineBreaksUtf8));
+#endif
+ SkASSERT(fUnicode);
return std::make_unique<ParagraphImpl>(
fUtf8, fParagraphStyle, fStyledBlocks, fPlaceholders, fFontCollection, fUnicode);
}
@@ -161,65 +178,123 @@
return fParagraphStyle;
}
-std::unique_ptr<Paragraph> ParagraphBuilderImpl::BuildWithClientInfo(
- std::vector<SkUnicode::BidiRegion> bidiRegionsUtf16,
- std::vector<SkUnicode::Position> wordsUtf16,
- std::vector<SkUnicode::Position> graphemeBreaksUtf16,
- std::vector<SkUnicode::LineBreakBefore> lineBreaksUtf16) {
-#ifndef SK_UNICODE_CLIENT_IMPLEMENTATION
- return nullptr;
-#else
- SkSpan text = SkSpan<char>(fUtf8.isEmpty() ? nullptr : &fUtf8[0], fUtf8.size());
-
- // TODO: This mapping is created twice. Here and in ParagraphImpl.cpp.
- SkTArray<TextIndex, true> utf8IndexForUtf16Index;
- SkUnicode::extractUtfConversionMapping(
- text,
- [&](size_t index) { utf8IndexForUtf16Index.emplace_back(index); },
+void ParagraphBuilderImpl::ensureUTF16Mapping() {
+ fillUTF16MappingOnce([&] {
+ SkUnicode::extractUtfConversionMapping(
+ this->getText(),
+ [&](size_t index) { fUTF8IndexForUTF16Index.emplace_back(index); },
[&](size_t index) {});
+ });
+}
+#if !defined(SK_UNICODE_ICU_IMPLEMENTATION) && defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
+void ParagraphBuilderImpl::setBidiRegionsUtf8(std::vector<SkUnicode::BidiRegion> bidiRegionsUtf8) {
+ fUsingClientInfo = true;
+ fBidiRegionsUtf8 = std::move(bidiRegionsUtf8);
+}
+
+void ParagraphBuilderImpl::setBidiRegionsUtf16(std::vector<SkUnicode::BidiRegion> bidiRegionsUtf16) {
+ ensureUTF16Mapping();
std::vector<SkUnicode::BidiRegion> bidiRegionsUtf8;
for (SkUnicode::BidiRegion bidiRegionUtf16: bidiRegionsUtf16) {
bidiRegionsUtf8.emplace_back(
- SkUnicode::BidiRegion(utf8IndexForUtf16Index[bidiRegionUtf16.start],
- utf8IndexForUtf16Index[bidiRegionUtf16.end],
+ SkUnicode::BidiRegion(fUTF8IndexForUTF16Index[bidiRegionUtf16.start],
+ fUTF8IndexForUTF16Index[bidiRegionUtf16.end],
bidiRegionUtf16.level));
}
+ setBidiRegionsUtf8(bidiRegionsUtf8);
+}
+void ParagraphBuilderImpl::setWordsUtf8(std::vector<SkUnicode::Position> wordsUtf8) {
+ fUsingClientInfo = true;
+ fWordsUtf8 = std::move(wordsUtf8);
+}
+
+void ParagraphBuilderImpl::setWordsUtf16(std::vector<SkUnicode::Position> wordsUtf16) {
+ ensureUTF16Mapping();
std::vector<SkUnicode::Position> wordsUtf8;
for (SkUnicode::Position indexUtf16: wordsUtf16) {
- wordsUtf8.emplace_back(utf8IndexForUtf16Index[indexUtf16]);
+ wordsUtf8.emplace_back(fUTF8IndexForUTF16Index[indexUtf16]);
}
+ setWordsUtf8(wordsUtf8);
+}
+void ParagraphBuilderImpl::setGraphemeBreaksUtf8(std::vector<SkUnicode::Position> graphemeBreaksUtf8) {
+ fUsingClientInfo = true;
+ fGraphemeBreaksUtf8 = std::move(graphemeBreaksUtf8);
+}
+
+void ParagraphBuilderImpl::setGraphemeBreaksUtf16(std::vector<SkUnicode::Position> graphemeBreaksUtf16) {
+ ensureUTF16Mapping();
std::vector<SkUnicode::Position> graphemeBreaksUtf8;
for (SkUnicode::Position indexUtf16: graphemeBreaksUtf16) {
- graphemeBreaksUtf8.emplace_back(utf8IndexForUtf16Index[indexUtf16]);
+ graphemeBreaksUtf8.emplace_back(fUTF8IndexForUTF16Index[indexUtf16]);
}
+ setGraphemeBreaksUtf8(graphemeBreaksUtf8);
+}
+void ParagraphBuilderImpl::setLineBreaksUtf8(std::vector<SkUnicode::LineBreakBefore> lineBreaksUtf8) {
+ fUsingClientInfo = true;
+ fLineBreaksUtf8 = std::move(lineBreaksUtf8);
+}
+
+void ParagraphBuilderImpl::setLineBreaksUtf16(std::vector<SkUnicode::LineBreakBefore> lineBreaksUtf16) {
+ ensureUTF16Mapping();
std::vector<SkUnicode::LineBreakBefore> lineBreaksUtf8;
for (SkUnicode::LineBreakBefore lineBreakUtf16: lineBreaksUtf16) {
lineBreaksUtf8.emplace_back(SkUnicode::LineBreakBefore(
- utf8IndexForUtf16Index[lineBreakUtf16.pos], lineBreakUtf16.breakType));
+ fUTF8IndexForUTF16Index[lineBreakUtf16.pos], lineBreakUtf16.breakType));
}
-
- utf8IndexForUtf16Index.clear();
-
- // This is the place where SkUnicode is paired with SkParagraph
- fUnicode = SkUnicode::MakeClientBasedUnicode(text,
- std::move(bidiRegionsUtf8),
- std::move(wordsUtf8),
- std::move(graphemeBreaksUtf8),
- std::move(lineBreaksUtf8));
- return this->Build();
-#endif
+ setLineBreaksUtf8(lineBreaksUtf8);
+}
+#else
+void ParagraphBuilderImpl::setBidiRegionsUtf8(std::vector<SkUnicode::BidiRegion> bidiRegionsUtf8) {
+ SkASSERT(false);
}
+void ParagraphBuilderImpl::setBidiRegionsUtf16(std::vector<SkUnicode::BidiRegion> bidiRegionsUtf16) {
+ SkASSERT(false);
+}
+
+void ParagraphBuilderImpl::setWordsUtf8(std::vector<SkUnicode::Position> wordsUtf8) {
+ SkASSERT(false);
+}
+
+void ParagraphBuilderImpl::setWordsUtf16(std::vector<SkUnicode::Position> wordsUtf16) {
+ SkASSERT(false);
+}
+
+void ParagraphBuilderImpl::setGraphemeBreaksUtf8(std::vector<SkUnicode::Position> graphemesUtf8) {
+ SkASSERT(false);
+}
+
+void ParagraphBuilderImpl::setGraphemeBreaksUtf16(std::vector<SkUnicode::Position> graphemesUtf16) {
+ SkASSERT(false);
+}
+
+void ParagraphBuilderImpl::setLineBreaksUtf8(std::vector<SkUnicode::LineBreakBefore> lineBreaksUtf8) {
+ SkASSERT(false);
+}
+
+void ParagraphBuilderImpl::setLineBreaksUtf16(std::vector<SkUnicode::LineBreakBefore> lineBreaksUtf16) {
+ SkASSERT(false);
+}
+#endif
+
void ParagraphBuilderImpl::Reset() {
+
fTextStyles.clear();
fUtf8.reset();
fStyledBlocks.clear();
fPlaceholders.clear();
+#if !defined(SK_UNICODE_ICU_IMPLEMENTATION) && defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
+ fUTF8IndexForUTF16Index.clear();
+ fBidiRegionsUtf8.clear();
+ fWordsUtf8.clear();
+ fGraphemeBreaksUtf8.clear();
+ fLineBreaksUtf8.clear();
+#endif
startStyledBlock();
}
diff --git a/modules/skparagraph/src/ParagraphBuilderImpl.h b/modules/skparagraph/src/ParagraphBuilderImpl.h
index 1b71b63..10273c2 100644
--- a/modules/skparagraph/src/ParagraphBuilderImpl.h
+++ b/modules/skparagraph/src/ParagraphBuilderImpl.h
@@ -6,6 +6,8 @@
#include <stack>
#include <string>
#include <tuple>
+#include "include/private/base/SkOnce.h"
+#include "include/private/base/SkTArray.h"
#include "modules/skparagraph/include/FontCollection.h"
#include "modules/skparagraph/include/Paragraph.h"
#include "modules/skparagraph/include/ParagraphBuilder.h"
@@ -62,11 +64,19 @@
// Support for "Client" unicode
SkSpan<char> getText();
const ParagraphStyle& getParagraphStyle() const;
- std::unique_ptr<Paragraph> BuildWithClientInfo(
- std::vector<SkUnicode::BidiRegion> bidiRegions,
- std::vector<SkUnicode::Position> words,
- std::vector<SkUnicode::Position> graphemeBreaks,
- std::vector<SkUnicode::LineBreakBefore> lineBreaks);
+
+ void setBidiRegionsUtf8(std::vector<SkUnicode::BidiRegion> bidiRegionsUtf8);
+ void setBidiRegionsUtf16(std::vector<SkUnicode::BidiRegion> bidiRegionsUtf16);
+
+ void setWordsUtf8(std::vector<SkUnicode::Position> wordsUtf8);
+ void setWordsUtf16(std::vector<SkUnicode::Position> wordsUtf16);
+
+ void setGraphemeBreaksUtf8(std::vector<SkUnicode::Position> graphemesUtf8);
+ void setGraphemeBreaksUtf16(std::vector<SkUnicode::Position> graphemesUtf16);
+
+ void setLineBreaksUtf8(std::vector<SkUnicode::LineBreakBefore> lineBreaksUtf8);
+ void setLineBreaksUtf16(std::vector<SkUnicode::LineBreakBefore> lineBreaksUtf16);
+
void SetUnicode(std::unique_ptr<SkUnicode> unicode) {
fUnicode = std::move(unicode);
}
@@ -94,6 +104,18 @@
ParagraphStyle fParagraphStyle;
std::shared_ptr<SkUnicode> fUnicode;
+
+private:
+ SkOnce fillUTF16MappingOnce;
+ void ensureUTF16Mapping();
+ SkTArray<TextIndex, true> fUTF8IndexForUTF16Index;
+#if !defined(SK_UNICODE_ICU_IMPLEMENTATION) && defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
+ bool fUsingClientInfo;
+ std::vector<SkUnicode::BidiRegion> fBidiRegionsUtf8;
+ std::vector<SkUnicode::Position> fWordsUtf8;
+ std::vector<SkUnicode::Position> fGraphemeBreaksUtf8;
+ std::vector<SkUnicode::LineBreakBefore> fLineBreaksUtf8;
+#endif
};
} // namespace textlayout
} // namespace skia