1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2020 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 "fuzz/Fuzz.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "fuzz/FuzzCommon.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontMgr.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontStyle.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSpan.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/DartTypes.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/FontCollection.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/Paragraph.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/ParagraphCache.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/ParagraphStyle.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/TextShadow.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/TextStyle.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/TypefaceFontProvider.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/src/ParagraphBuilderImpl.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/src/ParagraphImpl.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/src/Run.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/src/TextLine.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/utils/TestFontCollection.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skshaper/utils/FactoryHelpers.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkOSFile.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/utils/SkOSPath.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "tools/Resources.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h"
44*c8dee2aaSAndroid Build Coastguard Worker
45*c8dee2aaSAndroid Build Coastguard Worker #include <string.h>
46*c8dee2aaSAndroid Build Coastguard Worker #include <algorithm>
47*c8dee2aaSAndroid Build Coastguard Worker #include <limits>
48*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
49*c8dee2aaSAndroid Build Coastguard Worker #include <string>
50*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
51*c8dee2aaSAndroid Build Coastguard Worker #include <vector>
52*c8dee2aaSAndroid Build Coastguard Worker
53*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_ENABLE_PARAGRAPH)
54*c8dee2aaSAndroid Build Coastguard Worker
55*c8dee2aaSAndroid Build Coastguard Worker using namespace skia::textlayout;
56*c8dee2aaSAndroid Build Coastguard Worker namespace {
57*c8dee2aaSAndroid Build Coastguard Worker const uint8_t MAX_TEXT_LENGTH = 255;
58*c8dee2aaSAndroid Build Coastguard Worker const uint8_t MAX_TEXT_ADDITIONS = 4;
59*c8dee2aaSAndroid Build Coastguard Worker // Use 250 so uint8 can create text and layout width larger than the canvas.
60*c8dee2aaSAndroid Build Coastguard Worker const uint16_t TEST_CANVAS_DIM = 250;
61*c8dee2aaSAndroid Build Coastguard Worker
62*c8dee2aaSAndroid Build Coastguard Worker class ResourceFontCollection : public FontCollection {
63*c8dee2aaSAndroid Build Coastguard Worker public:
ResourceFontCollection(bool testOnly=false)64*c8dee2aaSAndroid Build Coastguard Worker ResourceFontCollection(bool testOnly = false)
65*c8dee2aaSAndroid Build Coastguard Worker : fFontsFound(false)
66*c8dee2aaSAndroid Build Coastguard Worker , fResolvedFonts(0)
67*c8dee2aaSAndroid Build Coastguard Worker , fResourceDir(GetResourcePath("fonts").c_str())
68*c8dee2aaSAndroid Build Coastguard Worker , fFontProvider(sk_make_sp<TypefaceFontProvider>()) {
69*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkString> fonts;
70*c8dee2aaSAndroid Build Coastguard Worker SkOSFile::Iter iter(fResourceDir.c_str());
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker SkString path;
73*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkFontMgr> mgr = ToolUtils::TestFontMgr();
74*c8dee2aaSAndroid Build Coastguard Worker while (iter.next(&path)) {
75*c8dee2aaSAndroid Build Coastguard Worker if (path.endsWith("Roboto-Italic.ttf")) {
76*c8dee2aaSAndroid Build Coastguard Worker fFontsFound = true;
77*c8dee2aaSAndroid Build Coastguard Worker }
78*c8dee2aaSAndroid Build Coastguard Worker fonts.emplace_back(path);
79*c8dee2aaSAndroid Build Coastguard Worker }
80*c8dee2aaSAndroid Build Coastguard Worker
81*c8dee2aaSAndroid Build Coastguard Worker if (!fFontsFound) {
82*c8dee2aaSAndroid Build Coastguard Worker // SkDebugf("Fonts not found, skipping all the tests\n");
83*c8dee2aaSAndroid Build Coastguard Worker return;
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker // Only register fonts if we have to
86*c8dee2aaSAndroid Build Coastguard Worker for (auto& font : fonts) {
87*c8dee2aaSAndroid Build Coastguard Worker SkString file_path;
88*c8dee2aaSAndroid Build Coastguard Worker file_path.printf("%s/%s", fResourceDir.c_str(), font.c_str());
89*c8dee2aaSAndroid Build Coastguard Worker fFontProvider->registerTypeface(mgr->makeFromFile(file_path.c_str(), 0));
90*c8dee2aaSAndroid Build Coastguard Worker }
91*c8dee2aaSAndroid Build Coastguard Worker
92*c8dee2aaSAndroid Build Coastguard Worker if (testOnly) {
93*c8dee2aaSAndroid Build Coastguard Worker this->setTestFontManager(std::move(fFontProvider));
94*c8dee2aaSAndroid Build Coastguard Worker } else {
95*c8dee2aaSAndroid Build Coastguard Worker this->setAssetFontManager(std::move(fFontProvider));
96*c8dee2aaSAndroid Build Coastguard Worker }
97*c8dee2aaSAndroid Build Coastguard Worker this->disableFontFallback();
98*c8dee2aaSAndroid Build Coastguard Worker }
99*c8dee2aaSAndroid Build Coastguard Worker
resolvedFonts() const100*c8dee2aaSAndroid Build Coastguard Worker size_t resolvedFonts() const { return fResolvedFonts; }
101*c8dee2aaSAndroid Build Coastguard Worker
102*c8dee2aaSAndroid Build Coastguard Worker // TODO: temp solution until we check in fonts
fontsFound() const103*c8dee2aaSAndroid Build Coastguard Worker bool fontsFound() const { return fFontsFound; }
104*c8dee2aaSAndroid Build Coastguard Worker
105*c8dee2aaSAndroid Build Coastguard Worker private:
106*c8dee2aaSAndroid Build Coastguard Worker bool fFontsFound;
107*c8dee2aaSAndroid Build Coastguard Worker size_t fResolvedFonts;
108*c8dee2aaSAndroid Build Coastguard Worker std::string fResourceDir;
109*c8dee2aaSAndroid Build Coastguard Worker sk_sp<TypefaceFontProvider> fFontProvider;
110*c8dee2aaSAndroid Build Coastguard Worker };
111*c8dee2aaSAndroid Build Coastguard Worker
112*c8dee2aaSAndroid Build Coastguard Worker // buffer must be at least MAX_TEXT_LENGTH in length.
113*c8dee2aaSAndroid Build Coastguard Worker // Returns size of text placed in buffer.
114*c8dee2aaSAndroid Build Coastguard Worker template <typename T>
RandomText(T * buffer,Fuzz * fuzz)115*c8dee2aaSAndroid Build Coastguard Worker uint8_t RandomText(T* buffer, Fuzz* fuzz) {
116*c8dee2aaSAndroid Build Coastguard Worker uint8_t text_length;
117*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&text_length, 0, MAX_TEXT_LENGTH);
118*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextN(buffer, text_length);
119*c8dee2aaSAndroid Build Coastguard Worker return text_length;
120*c8dee2aaSAndroid Build Coastguard Worker }
121*c8dee2aaSAndroid Build Coastguard Worker
122*c8dee2aaSAndroid Build Coastguard Worker // Add random bytes to the paragraph.
AddASCIIText(ParagraphBuilder * builder,Fuzz * fuzz)123*c8dee2aaSAndroid Build Coastguard Worker void AddASCIIText(ParagraphBuilder* builder,Fuzz* fuzz) {
124*c8dee2aaSAndroid Build Coastguard Worker char text[MAX_TEXT_LENGTH];
125*c8dee2aaSAndroid Build Coastguard Worker const auto text_length = RandomText(text, fuzz);
126*c8dee2aaSAndroid Build Coastguard Worker builder->addText(text, text_length);
127*c8dee2aaSAndroid Build Coastguard Worker }
128*c8dee2aaSAndroid Build Coastguard Worker // Add random bytes to the paragraph.
AddUnicodeText(ParagraphBuilder * builder,Fuzz * fuzz)129*c8dee2aaSAndroid Build Coastguard Worker void AddUnicodeText(ParagraphBuilder* builder,Fuzz* fuzz) {
130*c8dee2aaSAndroid Build Coastguard Worker char16_t text[MAX_TEXT_LENGTH];
131*c8dee2aaSAndroid Build Coastguard Worker const auto text_length = RandomText(text, fuzz);
132*c8dee2aaSAndroid Build Coastguard Worker builder->addText(std::u16string(text, text_length));
133*c8dee2aaSAndroid Build Coastguard Worker }
134*c8dee2aaSAndroid Build Coastguard Worker
135*c8dee2aaSAndroid Build Coastguard Worker // Combining characters to produce 'Zalgo' text.
136*c8dee2aaSAndroid Build Coastguard Worker const std::u16string COMBINING_DOWN = u"\u0316\u0317\u0318\u0319\u031c\u031d\u031e\u031f\u0320\u0324\u0325\u0326\u0329\u032a\u032b\u032c\u032d\u032e\u032f\u0330\u0331\u0332\u0333\u0339\u033a\u033b\u033c\u0345\u0347\u0348\u0349\u034d\u034e\u0353\u0354\u0355\u0356\u0359\u035a\u0323";
137*c8dee2aaSAndroid Build Coastguard Worker const std::u16string COMBINING_UP = u"\u030d\u030e\u0304\u0305\u033f\u0311\u0306\u0310\u0352\u0357\u0351\u0307\u0308\u030a\u0342\u0343\u0344\u034a\u034b\u034c\u0303\u0302\u030c\u0350\u0300\u0301\u030b\u030f\u0312\u0313\u0314\u033d\u0309\u0363\u0364\u0365\u0366\u0367\u0368\u0369\u036a\u036b\u036c\u036d\u036e\u035b\u0346\u031a";
138*c8dee2aaSAndroid Build Coastguard Worker const std::u16string COMBINING_MIDDLE = u"\u0315\u031b\u0340\u0341\u0358\u0321\u0322\u0327\u0328\u0334\u0335\u0336\u034f\u035c\u035d\u035e\u035f\u0360\u0362\u0338\u0337\u0361\u0489";
139*c8dee2aaSAndroid Build Coastguard Worker // Add random Zalgo text to the paragraph.
AddZalgoText(ParagraphBuilder * builder,Fuzz * fuzz)140*c8dee2aaSAndroid Build Coastguard Worker void AddZalgoText(ParagraphBuilder* builder, Fuzz* fuzz) {
141*c8dee2aaSAndroid Build Coastguard Worker char text[MAX_TEXT_LENGTH];
142*c8dee2aaSAndroid Build Coastguard Worker const auto text_length = RandomText(text, fuzz);
143*c8dee2aaSAndroid Build Coastguard Worker std::u16string result;
144*c8dee2aaSAndroid Build Coastguard Worker
145*c8dee2aaSAndroid Build Coastguard Worker for (auto& c : std::string(text, text_length)) {
146*c8dee2aaSAndroid Build Coastguard Worker result += c;
147*c8dee2aaSAndroid Build Coastguard Worker uint8_t mark_count;
148*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&mark_count);
149*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < mark_count; i++) {
150*c8dee2aaSAndroid Build Coastguard Worker uint8_t mark_type, mark_index;
151*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&mark_type, &mark_index);
152*c8dee2aaSAndroid Build Coastguard Worker switch (mark_type % 3) {
153*c8dee2aaSAndroid Build Coastguard Worker case 0:
154*c8dee2aaSAndroid Build Coastguard Worker result += COMBINING_UP[mark_index % COMBINING_UP.size()];
155*c8dee2aaSAndroid Build Coastguard Worker break;
156*c8dee2aaSAndroid Build Coastguard Worker case 1:
157*c8dee2aaSAndroid Build Coastguard Worker result += COMBINING_MIDDLE[mark_index % COMBINING_MIDDLE.size()];
158*c8dee2aaSAndroid Build Coastguard Worker break;
159*c8dee2aaSAndroid Build Coastguard Worker case 2:
160*c8dee2aaSAndroid Build Coastguard Worker default:
161*c8dee2aaSAndroid Build Coastguard Worker result += COMBINING_DOWN[mark_index % COMBINING_DOWN.size()];
162*c8dee2aaSAndroid Build Coastguard Worker break;
163*c8dee2aaSAndroid Build Coastguard Worker }
164*c8dee2aaSAndroid Build Coastguard Worker }
165*c8dee2aaSAndroid Build Coastguard Worker }
166*c8dee2aaSAndroid Build Coastguard Worker builder->addText(result);
167*c8dee2aaSAndroid Build Coastguard Worker }
168*c8dee2aaSAndroid Build Coastguard Worker
AddStyle(ParagraphBuilder * builder,Fuzz * fuzz)169*c8dee2aaSAndroid Build Coastguard Worker void AddStyle(ParagraphBuilder* builder, Fuzz* fuzz) {
170*c8dee2aaSAndroid Build Coastguard Worker // TODO(westont): Make this probabilistic, and fill in the remaining TextStyle fields.
171*c8dee2aaSAndroid Build Coastguard Worker TextStyle ts;
172*c8dee2aaSAndroid Build Coastguard Worker ts.setFontFamilies({SkString("Roboto")});
173*c8dee2aaSAndroid Build Coastguard Worker //ts.setColor(SK_ColorBLACK);
174*c8dee2aaSAndroid Build Coastguard Worker //ts.setForegroundColor
175*c8dee2aaSAndroid Build Coastguard Worker //ts.setBackgroundColor
176*c8dee2aaSAndroid Build Coastguard Worker //ts.setDecoration(TextDecoration decoration);
177*c8dee2aaSAndroid Build Coastguard Worker //ts.setDecorationMode(TextDecorationMode mode);
178*c8dee2aaSAndroid Build Coastguard Worker //ts.setDecorationStyle(TextDecorationStyle style);
179*c8dee2aaSAndroid Build Coastguard Worker //ts.setDecorationColor(SkColor color);
180*c8dee2aaSAndroid Build Coastguard Worker //ts.setDecorationThicknessMultiplier(SkScalar m);
181*c8dee2aaSAndroid Build Coastguard Worker //ts.setFontStyle
182*c8dee2aaSAndroid Build Coastguard Worker //ts.addShadow
183*c8dee2aaSAndroid Build Coastguard Worker //ts.addFontFeature
184*c8dee2aaSAndroid Build Coastguard Worker //ts.setFontSize
185*c8dee2aaSAndroid Build Coastguard Worker //ts.setHeight
186*c8dee2aaSAndroid Build Coastguard Worker //ts.setHeightOverride
187*c8dee2aaSAndroid Build Coastguard Worker //ts.setletterSpacing
188*c8dee2aaSAndroid Build Coastguard Worker //ts.setWordSpacing
189*c8dee2aaSAndroid Build Coastguard Worker //ts.setTypeface
190*c8dee2aaSAndroid Build Coastguard Worker //ts.setLocale
191*c8dee2aaSAndroid Build Coastguard Worker //ts.setTextBaseline
192*c8dee2aaSAndroid Build Coastguard Worker //ts.setPlaceholder
193*c8dee2aaSAndroid Build Coastguard Worker
194*c8dee2aaSAndroid Build Coastguard Worker builder->pushStyle(ts);
195*c8dee2aaSAndroid Build Coastguard Worker }
RemoveStyle(ParagraphBuilder * builder,Fuzz * fuzz)196*c8dee2aaSAndroid Build Coastguard Worker void RemoveStyle(ParagraphBuilder* builder, Fuzz* fuzz) {
197*c8dee2aaSAndroid Build Coastguard Worker bool pop;
198*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&pop);
199*c8dee2aaSAndroid Build Coastguard Worker if (pop) {
200*c8dee2aaSAndroid Build Coastguard Worker builder->pop();
201*c8dee2aaSAndroid Build Coastguard Worker }
202*c8dee2aaSAndroid Build Coastguard Worker }
203*c8dee2aaSAndroid Build Coastguard Worker
AddStyleAndText(ParagraphBuilder * builder,Fuzz * fuzz)204*c8dee2aaSAndroid Build Coastguard Worker void AddStyleAndText(ParagraphBuilder* builder, Fuzz* fuzz) {
205*c8dee2aaSAndroid Build Coastguard Worker AddStyle(builder, fuzz);
206*c8dee2aaSAndroid Build Coastguard Worker uint8_t text_type;
207*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&text_type);
208*c8dee2aaSAndroid Build Coastguard Worker switch (text_type % 3) {
209*c8dee2aaSAndroid Build Coastguard Worker case 0:
210*c8dee2aaSAndroid Build Coastguard Worker AddASCIIText(builder, fuzz);
211*c8dee2aaSAndroid Build Coastguard Worker break;
212*c8dee2aaSAndroid Build Coastguard Worker case 1:
213*c8dee2aaSAndroid Build Coastguard Worker AddUnicodeText(builder, fuzz);
214*c8dee2aaSAndroid Build Coastguard Worker break;
215*c8dee2aaSAndroid Build Coastguard Worker case 2:
216*c8dee2aaSAndroid Build Coastguard Worker AddZalgoText(builder, fuzz);
217*c8dee2aaSAndroid Build Coastguard Worker break;
218*c8dee2aaSAndroid Build Coastguard Worker }
219*c8dee2aaSAndroid Build Coastguard Worker RemoveStyle(builder, fuzz);
220*c8dee2aaSAndroid Build Coastguard Worker
221*c8dee2aaSAndroid Build Coastguard Worker }
222*c8dee2aaSAndroid Build Coastguard Worker
BuildParagraphStyle(Fuzz * fuzz)223*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle BuildParagraphStyle(Fuzz* fuzz) {
224*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle ps;
225*c8dee2aaSAndroid Build Coastguard Worker bool hinting;
226*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&hinting);
227*c8dee2aaSAndroid Build Coastguard Worker if (hinting) {
228*c8dee2aaSAndroid Build Coastguard Worker ps.turnHintingOff();
229*c8dee2aaSAndroid Build Coastguard Worker }
230*c8dee2aaSAndroid Build Coastguard Worker StrutStyle ss;
231*c8dee2aaSAndroid Build Coastguard Worker // TODO(westont): Fuzz this object.
232*c8dee2aaSAndroid Build Coastguard Worker ps.setStrutStyle(ss);
233*c8dee2aaSAndroid Build Coastguard Worker TextDirection td;
234*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&td, TextDirection::kRtl);
235*c8dee2aaSAndroid Build Coastguard Worker ps.setTextDirection(td);
236*c8dee2aaSAndroid Build Coastguard Worker TextAlign ta;
237*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextEnum(&ta, TextAlign::kEnd);
238*c8dee2aaSAndroid Build Coastguard Worker ps.setTextAlign(ta);
239*c8dee2aaSAndroid Build Coastguard Worker size_t ml;
240*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&ml);
241*c8dee2aaSAndroid Build Coastguard Worker ps.setMaxLines(ml);
242*c8dee2aaSAndroid Build Coastguard Worker // TODO(westont): Randomize with other values and no value.
243*c8dee2aaSAndroid Build Coastguard Worker ps.setEllipsis(u"\u2026");
244*c8dee2aaSAndroid Build Coastguard Worker SkScalar h;
245*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&h);
246*c8dee2aaSAndroid Build Coastguard Worker ps.setHeight(h);
247*c8dee2aaSAndroid Build Coastguard Worker TextHeightBehavior thb = TextHeightBehavior::kAll;
248*c8dee2aaSAndroid Build Coastguard Worker // TODO(westont): This crashes our seed test case, why?
249*c8dee2aaSAndroid Build Coastguard Worker //fuzz->nextEnum(&thb, TextHeightBehavior::kDisableAll);
250*c8dee2aaSAndroid Build Coastguard Worker ps.setTextHeightBehavior(thb);
251*c8dee2aaSAndroid Build Coastguard Worker
252*c8dee2aaSAndroid Build Coastguard Worker return ps;
253*c8dee2aaSAndroid Build Coastguard Worker }
254*c8dee2aaSAndroid Build Coastguard Worker
get_unicode()255*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkUnicode> get_unicode() {
256*c8dee2aaSAndroid Build Coastguard Worker auto factory = SkShapers::BestAvailable();
257*c8dee2aaSAndroid Build Coastguard Worker return sk_ref_sp<SkUnicode>(factory->getUnicode());
258*c8dee2aaSAndroid Build Coastguard Worker }
259*c8dee2aaSAndroid Build Coastguard Worker
260*c8dee2aaSAndroid Build Coastguard Worker } // namespace
261*c8dee2aaSAndroid Build Coastguard Worker
DEF_FUZZ(SkParagraph,fuzz)262*c8dee2aaSAndroid Build Coastguard Worker DEF_FUZZ(SkParagraph, fuzz) {
263*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
264*c8dee2aaSAndroid Build Coastguard Worker ParagraphStyle paragraph_style = BuildParagraphStyle(fuzz);
265*c8dee2aaSAndroid Build Coastguard Worker ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());
266*c8dee2aaSAndroid Build Coastguard Worker
267*c8dee2aaSAndroid Build Coastguard Worker uint8_t iterations;
268*c8dee2aaSAndroid Build Coastguard Worker fuzz->nextRange(&iterations, 1, MAX_TEXT_ADDITIONS);
269*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < iterations; i++) {
270*c8dee2aaSAndroid Build Coastguard Worker AddStyleAndText(&builder, fuzz);
271*c8dee2aaSAndroid Build Coastguard Worker }
272*c8dee2aaSAndroid Build Coastguard Worker // TODO(westont): Figure out if we can get more converage by having fontsFound, current
273*c8dee2aaSAndroid Build Coastguard Worker // they're not.
274*c8dee2aaSAndroid Build Coastguard Worker // if (!fontCollection->fontsFound()) return;
275*c8dee2aaSAndroid Build Coastguard Worker
276*c8dee2aaSAndroid Build Coastguard Worker builder.pop();
277*c8dee2aaSAndroid Build Coastguard Worker auto paragraph = builder.Build();
278*c8dee2aaSAndroid Build Coastguard Worker
279*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bm;
280*c8dee2aaSAndroid Build Coastguard Worker if (!bm.tryAllocN32Pixels(TEST_CANVAS_DIM, TEST_CANVAS_DIM)) {
281*c8dee2aaSAndroid Build Coastguard Worker return;
282*c8dee2aaSAndroid Build Coastguard Worker }
283*c8dee2aaSAndroid Build Coastguard Worker SkCanvas canvas(bm);
284*c8dee2aaSAndroid Build Coastguard Worker uint8_t layout_width;
285*c8dee2aaSAndroid Build Coastguard Worker fuzz->next(&layout_width);
286*c8dee2aaSAndroid Build Coastguard Worker paragraph->layout(layout_width);
287*c8dee2aaSAndroid Build Coastguard Worker paragraph->paint(&canvas, 0, 0);
288*c8dee2aaSAndroid Build Coastguard Worker }
289*c8dee2aaSAndroid Build Coastguard Worker
290*c8dee2aaSAndroid Build Coastguard Worker #endif // SK_ENABLE_PARAGRAPH
291