Reland "Removing ICU dependencies from skparagraph BUILD.gn file"
This reverts commit 05ce2817f2a060caf8acd5be25b4f29875d63049.
Reason for revert: Fixing the build
Original change's description:
> 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 <jlavrova@google.com>
> > Reviewed-by: Ben Wagner <bungeman@google.com>
>
> 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 <jlavrova@google.com>
> Commit-Queue: Julia Lavrova <jlavrova@google.com>
TBR=bungeman@google.com,jlavrova@google.com
Change-Id: I13d78d75698df47930adc2514d1328abc556a209
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/316444
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Commit-Queue: Julia Lavrova <jlavrova@google.com>
diff --git a/modules/canvaskit/paragraph_bindings.cpp b/modules/canvaskit/paragraph_bindings.cpp
index f5d59f3..a4e31f7 100644
--- a/modules/canvaskit/paragraph_bindings.cpp
+++ b/modules/canvaskit/paragraph_bindings.cpp
@@ -183,21 +183,21 @@
.function("layout", ¶::ParagraphImpl::layout);
class_<para::ParagraphBuilderImpl>("ParagraphBuilder")
- .class_function("_Make", optional_override([](SimpleParagraphStyle style,
- sk_sp<SkFontMgr> fontMgr)-> para::ParagraphBuilderImpl {
+ .class_function("_Make", optional_override([](SimpleParagraphStyle style, sk_sp<SkFontMgr> fontMgr)
+ -> std::unique_ptr<para::ParagraphBuilderImpl> {
auto fc = sk_make_sp<para::FontCollection>();
fc->setDefaultFontManager(fontMgr);
auto ps = toParagraphStyle(style);
- para::ParagraphBuilderImpl pbi(ps, fc);
- return pbi;
+ auto pb = para::ParagraphBuilderImpl::make(ps, fc);
+ return std::unique_ptr<para::ParagraphBuilderImpl>(static_cast<para::ParagraphBuilderImpl*>(pb.release()));
}), allow_raw_pointers())
.class_function("_MakeFromFontProvider", optional_override([](SimpleParagraphStyle style,
- sk_sp<para::TypefaceFontProvider> fontProvider)-> para::ParagraphBuilderImpl {
+ sk_sp<para::TypefaceFontProvider> fontProvider)-> std::unique_ptr<para::ParagraphBuilderImpl> {
auto fc = sk_make_sp<para::FontCollection>();
fc->setDefaultFontManager(fontProvider);
auto ps = toParagraphStyle(style);
- para::ParagraphBuilderImpl pbi(ps, fc);
- return pbi;
+ auto pb = para::ParagraphBuilderImpl::make(ps, fc);
+ return std::unique_ptr<para::ParagraphBuilderImpl>(static_cast<para::ParagraphBuilderImpl*>(pb.release()));
}), 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 48e0929..e8a8b48 100644
--- a/modules/skparagraph/BUILD.gn
+++ b/modules/skparagraph/BUILD.gn
@@ -1,6 +1,7 @@
# Copyright 2019 Google LLC.
import("../../gn/skia.gni")
+import("../skshaper/skshaper.gni")
declare_args() {
skia_enable_skparagraph = true
@@ -9,7 +10,8 @@
paragraph_bench_enabled = false
}
-if (skia_enable_skparagraph) {
+if (skia_enable_skparagraph && skia_enable_skshaper && skia_use_icu &&
+ skia_use_harfbuzz) {
config("public_config") {
include_dirs = [
"include",
@@ -21,16 +23,10 @@
import("skparagraph.gni")
public_configs = [ ":public_config" ]
public = skparagraph_public
- if (skia_use_icu && skia_use_harfbuzz) {
- sources = skparagraph_sources
- configs += [ "../../third_party/icu/config:no_cxx" ]
- } else {
- sources = []
- }
+ sources = skparagraph_sources
deps = [
"../..:skia",
"../skshaper",
- "//third_party/icu",
]
}
@@ -43,21 +39,15 @@
import("skparagraph.gni")
public_configs = [ ":utils_config" ]
configs += [ "../../:skia_private" ]
- if (skia_use_icu && skia_use_harfbuzz) {
- sources = skparagraph_utils
- configs += [ "../../third_party/icu/config:no_cxx" ]
- } else {
- sources = []
- }
+ sources = skparagraph_utils
deps = [
"../..:skia",
"../skshaper",
- "//third_party/icu",
]
}
source_set("gm") {
- if (skia_use_icu && skia_use_harfbuzz && paragraph_gms_enabled) {
+ if (paragraph_gms_enabled) {
testonly = true
sources = [ "gm/simple_gm.cpp" ]
deps = [
@@ -65,53 +55,63 @@
"../..:gpu_tool_utils",
"../..:skia",
"../skshaper",
- "//third_party/icu",
]
+ } else {
+ sources = []
}
}
source_set("tests") {
- if (skia_use_icu && skia_use_harfbuzz && paragraph_tests_enabled) {
+ if (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 (skia_use_icu && skia_use_harfbuzz && paragraph_bench_enabled) {
+ if (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") {
- 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",
- ]
- }
+ testonly = true
+ sources = [ "samples/SampleParagraph.cpp" ]
+ deps = [
+ ":skparagraph",
+ ":utils",
+ "../..:skia",
+ "../skshaper",
+ ]
}
}
+} 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 bd7d016..be7d15b 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/include/ParagraphBuilder.h"
+#include "modules/skparagraph/src/ParagraphBuilderImpl.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,7 +57,11 @@
auto collection = sk_make_sp<skia::textlayout::FontCollection>();
collection->setDefaultFontManager(SkFontMgr::RefDefault());
- auto builder = skia::textlayout::ParagraphBuilder::make(paraStyle, collection);
+ auto builder = skia::textlayout::ParagraphBuilderImpl::make(paraStyle, collection);
+ if (nullptr == builder) {
+ fPara = nullptr;
+ return;
+ }
builder->addText(gSpeach, strlen(gSpeach));
@@ -81,6 +85,9 @@
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 1f1e0ed..816691b 100644
--- a/modules/skparagraph/include/ParagraphBuilder.h
+++ b/modules/skparagraph/include/ParagraphBuilder.h
@@ -57,6 +57,8 @@
// Constructs a SkParagraph object that can be used to layout and paint the text to a SkCanvas.
virtual std::unique_ptr<Paragraph> Build() = 0;
+
+ // Just until we fix all the google3 code
static std::unique_ptr<ParagraphBuilder> make(const ParagraphStyle& style,
sk_sp<FontCollection> fontCollection);
};
diff --git a/modules/skparagraph/include/ParagraphStyle.h b/modules/skparagraph/include/ParagraphStyle.h
index 43fb71f..871e674 100644
--- a/modules/skparagraph/include/ParagraphStyle.h
+++ b/modules/skparagraph/include/ParagraphStyle.h
@@ -72,7 +72,9 @@
ParagraphStyle();
bool operator==(const ParagraphStyle& rhs) const {
- return this->fHeight == rhs.fHeight && this->fEllipsis == rhs.fEllipsis &&
+ return this->fHeight == rhs.fHeight &&
+ this->fEllipsis == rhs.fEllipsis &&
+ this->fEllipsisUtf16 == rhs.fEllipsisUtf16 &&
this->fTextDirection == rhs.fTextDirection && this->fTextAlign == rhs.fTextAlign &&
this->fDefaultTextStyle == rhs.fDefaultTextStyle;
}
@@ -92,8 +94,9 @@
size_t getMaxLines() const { return fLinesLimit; }
void setMaxLines(size_t maxLines) { fLinesLimit = maxLines; }
- const SkString& getEllipsis() const { return fEllipsis; }
- void setEllipsis(const std::u16string& ellipsis);
+ SkString getEllipsis() const { return fEllipsis; }
+ std::u16string getEllipsisUtf16() const { return fEllipsisUtf16; }
+ void setEllipsis(const std::u16string& ellipsis) { fEllipsisUtf16 = ellipsis; }
void setEllipsis(const SkString& ellipsis) { fEllipsis = ellipsis; }
SkScalar getHeight() const { return fHeight; }
@@ -105,7 +108,7 @@
bool unlimited_lines() const {
return fLinesLimit == std::numeric_limits<size_t>::max();
}
- bool ellipsized() const { return fEllipsis.size() != 0; }
+ bool ellipsized() const { return !fEllipsis.isEmpty() || !fEllipsisUtf16.empty(); }
TextAlign effective_align() const;
bool hintingIsOn() const { return fHintingIsOn; }
void turnHintingOff() { fHintingIsOn = false; }
@@ -118,6 +121,7 @@
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 c650cba..a2cff7b 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,7 +28,6 @@
#include "tools/Resources.h"
#include "tools/flags/CommandLineFlags.h"
-
static DEFINE_bool(verboseParagraph, false, "paragraph samples very verbose.");
using namespace skia::textlayout;
@@ -746,14 +745,15 @@
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<ParagraphImpl*>(paragraph.get());
+ if (this->isVerbose()) {
+ SkDebugf("Text: >%s<\n", impl->text().data());
+ }
+
paragraph->layout(w - margin * 2);
paragraph->paint(canvas, margin, margin);
}
@@ -1608,15 +1608,14 @@
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<ParagraphImpl*>(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 0221d78..df0091c 100644
--- a/modules/skparagraph/skparagraph.gni
+++ b/modules/skparagraph/skparagraph.gni
@@ -31,8 +31,6 @@
"$_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 d2a8ec2..45c622c 100644
--- a/modules/skparagraph/src/OneLineShaper.cpp
+++ b/modules/skparagraph/src/OneLineShaper.cpp
@@ -2,10 +2,15 @@
#include "modules/skparagraph/src/Iterators.h"
#include "modules/skparagraph/src/OneLineShaper.h"
-#include "modules/skparagraph/src/ParagraphUtil.h"
+#include "src/utils/SkUTF.h"
#include <algorithm>
#include <unordered_set>
+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 {
@@ -297,8 +302,8 @@
const char* cluster = text.begin() + clusterIndex(i);
SkUnichar codepoint = nextUtf8Unit(&cluster, text.end());
- bool isControl8 = isControl(codepoint);
- bool isWhitespace8 = isWhitespace(codepoint);
+ bool isControl8 = fParagraph->getUnicode()->isControl(codepoint);
+ bool isWhitespace8 = fParagraph->getUnicode()->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 5f904e9..1502012 100644
--- a/modules/skparagraph/src/ParagraphBuilderImpl.cpp
+++ b/modules/skparagraph/src/ParagraphBuilderImpl.cpp
@@ -8,24 +8,50 @@
#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 <algorithm>
#include <utility>
+#include "src/core/SkStringUtils.h"
namespace skia {
namespace textlayout {
std::unique_ptr<ParagraphBuilder> ParagraphBuilder::make(
const ParagraphStyle& style, sk_sp<FontCollection> fontCollection) {
+ return ParagraphBuilderImpl::make(style, fontCollection);
+}
+
+std::unique_ptr<ParagraphBuilder> ParagraphBuilderImpl::make(
+ const ParagraphStyle& style, sk_sp<FontCollection> fontCollection) {
+ auto unicode = SkUnicode::Make();
+ if (nullptr == unicode) {
+ return nullptr;
+ }
return std::make_unique<ParagraphBuilderImpl>(style, fontCollection);
}
+std::unique_ptr<ParagraphBuilder> ParagraphBuilderImpl::make(
+ const ParagraphStyle& style, sk_sp<FontCollection> fontCollection, std::unique_ptr<SkUnicode> unicode) {
+ if (nullptr == unicode) {
+ return nullptr;
+ }
+ return std::make_unique<ParagraphBuilderImpl>(style, fontCollection, std::move(unicode));
+}
+
+ParagraphBuilderImpl::ParagraphBuilderImpl(
+ const ParagraphStyle& style, sk_sp<FontCollection> fontCollection, std::unique_ptr<SkUnicode> 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> fontCollection)
- : ParagraphBuilder(style, fontCollection), fUtf8(), fFontCollection(std::move(fontCollection)) {
- this->setParagraphStyle(style);
-}
+ : ParagraphBuilderImpl(style, fontCollection, SkUnicode::Make())
+{ }
ParagraphBuilderImpl::~ParagraphBuilderImpl() = default;
@@ -74,7 +100,8 @@
}
void ParagraphBuilderImpl::addText(const std::u16string& text) {
- fUtf8.append(SkStringFromU16String(text));
+ auto utf8 = fUnicode->convertUtf16ToUtf8(text);
+ fUtf8.append(utf8);
}
void ParagraphBuilderImpl::addText(const char* text) {
@@ -128,7 +155,7 @@
// Add one fake placeholder with the rest of the text
addPlaceholder(PlaceholderStyle(), true);
return std::make_unique<ParagraphImpl>(
- fUtf8, fParagraphStyle, fStyledBlocks, fPlaceholders, fFontCollection);
+ fUtf8, fParagraphStyle, fStyledBlocks, fPlaceholders, fFontCollection, std::move(fUnicode));
}
} // namespace textlayout
diff --git a/modules/skparagraph/src/ParagraphBuilderImpl.h b/modules/skparagraph/src/ParagraphBuilderImpl.h
index 644769e..49a24c4 100644
--- a/modules/skparagraph/src/ParagraphBuilderImpl.h
+++ b/modules/skparagraph/src/ParagraphBuilderImpl.h
@@ -11,12 +11,18 @@
#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> fontCollection,
+ std::unique_ptr<SkUnicode> unicode);
+
+ // Just until we fix all the code; calls icu::make inside
ParagraphBuilderImpl(const ParagraphStyle& style, sk_sp<FontCollection> fontCollection);
~ParagraphBuilderImpl() override;
@@ -55,6 +61,13 @@
// Constructs a SkParagraph object that can be used to layout and paint the text to a SkCanvas.
std::unique_ptr<Paragraph> Build() override;
+ static std::unique_ptr<ParagraphBuilder> make(const ParagraphStyle& style,
+ sk_sp<FontCollection> fontCollection,
+ std::unique_ptr<SkUnicode> unicode);
+
+ // Just until we fix all the code; calls icu::make inside
+ static std::unique_ptr<ParagraphBuilder> make(const ParagraphStyle& style,
+ sk_sp<FontCollection> fontCollection);
private:
void endRunIfNeeded();
void addPlaceholder(const PlaceholderStyle& placeholderStyle, bool lastOne);
@@ -65,6 +78,8 @@
SkTArray<Placeholder, true> fPlaceholders;
sk_sp<FontCollection> fFontCollection;
ParagraphStyle fParagraphStyle;
+
+ std::unique_ptr<SkUnicode> fUnicode;
};
} // namespace textlayout
} // namespace skia
diff --git a/modules/skparagraph/src/ParagraphImpl.cpp b/modules/skparagraph/src/ParagraphImpl.cpp
index 487daf2..9804a8c 100644
--- a/modules/skparagraph/src/ParagraphImpl.cpp
+++ b/modules/skparagraph/src/ParagraphImpl.cpp
@@ -13,17 +13,11 @@
#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 <math.h>
#include <algorithm>
#include <utility>
@@ -71,7 +65,8 @@
ParagraphStyle style,
SkTArray<Block, true> blocks,
SkTArray<Placeholder, true> placeholders,
- sk_sp<FontCollection> fonts)
+ sk_sp<FontCollection> fonts,
+ std::unique_ptr<SkUnicode> unicode)
: Paragraph(std::move(style), std::move(fonts))
, fTextStyles(std::move(blocks))
, fPlaceholders(std::move(placeholders))
@@ -81,21 +76,28 @@
, fPicture(nullptr)
, fStrutMetrics(false)
, fOldWidth(0)
- , fOldHeight(0) {
- fICU = SkUnicode::Make();
+ , fOldHeight(0)
+ , fUnicode(std::move(unicode))
+{
+ SkASSERT(fUnicode);
}
ParagraphImpl::ParagraphImpl(const std::u16string& utf16text,
ParagraphStyle style,
SkTArray<Block, true> blocks,
SkTArray<Placeholder, true> placeholders,
- sk_sp<FontCollection> fonts)
- : ParagraphImpl(SkStringFromU16String(utf16text),
+ sk_sp<FontCollection> fonts,
+ std::unique_ptr<SkUnicode> unicode)
+ : ParagraphImpl(SkString(),
std::move(style),
std::move(blocks),
std::move(placeholders),
- std::move(fonts))
-{ }
+ std::move(fonts),
+ std::move(unicode))
+{
+ SkASSERT(fUnicode);
+ fText = fUnicode->convertUtf16ToUtf8(utf16text);
+}
ParagraphImpl::~ParagraphImpl() = default;
@@ -243,26 +245,23 @@
}
// shapeTextIntoEndlessLine is the thing that calls this method
-// (that contains all ICU dependencies except for words)
bool ParagraphImpl::computeCodeUnitProperties() {
- #if defined(SK_USING_THIRD_PARTY_ICU)
- if (!SkLoadICU()) {
+ if (nullptr == fUnicode) {
return false;
}
- #endif
// Get bidi regions
auto textDirection = fParagraphStyle.getTextDirection() == TextDirection::kLtr
? SkUnicode::TextDirection::kLTR
: SkUnicode::TextDirection::kRTL;
- if (!fICU->getBidiRegions(fText.c_str(), fText.size(), textDirection, &fBidiRegions)) {
+ if (!fUnicode->getBidiRegions(fText.c_str(), fText.size(), textDirection, &fBidiRegions)) {
return false;
}
// Get white spaces
std::vector<SkUnicode::Position> whitespaces;
- if (!fICU->getWhitespaces(fText.c_str(), fText.size(), &whitespaces)) {
+ if (!fUnicode->getWhitespaces(fText.c_str(), fText.size(), &whitespaces)) {
return false;
}
for (auto whitespace : whitespaces) {
@@ -271,7 +270,7 @@
// Get line breaks
std::vector<SkUnicode::LineBreakBefore> lineBreaks;
- if (!fICU->getLineBreaks(fText.c_str(), fText.size(), &lineBreaks)) {
+ if (!fUnicode->getLineBreaks(fText.c_str(), fText.size(), &lineBreaks)) {
return false;
}
for (auto& lineBreak : lineBreaks) {
@@ -282,7 +281,7 @@
// Get graphemes
std::vector<SkUnicode::Position> graphemes;
- if (!fICU->getGraphemes(fText.c_str(), fText.size(), &graphemes)) {
+ if (!fUnicode->getGraphemes(fText.c_str(), fText.size(), &graphemes)) {
return false;
}
for (auto pos : graphemes) {
@@ -429,7 +428,7 @@
// TODO: Take in account clipped edges
auto& line = this->addLine(offset, advance, text, textWithSpaces, clusters, clustersWithGhosts, widthWithSpaces, metrics);
if (addEllipsis) {
- line.createEllipsis(maxWidth, fParagraphStyle.getEllipsis(), true);
+ line.createEllipsis(maxWidth, getEllipsis(), true);
}
fLongestLine = std::max(fLongestLine, nearlyZero(advance.fX) ? widthWithSpaces : advance.fX);
@@ -686,7 +685,7 @@
SkRange<size_t> ParagraphImpl::getWordBoundary(unsigned offset) {
if (fWords.empty()) {
- if (!fICU->getWords(fText.c_str(), fText.size(), &fWords)) {
+ if (!fUnicode->getWords(fText.c_str(), fText.size(), &fWords)) {
return {0, 0 };
}
}
@@ -837,6 +836,17 @@
}
}
+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 4bd3d90..a4af3db 100644
--- a/modules/skparagraph/src/ParagraphImpl.h
+++ b/modules/skparagraph/src/ParagraphImpl.h
@@ -100,13 +100,15 @@
ParagraphStyle style,
SkTArray<Block, true> blocks,
SkTArray<Placeholder, true> placeholders,
- sk_sp<FontCollection> fonts);
+ sk_sp<FontCollection> fonts,
+ std::unique_ptr<SkUnicode> unicode);
ParagraphImpl(const std::u16string& utf16text,
ParagraphStyle style,
SkTArray<Block, true> blocks,
SkTArray<Placeholder, true> placeholders,
- sk_sp<FontCollection> fonts);
+ sk_sp<FontCollection> fonts,
+ std::unique_ptr<SkUnicode> unicode);
~ParagraphImpl() override;
void layout(SkScalar width) override;
@@ -155,6 +157,8 @@
}
InternalLineMetrics strutMetrics() const { return fStrutMetrics; }
+ SkString getEllipsis() const;
+
SkSpan<const char> text(TextRange textRange);
SkSpan<Cluster> clusters(ClusterRange clusterRange);
Cluster& cluster(ClusterIndex clusterIndex);
@@ -218,7 +222,7 @@
bool codeUnitHasProperty(size_t index, CodeUnitFlags property) const { return (fCodeUnitProperties[index] & property) == property; }
- SkUnicode* getICU() { return fICU.get(); }
+ SkUnicode* getUnicode() { return fUnicode.get(); }
private:
friend class ParagraphBuilder;
@@ -268,7 +272,7 @@
SkScalar fOldHeight;
SkScalar fMaxWidthWithTrailingSpaces;
- std::unique_ptr<SkUnicode> fICU;
+ std::unique_ptr<SkUnicode> fUnicode;
};
} // namespace textlayout
} // namespace skia
diff --git a/modules/skparagraph/src/ParagraphStyle.cpp b/modules/skparagraph/src/ParagraphStyle.cpp
index c40372d..4e3094f 100644
--- a/modules/skparagraph/src/ParagraphStyle.cpp
+++ b/modules/skparagraph/src/ParagraphStyle.cpp
@@ -2,7 +2,9 @@
#include "modules/skparagraph/include/DartTypes.h"
#include "modules/skparagraph/include/ParagraphStyle.h"
-#include "modules/skparagraph/src/ParagraphUtil.h"
+#include "modules/skshaper/src/SkUnicode.h"
+#include "src/core/SkStringUtils.h"
+#include "src/utils/SkUTF.h"
namespace skia {
namespace textlayout {
@@ -35,9 +37,5 @@
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
deleted file mode 100644
index f7b78a7..0000000
--- a/modules/skparagraph/src/ParagraphUtil.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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 <unicode/umachine.h>
-#include <unicode/uchar.h>
-#include <unicode/ustring.h>
-#include <unicode/utypes.h>
-#include <string>
-
-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
deleted file mode 100644
index 3b6432f..0000000
--- a/modules/skparagraph/src/ParagraphUtil.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 Google LLC.
-#ifndef ParagraphUtil_DEFINED
-#define ParagraphUtil_DEFINED
-
-#include "include/core/SkString.h"
-#include <string>
-
-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 1eddb93..b30651a 100644
--- a/modules/skparagraph/src/TextLine.cpp
+++ b/modules/skparagraph/src/TextLine.cpp
@@ -144,7 +144,7 @@
SkAutoSTArray<kPreallocCount, int32_t> logicalOrder(numRuns);
// TODO: hide all these logic in SkUnicode?
- fOwner->getICU()->reorderVisual(runLevels.data(), numRuns, logicalOrder.data());
+ fOwner->getUnicode()->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 747b2ffe..7f7b73a 100644
--- a/modules/skparagraph/src/TextWrapper.cpp
+++ b/modules/skparagraph/src/TextWrapper.cpp
@@ -224,11 +224,10 @@
return;
}
auto maxLines = parent->paragraphStyle().getMaxLines();
- auto& ellipsisStr = parent->paragraphStyle().getEllipsis();
auto align = parent->paragraphStyle().effective_align();
auto unlimitedLines = maxLines == std::numeric_limits<size_t>::max();
auto endlessLine = !SkScalarIsFinite(maxWidth);
- auto hasEllipsis = !ellipsisStr.isEmpty();
+ auto hasEllipsis = parent->paragraphStyle().ellipsized();
SkScalar softLineMaxIntrinsicWidth = 0;
fEndLine = TextStretch(span.begin(), span.begin(), parent->strutForceHeight());
diff --git a/modules/skshaper/BUILD.gn b/modules/skshaper/BUILD.gn
index 5acd981..57160c1 100644
--- a/modules/skshaper/BUILD.gn
+++ b/modules/skshaper/BUILD.gn
@@ -4,10 +4,7 @@
# found in the LICENSE file.
import("../../gn/skia.gni")
-
-declare_args() {
- skia_enable_skshaper = true
-}
+import("skshaper.gni")
if (skia_enable_skshaper) {
config("public_config") {
@@ -27,7 +24,6 @@
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 0618b63..27c9624 100644
--- a/modules/skshaper/skshaper.gni
+++ b/modules/skshaper/skshaper.gni
@@ -19,3 +19,7 @@
]
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 3bbb02e..5414ed2 100644
--- a/modules/skshaper/src/SkUnicode.h
+++ b/modules/skshaper/src/SkUnicode.h
@@ -9,6 +9,7 @@
#include "include/core/SkTypes.h"
#include "src/core/SkSpan.h"
+#include "src/utils/SkUTF.h"
#include <vector>
#if !defined(SKUNICODE_IMPLEMENTATION)
@@ -89,6 +90,10 @@
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<SkBidiIterator> 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 1a859fe..13de14d 100644
--- a/modules/skshaper/src/SkUnicode_icu.cpp
+++ b/modules/skshaper/src/SkUnicode_icu.cpp
@@ -4,17 +4,23 @@
* 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 <unicode/ubidi.h>
#include <unicode/ubrk.h>
+#include <unicode/ustring.h>
#include <unicode/utext.h>
#include <unicode/utypes.h>
#include <vector>
#include <functional>
+#if defined(SK_USING_THIRD_PARTY_ICU)
+#include "SkLoadICU.h"
+#endif
+
using SkUnicodeBidi = std::unique_ptr<UBiDi, SkFunctionWrapper<decltype(ubidi_close), ubidi_close>>;
using ICUUText = std::unique_ptr<UText, SkFunctionWrapper<decltype(utext_close), utext_close>>;
using ICUBreakIterator = std::unique_ptr<UBreakIterator, SkFunctionWrapper<decltype(ubrk_close), ubrk_close>>;
@@ -125,23 +131,11 @@
}
}
- static int convertUtf8ToUtf16(const char* utf8, size_t utf8Units, std::unique_ptr<uint16_t[]>* utf16) {
- int utf16Units = SkUTF::UTF8ToUTF16(nullptr, 0, utf8, utf8Units);
- if (utf16Units < 0) {
- SkDEBUGF("Convert error: Invalid utf8 input");
- return utf16Units;
- }
- *utf16 = std::unique_ptr<uint16_t[]>(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<BidiRegion>* bidiRegions) {
// Convert to UTF16 since for now bidi iterator only operates on utf16
std::unique_ptr<uint16_t[]> utf16;
- auto utf16Units = convertUtf8ToUtf16(utf8, utf8Units, &utf16);
+ auto utf16Units = utf8ToUtf16(utf8, utf8Units, &utf16);
if (utf16Units < 0) {
return false;
}
@@ -276,6 +270,29 @@
return true;
}
+ static int utf8ToUtf16(const char* utf8, size_t utf8Units, std::unique_ptr<uint16_t[]>* utf16) {
+ int utf16Units = SkUTF::UTF8ToUTF16(nullptr, 0, utf8, utf8Units);
+ if (utf16Units < 0) {
+ SkDEBUGF("Convert error: Invalid utf8 input");
+ return utf16Units;
+ }
+ *utf16 = std::unique_ptr<uint16_t[]>(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<char[]>* utf8) {
+ int utf8Units = SkUTF::UTF16ToUTF8(nullptr, 0, utf16, utf16Units);
+ if (utf8Units < 0) {
+ SkDEBUGF("Convert error: Invalid utf16 input");
+ return utf8Units;
+ }
+ *utf8 = std::unique_ptr<char[]>(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<SkBidiIterator> makeBidiIterator(const uint16_t text[], int count,
@@ -287,6 +304,25 @@
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<char[]> 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<BidiRegion>* results) override {
return extractBidi(utf8, utf8Units, dir, results);
}
@@ -305,7 +341,7 @@
// Convert to UTF16 since we want the results in utf16
std::unique_ptr<uint16_t[]> utf16;
- auto utf16Units = convertUtf8ToUtf16(utf8, utf8Units, &utf16);
+ auto utf16Units = utf8ToUtf16(utf8, utf8Units, &utf16);
if (utf16Units < 0) {
return false;
}
@@ -330,4 +366,12 @@
}
};
-std::unique_ptr<SkUnicode> SkUnicode::Make() { return std::make_unique<SkUnicode_icu>(); }
+std::unique_ptr<SkUnicode> SkUnicode::Make() {
+ #if defined(SK_USING_THIRD_PARTY_ICU)
+ if (!SkLoadICU()) {
+ SkDEBUGF("SkLoadICU() failed!\n");
+ return nullptr;
+ }
+ #endif
+ return std::make_unique<SkUnicode_icu>();
+}