1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2011 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorFilter.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorPriv.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkGraphics.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRegion.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkShader.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextBlob.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkGradientShader.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skshaper/include/SkShaper.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skshaper/include/SkShaper_skunicode.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkTime.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkUTF.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkOSFile.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "tools/viewer/Slide.h"
28*c8dee2aaSAndroid Build Coastguard Worker
29*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_SHAPER_CORETEXT_AVAILABLE)
30*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skshaper/include/SkShaper_coretext.h"
31*c8dee2aaSAndroid Build Coastguard Worker #endif
32*c8dee2aaSAndroid Build Coastguard Worker
33*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE)
34*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skshaper/include/SkShaper_harfbuzz.h"
35*c8dee2aaSAndroid Build Coastguard Worker #endif
36*c8dee2aaSAndroid Build Coastguard Worker
37*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU_IMPLEMENTATION)
38*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode_icu.h"
39*c8dee2aaSAndroid Build Coastguard Worker #endif
40*c8dee2aaSAndroid Build Coastguard Worker
41*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_LIBGRAPHEME_IMPLEMENTATION)
42*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode_libgrapheme.h"
43*c8dee2aaSAndroid Build Coastguard Worker #endif
44*c8dee2aaSAndroid Build Coastguard Worker
45*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
46*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode_icu4x.h"
47*c8dee2aaSAndroid Build Coastguard Worker #endif
48*c8dee2aaSAndroid Build Coastguard Worker
49*c8dee2aaSAndroid Build Coastguard Worker typedef std::unique_ptr<SkShaper> (*ShaperFactory)();
50*c8dee2aaSAndroid Build Coastguard Worker
51*c8dee2aaSAndroid Build Coastguard Worker static const char gText[] =
52*c8dee2aaSAndroid Build Coastguard Worker "When in the Course of human events it becomes necessary for one people "
53*c8dee2aaSAndroid Build Coastguard Worker "to dissolve the political bands which have connected them with another "
54*c8dee2aaSAndroid Build Coastguard Worker "and to assume among the powers of the earth, the separate and equal "
55*c8dee2aaSAndroid Build Coastguard Worker "station to which the Laws of Nature and of Nature's God entitle them, "
56*c8dee2aaSAndroid Build Coastguard Worker "a decent respect to the opinions of mankind requires that they should "
57*c8dee2aaSAndroid Build Coastguard Worker "declare the causes which impel them to the separation.";
58*c8dee2aaSAndroid Build Coastguard Worker
59*c8dee2aaSAndroid Build Coastguard Worker namespace {
get_unicode()60*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkUnicode> get_unicode() {
61*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU_IMPLEMENTATION)
62*c8dee2aaSAndroid Build Coastguard Worker if (auto unicode = SkUnicodes::ICU::Make()) {
63*c8dee2aaSAndroid Build Coastguard Worker return unicode;
64*c8dee2aaSAndroid Build Coastguard Worker }
65*c8dee2aaSAndroid Build Coastguard Worker #endif // defined(SK_UNICODE_ICU_IMPLEMENTATION)
66*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_LIBGRAPHEME_IMPLEMENTATION)
67*c8dee2aaSAndroid Build Coastguard Worker if (auto unicode = SkUnicodes::Libgrapheme::Make()) {
68*c8dee2aaSAndroid Build Coastguard Worker return unicode;
69*c8dee2aaSAndroid Build Coastguard Worker }
70*c8dee2aaSAndroid Build Coastguard Worker #endif
71*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
72*c8dee2aaSAndroid Build Coastguard Worker if (auto unicode = SkUnicodes::ICU4X::Make()) {
73*c8dee2aaSAndroid Build Coastguard Worker return unicode;
74*c8dee2aaSAndroid Build Coastguard Worker }
75*c8dee2aaSAndroid Build Coastguard Worker #endif
76*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
77*c8dee2aaSAndroid Build Coastguard Worker }
78*c8dee2aaSAndroid Build Coastguard Worker }
79*c8dee2aaSAndroid Build Coastguard Worker
80*c8dee2aaSAndroid Build Coastguard Worker using MakeBidiIteratorCallback = std::unique_ptr<SkShaper::BiDiRunIterator> (*)(sk_sp<SkUnicode> unicode,
81*c8dee2aaSAndroid Build Coastguard Worker const char* utf8,
82*c8dee2aaSAndroid Build Coastguard Worker size_t utf8Bytes,
83*c8dee2aaSAndroid Build Coastguard Worker uint8_t bidiLevel);
84*c8dee2aaSAndroid Build Coastguard Worker using MakeScriptRunCallback = std::unique_ptr<SkShaper::ScriptRunIterator> (*)(
85*c8dee2aaSAndroid Build Coastguard Worker const char* utf8, size_t utf8Bytes, SkFourByteTag script);
86*c8dee2aaSAndroid Build Coastguard Worker
make_trivial_bidi(sk_sp<SkUnicode>,const char *,size_t utf8Bytes,uint8_t bidiLevel)87*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkShaper::BiDiRunIterator> make_trivial_bidi(sk_sp<SkUnicode>,
88*c8dee2aaSAndroid Build Coastguard Worker const char*,
89*c8dee2aaSAndroid Build Coastguard Worker size_t utf8Bytes,
90*c8dee2aaSAndroid Build Coastguard Worker uint8_t bidiLevel) {
91*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<SkShaper::TrivialBiDiRunIterator>(bidiLevel, utf8Bytes);
92*c8dee2aaSAndroid Build Coastguard Worker }
93*c8dee2aaSAndroid Build Coastguard Worker
94*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) && defined(SK_SHAPER_UNICODE_AVAILABLE)
make_unicode_bidi(sk_sp<SkUnicode> unicode,const char * utf8,size_t utf8Bytes,uint8_t bidiLevel)95*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkShaper::BiDiRunIterator> make_unicode_bidi(sk_sp<SkUnicode> unicode,
96*c8dee2aaSAndroid Build Coastguard Worker const char* utf8,
97*c8dee2aaSAndroid Build Coastguard Worker size_t utf8Bytes,
98*c8dee2aaSAndroid Build Coastguard Worker uint8_t bidiLevel) {
99*c8dee2aaSAndroid Build Coastguard Worker if (auto bidi = SkShapers::unicode::BidiRunIterator(unicode, utf8, utf8Bytes, bidiLevel)) {
100*c8dee2aaSAndroid Build Coastguard Worker return bidi;
101*c8dee2aaSAndroid Build Coastguard Worker }
102*c8dee2aaSAndroid Build Coastguard Worker return make_trivial_bidi(unicode, utf8, utf8Bytes, bidiLevel);
103*c8dee2aaSAndroid Build Coastguard Worker }
104*c8dee2aaSAndroid Build Coastguard Worker #endif
105*c8dee2aaSAndroid Build Coastguard Worker
make_trivial_script_runner(const char *,size_t utf8Bytes,SkFourByteTag scriptTag)106*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkShaper::ScriptRunIterator> make_trivial_script_runner(
107*c8dee2aaSAndroid Build Coastguard Worker const char*, size_t utf8Bytes, SkFourByteTag scriptTag) {
108*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<SkShaper::TrivialScriptRunIterator>(scriptTag, utf8Bytes);
109*c8dee2aaSAndroid Build Coastguard Worker }
110*c8dee2aaSAndroid Build Coastguard Worker
111*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) && defined(SK_SHAPER_UNICODE_AVAILABLE)
make_harfbuzz_script_runner(const char * utf8,size_t utf8Bytes,SkFourByteTag scriptTag)112*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkShaper::ScriptRunIterator> make_harfbuzz_script_runner(
113*c8dee2aaSAndroid Build Coastguard Worker const char* utf8, size_t utf8Bytes, SkFourByteTag scriptTag) {
114*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkShaper::ScriptRunIterator> script =
115*c8dee2aaSAndroid Build Coastguard Worker SkShapers::HB::ScriptRunIterator(utf8, utf8Bytes, scriptTag);
116*c8dee2aaSAndroid Build Coastguard Worker if (script) {
117*c8dee2aaSAndroid Build Coastguard Worker return script;
118*c8dee2aaSAndroid Build Coastguard Worker }
119*c8dee2aaSAndroid Build Coastguard Worker return std::make_unique<SkShaper::TrivialScriptRunIterator>(scriptTag, utf8Bytes);
120*c8dee2aaSAndroid Build Coastguard Worker }
121*c8dee2aaSAndroid Build Coastguard Worker #endif
122*c8dee2aaSAndroid Build Coastguard Worker
123*c8dee2aaSAndroid Build Coastguard Worker class TextBoxSlide : public Slide {
124*c8dee2aaSAndroid Build Coastguard Worker public:
TextBoxSlide(ShaperFactory fact,MakeBidiIteratorCallback bidi,MakeScriptRunCallback script,const char suffix[])125*c8dee2aaSAndroid Build Coastguard Worker TextBoxSlide(ShaperFactory fact,
126*c8dee2aaSAndroid Build Coastguard Worker MakeBidiIteratorCallback bidi,
127*c8dee2aaSAndroid Build Coastguard Worker MakeScriptRunCallback script,
128*c8dee2aaSAndroid Build Coastguard Worker const char suffix[])
129*c8dee2aaSAndroid Build Coastguard Worker : fShaper(fact()), fBidiCallback(bidi), fScriptRunCallback(script) {
130*c8dee2aaSAndroid Build Coastguard Worker fName = SkStringPrintf("TextBox_%s", suffix);
131*c8dee2aaSAndroid Build Coastguard Worker }
132*c8dee2aaSAndroid Build Coastguard Worker
load(SkScalar w,SkScalar h)133*c8dee2aaSAndroid Build Coastguard Worker void load(SkScalar w, SkScalar h) override { fSize = {w, h}; }
134*c8dee2aaSAndroid Build Coastguard Worker
resize(SkScalar w,SkScalar h)135*c8dee2aaSAndroid Build Coastguard Worker void resize(SkScalar w, SkScalar h) override { fSize = {w, h}; }
136*c8dee2aaSAndroid Build Coastguard Worker
draw(SkCanvas * canvas)137*c8dee2aaSAndroid Build Coastguard Worker void draw(SkCanvas* canvas) override {
138*c8dee2aaSAndroid Build Coastguard Worker SkScalar width = fSize.width() / 3;
139*c8dee2aaSAndroid Build Coastguard Worker drawTest(canvas, width, fSize.height(), SK_ColorBLACK, SK_ColorWHITE);
140*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(width, 0);
141*c8dee2aaSAndroid Build Coastguard Worker drawTest(canvas, width, fSize.height(), SK_ColorWHITE, SK_ColorBLACK);
142*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(width, 0);
143*c8dee2aaSAndroid Build Coastguard Worker drawTest(canvas, width, fSize.height()/2, SK_ColorGRAY, SK_ColorWHITE);
144*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, fSize.height()/2);
145*c8dee2aaSAndroid Build Coastguard Worker drawTest(canvas, width, fSize.height()/2, SK_ColorGRAY, SK_ColorBLACK);
146*c8dee2aaSAndroid Build Coastguard Worker }
147*c8dee2aaSAndroid Build Coastguard Worker
148*c8dee2aaSAndroid Build Coastguard Worker private:
drawTest(SkCanvas * canvas,SkScalar w,SkScalar h,SkColor fg,SkColor bg)149*c8dee2aaSAndroid Build Coastguard Worker void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) {
150*c8dee2aaSAndroid Build Coastguard Worker SkAutoCanvasRestore acr(canvas, true);
151*c8dee2aaSAndroid Build Coastguard Worker
152*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect(SkRect::MakeWH(w, h));
153*c8dee2aaSAndroid Build Coastguard Worker canvas->drawColor(bg);
154*c8dee2aaSAndroid Build Coastguard Worker
155*c8dee2aaSAndroid Build Coastguard Worker SkScalar margin = 20;
156*c8dee2aaSAndroid Build Coastguard Worker
157*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
158*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(fg);
159*c8dee2aaSAndroid Build Coastguard Worker
160*c8dee2aaSAndroid Build Coastguard Worker for (int i = 9; i < 24; i += 2) {
161*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) && defined(SK_SHAPER_UNICODE_AVAILABLE)
162*c8dee2aaSAndroid Build Coastguard Worker SkShapers::HB::PurgeCaches();
163*c8dee2aaSAndroid Build Coastguard Worker #endif
164*c8dee2aaSAndroid Build Coastguard Worker SkTextBlobBuilderRunHandler builder(gText, { margin, margin });
165*c8dee2aaSAndroid Build Coastguard Worker SkFont srcFont(nullptr, SkIntToScalar(i));
166*c8dee2aaSAndroid Build Coastguard Worker srcFont.setEdging(SkFont::Edging::kSubpixelAntiAlias);
167*c8dee2aaSAndroid Build Coastguard Worker srcFont.setSubpixel(true);
168*c8dee2aaSAndroid Build Coastguard Worker
169*c8dee2aaSAndroid Build Coastguard Worker const char* utf8 = gText;
170*c8dee2aaSAndroid Build Coastguard Worker size_t utf8Bytes = sizeof(gText) - 1;
171*c8dee2aaSAndroid Build Coastguard Worker
172*c8dee2aaSAndroid Build Coastguard Worker auto unicode = get_unicode();
173*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkShaper::BiDiRunIterator> bidi =
174*c8dee2aaSAndroid Build Coastguard Worker fBidiCallback(unicode, utf8, utf8Bytes, 0xfe);
175*c8dee2aaSAndroid Build Coastguard Worker if (!bidi) {
176*c8dee2aaSAndroid Build Coastguard Worker return;
177*c8dee2aaSAndroid Build Coastguard Worker }
178*c8dee2aaSAndroid Build Coastguard Worker
179*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkShaper::LanguageRunIterator> language(
180*c8dee2aaSAndroid Build Coastguard Worker SkShaper::MakeStdLanguageRunIterator(utf8, utf8Bytes));
181*c8dee2aaSAndroid Build Coastguard Worker if (!language) {
182*c8dee2aaSAndroid Build Coastguard Worker return;
183*c8dee2aaSAndroid Build Coastguard Worker }
184*c8dee2aaSAndroid Build Coastguard Worker
185*c8dee2aaSAndroid Build Coastguard Worker SkFourByteTag undeterminedScript = SkSetFourByteTag('Z','y','y','y');
186*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkShaper::ScriptRunIterator> script =
187*c8dee2aaSAndroid Build Coastguard Worker fScriptRunCallback(utf8, utf8Bytes, undeterminedScript);
188*c8dee2aaSAndroid Build Coastguard Worker if (!script) {
189*c8dee2aaSAndroid Build Coastguard Worker return;
190*c8dee2aaSAndroid Build Coastguard Worker }
191*c8dee2aaSAndroid Build Coastguard Worker
192*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkShaper::FontRunIterator> font(
193*c8dee2aaSAndroid Build Coastguard Worker SkShaper::MakeFontMgrRunIterator(utf8,
194*c8dee2aaSAndroid Build Coastguard Worker utf8Bytes,
195*c8dee2aaSAndroid Build Coastguard Worker srcFont,
196*c8dee2aaSAndroid Build Coastguard Worker ToolUtils::TestFontMgr(),
197*c8dee2aaSAndroid Build Coastguard Worker "Arial",
198*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::Bold(),
199*c8dee2aaSAndroid Build Coastguard Worker &*language));
200*c8dee2aaSAndroid Build Coastguard Worker if (!font) {
201*c8dee2aaSAndroid Build Coastguard Worker return;
202*c8dee2aaSAndroid Build Coastguard Worker }
203*c8dee2aaSAndroid Build Coastguard Worker
204*c8dee2aaSAndroid Build Coastguard Worker fShaper->shape(utf8,
205*c8dee2aaSAndroid Build Coastguard Worker utf8Bytes,
206*c8dee2aaSAndroid Build Coastguard Worker *font,
207*c8dee2aaSAndroid Build Coastguard Worker *bidi,
208*c8dee2aaSAndroid Build Coastguard Worker *script,
209*c8dee2aaSAndroid Build Coastguard Worker *language,
210*c8dee2aaSAndroid Build Coastguard Worker nullptr,
211*c8dee2aaSAndroid Build Coastguard Worker 0,
212*c8dee2aaSAndroid Build Coastguard Worker w - margin,
213*c8dee2aaSAndroid Build Coastguard Worker &builder);
214*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(builder.makeBlob(), 0, 0, paint);
215*c8dee2aaSAndroid Build Coastguard Worker
216*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, builder.endPoint().y());
217*c8dee2aaSAndroid Build Coastguard Worker }
218*c8dee2aaSAndroid Build Coastguard Worker }
219*c8dee2aaSAndroid Build Coastguard Worker
220*c8dee2aaSAndroid Build Coastguard Worker SkSize fSize;
221*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkShaper> fShaper;
222*c8dee2aaSAndroid Build Coastguard Worker MakeBidiIteratorCallback fBidiCallback;
223*c8dee2aaSAndroid Build Coastguard Worker MakeScriptRunCallback fScriptRunCallback;
224*c8dee2aaSAndroid Build Coastguard Worker };
225*c8dee2aaSAndroid Build Coastguard Worker
226*c8dee2aaSAndroid Build Coastguard Worker DEF_SLIDE(return new TextBoxSlide(SkShapers::Primitive::PrimitiveText,
227*c8dee2aaSAndroid Build Coastguard Worker make_trivial_bidi,
228*c8dee2aaSAndroid Build Coastguard Worker make_trivial_script_runner,
229*c8dee2aaSAndroid Build Coastguard Worker "primitive"););
230*c8dee2aaSAndroid Build Coastguard Worker
231*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_SHAPER_CORETEXT_AVAILABLE)
232*c8dee2aaSAndroid Build Coastguard Worker DEF_SLIDE(return new TextBoxSlide(SkShapers::CT::CoreText,
233*c8dee2aaSAndroid Build Coastguard Worker make_trivial_bidi,
234*c8dee2aaSAndroid Build Coastguard Worker make_trivial_script_runner,
235*c8dee2aaSAndroid Build Coastguard Worker "coretext"););
236*c8dee2aaSAndroid Build Coastguard Worker #endif
237*c8dee2aaSAndroid Build Coastguard Worker
238*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) && defined(SK_SHAPER_UNICODE_AVAILABLE)
239*c8dee2aaSAndroid Build Coastguard Worker DEF_SLIDE(return new TextBoxSlide(
__anoncc9255cf0202() 240*c8dee2aaSAndroid Build Coastguard Worker []() {
241*c8dee2aaSAndroid Build Coastguard Worker return SkShapers::HB::ShaperDrivenWrapper(get_unicode(),
242*c8dee2aaSAndroid Build Coastguard Worker SkFontMgr::RefEmpty());
243*c8dee2aaSAndroid Build Coastguard Worker },
244*c8dee2aaSAndroid Build Coastguard Worker make_unicode_bidi,
245*c8dee2aaSAndroid Build Coastguard Worker make_harfbuzz_script_runner,
246*c8dee2aaSAndroid Build Coastguard Worker "harfbuzz"););
247*c8dee2aaSAndroid Build Coastguard Worker #endif
248*c8dee2aaSAndroid Build Coastguard Worker
249*c8dee2aaSAndroid Build Coastguard Worker class ShaperSlide : public Slide {
250*c8dee2aaSAndroid Build Coastguard Worker public:
ShaperSlide()251*c8dee2aaSAndroid Build Coastguard Worker ShaperSlide() { fName = "shaper"; }
252*c8dee2aaSAndroid Build Coastguard Worker
draw(SkCanvas * canvas)253*c8dee2aaSAndroid Build Coastguard Worker void draw(SkCanvas* canvas) override {
254*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(10, 30);
255*c8dee2aaSAndroid Build Coastguard Worker
256*c8dee2aaSAndroid Build Coastguard Worker const char text[] = "world";
257*c8dee2aaSAndroid Build Coastguard Worker
258*c8dee2aaSAndroid Build Coastguard Worker for (SkScalar size = 30; size <= 30; size += 10) {
259*c8dee2aaSAndroid Build Coastguard Worker this->drawTest(canvas,
260*c8dee2aaSAndroid Build Coastguard Worker text,
261*c8dee2aaSAndroid Build Coastguard Worker size,
262*c8dee2aaSAndroid Build Coastguard Worker SkShapers::Primitive::PrimitiveText(),
263*c8dee2aaSAndroid Build Coastguard Worker make_trivial_bidi,
264*c8dee2aaSAndroid Build Coastguard Worker make_trivial_script_runner);
265*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, size + 5);
266*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_SHAPER_CORETEXT_AVAILABLE)
267*c8dee2aaSAndroid Build Coastguard Worker this->drawTest(canvas,
268*c8dee2aaSAndroid Build Coastguard Worker text,
269*c8dee2aaSAndroid Build Coastguard Worker size,
270*c8dee2aaSAndroid Build Coastguard Worker SkShapers::CT::CoreText(),
271*c8dee2aaSAndroid Build Coastguard Worker make_trivial_bidi,
272*c8dee2aaSAndroid Build Coastguard Worker make_trivial_script_runner);
273*c8dee2aaSAndroid Build Coastguard Worker #endif
274*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, size + 5);
275*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) && defined(SK_SHAPER_UNICODE_AVAILABLE)
276*c8dee2aaSAndroid Build Coastguard Worker auto unicode = get_unicode();
277*c8dee2aaSAndroid Build Coastguard Worker this->drawTest(
278*c8dee2aaSAndroid Build Coastguard Worker canvas,
279*c8dee2aaSAndroid Build Coastguard Worker text,
280*c8dee2aaSAndroid Build Coastguard Worker size,
281*c8dee2aaSAndroid Build Coastguard Worker SkShapers::HB::ShaperDrivenWrapper(unicode, SkFontMgr::RefEmpty()),
282*c8dee2aaSAndroid Build Coastguard Worker make_unicode_bidi,
283*c8dee2aaSAndroid Build Coastguard Worker make_harfbuzz_script_runner);
284*c8dee2aaSAndroid Build Coastguard Worker #endif
285*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, size*2);
286*c8dee2aaSAndroid Build Coastguard Worker }
287*c8dee2aaSAndroid Build Coastguard Worker }
288*c8dee2aaSAndroid Build Coastguard Worker
289*c8dee2aaSAndroid Build Coastguard Worker private:
drawTest(SkCanvas * canvas,const char str[],SkScalar size,std::unique_ptr<SkShaper> shaper,MakeBidiIteratorCallback bidiCallback,MakeScriptRunCallback scriptRunCallback)290*c8dee2aaSAndroid Build Coastguard Worker void drawTest(SkCanvas* canvas,
291*c8dee2aaSAndroid Build Coastguard Worker const char str[],
292*c8dee2aaSAndroid Build Coastguard Worker SkScalar size,
293*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkShaper> shaper,
294*c8dee2aaSAndroid Build Coastguard Worker MakeBidiIteratorCallback bidiCallback,
295*c8dee2aaSAndroid Build Coastguard Worker MakeScriptRunCallback scriptRunCallback) {
296*c8dee2aaSAndroid Build Coastguard Worker if (!shaper) return;
297*c8dee2aaSAndroid Build Coastguard Worker
298*c8dee2aaSAndroid Build Coastguard Worker SkTextBlobBuilderRunHandler builder(str, {0, 0});
299*c8dee2aaSAndroid Build Coastguard Worker SkFont srcFont;
300*c8dee2aaSAndroid Build Coastguard Worker srcFont.setSize(size);
301*c8dee2aaSAndroid Build Coastguard Worker srcFont.setEdging(SkFont::Edging::kSubpixelAntiAlias);
302*c8dee2aaSAndroid Build Coastguard Worker srcFont.setSubpixel(true);
303*c8dee2aaSAndroid Build Coastguard Worker
304*c8dee2aaSAndroid Build Coastguard Worker size_t len = strlen(str);
305*c8dee2aaSAndroid Build Coastguard Worker
306*c8dee2aaSAndroid Build Coastguard Worker auto unicode = get_unicode();
307*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkShaper::BiDiRunIterator> bidi =
308*c8dee2aaSAndroid Build Coastguard Worker bidiCallback(unicode, str, len, 0xfe);
309*c8dee2aaSAndroid Build Coastguard Worker if (!bidi) {
310*c8dee2aaSAndroid Build Coastguard Worker return;
311*c8dee2aaSAndroid Build Coastguard Worker }
312*c8dee2aaSAndroid Build Coastguard Worker
313*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkShaper::LanguageRunIterator> language(
314*c8dee2aaSAndroid Build Coastguard Worker SkShaper::MakeStdLanguageRunIterator(str, len));
315*c8dee2aaSAndroid Build Coastguard Worker if (!language) {
316*c8dee2aaSAndroid Build Coastguard Worker return;
317*c8dee2aaSAndroid Build Coastguard Worker }
318*c8dee2aaSAndroid Build Coastguard Worker
319*c8dee2aaSAndroid Build Coastguard Worker SkFourByteTag undeterminedScript = SkSetFourByteTag('Z','y','y','y');
320*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkShaper::ScriptRunIterator> script(
321*c8dee2aaSAndroid Build Coastguard Worker scriptRunCallback(str, len, undeterminedScript));
322*c8dee2aaSAndroid Build Coastguard Worker if (!script) {
323*c8dee2aaSAndroid Build Coastguard Worker return;
324*c8dee2aaSAndroid Build Coastguard Worker }
325*c8dee2aaSAndroid Build Coastguard Worker
326*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkShaper::FontRunIterator> font(
327*c8dee2aaSAndroid Build Coastguard Worker SkShaper::MakeFontMgrRunIterator(str,
328*c8dee2aaSAndroid Build Coastguard Worker len,
329*c8dee2aaSAndroid Build Coastguard Worker srcFont,
330*c8dee2aaSAndroid Build Coastguard Worker ToolUtils::TestFontMgr(),
331*c8dee2aaSAndroid Build Coastguard Worker "Arial",
332*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle::Bold(),
333*c8dee2aaSAndroid Build Coastguard Worker &*language));
334*c8dee2aaSAndroid Build Coastguard Worker if (!font) {
335*c8dee2aaSAndroid Build Coastguard Worker return;
336*c8dee2aaSAndroid Build Coastguard Worker }
337*c8dee2aaSAndroid Build Coastguard Worker
338*c8dee2aaSAndroid Build Coastguard Worker shaper->shape(str, len, *font, *bidi, *script, *language, nullptr, 0, 2000, &builder);
339*c8dee2aaSAndroid Build Coastguard Worker
340*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(builder.makeBlob(), 0, 0, SkPaint());
341*c8dee2aaSAndroid Build Coastguard Worker }
342*c8dee2aaSAndroid Build Coastguard Worker };
343*c8dee2aaSAndroid Build Coastguard Worker
344*c8dee2aaSAndroid Build Coastguard Worker DEF_SLIDE( return new ShaperSlide; );
345