blob: 129d4f218d75700ebd5695bfc0085c8693072641 [file] [log] [blame]
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001// Copyright 2019 Google LLC.
Julia Lavrovaa3552c52019-05-30 16:12:56 -04002#include "include/core/SkCanvas.h"
3#include "include/core/SkColorFilter.h"
4#include "include/core/SkColorPriv.h"
5#include "include/core/SkGraphics.h"
6#include "include/core/SkPath.h"
7#include "include/core/SkRegion.h"
8#include "include/core/SkShader.h"
9#include "include/core/SkStream.h"
10#include "include/core/SkTextBlob.h"
11#include "include/core/SkTime.h"
12#include "include/core/SkTypeface.h"
13#include "include/effects/SkBlurMaskFilter.h"
14#include "include/effects/SkGradientShader.h"
15#include "include/utils/SkRandom.h"
16#include "modules/skparagraph/include/Paragraph.h"
Julia Lavrova6e6333f2019-06-17 10:34:10 -040017#include "modules/skparagraph/include/TypefaceFontProvider.h"
Julia Lavrovaa3552c52019-05-30 16:12:56 -040018#include "modules/skparagraph/src/ParagraphBuilderImpl.h"
19#include "modules/skparagraph/src/ParagraphImpl.h"
Julia Lavrova9af5cc42019-06-19 13:32:01 -040020#include "modules/skparagraph/utils/TestFontCollection.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040021#include "samplecode/Sample.h"
Julia Lavrovaa3552c52019-05-30 16:12:56 -040022#include "src/core/SkOSFile.h"
23#include "src/shaders/SkColorShader.h"
24#include "src/utils/SkUTF.h"
25#include "tools/Resources.h"
26
27using namespace skia::textlayout;
28namespace {
29
Mike Reed21a940d2019-07-23 10:11:03 -040030class ParagraphView_Base : public Sample {
31protected:
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -040032 sk_sp<TestFontCollection> getFontCollection() {
33 // If we reset font collection we need to reset paragraph cache
34 static sk_sp<TestFontCollection> fFC = nullptr;
35 if (fFC == nullptr) {
36 fFC = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str());
37 }
38 return fFC;
Mike Reed21a940d2019-07-23 10:11:03 -040039 }
40};
41
Julia Lavrovaa3552c52019-05-30 16:12:56 -040042sk_sp<SkShader> setgrad(const SkRect& r, SkColor c0, SkColor c1) {
43 SkColor colors[] = {c0, c1};
44 SkPoint pts[] = {{r.fLeft, r.fTop}, {r.fRight, r.fTop}};
45 return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
46}
Julia Lavrova5207f352019-06-21 12:22:32 -040047
48const char* gText =
49 "This is a very long sentence to test if the text will properly wrap "
50 "around and go to the next line. Sometimes, short sentence. Longer "
51 "sentences are okay too because they are nessecary. Very short. "
52 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
53 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
54 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
55 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
56 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
57 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
58 "mollit anim id est laborum. "
59 "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
60 "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
61 "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
62 "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
63 "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
64 "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
65 "mollit anim id est laborum.";
66
Julia Lavrovaa3552c52019-05-30 16:12:56 -040067} // namespace
68
Mike Reed21a940d2019-07-23 10:11:03 -040069class ParagraphView1 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -040070protected:
Hal Canary8a027312019-07-03 10:55:44 -040071 SkString name() override { return SkString("Paragraph1"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -040072
73 void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) {
74 const std::vector<
75 std::tuple<std::string, bool, bool, int, SkColor, SkColor, bool, TextDecorationStyle>>
76 gParagraph = {{"monospace", true, false, 14, SK_ColorWHITE, SK_ColorRED, true,
77 TextDecorationStyle::kDashed},
78 {"Assyrian", false, false, 20, SK_ColorWHITE, SK_ColorBLUE, false,
79 TextDecorationStyle::kDotted},
80 {"serif", true, true, 10, SK_ColorWHITE, SK_ColorRED, true,
81 TextDecorationStyle::kDouble},
82 {"Arial", false, true, 16, SK_ColorGRAY, SK_ColorGREEN, true,
83 TextDecorationStyle::kSolid},
84 {"sans-serif", false, false, 8, SK_ColorWHITE, SK_ColorRED, false,
85 TextDecorationStyle::kWavy}};
86 SkAutoCanvasRestore acr(canvas, true);
87
88 canvas->clipRect(SkRect::MakeWH(w, h));
89 canvas->drawColor(SK_ColorWHITE);
90
91 SkScalar margin = 20;
92
93 SkPaint paint;
94 paint.setAntiAlias(true);
95 paint.setColor(fg);
96
97 SkPaint blue;
98 blue.setColor(SK_ColorBLUE);
99
100 TextStyle defaultStyle;
101 defaultStyle.setBackgroundColor(blue);
102 defaultStyle.setForegroundColor(paint);
103 ParagraphStyle paraStyle;
104
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400105 auto fontCollection = sk_make_sp<FontCollection>();
106 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400107 for (auto i = 1; i < 5; ++i) {
108 defaultStyle.setFontSize(24 * i);
109 paraStyle.setTextStyle(defaultStyle);
Julia Lavrova5207f352019-06-21 12:22:32 -0400110 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400111 std::string name = "Paragraph: " + std::to_string(24 * i);
112 builder.addText(name.c_str());
113 for (auto para : gParagraph) {
114 TextStyle style;
115 style.setFontFamilies({SkString(std::get<0>(para).c_str())});
116 SkFontStyle fontStyle(std::get<1>(para) ? SkFontStyle::Weight::kBold_Weight
117 : SkFontStyle::Weight::kNormal_Weight,
118 SkFontStyle::Width::kNormal_Width,
119 std::get<2>(para) ? SkFontStyle::Slant::kItalic_Slant
120 : SkFontStyle::Slant::kUpright_Slant);
121 style.setFontStyle(fontStyle);
122 style.setFontSize(std::get<3>(para) * i);
123 SkPaint background;
124 background.setColor(std::get<4>(para));
125 style.setBackgroundColor(background);
126 SkPaint foreground;
127 foreground.setColor(std::get<5>(para));
128 foreground.setAntiAlias(true);
129 style.setForegroundColor(foreground);
130 if (std::get<6>(para)) {
131 style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(5, 5), 2));
132 }
133
134 auto decoration = (i % 4);
135 if (decoration == 3) {
136 decoration = 4;
137 }
138
139 bool test = (TextDecoration)decoration != TextDecoration::kNoDecoration;
140 std::string deco = std::to_string((int)decoration);
141 if (test) {
142 style.setDecoration((TextDecoration)decoration);
143 style.setDecorationStyle(std::get<7>(para));
144 style.setDecorationColor(std::get<5>(para));
145 }
146 builder.pushStyle(style);
147 std::string name = " " + std::get<0>(para) + " " +
148 (std::get<1>(para) ? ", bold" : "") +
149 (std::get<2>(para) ? ", italic" : "") + " " +
150 std::to_string(std::get<3>(para) * i) +
151 (std::get<4>(para) != bg ? ", background" : "") +
152 (std::get<5>(para) != fg ? ", foreground" : "") +
153 (std::get<6>(para) ? ", shadow" : "") +
154 (test ? ", decorations " + deco : "") + ";";
155 builder.addText(name.c_str());
156 builder.pop();
157 }
158
159 auto paragraph = builder.Build();
160 paragraph->layout(w - margin * 2);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400161 paragraph->paint(canvas, margin, margin);
162
163 canvas->translate(0, paragraph->getHeight());
164 }
165 }
166
167 void onDrawContent(SkCanvas* canvas) override {
168 drawTest(canvas, this->width(), this->height(), SK_ColorRED, SK_ColorWHITE);
169 }
170
171private:
172
173 typedef Sample INHERITED;
174};
175
Mike Reed21a940d2019-07-23 10:11:03 -0400176class ParagraphView2 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400177protected:
Hal Canary8a027312019-07-03 10:55:44 -0400178 SkString name() override { return SkString("Paragraph2"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400179
180 void drawCode(SkCanvas* canvas, SkScalar w, SkScalar h) {
181 SkPaint comment;
182 comment.setColor(SK_ColorGRAY);
183 SkPaint constant;
184 constant.setColor(SK_ColorMAGENTA);
185 SkPaint null;
186 null.setColor(SK_ColorMAGENTA);
187 SkPaint literal;
188 literal.setColor(SK_ColorGREEN);
189 SkPaint code;
190 code.setColor(SK_ColorDKGRAY);
191 SkPaint number;
192 number.setColor(SK_ColorBLUE);
193 SkPaint name;
194 name.setColor(SK_ColorRED);
195
196 SkPaint white;
197 white.setColor(SK_ColorWHITE);
198
199 TextStyle defaultStyle;
200 defaultStyle.setBackgroundColor(white);
201 defaultStyle.setForegroundColor(code);
202 defaultStyle.setFontFamilies({SkString("monospace")});
203 defaultStyle.setFontSize(30);
204 ParagraphStyle paraStyle;
205 paraStyle.setTextStyle(defaultStyle);
206
Julia Lavrova5207f352019-06-21 12:22:32 -0400207 auto fontCollection = sk_make_sp<FontCollection>();
208 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
209 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400210
211 builder.pushStyle(style(name));
212 builder.addText("RaisedButton");
213 builder.pop();
214 builder.addText("(\n");
215 builder.addText(" child: ");
216 builder.pushStyle(style(constant));
217 builder.addText("const");
218 builder.pop();
219 builder.addText(" ");
220 builder.pushStyle(style(name));
221 builder.addText("Text");
222 builder.pop();
223 builder.addText("(");
224 builder.pushStyle(style(literal));
225 builder.addText("'BUTTON TITLE'");
226 builder.pop();
227 builder.addText("),\n");
228
229 auto paragraph = builder.Build();
230 paragraph->layout(w - 20);
231
232 paragraph->paint(canvas, 20, 20);
233 }
234
235 TextStyle style(SkPaint paint) {
236 TextStyle style;
237 paint.setAntiAlias(true);
238 style.setForegroundColor(paint);
239 style.setFontFamilies({SkString("monospace")});
240 style.setFontSize(30);
241
242 return style;
243 }
244
Julia Lavrova5207f352019-06-21 12:22:32 -0400245 void drawText(SkCanvas* canvas, SkScalar w, SkScalar h, std::vector<const char*>& text,
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400246 SkColor fg = SK_ColorDKGRAY, SkColor bg = SK_ColorWHITE,
247 const char* ff = "sans-serif", SkScalar fs = 24,
248 size_t lineLimit = 30,
249 const std::u16string& ellipsis = u"\u2026") {
250 SkAutoCanvasRestore acr(canvas, true);
251
252 canvas->clipRect(SkRect::MakeWH(w, h));
253 canvas->drawColor(bg);
254
255 SkScalar margin = 20;
256
257 SkPaint paint;
258 paint.setAntiAlias(true);
259 paint.setColor(fg);
260
261 SkPaint blue;
262 blue.setColor(SK_ColorBLUE);
263
264 SkPaint background;
265 background.setColor(bg);
266
267 TextStyle style;
268 style.setBackgroundColor(blue);
269 style.setForegroundColor(paint);
270 style.setFontFamilies({SkString(ff)});
271 style.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight,
272 SkFontStyle::kNormal_Width,
273 SkFontStyle::kUpright_Slant));
274 style.setFontSize(fs);
275 ParagraphStyle paraStyle;
276 paraStyle.setTextStyle(style);
277 paraStyle.setMaxLines(lineLimit);
278
279 paraStyle.setEllipsis(ellipsis);
280 TextStyle defaultStyle;
281 defaultStyle.setFontSize(20);
282 paraStyle.setTextStyle(defaultStyle);
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400283 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400284
285 SkPaint foreground;
286 foreground.setColor(fg);
287 style.setForegroundColor(foreground);
288 style.setBackgroundColor(background);
289
290 for (auto& part : text) {
291 builder.pushStyle(style);
Julia Lavrova5207f352019-06-21 12:22:32 -0400292 builder.addText(part);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400293 builder.pop();
294 }
295
296 auto paragraph = builder.Build();
297 paragraph->layout(w - margin * 2);
298 paragraph->paint(canvas, margin, margin);
299
300 canvas->translate(0, paragraph->getHeight() + margin);
301 }
302
303 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
304 TextAlign align) {
305 SkAutoCanvasRestore acr(canvas, true);
306
307 canvas->clipRect(SkRect::MakeWH(w, h));
308 canvas->drawColor(SK_ColorWHITE);
309
310 SkScalar margin = 20;
311
312 SkPaint paint;
313 paint.setAntiAlias(true);
314 paint.setColor(SK_ColorBLUE);
315
316 SkPaint gray;
317 gray.setColor(SK_ColorLTGRAY);
318
319 TextStyle style;
320 style.setBackgroundColor(gray);
321 style.setForegroundColor(paint);
322 style.setFontFamilies({SkString("Arial")});
323 style.setFontSize(30);
324 ParagraphStyle paraStyle;
325 paraStyle.setTextStyle(style);
326 paraStyle.setTextAlign(align);
327
Julia Lavrova5207f352019-06-21 12:22:32 -0400328 auto fontCollection = sk_make_sp<FontCollection>();
329 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
330 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400331 builder.addText(text.c_str());
332
333 auto paragraph = builder.Build();
334 paragraph->layout(w - margin * 2);
335 paragraph->layout(w - margin);
336 paragraph->paint(canvas, margin, margin);
337
338 canvas->translate(0, paragraph->getHeight() + margin);
339 }
340
341 void onDrawContent(SkCanvas* canvas) override {
Julia Lavrova5207f352019-06-21 12:22:32 -0400342 std::vector<const char*> cupertino = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400343 "google_logogoogle_gsuper_g_logo 1 "
344 "google_logogoogle_gsuper_g_logo 12 "
345 "google_logogoogle_gsuper_g_logo 123 "
346 "google_logogoogle_gsuper_g_logo 1234 "
347 "google_logogoogle_gsuper_g_logo 12345 "
348 "google_logogoogle_gsuper_g_logo 123456 "
349 "google_logogoogle_gsuper_g_logo 1234567 "
350 "google_logogoogle_gsuper_g_logo 12345678 "
351 "google_logogoogle_gsuper_g_logo 123456789 "
352 "google_logogoogle_gsuper_g_logo 1234567890 "
353 "google_logogoogle_gsuper_g_logo 123456789 "
354 "google_logogoogle_gsuper_g_logo 12345678 "
355 "google_logogoogle_gsuper_g_logo 1234567 "
356 "google_logogoogle_gsuper_g_logo 123456 "
357 "google_logogoogle_gsuper_g_logo 12345 "
358 "google_logogoogle_gsuper_g_logo 1234 "
359 "google_logogoogle_gsuper_g_logo 123 "
360 "google_logogoogle_gsuper_g_logo 12 "
361 "google_logogoogle_gsuper_g_logo 1 "
362 "google_logogoogle_gsuper_g_logo "
363 "google_logogoogle_gsuper_g_logo "
364 "google_logogoogle_gsuper_g_logo "
365 "google_logogoogle_gsuper_g_logo "
366 "google_logogoogle_gsuper_g_logo "
367 "google_logogoogle_gsuper_g_logo"};
Julia Lavrova5207f352019-06-21 12:22:32 -0400368 std::vector<const char*> text = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400369 "My neighbor came over to say,\n"
370 "Although not in a neighborly way,\n\n"
371 "That he'd knock me around,\n\n\n"
372 "If I didn't stop the sound,\n\n\n\n"
373 "Of the classical music I play."};
374
Julia Lavrova5207f352019-06-21 12:22:32 -0400375 std::vector<const char*> long_word = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400376 "A_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
377 "very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
378 "very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
379 "very_very_very_very_very_very_very_long_text"};
380
Julia Lavrova5207f352019-06-21 12:22:32 -0400381 std::vector<const char*> very_long = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400382 "A very very very very very very very very very very very very very very very very "
383 "very very very very very very very very very very very very very very very very "
384 "very very very very very very very very very very very very very very very very "
385 "very very very very very very very long text"};
386
Julia Lavrova5207f352019-06-21 12:22:32 -0400387 std::vector<const char*> very_word = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400388 "A very_very_very_very_very_very_very_very_very_very "
389 "very_very_very_very_very_very_very_very_very_very very very very very very very "
390 "very very very very very very very very very very very very very very very very "
391 "very very very very very very very very very very very very very long text"};
392
393 SkScalar width = this->width() / 5;
394 SkScalar height = this->height();
395 drawText(canvas, width, height, long_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
396 canvas->translate(width, 0);
397 drawText(canvas, width, height, very_long, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
398 canvas->translate(width, 0);
399 drawText(canvas, width, height, very_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
400 canvas->translate(width, 0);
401
402 drawText(canvas, width, height / 2, text, SK_ColorBLACK, SK_ColorWHITE, "Roboto", 20, 100,
403 u"\u2026");
404 canvas->translate(0, height / 2);
405 drawCode(canvas, width, height / 2);
406 canvas->translate(width, -height / 2);
407
408 drawText(canvas, width, height, cupertino, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
409 }
410
411private:
412 typedef Sample INHERITED;
413};
414
Mike Reed21a940d2019-07-23 10:11:03 -0400415class ParagraphView3 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400416protected:
Hal Canary8a027312019-07-03 10:55:44 -0400417 SkString name() override { return SkString("Paragraph3"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400418
419 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
420 TextAlign align, size_t lineLimit = std::numeric_limits<size_t>::max(),
421 bool RTL = false, SkColor background = SK_ColorGRAY,
422 const std::u16string& ellipsis = u"\u2026") {
423 SkAutoCanvasRestore acr(canvas, true);
424
425 canvas->clipRect(SkRect::MakeWH(w, h));
426 canvas->drawColor(SK_ColorWHITE);
427
428 SkScalar margin = 20;
429
430 SkPaint paint;
431 paint.setAntiAlias(true);
432 paint.setColor(SK_ColorBLACK);
433
434 SkPaint gray;
435 gray.setColor(background);
436
437 SkPaint yellow;
438 yellow.setColor(SK_ColorYELLOW);
439
440 TextStyle style;
441 style.setBackgroundColor(gray);
442 style.setForegroundColor(paint);
443 style.setFontFamilies({SkString("sans-serif")});
444 style.setFontSize(30);
445 ParagraphStyle paraStyle;
446 paraStyle.setTextStyle(style);
447 paraStyle.setTextAlign(align);
448 paraStyle.setMaxLines(lineLimit);
449 paraStyle.setEllipsis(ellipsis);
450 // paraStyle.setTextDirection(RTL ? SkTextDirection::rtl : SkTextDirection::ltr);
451
Julia Lavrova5207f352019-06-21 12:22:32 -0400452 auto fontCollection = sk_make_sp<FontCollection>();
453 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
454 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400455 if (RTL) {
456 builder.addText(mirror(text));
457 } else {
458 builder.addText(normal(text));
459 }
460
461 canvas->drawRect(SkRect::MakeXYWH(margin, margin, w - margin * 2, h - margin * 2), yellow);
462 auto paragraph = builder.Build();
463 paragraph->layout(w - margin * 2);
464 paragraph->paint(canvas, margin, margin);
465 }
466
467 std::u16string mirror(const std::string& text) {
468 std::u16string result;
469 result += u"\u202E";
470 // for (auto i = text.size(); i > 0; --i) {
471 // result += text[i - 1];
472 //}
473
474 for (auto i = text.size(); i > 0; --i) {
475 auto ch = text[i - 1];
476 if (ch == ',') {
477 result += u"!";
478 } else if (ch == '.') {
479 result += u"!";
480 } else {
481 result += ch;
482 }
483 }
484
485 result += u"\u202C";
486 return result;
487 }
488
489 std::u16string normal(const std::string& text) {
490 std::u16string result;
491 result += u"\u202D";
492 for (auto ch : text) {
493 result += ch;
494 }
495 result += u"\u202C";
496 return result;
497 }
498
499 void onDrawContent(SkCanvas* canvas) override {
500 const std::string options = // { "open-source open-source open-source open-source" };
501 {"Flutter is an open-source project to help developers "
502 "build high-performance, high-fidelity, mobile apps for "
503 "iOS and Android "
504 "from a single codebase. This design lab is a playground "
505 "and showcase of Flutter's many widgets, behaviors, "
506 "animations, layouts, and more."};
507
508 canvas->drawColor(SK_ColorDKGRAY);
509 SkScalar width = this->width() / 4;
510 SkScalar height = this->height() / 2;
511
512 const std::string line =
513 "World domination is such an ugly phrase - I prefer to call it world optimisation";
514
515 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, false, SK_ColorLTGRAY);
516 canvas->translate(width, 0);
517 drawLine(canvas, width, height, line, TextAlign::kRight, 2, false, SK_ColorLTGRAY);
518 canvas->translate(width, 0);
519 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, false, SK_ColorLTGRAY);
520 canvas->translate(width, 0);
521 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, false, SK_ColorLTGRAY);
522 canvas->translate(-width * 3, height);
523
524 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, true, SK_ColorLTGRAY);
525 canvas->translate(width, 0);
526 drawLine(canvas, width, height, line, TextAlign::kRight, 2, true, SK_ColorLTGRAY);
527 canvas->translate(width, 0);
528 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, true, SK_ColorLTGRAY);
529 canvas->translate(width, 0);
530 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, true, SK_ColorLTGRAY);
531 canvas->translate(width, 0);
532 }
533
534private:
535 typedef Sample INHERITED;
536};
537
Mike Reed21a940d2019-07-23 10:11:03 -0400538class ParagraphView4 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400539protected:
Hal Canary8a027312019-07-03 10:55:44 -0400540 SkString name() override { return SkString("Paragraph4"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400541
542 void drawFlutter(SkCanvas* canvas, SkScalar w, SkScalar h,
543 const char* ff = "Google Sans", SkScalar fs = 30,
544 size_t lineLimit = std::numeric_limits<size_t>::max(),
545 const std::u16string& ellipsis = u"\u2026") {
546 SkAutoCanvasRestore acr(canvas, true);
547
548 canvas->clipRect(SkRect::MakeWH(w, h));
549
550 SkScalar margin = 20;
551
552 SkPaint black;
553 black.setAntiAlias(true);
554 black.setColor(SK_ColorBLACK);
555
556 SkPaint blue;
557 blue.setAntiAlias(true);
558 blue.setColor(SK_ColorBLUE);
559
560 SkPaint red;
561 red.setAntiAlias(true);
562 red.setColor(SK_ColorRED);
563
564 SkPaint green;
565 green.setAntiAlias(true);
566 green.setColor(SK_ColorGREEN);
567
568 SkPaint gray;
569 gray.setColor(SK_ColorLTGRAY);
570
571 SkPaint yellow;
572 yellow.setColor(SK_ColorYELLOW);
573
574 SkPaint magenta;
575 magenta.setAntiAlias(true);
576 magenta.setColor(SK_ColorMAGENTA);
577
578 TextStyle style;
579 style.setFontFamilies({SkString(ff)});
580 style.setFontSize(fs);
581
582 TextStyle style0;
583 style0.setForegroundColor(black);
584 style0.setBackgroundColor(gray);
585 style0.setFontFamilies({SkString(ff)});
586 style0.setFontSize(fs);
587 style0.setDecoration(TextDecoration::kUnderline);
588 style0.setDecorationStyle(TextDecorationStyle::kDouble);
589 style0.setDecorationColor(SK_ColorBLACK);
590
591 TextStyle style1;
592 style1.setForegroundColor(blue);
593 style1.setBackgroundColor(yellow);
594 style1.setFontFamilies({SkString(ff)});
595 style1.setFontSize(fs);
596 style1.setDecoration(TextDecoration::kOverline);
597 style1.setDecorationStyle(TextDecorationStyle::kWavy);
598 style1.setDecorationColor(SK_ColorBLACK);
599
600 TextStyle style2;
601 style2.setForegroundColor(red);
602 style2.setFontFamilies({SkString(ff)});
603 style2.setFontSize(fs);
604
605 TextStyle style3;
606 style3.setForegroundColor(green);
607 style3.setFontFamilies({SkString(ff)});
608 style3.setFontSize(fs);
609
610 TextStyle style4;
611 style4.setForegroundColor(magenta);
612 style4.setFontFamilies({SkString(ff)});
613 style4.setFontSize(fs);
614
615 ParagraphStyle paraStyle;
616 paraStyle.setTextStyle(style);
617 paraStyle.setMaxLines(lineLimit);
618
619 paraStyle.setEllipsis(ellipsis);
620
621 const char* logo1 = "google_";
622 const char* logo2 = "logo";
623 const char* logo3 = "go";
624 const char* logo4 = "ogle_logo";
625 const char* logo5 = "google_lo";
626 const char* logo6 = "go";
627 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400628 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400629
630 builder.pushStyle(style0);
631 builder.addText(logo1);
632 builder.pop();
633 builder.pushStyle(style1);
634 builder.addText(logo2);
635 builder.pop();
636
637 builder.addText(" ");
638
639 builder.pushStyle(style0);
640 builder.addText(logo3);
641 builder.pop();
642 builder.pushStyle(style1);
643 builder.addText(logo4);
644 builder.pop();
645
646 builder.addText(" ");
647
648 builder.pushStyle(style0);
649 builder.addText(logo5);
650 builder.pop();
651 builder.pushStyle(style1);
652 builder.addText(logo6);
653 builder.pop();
654
655 auto paragraph = builder.Build();
656 paragraph->layout(w - margin * 2);
657 paragraph->paint(canvas, margin, margin);
658 canvas->translate(0, h + margin);
659 }
660 }
661
662 void onDrawContent(SkCanvas* canvas) override {
663 canvas->drawColor(SK_ColorWHITE);
664 SkScalar width = this->width();
665 SkScalar height = this->height();
666
667 drawFlutter(canvas, width, height / 2);
668 }
669
670private:
671 typedef Sample INHERITED;
672};
673
Mike Reed21a940d2019-07-23 10:11:03 -0400674class ParagraphView5 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400675protected:
Julia Lavrova5207f352019-06-21 12:22:32 -0400676 SkString name() override { return SkString("Paragraph5"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400677
678 void bidi(SkCanvas* canvas, SkScalar w, SkScalar h, const std::u16string& text,
679 const std::u16string& expected, size_t lineLimit = std::numeric_limits<size_t>::max(),
680 const char* ff = "Roboto", SkScalar fs = 30,
681 const std::u16string& ellipsis = u"\u2026") {
682 SkAutoCanvasRestore acr(canvas, true);
683
684 canvas->clipRect(SkRect::MakeWH(w, h));
685
686 SkScalar margin = 20;
687
688 SkPaint black;
689 black.setColor(SK_ColorBLACK);
690 SkPaint gray;
691 gray.setColor(SK_ColorLTGRAY);
692
693 TextStyle style;
694 style.setForegroundColor(black);
695 style.setFontFamilies({SkString(ff)});
696 style.setFontSize(fs);
697
698 TextStyle style0;
699 style0.setForegroundColor(black);
700 style0.setFontFamilies({SkString(ff)});
701 style0.setFontSize(fs);
702 style0.setFontStyle(SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
703 SkFontStyle::kItalic_Slant));
704
705 TextStyle style1;
706 style1.setForegroundColor(gray);
707 style1.setFontFamilies({SkString(ff)});
708 style1.setFontSize(fs);
709 style1.setFontStyle(SkFontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
710 SkFontStyle::kUpright_Slant));
711
712 ParagraphStyle paraStyle;
713 paraStyle.setTextStyle(style);
714 paraStyle.setMaxLines(lineLimit);
715
716 paraStyle.setEllipsis(ellipsis);
717
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400718 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400719
720 if (text.empty()) {
721 const std::u16string text0 = u"\u202Dabc";
722 const std::u16string text1 = u"\u202EFED";
723 const std::u16string text2 = u"\u202Dghi";
724 const std::u16string text3 = u"\u202ELKJ";
725 const std::u16string text4 = u"\u202Dmno";
726 builder.pushStyle(style0);
727 builder.addText(text0);
728 builder.pop();
729 builder.pushStyle(style1);
730 builder.addText(text1);
731 builder.pop();
732 builder.pushStyle(style0);
733 builder.addText(text2);
734 builder.pop();
735 builder.pushStyle(style1);
736 builder.addText(text3);
737 builder.pop();
738 builder.pushStyle(style0);
739 builder.addText(text4);
740 builder.pop();
741 } else {
742 // icu::UnicodeString unicode((UChar*) text.data(), SkToS32(text.size()));
743 // std::string str;
744 // unicode.toUTF8String(str);
745 // SkDebugf("Text: %s\n", str.c_str());
746 builder.addText(text + expected);
747 }
748
749 auto paragraph = builder.Build();
750 paragraph->layout(w - margin * 2);
751 paragraph->paint(canvas, margin, margin);
752 }
753
754 void onDrawContent(SkCanvas* canvas) override {
755 canvas->drawColor(SK_ColorWHITE);
756 SkScalar width = this->width();
757 SkScalar height = this->height() / 8;
758
759 const std::u16string text1 =
760 u"A \u202ENAC\u202Cner, exceedingly \u202ENAC\u202Cny,\n"
761 "One morning remarked to his granny:\n"
762 "A \u202ENAC\u202Cner \u202ENAC\u202C \u202ENAC\u202C,\n"
763 "Anything that he \u202ENAC\u202C,\n"
764 "But a \u202ENAC\u202Cner \u202ENAC\u202C't \u202ENAC\u202C a \u202ENAC\u202C, "
765 "\u202ENAC\u202C he?";
766 bidi(canvas, width, height * 3, text1, u"", 5);
767 canvas->translate(0, height * 3);
768
769 bidi(canvas, width, height, u"\u2067DETALOSI\u2069", u"");
770 canvas->translate(0, height);
771
772 bidi(canvas, width, height, u"\u202BDEDDEBME\u202C", u"");
773 canvas->translate(0, height);
774
775 bidi(canvas, width, height, u"\u202EEDIRREVO\u202C", u"");
776 canvas->translate(0, height);
777
778 bidi(canvas, width, height, u"\u200FTICILPMI\u200E", u"");
779 canvas->translate(0, height);
780
781 bidi(canvas, width, height, u"123 456 7890 \u202EZYXWV UTS RQP ONM LKJ IHG FED CBA\u202C.",
782 u"", 2);
783 canvas->translate(0, height);
784
785 // bidi(canvas, width, height, u"", u"");
786 // canvas->translate(0, height);
787 }
788
789private:
790 typedef Sample INHERITED;
791};
792
Mike Reed21a940d2019-07-23 10:11:03 -0400793class ParagraphView6 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400794protected:
Julia Lavrova5207f352019-06-21 12:22:32 -0400795 SkString name() override { return SkString("Paragraph6"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400796
797 void hangingS(SkCanvas* canvas, SkScalar w, SkScalar h, SkScalar fs = 60.0) {
798 auto ff = "HangingS";
799
800 canvas->drawColor(SK_ColorLTGRAY);
801
802 SkPaint black;
803 black.setAntiAlias(true);
804 black.setColor(SK_ColorBLACK);
805
806 SkPaint blue;
807 blue.setAntiAlias(true);
808 blue.setColor(SK_ColorBLUE);
809
810 SkPaint red;
811 red.setAntiAlias(true);
812 red.setColor(SK_ColorRED);
813
814 SkPaint green;
815 green.setAntiAlias(true);
816 green.setColor(SK_ColorGREEN);
817
818 SkPaint gray;
819 gray.setColor(SK_ColorCYAN);
820
821 SkPaint yellow;
822 yellow.setColor(SK_ColorYELLOW);
823
824 SkPaint magenta;
825 magenta.setAntiAlias(true);
826 magenta.setColor(SK_ColorMAGENTA);
827
828 SkFontStyle fontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
829 SkFontStyle::kItalic_Slant);
830
831 TextStyle style;
832 style.setFontFamilies({SkString(ff)});
833 style.setFontSize(fs);
834 style.setFontStyle(fontStyle);
835
836 TextStyle style0;
837 style0.setForegroundColor(black);
838 style0.setBackgroundColor(gray);
839 style0.setFontFamilies({SkString(ff)});
840 style0.setFontSize(fs);
841 style0.setFontStyle(fontStyle);
842
843 TextStyle style1;
844 style1.setForegroundColor(blue);
845 style1.setBackgroundColor(yellow);
846 style1.setFontFamilies({SkString(ff)});
847 style1.setFontSize(fs);
848 style1.setFontStyle(fontStyle);
849
850 TextStyle style2;
851 style2.setForegroundColor(red);
852 style2.setFontFamilies({SkString(ff)});
853 style2.setFontSize(fs);
854 style2.setFontStyle(fontStyle);
855
856 TextStyle style3;
857 style3.setForegroundColor(green);
858 style3.setFontFamilies({SkString(ff)});
859 style3.setFontSize(fs);
860 style3.setFontStyle(fontStyle);
861
862 TextStyle style4;
863 style4.setForegroundColor(magenta);
864 style4.setFontFamilies({SkString(ff)});
865 style4.setFontSize(fs);
866 style4.setFontStyle(fontStyle);
867
868 ParagraphStyle paraStyle;
869 paraStyle.setTextStyle(style);
870
871 const char* logo1 = "S";
872 const char* logo2 = "kia";
873 const char* logo3 = "Sk";
874 const char* logo4 = "ia";
875 const char* logo5 = "Ski";
876 const char* logo6 = "a";
877 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400878 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400879
880 builder.pushStyle(style0);
881 builder.addText(logo1);
882 builder.pop();
883 builder.pushStyle(style1);
884 builder.addText(logo2);
885 builder.pop();
886
887 builder.addText(" ");
888
889 builder.pushStyle(style0);
890 builder.addText(logo3);
891 builder.pop();
892 builder.pushStyle(style1);
893 builder.addText(logo4);
894 builder.pop();
895
896 builder.addText(" ");
897
898 builder.pushStyle(style0);
899 builder.addText(logo5);
900 builder.pop();
901 builder.pushStyle(style1);
902 builder.addText(logo6);
903 builder.pop();
904
905 auto paragraph = builder.Build();
906 paragraph->layout(w);
907 paragraph->paint(canvas, 40, 40);
908 canvas->translate(0, h);
909 }
910
911 const char* logo11 = "S";
912 const char* logo12 = "S";
913 const char* logo13 = "S";
914 const char* logo14 = "S";
915 const char* logo15 = "S";
916 const char* logo16 = "S";
917 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400918 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400919
920 builder.pushStyle(style0);
921 builder.addText(logo11);
922 builder.pop();
923 builder.pushStyle(style1);
924 builder.addText(logo12);
925 builder.pop();
926
927 builder.addText(" ");
928
929 builder.pushStyle(style0);
930 builder.addText(logo13);
931 builder.pop();
932 builder.pushStyle(style1);
933 builder.addText(logo14);
934 builder.pop();
935
936 builder.addText(" ");
937
938 builder.pushStyle(style0);
939 builder.addText(logo15);
940 builder.pop();
941 builder.pushStyle(style1);
942 builder.addText(logo16);
943 builder.pop();
944
945 auto paragraph = builder.Build();
946 paragraph->layout(w);
947 paragraph->paint(canvas, 40, h);
948 canvas->translate(0, h);
949 }
950 }
951
952 void onDrawContent(SkCanvas* canvas) override {
953 canvas->drawColor(SK_ColorWHITE);
954 SkScalar width = this->width();
955 SkScalar height = this->height() / 4;
956
957 hangingS(canvas, width, height);
958 }
959
960private:
961 typedef Sample INHERITED;
962};
963
Mike Reed21a940d2019-07-23 10:11:03 -0400964class ParagraphView7 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400965protected:
Hal Canary8a027312019-07-03 10:55:44 -0400966 SkString name() override { return SkString("Paragraph7"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400967
968 void drawText(SkCanvas* canvas, SkColor background, SkScalar letterSpace, SkScalar w,
969 SkScalar h) {
970 SkAutoCanvasRestore acr(canvas, true);
971 canvas->clipRect(SkRect::MakeWH(w, h));
972 canvas->drawColor(background);
973
974 const char* line =
Julia Lavrovadb9f6692019-08-01 16:02:17 -0400975 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400976
977 ParagraphStyle paragraphStyle;
978 paragraphStyle.setTextAlign(TextAlign::kLeft);
979 paragraphStyle.setMaxLines(10);
980 paragraphStyle.turnHintingOff();
981 TextStyle textStyle;
982 textStyle.setFontFamilies({SkString("Roboto")});
983 textStyle.setFontSize(30);
984 textStyle.setLetterSpacing(letterSpace);
985 textStyle.setColor(SK_ColorBLACK);
986 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
987 SkFontStyle::kUpright_Slant));
988
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400989 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400990 builder.pushStyle(textStyle);
991 builder.addText(line);
992 builder.pop();
993
994 auto paragraph = builder.Build();
995 paragraph->layout(w - 20);
996 paragraph->paint(canvas, 10, 10);
997 }
998
999 void onDrawContent(SkCanvas* canvas) override {
1000 canvas->drawColor(SK_ColorWHITE);
1001
1002 auto h = this->height() / 4;
1003 auto w = this->width() / 2;
1004
1005 drawText(canvas, SK_ColorGRAY, 1, w, h);
1006 canvas->translate(0, h);
1007
1008 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
1009 canvas->translate(0, h);
1010
1011 drawText(canvas, SK_ColorCYAN, 3, w, h);
1012 canvas->translate(0, h);
1013
1014 drawText(canvas, SK_ColorGRAY, 4, w, h);
1015 canvas->translate(w, -3 * h);
1016
1017 drawText(canvas, SK_ColorYELLOW, 5, w, h);
1018 canvas->translate(0, h);
1019
1020 drawText(canvas, SK_ColorGREEN, 10, w, h);
1021 canvas->translate(0, h);
1022
1023 drawText(canvas, SK_ColorRED, 15, w, h);
1024 canvas->translate(0, h);
1025
1026 drawText(canvas, SK_ColorBLUE, 20, w, h);
1027 canvas->translate(0, h);
1028 }
1029
1030private:
1031 typedef Sample INHERITED;
1032};
1033
Mike Reed21a940d2019-07-23 10:11:03 -04001034class ParagraphView8 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001035protected:
Julia Lavrovadb9f6692019-08-01 16:02:17 -04001036 SkString name() override { return SkString("Paragraph8"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001037
1038 void drawText(SkCanvas* canvas, SkColor background, SkScalar wordSpace, SkScalar w,
1039 SkScalar h) {
1040 SkAutoCanvasRestore acr(canvas, true);
1041 canvas->clipRect(SkRect::MakeWH(w, h));
1042 canvas->drawColor(background);
1043
1044 const char* line =
Julia Lavrovadb9f6692019-08-01 16:02:17 -04001045 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001046
1047 ParagraphStyle paragraphStyle;
1048 paragraphStyle.setTextAlign(TextAlign::kLeft);
1049 paragraphStyle.setMaxLines(10);
1050 paragraphStyle.turnHintingOff();
1051 TextStyle textStyle;
1052 textStyle.setFontFamilies({SkString("Roboto")});
1053 textStyle.setFontSize(30);
1054 textStyle.setWordSpacing(wordSpace);
1055 textStyle.setColor(SK_ColorBLACK);
1056 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1057 SkFontStyle::kUpright_Slant));
1058
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001059 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001060 builder.pushStyle(textStyle);
1061 builder.addText(line);
1062 builder.pop();
1063
1064 auto paragraph = builder.Build();
1065 paragraph->layout(w - 20);
1066 paragraph->paint(canvas, 10, 10);
1067 }
1068
1069 void onDrawContent(SkCanvas* canvas) override {
1070 canvas->drawColor(SK_ColorWHITE);
1071
1072 auto h = this->height() / 4;
1073 auto w = this->width() / 2;
1074
1075 drawText(canvas, SK_ColorGRAY, 1, w, h);
1076 canvas->translate(0, h);
1077
1078 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
1079 canvas->translate(0, h);
1080
1081 drawText(canvas, SK_ColorCYAN, 3, w, h);
1082 canvas->translate(0, h);
1083
1084 drawText(canvas, SK_ColorGRAY, 4, w, h);
1085 canvas->translate(w, -3 * h);
1086
1087 drawText(canvas, SK_ColorYELLOW, 5, w, h);
1088 canvas->translate(0, h);
1089
1090 drawText(canvas, SK_ColorGREEN, 10, w, h);
1091 canvas->translate(0, h);
1092
1093 drawText(canvas, SK_ColorRED, 15, w, h);
1094 canvas->translate(0, h);
1095
1096 drawText(canvas, SK_ColorBLUE, 20, w, h);
1097 canvas->translate(0, h);
1098 }
1099
1100private:
1101 typedef Sample INHERITED;
1102};
1103
Mike Reed21a940d2019-07-23 10:11:03 -04001104class ParagraphView9 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001105protected:
Hal Canary8a027312019-07-03 10:55:44 -04001106 SkString name() override { return SkString("Paragraph9"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001107
Hal Canary6cc65e12019-07-03 15:53:04 -04001108 bool onChar(SkUnichar uni) override {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001109 switch (uni) {
1110 case 'w':
1111 ++wordSpacing;
1112 return true;
1113 case 'q':
1114 if (wordSpacing > 0) --wordSpacing;
1115 return true;
1116 case 'l':
1117 ++letterSpacing;
1118 return true;
1119 case 'k':
1120 if (letterSpacing > 0) --letterSpacing;
1121 return true;
1122 default:
1123 break;
1124 }
Hal Canary6cc65e12019-07-03 15:53:04 -04001125 return false;
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001126 }
1127
1128 void drawText(SkCanvas* canvas, SkColor background, SkScalar w, SkScalar h) {
1129 SkAutoCanvasRestore acr(canvas, true);
1130 canvas->clipRect(SkRect::MakeWH(w, h));
1131 canvas->drawColor(background);
1132
1133 const char* text =
1134 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1135 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1136 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
1137
1138 ParagraphStyle paragraphStyle;
1139 paragraphStyle.setTextAlign(TextAlign::kLeft);
1140 paragraphStyle.setMaxLines(10);
1141 paragraphStyle.turnHintingOff();
1142 TextStyle textStyle;
1143 textStyle.setFontFamilies({SkString("Roboto")});
1144 textStyle.setFontSize(50);
1145 textStyle.setHeight(1.3f);
1146 textStyle.setColor(SK_ColorBLACK);
1147 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1148 SkFontStyle::kUpright_Slant));
1149
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001150 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001151 builder.pushStyle(textStyle);
1152 builder.addText(text);
1153 builder.pop();
1154
1155 auto paragraph = builder.Build();
1156 paragraph->layout(550);
1157
1158 std::vector<size_t> sizes = {0, 1, 2, 8, 19, 21, 22, 30, 150};
1159
1160 std::vector<size_t> colors = {SK_ColorBLUE, SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGREEN,
1161 SK_ColorRED, SK_ColorWHITE, SK_ColorYELLOW, SK_ColorMAGENTA};
1162
1163 RectHeightStyle rect_height_style = RectHeightStyle::kTight;
1164 RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1165
1166 for (size_t i = 0; i < sizes.size() - 1; ++i) {
1167 size_t from = (i == 0 ? 0 : 1) + sizes[i];
1168 size_t to = sizes[i + 1];
1169 auto boxes = paragraph->getRectsForRange(from, to, rect_height_style, rect_width_style);
1170 if (boxes.empty()) {
1171 continue;
1172 }
1173 for (auto& box : boxes) {
1174 SkPaint paint;
1175 paint.setColor(colors[i % colors.size()]);
1176 paint.setShader(setgrad(box.rect, colors[i % colors.size()], SK_ColorWHITE));
1177 canvas->drawRect(box.rect, paint);
1178 }
1179 }
1180
1181 paragraph->paint(canvas, 0, 0);
1182 }
1183
1184 void onDrawContent(SkCanvas* canvas) override {
1185 canvas->drawColor(SK_ColorWHITE);
1186
1187 auto h = this->height();
1188 auto w = this->width();
1189
1190 drawText(canvas, SK_ColorGRAY, w, h);
1191 }
1192
1193private:
1194 typedef Sample INHERITED;
1195 SkScalar letterSpacing;
1196 SkScalar wordSpacing;
1197};
1198
Mike Reed21a940d2019-07-23 10:11:03 -04001199class ParagraphView10 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001200protected:
Hal Canary8a027312019-07-03 10:55:44 -04001201 SkString name() override { return SkString("Paragraph10"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001202
1203 void onDrawContent(SkCanvas* canvas) override {
1204 canvas->drawColor(SK_ColorWHITE);
1205
1206 const char* text = "English English 字典 字典 😀😃😄 😀😃😄";
1207 ParagraphStyle paragraph_style;
1208 paragraph_style.turnHintingOff();
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001209 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001210
1211 TextStyle text_style;
Julia Lavrova5207f352019-06-21 12:22:32 -04001212 text_style.setFontFamilies({SkString("Roboto"),
1213 SkString("Noto Color Emoji"),
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001214 SkString("Source Han Serif CN")});
1215 text_style.setColor(SK_ColorRED);
1216 text_style.setFontSize(60);
1217 text_style.setLetterSpacing(0);
1218 text_style.setWordSpacing(0);
1219 text_style.setColor(SK_ColorBLACK);
1220 text_style.setHeight(1);
1221 builder.pushStyle(text_style);
1222 builder.addText(text);
1223 builder.pop();
1224
1225 auto paragraph = builder.Build();
1226 paragraph->layout(width());
1227
1228 paragraph->paint(canvas, 0, 0);
1229 SkDEBUGCODE(auto impl = reinterpret_cast<ParagraphImpl*>(paragraph.get()));
1230 SkASSERT(impl->runs().size() == 3);
Julia Lavrova5207f352019-06-21 12:22:32 -04001231 SkASSERT(impl->runs()[0].textRange().end == impl->runs()[1].textRange().start);
1232 SkASSERT(impl->runs()[1].textRange().end == impl->runs()[2].textRange().start);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001233 }
1234
1235private:
1236 typedef Sample INHERITED;
1237};
1238
Mike Reed21a940d2019-07-23 10:11:03 -04001239class ParagraphView11 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001240protected:
Hal Canary8a027312019-07-03 10:55:44 -04001241 SkString name() override { return SkString("Paragraph11"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001242
1243 void onDrawContent(SkCanvas* canvas) override {
1244 canvas->drawColor(SK_ColorWHITE);
Julia Lavrova5207f352019-06-21 12:22:32 -04001245 const char* text = "The same text many times";
1246
1247 for (size_t i = 0; i < 10; i++) {
1248 ParagraphStyle paragraph_style;
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001249 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
Julia Lavrova5207f352019-06-21 12:22:32 -04001250 TextStyle text_style;
1251 text_style.setFontFamilies({SkString("Roboto")});
1252 text_style.setColor(SK_ColorBLACK);
1253 text_style.setFontSize(10 + 2 * (i % 10));
1254 builder.pushStyle(text_style);
1255 builder.addText(text);
1256 builder.pop();
1257 auto paragraph = builder.Build();
1258 paragraph->layout(500);
Mike Reed21a940d2019-07-23 10:11:03 -04001259 paragraph->paint(canvas, 0, 40 * (i % 10));
Julia Lavrova5207f352019-06-21 12:22:32 -04001260 }
1261 }
1262
1263private:
1264 typedef Sample INHERITED;
1265};
1266
1267// Measure different stages of layout/paint
Mike Reed21a940d2019-07-23 10:11:03 -04001268class ParagraphView12 : public ParagraphView_Base {
Julia Lavrova5207f352019-06-21 12:22:32 -04001269protected:
1270 SkString name() override { return SkString("Paragraph12"); }
1271
1272 void onDrawContent(SkCanvas* canvas) override {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001273 ParagraphStyle paragraph_style;
Julia Lavrova5207f352019-06-21 12:22:32 -04001274 paragraph_style.setMaxLines(14);
1275 paragraph_style.setTextAlign(TextAlign::kLeft);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001276 paragraph_style.turnHintingOff();
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001277 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001278
1279 TextStyle text_style;
Julia Lavrova5207f352019-06-21 12:22:32 -04001280 text_style.setFontFamilies({SkString("Roboto")});
1281 text_style.setFontSize(26);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001282 text_style.setColor(SK_ColorBLACK);
Julia Lavrova5207f352019-06-21 12:22:32 -04001283 text_style.setHeight(1);
1284 text_style.setDecoration(TextDecoration::kUnderline);
1285 text_style.setDecorationColor(SK_ColorBLACK);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001286 builder.pushStyle(text_style);
Julia Lavrova5207f352019-06-21 12:22:32 -04001287 builder.addText(gText);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001288 builder.pop();
1289
1290 auto paragraph = builder.Build();
Julia Lavrova5207f352019-06-21 12:22:32 -04001291 auto impl = reinterpret_cast<ParagraphImpl*>(paragraph.get());
Julia Lavrova9af5cc42019-06-19 13:32:01 -04001292
Julia Lavrova5207f352019-06-21 12:22:32 -04001293 for (auto i = 0; i < 1000; ++i) {
1294 impl->setState(kUnknown);
1295 impl->shapeTextIntoEndlessLine();
1296 impl->setState(kShaped);
1297 }
1298
1299 for (auto i = 0; i < 1000; ++i) {
1300 impl->setState(kShaped);
1301 impl->buildClusterTable();
1302 impl->markLineBreaks();
1303 impl->setState(kMarked);
1304 }
1305
1306 for (auto i = 0; i < 1000; ++i) {
1307 impl->setState(kMarked);
1308 impl->breakShapedTextIntoLines(1000);
1309 impl->setState(kLineBroken);
1310 }
1311
1312 for (auto i = 0; i < 1000; ++i) {
1313 impl->setState(kLineBroken);
1314 impl->formatLines(1000);
1315 impl->setState(kFormatted);
1316 }
1317
1318 for (auto i = 0; i < 1000; ++i) {
1319 impl->setState(kFormatted);
1320 impl->paintLinesIntoPicture();
1321 impl->setState(kDrawn);
1322 }
1323
1324 auto picture = impl->getPicture();
1325 SkMatrix matrix = SkMatrix::MakeTrans(0, 0);
1326 for (auto i = 0; i < 1000; ++i) {
1327 canvas->drawPicture(picture, &matrix, nullptr);
1328 }
Julia Lavrova35f88222019-06-21 12:22:32 -04001329
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001330 }
1331
1332private:
1333 typedef Sample INHERITED;
1334};
1335//////////////////////////////////////////////////////////////////////////////
1336
1337DEF_SAMPLE(return new ParagraphView1();)
1338DEF_SAMPLE(return new ParagraphView2();)
1339DEF_SAMPLE(return new ParagraphView3();)
1340DEF_SAMPLE(return new ParagraphView4();)
1341DEF_SAMPLE(return new ParagraphView5();)
1342DEF_SAMPLE(return new ParagraphView6();)
1343DEF_SAMPLE(return new ParagraphView7();)
1344DEF_SAMPLE(return new ParagraphView8();)
1345DEF_SAMPLE(return new ParagraphView9();)
1346DEF_SAMPLE(return new ParagraphView10();)
1347DEF_SAMPLE(return new ParagraphView11();)
Julia Lavrova5207f352019-06-21 12:22:32 -04001348DEF_SAMPLE(return new ParagraphView12();)