From 05ce2817f2a060caf8acd5be25b4f29875d63049 Mon Sep 17 00:00:00 2001 From: Julia Lavrova Date: Tue, 1 Sep 2020 20:51:05 +0000 Subject: [PATCH] Revert "Removing ICU dependencies from skparagraph BUILD.gn file" This reverts commit f1711adb1a04595eba1e9984976bfb92d41d0035. Reason for revert: Build break Original change's description: > Removing ICU dependencies from skparagraph BUILD.gn file > > (and from the sources, too) > > Change-Id: I9d8ff51c91aad4b770b1f183c04734d31252b851 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/313148 > Commit-Queue: Julia Lavrova > Reviewed-by: Ben Wagner TBR=bungeman@google.com,jlavrova@google.com Change-Id: I1fce2436855e3e2a4cb7d1d7204b3ae49fd530e8 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://skia-review.googlesource.com/c/skia/+/314540 Reviewed-by: Julia Lavrova Commit-Queue: Julia Lavrova --- modules/canvaskit/paragraph_bindings.cpp | 12 +-- modules/skparagraph/BUILD.gn | 70 +++++++++--------- modules/skparagraph/gm/simple_gm.cpp | 11 +-- .../skparagraph/include/ParagraphBuilder.h | 2 - modules/skparagraph/include/ParagraphStyle.h | 12 +-- .../skparagraph/samples/SampleParagraph.cpp | 19 ++--- modules/skparagraph/skparagraph.gni | 2 + modules/skparagraph/src/OneLineShaper.cpp | 11 +-- .../skparagraph/src/ParagraphBuilderImpl.cpp | 39 ++-------- .../skparagraph/src/ParagraphBuilderImpl.h | 15 ---- modules/skparagraph/src/ParagraphImpl.cpp | 56 ++++++-------- modules/skparagraph/src/ParagraphImpl.h | 12 +-- modules/skparagraph/src/ParagraphStyle.cpp | 8 +- modules/skparagraph/src/ParagraphUtil.cpp | 49 ++++++++++++ modules/skparagraph/src/ParagraphUtil.h | 17 +++++ modules/skparagraph/src/TextLine.cpp | 2 +- modules/skparagraph/src/TextWrapper.cpp | 3 +- modules/skshaper/BUILD.gn | 6 +- modules/skshaper/skshaper.gni | 4 - modules/skshaper/src/SkUnicode.h | 5 -- modules/skshaper/src/SkUnicode_icu.cpp | 74 ++++--------------- src/utils/SkUTF.cpp | 24 ------ src/utils/SkUTF.h | 7 -- third_party/icu/SkLoadICU.cpp | 2 +- 24 files changed, 191 insertions(+), 271 deletions(-) create mode 100644 modules/skparagraph/src/ParagraphUtil.cpp create mode 100644 modules/skparagraph/src/ParagraphUtil.h diff --git a/modules/canvaskit/paragraph_bindings.cpp b/modules/canvaskit/paragraph_bindings.cpp index 6c6b35196a..f5d59f3527 100644 --- a/modules/canvaskit/paragraph_bindings.cpp +++ b/modules/canvaskit/paragraph_bindings.cpp @@ -183,19 +183,21 @@ EMSCRIPTEN_BINDINGS(Paragraph) { .function("layout", ¶::ParagraphImpl::layout); class_("ParagraphBuilder") - .class_function("_Make", optional_override([](SimpleParagraphStyle style, sk_sp fontMgr) - -> std::unique_ptr { + .class_function("_Make", optional_override([](SimpleParagraphStyle style, + sk_sp fontMgr)-> para::ParagraphBuilderImpl { auto fc = sk_make_sp(); fc->setDefaultFontManager(fontMgr); auto ps = toParagraphStyle(style); - return para::ParagraphBuilderImpl::make(ps, fc); + para::ParagraphBuilderImpl pbi(ps, fc); + return pbi; }), allow_raw_pointers()) .class_function("_MakeFromFontProvider", optional_override([](SimpleParagraphStyle style, - sk_sp fontProvider)-> std::unique_ptr { + sk_sp fontProvider)-> para::ParagraphBuilderImpl { auto fc = sk_make_sp(); fc->setDefaultFontManager(fontProvider); auto ps = toParagraphStyle(style); - return para::ParagraphBuilderImpl::make(ps, fc); + para::ParagraphBuilderImpl pbi(ps, fc); + return pbi; }), allow_raw_pointers()) .function("addText", optional_override([](para::ParagraphBuilderImpl& self, std::string text) { return self.addText(text.c_str(), text.length()); diff --git a/modules/skparagraph/BUILD.gn b/modules/skparagraph/BUILD.gn index e8a8b48df6..48e09296c8 100644 --- a/modules/skparagraph/BUILD.gn +++ b/modules/skparagraph/BUILD.gn @@ -1,7 +1,6 @@ # Copyright 2019 Google LLC. import("../../gn/skia.gni") -import("../skshaper/skshaper.gni") declare_args() { skia_enable_skparagraph = true @@ -10,8 +9,7 @@ declare_args() { paragraph_bench_enabled = false } -if (skia_enable_skparagraph && skia_enable_skshaper && skia_use_icu && - skia_use_harfbuzz) { +if (skia_enable_skparagraph) { config("public_config") { include_dirs = [ "include", @@ -23,10 +21,16 @@ if (skia_enable_skparagraph && skia_enable_skshaper && skia_use_icu && import("skparagraph.gni") public_configs = [ ":public_config" ] public = skparagraph_public - sources = skparagraph_sources + if (skia_use_icu && skia_use_harfbuzz) { + sources = skparagraph_sources + configs += [ "../../third_party/icu/config:no_cxx" ] + } else { + sources = [] + } deps = [ "../..:skia", "../skshaper", + "//third_party/icu", ] } @@ -39,15 +43,21 @@ if (skia_enable_skparagraph && skia_enable_skshaper && skia_use_icu && import("skparagraph.gni") public_configs = [ ":utils_config" ] configs += [ "../../:skia_private" ] - sources = skparagraph_utils + if (skia_use_icu && skia_use_harfbuzz) { + sources = skparagraph_utils + configs += [ "../../third_party/icu/config:no_cxx" ] + } else { + sources = [] + } deps = [ "../..:skia", "../skshaper", + "//third_party/icu", ] } source_set("gm") { - if (paragraph_gms_enabled) { + if (skia_use_icu && skia_use_harfbuzz && paragraph_gms_enabled) { testonly = true sources = [ "gm/simple_gm.cpp" ] deps = [ @@ -55,63 +65,53 @@ if (skia_enable_skparagraph && skia_enable_skshaper && skia_use_icu && "../..:gpu_tool_utils", "../..:skia", "../skshaper", + "//third_party/icu", ] - } else { - sources = [] } } source_set("tests") { - if (paragraph_tests_enabled) { + if (skia_use_icu && skia_use_harfbuzz && paragraph_tests_enabled) { testonly = true sources = [ "tests/SkParagraphTest.cpp" ] + configs += [ "../../third_party/icu/config:no_cxx" ] deps = [ ":skparagraph", "../..:gpu_tool_utils", "../..:skia", "../skshaper", + "//third_party/icu", ] - } else { - sources = [] } } source_set("bench") { - if (paragraph_bench_enabled) { + if (skia_use_icu && skia_use_harfbuzz && paragraph_bench_enabled) { testonly = true sources = [ "bench/ParagraphBench.cpp" ] + configs += [ "../../third_party/icu/config:no_cxx" ] deps = [ ":skparagraph", "../..:skia", "../skshaper", + "//third_party/icu", ] - } else { - sources = [] } } source_set("samples") { - testonly = true - sources = [ "samples/SampleParagraph.cpp" ] - deps = [ - ":skparagraph", - ":utils", - "../..:skia", - "../skshaper", - ] + if (skia_use_icu && skia_use_harfbuzz) { + testonly = true + sources = [ "samples/SampleParagraph.cpp" ] + configs += [ "../../third_party/icu/config:no_cxx" ] + deps = [ + ":skparagraph", + ":utils", + "../..:skia", + "../skshaper", + "//third_party/icu", + ] + } } } -} else { - group("skparagraph") { - } - group("utils") { - } - group("gm") { - } - group("tests") { - } - group("bench") { - } - group("samples") { - } } diff --git a/modules/skparagraph/gm/simple_gm.cpp b/modules/skparagraph/gm/simple_gm.cpp index 00a1766c63..38af4f7543 100644 --- a/modules/skparagraph/gm/simple_gm.cpp +++ b/modules/skparagraph/gm/simple_gm.cpp @@ -21,7 +21,7 @@ #include "tools/ToolUtils.h" #include "modules/skparagraph/include/Paragraph.h" -#include "modules/skparagraph/src/ParagraphBuilderImpl.h" +#include "modules/skparagraph/include/ParagraphBuilder.h" static const char* gSpeach = "Five score years ago, a great American, in whose symbolic shadow we stand today, signed the Emancipation Proclamation. This momentous decree came as a great beacon light of hope to millions of Negro slaves who had been seared in the flames of withering injustice. It came as a joyous daybreak to end the long night of their captivity."; @@ -57,11 +57,7 @@ public: auto collection = sk_make_sp(); collection->setDefaultFontManager(SkFontMgr::RefDefault()); - auto builder = skia::textlayout::ParagraphBuilderImpl::make(paraStyle, collection); - if (nullptr == builder) { - fPara = nullptr; - return; - } + auto builder = skia::textlayout::ParagraphBuilder::make(paraStyle, collection); builder->addText(gSpeach, strlen(gSpeach)); @@ -85,9 +81,6 @@ protected: SkISize onISize() override { return SkISize::Make(412, 420); } DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override { - if (nullptr == fPara) { - return DrawResult::kSkip; - } const int loop = (this->getMode() == kGM_Mode) ? 1 : 50; int parity = 0; diff --git a/modules/skparagraph/include/ParagraphBuilder.h b/modules/skparagraph/include/ParagraphBuilder.h index 816691bda4..1f1e0ed768 100644 --- a/modules/skparagraph/include/ParagraphBuilder.h +++ b/modules/skparagraph/include/ParagraphBuilder.h @@ -57,8 +57,6 @@ public: // Constructs a SkParagraph object that can be used to layout and paint the text to a SkCanvas. virtual std::unique_ptr Build() = 0; - - // Just until we fix all the google3 code static std::unique_ptr make(const ParagraphStyle& style, sk_sp fontCollection); }; diff --git a/modules/skparagraph/include/ParagraphStyle.h b/modules/skparagraph/include/ParagraphStyle.h index 37ccbc32ff..d075432959 100644 --- a/modules/skparagraph/include/ParagraphStyle.h +++ b/modules/skparagraph/include/ParagraphStyle.h @@ -72,9 +72,7 @@ struct ParagraphStyle { ParagraphStyle(); bool operator==(const ParagraphStyle& rhs) const { - return this->fHeight == rhs.fHeight && - this->fEllipsis == rhs.fEllipsis && - this->fEllipsisUtf16 == rhs.fEllipsisUtf16 && + return this->fHeight == rhs.fHeight && this->fEllipsis == rhs.fEllipsis && this->fTextDirection == rhs.fTextDirection && this->fTextAlign == rhs.fTextAlign && this->fDefaultTextStyle == rhs.fDefaultTextStyle; } @@ -94,9 +92,8 @@ struct ParagraphStyle { size_t getMaxLines() const { return fLinesLimit; } void setMaxLines(size_t maxLines) { fLinesLimit = maxLines; } - SkString getEllipsis() const { return fEllipsis; } - std::u16string getEllipsisUtf16() const { return fEllipsisUtf16; } - void setEllipsis(const std::u16string& ellipsis) { fEllipsisUtf16 = ellipsis; } + const SkString& getEllipsis() const { return fEllipsis; } + void setEllipsis(const std::u16string& ellipsis); void setEllipsis(const SkString& ellipsis) { fEllipsis = ellipsis; } SkScalar getHeight() const { return fHeight; } @@ -108,7 +105,7 @@ struct ParagraphStyle { bool unlimited_lines() const { return fLinesLimit == std::numeric_limits::max(); } - bool ellipsized() const { return !fEllipsis.isEmpty() || !fEllipsisUtf16.empty(); } + bool ellipsized() const { return fEllipsis.size() != 0; } TextAlign effective_align() const; bool hintingIsOn() const { return fHintingIsOn; } void turnHintingOff() { fHintingIsOn = false; } @@ -121,7 +118,6 @@ private: TextAlign fTextAlign; TextDirection fTextDirection; size_t fLinesLimit; - std::u16string fEllipsisUtf16; SkString fEllipsis; SkScalar fHeight; TextHeightBehavior fTextHeightBehavior; diff --git a/modules/skparagraph/samples/SampleParagraph.cpp b/modules/skparagraph/samples/SampleParagraph.cpp index d9e895cbb2..71e879d14b 100644 --- a/modules/skparagraph/samples/SampleParagraph.cpp +++ b/modules/skparagraph/samples/SampleParagraph.cpp @@ -17,9 +17,9 @@ #include "modules/skparagraph/include/TypefaceFontProvider.h" #include "modules/skparagraph/src/ParagraphBuilderImpl.h" #include "modules/skparagraph/src/ParagraphImpl.h" +#include "modules/skparagraph/src/ParagraphUtil.h" #include "modules/skparagraph/src/TextLine.h" #include "modules/skparagraph/utils/TestFontCollection.h" -#include "modules/skshaper/src/SkUnicode.h" #include "samplecode/Sample.h" #include "src/core/SkOSFile.h" #include "src/shaders/SkColorShader.h" @@ -28,6 +28,7 @@ #include "tools/Resources.h" #include "tools/flags/CommandLineFlags.h" + static DEFINE_bool(verboseParagraph, false, "paragraph samples very verbose."); using namespace skia::textlayout; @@ -745,15 +746,14 @@ protected: builder.addText(text4); builder.pop(); } else { + if (this->isVerbose()) { + SkString str = SkStringFromU16String(text); + SkDebugf("Text: %s\n", str.c_str()); + } builder.addText(text + expected); } auto paragraph = builder.Build(); - auto impl = static_cast(paragraph.get()); - if (this->isVerbose()) { - SkDebugf("Text: >%s<\n", impl->text().data()); - } - paragraph->layout(w - margin * 2); paragraph->paint(canvas, margin, margin); } @@ -1608,14 +1608,15 @@ protected: ParagraphBuilderImpl builder(paragraph_style, fontCollection); builder.pushStyle(text_style); auto utf16text = zalgo.zalgo("SkParagraph"); + if (this->isVerbose()) { + SkString str = SkStringFromU16String(utf16text); + SkDebugf("Text:>%s<\n", str.c_str()); + } builder.addText(utf16text); fParagraph = builder.Build(); } auto impl = static_cast(fParagraph.get()); - if (this->isVerbose()) { - SkDebugf("Text:>%s<\n", impl->text().data()); - } impl->setState(InternalState::kUnknown); fParagraph->layout(1000); fParagraph->paint(canvas, 300, 200); diff --git a/modules/skparagraph/skparagraph.gni b/modules/skparagraph/skparagraph.gni index df0091cc8f..0221d78680 100644 --- a/modules/skparagraph/skparagraph.gni +++ b/modules/skparagraph/skparagraph.gni @@ -31,6 +31,8 @@ skparagraph_sources = [ "$_src/ParagraphImpl.cpp", "$_src/ParagraphImpl.h", "$_src/ParagraphStyle.cpp", + "$_src/ParagraphUtil.cpp", + "$_src/ParagraphUtil.h", "$_src/Run.cpp", "$_src/Run.h", "$_src/TextLine.cpp", diff --git a/modules/skparagraph/src/OneLineShaper.cpp b/modules/skparagraph/src/OneLineShaper.cpp index 45c622cc7f..d2a8ec225a 100644 --- a/modules/skparagraph/src/OneLineShaper.cpp +++ b/modules/skparagraph/src/OneLineShaper.cpp @@ -2,15 +2,10 @@ #include "modules/skparagraph/src/Iterators.h" #include "modules/skparagraph/src/OneLineShaper.h" -#include "src/utils/SkUTF.h" +#include "modules/skparagraph/src/ParagraphUtil.h" #include #include -static inline SkUnichar nextUtf8Unit(const char** ptr, const char* end) { - SkUnichar val = SkUTF::NextUTF8(ptr, end); - return val < 0 ? 0xFFFD : val; -} - namespace skia { namespace textlayout { @@ -302,8 +297,8 @@ void OneLineShaper::sortOutGlyphs(std::function&& sortOutUnres const char* cluster = text.begin() + clusterIndex(i); SkUnichar codepoint = nextUtf8Unit(&cluster, text.end()); - bool isControl8 = fParagraph->getUnicode()->isControl(codepoint); - bool isWhitespace8 = fParagraph->getUnicode()->isWhitespace(codepoint); + bool isControl8 = isControl(codepoint); + bool isWhitespace8 = isWhitespace(codepoint); // Inspect the glyph auto glyph = fCurrentRun->fGlyphs[i]; diff --git a/modules/skparagraph/src/ParagraphBuilderImpl.cpp b/modules/skparagraph/src/ParagraphBuilderImpl.cpp index 1502012dbd..5f904e9489 100644 --- a/modules/skparagraph/src/ParagraphBuilderImpl.cpp +++ b/modules/skparagraph/src/ParagraphBuilderImpl.cpp @@ -8,50 +8,24 @@ #include "modules/skparagraph/include/TextStyle.h" #include "modules/skparagraph/src/ParagraphBuilderImpl.h" #include "modules/skparagraph/src/ParagraphImpl.h" +#include "modules/skparagraph/src/ParagraphUtil.h" #include #include -#include "src/core/SkStringUtils.h" namespace skia { namespace textlayout { std::unique_ptr ParagraphBuilder::make( const ParagraphStyle& style, sk_sp fontCollection) { - return ParagraphBuilderImpl::make(style, fontCollection); -} - -std::unique_ptr ParagraphBuilderImpl::make( - const ParagraphStyle& style, sk_sp fontCollection) { - auto unicode = SkUnicode::Make(); - if (nullptr == unicode) { - return nullptr; - } return std::make_unique(style, fontCollection); } -std::unique_ptr ParagraphBuilderImpl::make( - const ParagraphStyle& style, sk_sp fontCollection, std::unique_ptr unicode) { - if (nullptr == unicode) { - return nullptr; - } - return std::make_unique(style, fontCollection, std::move(unicode)); -} - -ParagraphBuilderImpl::ParagraphBuilderImpl( - const ParagraphStyle& style, sk_sp fontCollection, std::unique_ptr unicode) - : ParagraphBuilder(style, fontCollection) - , fUtf8() - , fFontCollection(std::move(fontCollection)) - , fUnicode(std::move(unicode)) { - SkASSERT(fUnicode); - this->setParagraphStyle(style); -} - ParagraphBuilderImpl::ParagraphBuilderImpl( const ParagraphStyle& style, sk_sp fontCollection) - : ParagraphBuilderImpl(style, fontCollection, SkUnicode::Make()) -{ } + : ParagraphBuilder(style, fontCollection), fUtf8(), fFontCollection(std::move(fontCollection)) { + this->setParagraphStyle(style); +} ParagraphBuilderImpl::~ParagraphBuilderImpl() = default; @@ -100,8 +74,7 @@ TextStyle ParagraphBuilderImpl::peekStyle() { } void ParagraphBuilderImpl::addText(const std::u16string& text) { - auto utf8 = fUnicode->convertUtf16ToUtf8(text); - fUtf8.append(utf8); + fUtf8.append(SkStringFromU16String(text)); } void ParagraphBuilderImpl::addText(const char* text) { @@ -155,7 +128,7 @@ std::unique_ptr ParagraphBuilderImpl::Build() { // Add one fake placeholder with the rest of the text addPlaceholder(PlaceholderStyle(), true); return std::make_unique( - fUtf8, fParagraphStyle, fStyledBlocks, fPlaceholders, fFontCollection, std::move(fUnicode)); + fUtf8, fParagraphStyle, fStyledBlocks, fPlaceholders, fFontCollection); } } // namespace textlayout diff --git a/modules/skparagraph/src/ParagraphBuilderImpl.h b/modules/skparagraph/src/ParagraphBuilderImpl.h index 49a24c409f..644769e1f2 100644 --- a/modules/skparagraph/src/ParagraphBuilderImpl.h +++ b/modules/skparagraph/src/ParagraphBuilderImpl.h @@ -11,18 +11,12 @@ #include "modules/skparagraph/include/ParagraphBuilder.h" #include "modules/skparagraph/include/ParagraphStyle.h" #include "modules/skparagraph/include/TextStyle.h" -#include "modules/skshaper/src/SkUnicode.h" namespace skia { namespace textlayout { class ParagraphBuilderImpl : public ParagraphBuilder { public: - ParagraphBuilderImpl(const ParagraphStyle& style, - sk_sp fontCollection, - std::unique_ptr unicode); - - // Just until we fix all the code; calls icu::make inside ParagraphBuilderImpl(const ParagraphStyle& style, sk_sp fontCollection); ~ParagraphBuilderImpl() override; @@ -61,13 +55,6 @@ public: // Constructs a SkParagraph object that can be used to layout and paint the text to a SkCanvas. std::unique_ptr Build() override; - static std::unique_ptr make(const ParagraphStyle& style, - sk_sp fontCollection, - std::unique_ptr unicode); - - // Just until we fix all the code; calls icu::make inside - static std::unique_ptr make(const ParagraphStyle& style, - sk_sp fontCollection); private: void endRunIfNeeded(); void addPlaceholder(const PlaceholderStyle& placeholderStyle, bool lastOne); @@ -78,8 +65,6 @@ private: SkTArray fPlaceholders; sk_sp fFontCollection; ParagraphStyle fParagraphStyle; - - std::unique_ptr fUnicode; }; } // namespace textlayout } // namespace skia diff --git a/modules/skparagraph/src/ParagraphImpl.cpp b/modules/skparagraph/src/ParagraphImpl.cpp index 07148c57dd..42c3fcc3b8 100644 --- a/modules/skparagraph/src/ParagraphImpl.cpp +++ b/modules/skparagraph/src/ParagraphImpl.cpp @@ -13,11 +13,17 @@ #include "modules/skparagraph/include/TextStyle.h" #include "modules/skparagraph/src/OneLineShaper.h" #include "modules/skparagraph/src/ParagraphImpl.h" +#include "modules/skparagraph/src/ParagraphUtil.h" #include "modules/skparagraph/src/Run.h" #include "modules/skparagraph/src/TextLine.h" #include "modules/skparagraph/src/TextWrapper.h" #include "src/core/SkSpan.h" #include "src/utils/SkUTF.h" + +#if defined(SK_USING_THIRD_PARTY_ICU) +#include "third_party/icu/SkLoadICU.h" +#endif + #include #include #include @@ -65,8 +71,7 @@ ParagraphImpl::ParagraphImpl(const SkString& text, ParagraphStyle style, SkTArray blocks, SkTArray placeholders, - sk_sp fonts, - std::unique_ptr unicode) + sk_sp fonts) : Paragraph(std::move(style), std::move(fonts)) , fTextStyles(std::move(blocks)) , fPlaceholders(std::move(placeholders)) @@ -76,28 +81,21 @@ ParagraphImpl::ParagraphImpl(const SkString& text, , fPicture(nullptr) , fStrutMetrics(false) , fOldWidth(0) - , fOldHeight(0) - , fUnicode(std::move(unicode)) -{ - SkASSERT(fUnicode); + , fOldHeight(0) { + fICU = SkUnicode::Make(); } ParagraphImpl::ParagraphImpl(const std::u16string& utf16text, ParagraphStyle style, SkTArray blocks, SkTArray placeholders, - sk_sp fonts, - std::unique_ptr unicode) - : ParagraphImpl(SkString(), + sk_sp fonts) + : ParagraphImpl(SkStringFromU16String(utf16text), std::move(style), std::move(blocks), std::move(placeholders), - std::move(fonts), - std::move(unicode)) -{ - SkASSERT(fUnicode); - fText = fUnicode->convertUtf16ToUtf8(utf16text); -} + std::move(fonts)) +{ } ParagraphImpl::~ParagraphImpl() = default; @@ -247,23 +245,26 @@ void ParagraphImpl::resetContext() { } // shapeTextIntoEndlessLine is the thing that calls this method +// (that contains all ICU dependencies except for words) bool ParagraphImpl::computeCodeUnitProperties() { - if (nullptr == fUnicode) { + #if defined(SK_USING_THIRD_PARTY_ICU) + if (!SkLoadICU()) { return false; } + #endif // Get bidi regions auto textDirection = fParagraphStyle.getTextDirection() == TextDirection::kLtr ? SkUnicode::TextDirection::kLTR : SkUnicode::TextDirection::kRTL; - if (!fUnicode->getBidiRegions(fText.c_str(), fText.size(), textDirection, &fBidiRegions)) { + if (!fICU->getBidiRegions(fText.c_str(), fText.size(), textDirection, &fBidiRegions)) { return false; } // Get white spaces std::vector whitespaces; - if (!fUnicode->getWhitespaces(fText.c_str(), fText.size(), &whitespaces)) { + if (!fICU->getWhitespaces(fText.c_str(), fText.size(), &whitespaces)) { return false; } for (auto whitespace : whitespaces) { @@ -272,7 +273,7 @@ bool ParagraphImpl::computeCodeUnitProperties() { // Get line breaks std::vector lineBreaks; - if (!fUnicode->getLineBreaks(fText.c_str(), fText.size(), &lineBreaks)) { + if (!fICU->getLineBreaks(fText.c_str(), fText.size(), &lineBreaks)) { return false; } for (auto& lineBreak : lineBreaks) { @@ -283,7 +284,7 @@ bool ParagraphImpl::computeCodeUnitProperties() { // Get graphemes std::vector graphemes; - if (!fUnicode->getGraphemes(fText.c_str(), fText.size(), &graphemes)) { + if (!fICU->getGraphemes(fText.c_str(), fText.size(), &graphemes)) { return false; } for (auto pos : graphemes) { @@ -430,7 +431,7 @@ void ParagraphImpl::breakShapedTextIntoLines(SkScalar maxWidth) { // TODO: Take in account clipped edges auto& line = this->addLine(offset, advance, text, textWithSpaces, clusters, clustersWithGhosts, widthWithSpaces, metrics); if (addEllipsis) { - line.createEllipsis(maxWidth, getEllipsis(), true); + line.createEllipsis(maxWidth, fParagraphStyle.getEllipsis(), true); } fLongestLine = std::max(fLongestLine, nearlyZero(advance.fX) ? widthWithSpaces : advance.fX); @@ -687,7 +688,7 @@ PositionWithAffinity ParagraphImpl::getGlyphPositionAtCoordinate(SkScalar dx, Sk SkRange ParagraphImpl::getWordBoundary(unsigned offset) { if (fWords.empty()) { - if (!fUnicode->getWords(fText.c_str(), fText.size(), &fWords)) { + if (!fICU->getWords(fText.c_str(), fText.size(), &fWords)) { return {0, 0 }; } } @@ -838,17 +839,6 @@ void ParagraphImpl::computeEmptyMetrics() { } } -SkString ParagraphImpl::getEllipsis() const { - - auto ellipsis8 = fParagraphStyle.getEllipsis(); - auto ellipsis16 = fParagraphStyle.getEllipsisUtf16(); - if (!ellipsis8.isEmpty()) { - return ellipsis8; - } else { - return fUnicode->convertUtf16ToUtf8(fParagraphStyle.getEllipsisUtf16()); - } -} - void ParagraphImpl::updateText(size_t from, SkString text) { fText.remove(from, from + text.size()); fText.insert(from, text); diff --git a/modules/skparagraph/src/ParagraphImpl.h b/modules/skparagraph/src/ParagraphImpl.h index 19ad4a447d..420c345bf7 100644 --- a/modules/skparagraph/src/ParagraphImpl.h +++ b/modules/skparagraph/src/ParagraphImpl.h @@ -100,15 +100,13 @@ public: ParagraphStyle style, SkTArray blocks, SkTArray placeholders, - sk_sp fonts, - std::unique_ptr unicode); + sk_sp fonts); ParagraphImpl(const std::u16string& utf16text, ParagraphStyle style, SkTArray blocks, SkTArray placeholders, - sk_sp fonts, - std::unique_ptr unicode); + sk_sp fonts); ~ParagraphImpl() override; void layout(SkScalar width) override; @@ -157,8 +155,6 @@ public: } InternalLineMetrics strutMetrics() const { return fStrutMetrics; } - SkString getEllipsis() const; - SkSpan text(TextRange textRange); SkSpan clusters(ClusterRange clusterRange); Cluster& cluster(ClusterIndex clusterIndex); @@ -222,7 +218,7 @@ public: bool codeUnitHasProperty(size_t index, CodeUnitFlags property) const { return (fCodeUnitProperties[index] & property) == property; } - SkUnicode* getUnicode() { return fUnicode.get(); } + SkUnicode* getICU() { return fICU.get(); } private: friend class ParagraphBuilder; @@ -272,7 +268,7 @@ private: SkScalar fOldHeight; SkScalar fMaxWidthWithTrailingSpaces; - std::unique_ptr fUnicode; + std::unique_ptr fICU; }; } // namespace textlayout } // namespace skia diff --git a/modules/skparagraph/src/ParagraphStyle.cpp b/modules/skparagraph/src/ParagraphStyle.cpp index 4e3094f472..c40372dce0 100644 --- a/modules/skparagraph/src/ParagraphStyle.cpp +++ b/modules/skparagraph/src/ParagraphStyle.cpp @@ -2,9 +2,7 @@ #include "modules/skparagraph/include/DartTypes.h" #include "modules/skparagraph/include/ParagraphStyle.h" -#include "modules/skshaper/src/SkUnicode.h" -#include "src/core/SkStringUtils.h" -#include "src/utils/SkUTF.h" +#include "modules/skparagraph/src/ParagraphUtil.h" namespace skia { namespace textlayout { @@ -37,5 +35,9 @@ TextAlign ParagraphStyle::effective_align() const { return fTextAlign; } } + +void ParagraphStyle::setEllipsis(const std::u16string& ellipsis) { + fEllipsis = SkStringFromU16String(ellipsis); +} } // namespace textlayout } // namespace skia diff --git a/modules/skparagraph/src/ParagraphUtil.cpp b/modules/skparagraph/src/ParagraphUtil.cpp new file mode 100644 index 0000000000..f7b78a710f --- /dev/null +++ b/modules/skparagraph/src/ParagraphUtil.cpp @@ -0,0 +1,49 @@ +// Copyright 2019 Google LLC. + +#include "include/core/SkString.h" +#include "include/core/SkTypes.h" +#include "include/private/SkTo.h" +#include "modules/skparagraph/src/ParagraphUtil.h" +#include "src/utils/SkUTF.h" + +#include +#include +#include +#include +#include + +namespace skia { +namespace textlayout { + +SkString SkStringFromU16String(const std::u16string& utf16text) { + SkString dst; + UErrorCode status = U_ZERO_ERROR; + int32_t dstSize; + // Getting the length like this seems to always set U_BUFFER_OVERFLOW_ERROR + u_strToUTF8(nullptr, 0, &dstSize, (UChar*)utf16text.data(), SkToS32(utf16text.size()), &status); + dst.resize(dstSize); + status = U_ZERO_ERROR; + u_strToUTF8(dst.writable_str(), dst.size(), nullptr, + (UChar*)utf16text.data(), SkToS32(utf16text.size()), &status); + if (U_FAILURE(status)) { + SkDEBUGF("Invalid UTF-16 input: %s", u_errorName(status)); + return dst; + } + return dst; +} + +SkUnichar nextUtf8Unit(const char** ptr, const char* end) { + SkUnichar val = SkUTF::NextUTF8(ptr, end); + return val < 0 ? 0xFFFD : val; +} + +bool isControl(SkUnichar utf8) { + return u_iscntrl(utf8); +} + +bool isWhitespace(SkUnichar utf8) { + return u_isWhitespace(utf8); +} + +} // namespace textlayout +} // namespace skia diff --git a/modules/skparagraph/src/ParagraphUtil.h b/modules/skparagraph/src/ParagraphUtil.h new file mode 100644 index 0000000000..3b6432f67f --- /dev/null +++ b/modules/skparagraph/src/ParagraphUtil.h @@ -0,0 +1,17 @@ +// Copyright 2020 Google LLC. +#ifndef ParagraphUtil_DEFINED +#define ParagraphUtil_DEFINED + +#include "include/core/SkString.h" +#include + +namespace skia { +namespace textlayout { +SkString SkStringFromU16String(const std::u16string& utf16text); +SkUnichar nextUtf8Unit(const char** ptr, const char* end); +bool isControl(SkUnichar utf8); +bool isWhitespace(SkUnichar utf8); +} // namespace textlayout +} // namespace skia + +#endif diff --git a/modules/skparagraph/src/TextLine.cpp b/modules/skparagraph/src/TextLine.cpp index e18f227a94..50047a64b0 100644 --- a/modules/skparagraph/src/TextLine.cpp +++ b/modules/skparagraph/src/TextLine.cpp @@ -144,7 +144,7 @@ TextLine::TextLine(ParagraphImpl* owner, SkAutoSTArray logicalOrder(numRuns); // TODO: hide all these logic in SkUnicode? - fOwner->getUnicode()->reorderVisual(runLevels.data(), numRuns, logicalOrder.data()); + fOwner->getICU()->reorderVisual(runLevels.data(), numRuns, logicalOrder.data()); auto firstRunIndex = start.runIndex(); for (auto index : logicalOrder) { fRunsInVisualOrder.push_back(firstRunIndex + index); diff --git a/modules/skparagraph/src/TextWrapper.cpp b/modules/skparagraph/src/TextWrapper.cpp index 7f7b73a8ee..747b2ffeb6 100644 --- a/modules/skparagraph/src/TextWrapper.cpp +++ b/modules/skparagraph/src/TextWrapper.cpp @@ -224,10 +224,11 @@ void TextWrapper::breakTextIntoLines(ParagraphImpl* parent, return; } auto maxLines = parent->paragraphStyle().getMaxLines(); + auto& ellipsisStr = parent->paragraphStyle().getEllipsis(); auto align = parent->paragraphStyle().effective_align(); auto unlimitedLines = maxLines == std::numeric_limits::max(); auto endlessLine = !SkScalarIsFinite(maxWidth); - auto hasEllipsis = parent->paragraphStyle().ellipsized(); + auto hasEllipsis = !ellipsisStr.isEmpty(); SkScalar softLineMaxIntrinsicWidth = 0; fEndLine = TextStretch(span.begin(), span.begin(), parent->strutForceHeight()); diff --git a/modules/skshaper/BUILD.gn b/modules/skshaper/BUILD.gn index 57160c1c19..5acd98151b 100644 --- a/modules/skshaper/BUILD.gn +++ b/modules/skshaper/BUILD.gn @@ -4,7 +4,10 @@ # found in the LICENSE file. import("../../gn/skia.gni") -import("skshaper.gni") + +declare_args() { + skia_enable_skshaper = true +} if (skia_enable_skshaper) { config("public_config") { @@ -24,6 +27,7 @@ if (skia_enable_skshaper) { component("skshaper") { check_includes = false + import("skshaper.gni") public_configs = [ ":public_config" ] public = skia_shaper_public deps = [ "../..:skia" ] diff --git a/modules/skshaper/skshaper.gni b/modules/skshaper/skshaper.gni index 27c9624f78..0618b630a1 100644 --- a/modules/skshaper/skshaper.gni +++ b/modules/skshaper/skshaper.gni @@ -19,7 +19,3 @@ skia_shaper_icu_sources = [ ] skia_shaper_harfbuzz_sources = [ "$_src/SkShaper_harfbuzz.cpp" ] skia_shaper_coretext_sources = [ "$_src/SkShaper_coretext.cpp" ] - -declare_args() { - skia_enable_skshaper = true -} diff --git a/modules/skshaper/src/SkUnicode.h b/modules/skshaper/src/SkUnicode.h index 5414ed26fb..3bbb02ed06 100644 --- a/modules/skshaper/src/SkUnicode.h +++ b/modules/skshaper/src/SkUnicode.h @@ -9,7 +9,6 @@ #include "include/core/SkTypes.h" #include "src/core/SkSpan.h" -#include "src/utils/SkUTF.h" #include #if !defined(SKUNICODE_IMPLEMENTATION) @@ -90,10 +89,6 @@ class SKUNICODE_API SkUnicode { virtual ~SkUnicode() = default; - virtual bool isControl(SkUnichar utf8) = 0; - virtual bool isWhitespace(SkUnichar utf8) = 0; - virtual SkString convertUtf16ToUtf8(const std::u16string& utf16) = 0; - // Iterators (used in SkShaper) virtual std::unique_ptr makeBidiIterator (const uint16_t text[], int count, SkBidiIterator::Direction) = 0; diff --git a/modules/skshaper/src/SkUnicode_icu.cpp b/modules/skshaper/src/SkUnicode_icu.cpp index 13de14d131..1a859fed55 100644 --- a/modules/skshaper/src/SkUnicode_icu.cpp +++ b/modules/skshaper/src/SkUnicode_icu.cpp @@ -4,23 +4,17 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -#include "include/core/SkString.h" #include "include/private/SkTFitsIn.h" #include "include/private/SkTemplates.h" #include "modules/skshaper/src/SkUnicode.h" #include "src/utils/SkUTF.h" #include #include -#include #include #include #include #include -#if defined(SK_USING_THIRD_PARTY_ICU) -#include "SkLoadICU.h" -#endif - using SkUnicodeBidi = std::unique_ptr>; using ICUUText = std::unique_ptr>; using ICUBreakIterator = std::unique_ptr>; @@ -131,11 +125,23 @@ class SkUnicode_icu : public SkUnicode { } } + static int convertUtf8ToUtf16(const char* utf8, size_t utf8Units, std::unique_ptr* utf16) { + int utf16Units = SkUTF::UTF8ToUTF16(nullptr, 0, utf8, utf8Units); + if (utf16Units < 0) { + SkDEBUGF("Convert error: Invalid utf8 input"); + return utf16Units; + } + *utf16 = std::unique_ptr(new uint16_t[utf16Units]); + SkDEBUGCODE(int dstLen =) SkUTF::UTF8ToUTF16(utf16->get(), utf16Units, utf8, utf8Units); + SkASSERT(dstLen == utf16Units); + return utf16Units; + } + static bool extractBidi(const char utf8[], int utf8Units, TextDirection dir, std::vector* bidiRegions) { // Convert to UTF16 since for now bidi iterator only operates on utf16 std::unique_ptr utf16; - auto utf16Units = utf8ToUtf16(utf8, utf8Units, &utf16); + auto utf16Units = convertUtf8ToUtf16(utf8, utf8Units, &utf16); if (utf16Units < 0) { return false; } @@ -270,29 +276,6 @@ class SkUnicode_icu : public SkUnicode { return true; } - static int utf8ToUtf16(const char* utf8, size_t utf8Units, std::unique_ptr* utf16) { - int utf16Units = SkUTF::UTF8ToUTF16(nullptr, 0, utf8, utf8Units); - if (utf16Units < 0) { - SkDEBUGF("Convert error: Invalid utf8 input"); - return utf16Units; - } - *utf16 = std::unique_ptr(new uint16_t[utf16Units]); - SkDEBUGCODE(int dstLen =) SkUTF::UTF8ToUTF16(utf16->get(), utf16Units, utf8, utf8Units); - SkASSERT(dstLen == utf16Units); - return utf16Units; - } - - static int utf16ToUtf8(const uint16_t* utf16, size_t utf16Units, std::unique_ptr* utf8) { - int utf8Units = SkUTF::UTF16ToUTF8(nullptr, 0, utf16, utf16Units); - if (utf8Units < 0) { - SkDEBUGF("Convert error: Invalid utf16 input"); - return utf8Units; - } - *utf8 = std::unique_ptr(new char[utf8Units]); - SkDEBUGCODE(int dstLen =) SkUTF::UTF16ToUTF8(utf8->get(), utf8Units, utf16, utf16Units); - SkASSERT(dstLen == utf8Units); - return utf8Units; - } public: ~SkUnicode_icu() override { } std::unique_ptr makeBidiIterator(const uint16_t text[], int count, @@ -304,25 +287,6 @@ public: return SkBidiIterator_icu::makeBidiIterator(text, count, dir); } - // TODO: Use ICU data file to detect controls and whitespaces - bool isControl(SkUnichar utf8) override { - return u_iscntrl(utf8); - } - - bool isWhitespace(SkUnichar utf8) override { - return u_isWhitespace(utf8); - } - - SkString convertUtf16ToUtf8(const std::u16string& utf16) override { - std::unique_ptr utf8; - auto utf8Units = SkUnicode_icu::utf16ToUtf8((uint16_t*)utf16.data(), utf16.size(), &utf8); - if (utf8Units >= 0) { - return SkString(utf8.get(), utf8Units); - } else { - return SkString(); - } - } - bool getBidiRegions(const char utf8[], int utf8Units, TextDirection dir, std::vector* results) override { return extractBidi(utf8, utf8Units, dir, results); } @@ -341,7 +305,7 @@ public: // Convert to UTF16 since we want the results in utf16 std::unique_ptr utf16; - auto utf16Units = utf8ToUtf16(utf8, utf8Units, &utf16); + auto utf16Units = convertUtf8ToUtf16(utf8, utf8Units, &utf16); if (utf16Units < 0) { return false; } @@ -366,12 +330,4 @@ public: } }; -std::unique_ptr SkUnicode::Make() { - #if defined(SK_USING_THIRD_PARTY_ICU) - if (!SkLoadICU()) { - SkDEBUGF("SkLoadICU() failed!\n"); - return nullptr; - } - #endif - return std::make_unique(); -} +std::unique_ptr SkUnicode::Make() { return std::make_unique(); } diff --git a/src/utils/SkUTF.cpp b/src/utils/SkUTF.cpp index 500b1ec024..ff174625a4 100644 --- a/src/utils/SkUTF.cpp +++ b/src/utils/SkUTF.cpp @@ -283,28 +283,4 @@ int SkUTF::UTF8ToUTF16(uint16_t dst[], int dstCapacity, const char src[], size_t return dstLength; } -int SkUTF::UTF16ToUTF8(char dst[], int dstCapacity, const uint16_t src[], size_t srcLength) { - if (!dst) { - dstCapacity = 0; - } - - int dstLength = 0; - const char* endDst = dst + dstCapacity; - for (size_t i = 0; i < srcLength; ++i) { - char utf8[SkUTF::kMaxBytesInUTF8Sequence]; - size_t count = ToUTF8(src[i], utf8); - if (count == 0) { - return -1; - } - dstLength += count; - if (dst) { - const char* elems = utf8; - while (dst < endDst && count > 0) { - *dst++ = *elems++; - count -= 1; - } - } - } - return dstLength; -} diff --git a/src/utils/SkUTF.h b/src/utils/SkUTF.h index 23344a47ef..eb1ee9159f 100644 --- a/src/utils/SkUTF.h +++ b/src/utils/SkUTF.h @@ -6,7 +6,6 @@ #include "include/core/SkTypes.h" #include #include -#include typedef int32_t SkUnichar; @@ -71,12 +70,6 @@ SK_SPI size_t ToUTF16(SkUnichar uni, uint16_t utf16[2] = nullptr); */ SK_SPI int UTF8ToUTF16(uint16_t dst[], int dstCapacity, const char src[], size_t srcByteLength); -/** Returns the number of resulting UTF8 values needed to convert the src utf16 sequence. - * If dst is not null, it is filled with the corresponding values up to its capacity. - * If there is an error, -1 is returned and the dst[] buffer is undefined. - */ -SK_SPI int UTF16ToUTF8(char dst[], int dstCapacity, const uint16_t src[], size_t srcLength); - } // namespace SkUTF #endif // SkUTF_DEFINED diff --git a/third_party/icu/SkLoadICU.cpp b/third_party/icu/SkLoadICU.cpp index 5b3b153336..b41af4e85a 100644 --- a/third_party/icu/SkLoadICU.cpp +++ b/third_party/icu/SkLoadICU.cpp @@ -25,7 +25,7 @@ static void* win_mmap(const char* dataFile) { struct FCloseWrapper { void operator()(FILE* f) { fclose(f); } }; std::unique_ptr stream(fopen(dataFile, "rb")); if (!stream) { - fprintf(stderr, "SkIcuLoader: datafile missing: %s.\n", dataFile); + fprintf(stderr, "SkIcuLoader: datafile missing.\n"); return nullptr; } int fileno = _fileno(stream.get());