blob: 6fdcdee5eab4f2c45d7e585b1c66f688ec8cbb39 [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
Julia Lavrovaa3552c52019-05-30 16:12:56 -040048} // namespace
49
Mike Reed21a940d2019-07-23 10:11:03 -040050class ParagraphView1 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -040051protected:
Hal Canary8a027312019-07-03 10:55:44 -040052 SkString name() override { return SkString("Paragraph1"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -040053
54 void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) {
55 const std::vector<
56 std::tuple<std::string, bool, bool, int, SkColor, SkColor, bool, TextDecorationStyle>>
57 gParagraph = {{"monospace", true, false, 14, SK_ColorWHITE, SK_ColorRED, true,
58 TextDecorationStyle::kDashed},
59 {"Assyrian", false, false, 20, SK_ColorWHITE, SK_ColorBLUE, false,
60 TextDecorationStyle::kDotted},
61 {"serif", true, true, 10, SK_ColorWHITE, SK_ColorRED, true,
62 TextDecorationStyle::kDouble},
63 {"Arial", false, true, 16, SK_ColorGRAY, SK_ColorGREEN, true,
64 TextDecorationStyle::kSolid},
65 {"sans-serif", false, false, 8, SK_ColorWHITE, SK_ColorRED, false,
66 TextDecorationStyle::kWavy}};
67 SkAutoCanvasRestore acr(canvas, true);
68
69 canvas->clipRect(SkRect::MakeWH(w, h));
70 canvas->drawColor(SK_ColorWHITE);
71
72 SkScalar margin = 20;
73
74 SkPaint paint;
75 paint.setAntiAlias(true);
76 paint.setColor(fg);
77
78 SkPaint blue;
79 blue.setColor(SK_ColorBLUE);
80
81 TextStyle defaultStyle;
82 defaultStyle.setBackgroundColor(blue);
83 defaultStyle.setForegroundColor(paint);
84 ParagraphStyle paraStyle;
85
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -040086 auto fontCollection = sk_make_sp<FontCollection>();
87 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
Julia Lavrovaa3552c52019-05-30 16:12:56 -040088 for (auto i = 1; i < 5; ++i) {
89 defaultStyle.setFontSize(24 * i);
90 paraStyle.setTextStyle(defaultStyle);
Julia Lavrova5207f352019-06-21 12:22:32 -040091 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -040092 std::string name = "Paragraph: " + std::to_string(24 * i);
93 builder.addText(name.c_str());
94 for (auto para : gParagraph) {
95 TextStyle style;
96 style.setFontFamilies({SkString(std::get<0>(para).c_str())});
97 SkFontStyle fontStyle(std::get<1>(para) ? SkFontStyle::Weight::kBold_Weight
98 : SkFontStyle::Weight::kNormal_Weight,
99 SkFontStyle::Width::kNormal_Width,
100 std::get<2>(para) ? SkFontStyle::Slant::kItalic_Slant
101 : SkFontStyle::Slant::kUpright_Slant);
102 style.setFontStyle(fontStyle);
103 style.setFontSize(std::get<3>(para) * i);
104 SkPaint background;
105 background.setColor(std::get<4>(para));
106 style.setBackgroundColor(background);
107 SkPaint foreground;
108 foreground.setColor(std::get<5>(para));
109 foreground.setAntiAlias(true);
110 style.setForegroundColor(foreground);
111 if (std::get<6>(para)) {
112 style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(5, 5), 2));
113 }
114
115 auto decoration = (i % 4);
116 if (decoration == 3) {
117 decoration = 4;
118 }
119
120 bool test = (TextDecoration)decoration != TextDecoration::kNoDecoration;
121 std::string deco = std::to_string((int)decoration);
122 if (test) {
123 style.setDecoration((TextDecoration)decoration);
124 style.setDecorationStyle(std::get<7>(para));
125 style.setDecorationColor(std::get<5>(para));
126 }
127 builder.pushStyle(style);
128 std::string name = " " + std::get<0>(para) + " " +
129 (std::get<1>(para) ? ", bold" : "") +
130 (std::get<2>(para) ? ", italic" : "") + " " +
131 std::to_string(std::get<3>(para) * i) +
132 (std::get<4>(para) != bg ? ", background" : "") +
133 (std::get<5>(para) != fg ? ", foreground" : "") +
134 (std::get<6>(para) ? ", shadow" : "") +
135 (test ? ", decorations " + deco : "") + ";";
136 builder.addText(name.c_str());
137 builder.pop();
138 }
139
140 auto paragraph = builder.Build();
141 paragraph->layout(w - margin * 2);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400142 paragraph->paint(canvas, margin, margin);
143
144 canvas->translate(0, paragraph->getHeight());
145 }
146 }
147
148 void onDrawContent(SkCanvas* canvas) override {
149 drawTest(canvas, this->width(), this->height(), SK_ColorRED, SK_ColorWHITE);
150 }
151
152private:
153
154 typedef Sample INHERITED;
155};
156
Mike Reed21a940d2019-07-23 10:11:03 -0400157class ParagraphView2 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400158protected:
Hal Canary8a027312019-07-03 10:55:44 -0400159 SkString name() override { return SkString("Paragraph2"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400160
161 void drawCode(SkCanvas* canvas, SkScalar w, SkScalar h) {
162 SkPaint comment;
163 comment.setColor(SK_ColorGRAY);
164 SkPaint constant;
165 constant.setColor(SK_ColorMAGENTA);
166 SkPaint null;
167 null.setColor(SK_ColorMAGENTA);
168 SkPaint literal;
169 literal.setColor(SK_ColorGREEN);
170 SkPaint code;
171 code.setColor(SK_ColorDKGRAY);
172 SkPaint number;
173 number.setColor(SK_ColorBLUE);
174 SkPaint name;
175 name.setColor(SK_ColorRED);
176
177 SkPaint white;
178 white.setColor(SK_ColorWHITE);
179
180 TextStyle defaultStyle;
181 defaultStyle.setBackgroundColor(white);
182 defaultStyle.setForegroundColor(code);
183 defaultStyle.setFontFamilies({SkString("monospace")});
184 defaultStyle.setFontSize(30);
185 ParagraphStyle paraStyle;
186 paraStyle.setTextStyle(defaultStyle);
187
Julia Lavrova5207f352019-06-21 12:22:32 -0400188 auto fontCollection = sk_make_sp<FontCollection>();
189 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
190 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400191
192 builder.pushStyle(style(name));
193 builder.addText("RaisedButton");
194 builder.pop();
195 builder.addText("(\n");
196 builder.addText(" child: ");
197 builder.pushStyle(style(constant));
198 builder.addText("const");
199 builder.pop();
200 builder.addText(" ");
201 builder.pushStyle(style(name));
202 builder.addText("Text");
203 builder.pop();
204 builder.addText("(");
205 builder.pushStyle(style(literal));
206 builder.addText("'BUTTON TITLE'");
207 builder.pop();
208 builder.addText("),\n");
209
210 auto paragraph = builder.Build();
211 paragraph->layout(w - 20);
212
213 paragraph->paint(canvas, 20, 20);
214 }
215
216 TextStyle style(SkPaint paint) {
217 TextStyle style;
218 paint.setAntiAlias(true);
219 style.setForegroundColor(paint);
220 style.setFontFamilies({SkString("monospace")});
221 style.setFontSize(30);
222
223 return style;
224 }
225
Julia Lavrova5207f352019-06-21 12:22:32 -0400226 void drawText(SkCanvas* canvas, SkScalar w, SkScalar h, std::vector<const char*>& text,
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400227 SkColor fg = SK_ColorDKGRAY, SkColor bg = SK_ColorWHITE,
228 const char* ff = "sans-serif", SkScalar fs = 24,
229 size_t lineLimit = 30,
230 const std::u16string& ellipsis = u"\u2026") {
231 SkAutoCanvasRestore acr(canvas, true);
232
233 canvas->clipRect(SkRect::MakeWH(w, h));
234 canvas->drawColor(bg);
235
236 SkScalar margin = 20;
237
238 SkPaint paint;
239 paint.setAntiAlias(true);
240 paint.setColor(fg);
241
242 SkPaint blue;
243 blue.setColor(SK_ColorBLUE);
244
245 SkPaint background;
246 background.setColor(bg);
247
248 TextStyle style;
249 style.setBackgroundColor(blue);
250 style.setForegroundColor(paint);
251 style.setFontFamilies({SkString(ff)});
252 style.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight,
253 SkFontStyle::kNormal_Width,
254 SkFontStyle::kUpright_Slant));
255 style.setFontSize(fs);
256 ParagraphStyle paraStyle;
257 paraStyle.setTextStyle(style);
258 paraStyle.setMaxLines(lineLimit);
259
260 paraStyle.setEllipsis(ellipsis);
261 TextStyle defaultStyle;
262 defaultStyle.setFontSize(20);
263 paraStyle.setTextStyle(defaultStyle);
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400264 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400265
266 SkPaint foreground;
267 foreground.setColor(fg);
268 style.setForegroundColor(foreground);
269 style.setBackgroundColor(background);
270
271 for (auto& part : text) {
272 builder.pushStyle(style);
Julia Lavrova5207f352019-06-21 12:22:32 -0400273 builder.addText(part);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400274 builder.pop();
275 }
276
277 auto paragraph = builder.Build();
278 paragraph->layout(w - margin * 2);
279 paragraph->paint(canvas, margin, margin);
280
281 canvas->translate(0, paragraph->getHeight() + margin);
282 }
283
284 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
285 TextAlign align) {
286 SkAutoCanvasRestore acr(canvas, true);
287
288 canvas->clipRect(SkRect::MakeWH(w, h));
289 canvas->drawColor(SK_ColorWHITE);
290
291 SkScalar margin = 20;
292
293 SkPaint paint;
294 paint.setAntiAlias(true);
295 paint.setColor(SK_ColorBLUE);
296
297 SkPaint gray;
298 gray.setColor(SK_ColorLTGRAY);
299
300 TextStyle style;
301 style.setBackgroundColor(gray);
302 style.setForegroundColor(paint);
303 style.setFontFamilies({SkString("Arial")});
304 style.setFontSize(30);
305 ParagraphStyle paraStyle;
306 paraStyle.setTextStyle(style);
307 paraStyle.setTextAlign(align);
308
Julia Lavrova5207f352019-06-21 12:22:32 -0400309 auto fontCollection = sk_make_sp<FontCollection>();
310 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
311 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400312 builder.addText(text.c_str());
313
314 auto paragraph = builder.Build();
315 paragraph->layout(w - margin * 2);
316 paragraph->layout(w - margin);
317 paragraph->paint(canvas, margin, margin);
318
319 canvas->translate(0, paragraph->getHeight() + margin);
320 }
321
322 void onDrawContent(SkCanvas* canvas) override {
Julia Lavrova5207f352019-06-21 12:22:32 -0400323 std::vector<const char*> cupertino = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400324 "google_logogoogle_gsuper_g_logo 1 "
325 "google_logogoogle_gsuper_g_logo 12 "
326 "google_logogoogle_gsuper_g_logo 123 "
327 "google_logogoogle_gsuper_g_logo 1234 "
328 "google_logogoogle_gsuper_g_logo 12345 "
329 "google_logogoogle_gsuper_g_logo 123456 "
330 "google_logogoogle_gsuper_g_logo 1234567 "
331 "google_logogoogle_gsuper_g_logo 12345678 "
332 "google_logogoogle_gsuper_g_logo 123456789 "
333 "google_logogoogle_gsuper_g_logo 1234567890 "
334 "google_logogoogle_gsuper_g_logo 123456789 "
335 "google_logogoogle_gsuper_g_logo 12345678 "
336 "google_logogoogle_gsuper_g_logo 1234567 "
337 "google_logogoogle_gsuper_g_logo 123456 "
338 "google_logogoogle_gsuper_g_logo 12345 "
339 "google_logogoogle_gsuper_g_logo 1234 "
340 "google_logogoogle_gsuper_g_logo 123 "
341 "google_logogoogle_gsuper_g_logo 12 "
342 "google_logogoogle_gsuper_g_logo 1 "
343 "google_logogoogle_gsuper_g_logo "
344 "google_logogoogle_gsuper_g_logo "
345 "google_logogoogle_gsuper_g_logo "
346 "google_logogoogle_gsuper_g_logo "
347 "google_logogoogle_gsuper_g_logo "
348 "google_logogoogle_gsuper_g_logo"};
Julia Lavrova5207f352019-06-21 12:22:32 -0400349 std::vector<const char*> text = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400350 "My neighbor came over to say,\n"
351 "Although not in a neighborly way,\n\n"
352 "That he'd knock me around,\n\n\n"
353 "If I didn't stop the sound,\n\n\n\n"
354 "Of the classical music I play."};
355
Julia Lavrova5207f352019-06-21 12:22:32 -0400356 std::vector<const char*> long_word = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400357 "A_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
358 "very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
359 "very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
360 "very_very_very_very_very_very_very_long_text"};
361
Julia Lavrova5207f352019-06-21 12:22:32 -0400362 std::vector<const char*> very_long = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400363 "A very very very very very very very very very very very very very very very very "
364 "very very very very very very very very very very very very very very very very "
365 "very very very very very very very very very very very very very very very very "
366 "very very very very very very very long text"};
367
Julia Lavrova5207f352019-06-21 12:22:32 -0400368 std::vector<const char*> very_word = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400369 "A very_very_very_very_very_very_very_very_very_very "
370 "very_very_very_very_very_very_very_very_very_very very very very very very very "
371 "very very very very very very very very very very very very very very very very "
372 "very very very very very very very very very very very very very long text"};
373
374 SkScalar width = this->width() / 5;
375 SkScalar height = this->height();
376 drawText(canvas, width, height, long_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
377 canvas->translate(width, 0);
378 drawText(canvas, width, height, very_long, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
379 canvas->translate(width, 0);
380 drawText(canvas, width, height, very_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
381 canvas->translate(width, 0);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400382 drawText(canvas, width, height / 2, text, SK_ColorBLACK, SK_ColorWHITE, "Roboto", 20, 100,
383 u"\u2026");
384 canvas->translate(0, height / 2);
385 drawCode(canvas, width, height / 2);
386 canvas->translate(width, -height / 2);
387
388 drawText(canvas, width, height, cupertino, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
389 }
390
391private:
392 typedef Sample INHERITED;
393};
394
Mike Reed21a940d2019-07-23 10:11:03 -0400395class ParagraphView3 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400396protected:
Hal Canary8a027312019-07-03 10:55:44 -0400397 SkString name() override { return SkString("Paragraph3"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400398
399 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
400 TextAlign align, size_t lineLimit = std::numeric_limits<size_t>::max(),
401 bool RTL = false, SkColor background = SK_ColorGRAY,
402 const std::u16string& ellipsis = u"\u2026") {
403 SkAutoCanvasRestore acr(canvas, true);
404
405 canvas->clipRect(SkRect::MakeWH(w, h));
406 canvas->drawColor(SK_ColorWHITE);
407
408 SkScalar margin = 20;
409
410 SkPaint paint;
411 paint.setAntiAlias(true);
412 paint.setColor(SK_ColorBLACK);
413
414 SkPaint gray;
415 gray.setColor(background);
416
417 SkPaint yellow;
418 yellow.setColor(SK_ColorYELLOW);
419
420 TextStyle style;
421 style.setBackgroundColor(gray);
422 style.setForegroundColor(paint);
423 style.setFontFamilies({SkString("sans-serif")});
424 style.setFontSize(30);
425 ParagraphStyle paraStyle;
426 paraStyle.setTextStyle(style);
427 paraStyle.setTextAlign(align);
428 paraStyle.setMaxLines(lineLimit);
429 paraStyle.setEllipsis(ellipsis);
430 // paraStyle.setTextDirection(RTL ? SkTextDirection::rtl : SkTextDirection::ltr);
431
Julia Lavrova5207f352019-06-21 12:22:32 -0400432 auto fontCollection = sk_make_sp<FontCollection>();
433 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
434 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400435 if (RTL) {
436 builder.addText(mirror(text));
437 } else {
438 builder.addText(normal(text));
439 }
440
441 canvas->drawRect(SkRect::MakeXYWH(margin, margin, w - margin * 2, h - margin * 2), yellow);
442 auto paragraph = builder.Build();
443 paragraph->layout(w - margin * 2);
444 paragraph->paint(canvas, margin, margin);
445 }
446
447 std::u16string mirror(const std::string& text) {
448 std::u16string result;
449 result += u"\u202E";
450 // for (auto i = text.size(); i > 0; --i) {
451 // result += text[i - 1];
452 //}
453
454 for (auto i = text.size(); i > 0; --i) {
455 auto ch = text[i - 1];
456 if (ch == ',') {
457 result += u"!";
458 } else if (ch == '.') {
459 result += u"!";
460 } else {
461 result += ch;
462 }
463 }
464
465 result += u"\u202C";
466 return result;
467 }
468
469 std::u16string normal(const std::string& text) {
470 std::u16string result;
471 result += u"\u202D";
472 for (auto ch : text) {
473 result += ch;
474 }
475 result += u"\u202C";
476 return result;
477 }
478
479 void onDrawContent(SkCanvas* canvas) override {
480 const std::string options = // { "open-source open-source open-source open-source" };
481 {"Flutter is an open-source project to help developers "
482 "build high-performance, high-fidelity, mobile apps for "
483 "iOS and Android "
484 "from a single codebase. This design lab is a playground "
485 "and showcase of Flutter's many widgets, behaviors, "
486 "animations, layouts, and more."};
487
488 canvas->drawColor(SK_ColorDKGRAY);
489 SkScalar width = this->width() / 4;
490 SkScalar height = this->height() / 2;
491
492 const std::string line =
493 "World domination is such an ugly phrase - I prefer to call it world optimisation";
494
495 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, false, SK_ColorLTGRAY);
496 canvas->translate(width, 0);
497 drawLine(canvas, width, height, line, TextAlign::kRight, 2, false, SK_ColorLTGRAY);
498 canvas->translate(width, 0);
499 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, false, SK_ColorLTGRAY);
500 canvas->translate(width, 0);
501 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, false, SK_ColorLTGRAY);
502 canvas->translate(-width * 3, height);
503
504 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, true, SK_ColorLTGRAY);
505 canvas->translate(width, 0);
506 drawLine(canvas, width, height, line, TextAlign::kRight, 2, true, SK_ColorLTGRAY);
507 canvas->translate(width, 0);
508 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, true, SK_ColorLTGRAY);
509 canvas->translate(width, 0);
510 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, true, SK_ColorLTGRAY);
511 canvas->translate(width, 0);
512 }
513
514private:
515 typedef Sample INHERITED;
516};
517
Mike Reed21a940d2019-07-23 10:11:03 -0400518class ParagraphView4 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400519protected:
Hal Canary8a027312019-07-03 10:55:44 -0400520 SkString name() override { return SkString("Paragraph4"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400521
522 void drawFlutter(SkCanvas* canvas, SkScalar w, SkScalar h,
523 const char* ff = "Google Sans", SkScalar fs = 30,
524 size_t lineLimit = std::numeric_limits<size_t>::max(),
525 const std::u16string& ellipsis = u"\u2026") {
526 SkAutoCanvasRestore acr(canvas, true);
527
528 canvas->clipRect(SkRect::MakeWH(w, h));
529
530 SkScalar margin = 20;
531
532 SkPaint black;
533 black.setAntiAlias(true);
534 black.setColor(SK_ColorBLACK);
535
536 SkPaint blue;
537 blue.setAntiAlias(true);
538 blue.setColor(SK_ColorBLUE);
539
540 SkPaint red;
541 red.setAntiAlias(true);
542 red.setColor(SK_ColorRED);
543
544 SkPaint green;
545 green.setAntiAlias(true);
546 green.setColor(SK_ColorGREEN);
547
548 SkPaint gray;
549 gray.setColor(SK_ColorLTGRAY);
550
551 SkPaint yellow;
552 yellow.setColor(SK_ColorYELLOW);
553
554 SkPaint magenta;
555 magenta.setAntiAlias(true);
556 magenta.setColor(SK_ColorMAGENTA);
557
558 TextStyle style;
559 style.setFontFamilies({SkString(ff)});
560 style.setFontSize(fs);
561
562 TextStyle style0;
563 style0.setForegroundColor(black);
564 style0.setBackgroundColor(gray);
565 style0.setFontFamilies({SkString(ff)});
566 style0.setFontSize(fs);
567 style0.setDecoration(TextDecoration::kUnderline);
568 style0.setDecorationStyle(TextDecorationStyle::kDouble);
569 style0.setDecorationColor(SK_ColorBLACK);
570
571 TextStyle style1;
572 style1.setForegroundColor(blue);
573 style1.setBackgroundColor(yellow);
574 style1.setFontFamilies({SkString(ff)});
575 style1.setFontSize(fs);
576 style1.setDecoration(TextDecoration::kOverline);
577 style1.setDecorationStyle(TextDecorationStyle::kWavy);
578 style1.setDecorationColor(SK_ColorBLACK);
579
580 TextStyle style2;
581 style2.setForegroundColor(red);
582 style2.setFontFamilies({SkString(ff)});
583 style2.setFontSize(fs);
584
585 TextStyle style3;
586 style3.setForegroundColor(green);
587 style3.setFontFamilies({SkString(ff)});
588 style3.setFontSize(fs);
589
590 TextStyle style4;
591 style4.setForegroundColor(magenta);
592 style4.setFontFamilies({SkString(ff)});
593 style4.setFontSize(fs);
594
595 ParagraphStyle paraStyle;
596 paraStyle.setTextStyle(style);
597 paraStyle.setMaxLines(lineLimit);
598
599 paraStyle.setEllipsis(ellipsis);
600
601 const char* logo1 = "google_";
602 const char* logo2 = "logo";
603 const char* logo3 = "go";
604 const char* logo4 = "ogle_logo";
605 const char* logo5 = "google_lo";
606 const char* logo6 = "go";
607 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400608 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400609
610 builder.pushStyle(style0);
611 builder.addText(logo1);
612 builder.pop();
613 builder.pushStyle(style1);
614 builder.addText(logo2);
615 builder.pop();
616
617 builder.addText(" ");
618
619 builder.pushStyle(style0);
620 builder.addText(logo3);
621 builder.pop();
622 builder.pushStyle(style1);
623 builder.addText(logo4);
624 builder.pop();
625
626 builder.addText(" ");
627
628 builder.pushStyle(style0);
629 builder.addText(logo5);
630 builder.pop();
631 builder.pushStyle(style1);
632 builder.addText(logo6);
633 builder.pop();
634
635 auto paragraph = builder.Build();
636 paragraph->layout(w - margin * 2);
637 paragraph->paint(canvas, margin, margin);
638 canvas->translate(0, h + margin);
639 }
640 }
641
642 void onDrawContent(SkCanvas* canvas) override {
643 canvas->drawColor(SK_ColorWHITE);
644 SkScalar width = this->width();
645 SkScalar height = this->height();
646
647 drawFlutter(canvas, width, height / 2);
648 }
649
650private:
651 typedef Sample INHERITED;
652};
653
Mike Reed21a940d2019-07-23 10:11:03 -0400654class ParagraphView5 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400655protected:
Julia Lavrova5207f352019-06-21 12:22:32 -0400656 SkString name() override { return SkString("Paragraph5"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400657
658 void bidi(SkCanvas* canvas, SkScalar w, SkScalar h, const std::u16string& text,
659 const std::u16string& expected, size_t lineLimit = std::numeric_limits<size_t>::max(),
660 const char* ff = "Roboto", SkScalar fs = 30,
661 const std::u16string& ellipsis = u"\u2026") {
662 SkAutoCanvasRestore acr(canvas, true);
663
664 canvas->clipRect(SkRect::MakeWH(w, h));
665
666 SkScalar margin = 20;
667
668 SkPaint black;
669 black.setColor(SK_ColorBLACK);
670 SkPaint gray;
671 gray.setColor(SK_ColorLTGRAY);
672
673 TextStyle style;
674 style.setForegroundColor(black);
675 style.setFontFamilies({SkString(ff)});
676 style.setFontSize(fs);
677
678 TextStyle style0;
679 style0.setForegroundColor(black);
680 style0.setFontFamilies({SkString(ff)});
681 style0.setFontSize(fs);
682 style0.setFontStyle(SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
683 SkFontStyle::kItalic_Slant));
684
685 TextStyle style1;
686 style1.setForegroundColor(gray);
687 style1.setFontFamilies({SkString(ff)});
688 style1.setFontSize(fs);
689 style1.setFontStyle(SkFontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
690 SkFontStyle::kUpright_Slant));
691
692 ParagraphStyle paraStyle;
693 paraStyle.setTextStyle(style);
694 paraStyle.setMaxLines(lineLimit);
695
696 paraStyle.setEllipsis(ellipsis);
697
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400698 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400699
700 if (text.empty()) {
701 const std::u16string text0 = u"\u202Dabc";
702 const std::u16string text1 = u"\u202EFED";
703 const std::u16string text2 = u"\u202Dghi";
704 const std::u16string text3 = u"\u202ELKJ";
705 const std::u16string text4 = u"\u202Dmno";
706 builder.pushStyle(style0);
707 builder.addText(text0);
708 builder.pop();
709 builder.pushStyle(style1);
710 builder.addText(text1);
711 builder.pop();
712 builder.pushStyle(style0);
713 builder.addText(text2);
714 builder.pop();
715 builder.pushStyle(style1);
716 builder.addText(text3);
717 builder.pop();
718 builder.pushStyle(style0);
719 builder.addText(text4);
720 builder.pop();
721 } else {
722 // icu::UnicodeString unicode((UChar*) text.data(), SkToS32(text.size()));
723 // std::string str;
724 // unicode.toUTF8String(str);
725 // SkDebugf("Text: %s\n", str.c_str());
726 builder.addText(text + expected);
727 }
728
729 auto paragraph = builder.Build();
730 paragraph->layout(w - margin * 2);
731 paragraph->paint(canvas, margin, margin);
732 }
733
734 void onDrawContent(SkCanvas* canvas) override {
735 canvas->drawColor(SK_ColorWHITE);
736 SkScalar width = this->width();
737 SkScalar height = this->height() / 8;
738
739 const std::u16string text1 =
740 u"A \u202ENAC\u202Cner, exceedingly \u202ENAC\u202Cny,\n"
741 "One morning remarked to his granny:\n"
742 "A \u202ENAC\u202Cner \u202ENAC\u202C \u202ENAC\u202C,\n"
743 "Anything that he \u202ENAC\u202C,\n"
744 "But a \u202ENAC\u202Cner \u202ENAC\u202C't \u202ENAC\u202C a \u202ENAC\u202C, "
745 "\u202ENAC\u202C he?";
746 bidi(canvas, width, height * 3, text1, u"", 5);
747 canvas->translate(0, height * 3);
748
749 bidi(canvas, width, height, u"\u2067DETALOSI\u2069", u"");
750 canvas->translate(0, height);
751
752 bidi(canvas, width, height, u"\u202BDEDDEBME\u202C", u"");
753 canvas->translate(0, height);
754
755 bidi(canvas, width, height, u"\u202EEDIRREVO\u202C", u"");
756 canvas->translate(0, height);
757
758 bidi(canvas, width, height, u"\u200FTICILPMI\u200E", u"");
759 canvas->translate(0, height);
760
761 bidi(canvas, width, height, u"123 456 7890 \u202EZYXWV UTS RQP ONM LKJ IHG FED CBA\u202C.",
762 u"", 2);
763 canvas->translate(0, height);
764
765 // bidi(canvas, width, height, u"", u"");
766 // canvas->translate(0, height);
767 }
768
769private:
770 typedef Sample INHERITED;
771};
772
Mike Reed21a940d2019-07-23 10:11:03 -0400773class ParagraphView6 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400774protected:
Julia Lavrova5207f352019-06-21 12:22:32 -0400775 SkString name() override { return SkString("Paragraph6"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400776
777 void hangingS(SkCanvas* canvas, SkScalar w, SkScalar h, SkScalar fs = 60.0) {
778 auto ff = "HangingS";
779
780 canvas->drawColor(SK_ColorLTGRAY);
781
782 SkPaint black;
783 black.setAntiAlias(true);
784 black.setColor(SK_ColorBLACK);
785
786 SkPaint blue;
787 blue.setAntiAlias(true);
788 blue.setColor(SK_ColorBLUE);
789
790 SkPaint red;
791 red.setAntiAlias(true);
792 red.setColor(SK_ColorRED);
793
794 SkPaint green;
795 green.setAntiAlias(true);
796 green.setColor(SK_ColorGREEN);
797
798 SkPaint gray;
799 gray.setColor(SK_ColorCYAN);
800
801 SkPaint yellow;
802 yellow.setColor(SK_ColorYELLOW);
803
804 SkPaint magenta;
805 magenta.setAntiAlias(true);
806 magenta.setColor(SK_ColorMAGENTA);
807
808 SkFontStyle fontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
809 SkFontStyle::kItalic_Slant);
810
811 TextStyle style;
812 style.setFontFamilies({SkString(ff)});
813 style.setFontSize(fs);
814 style.setFontStyle(fontStyle);
815
816 TextStyle style0;
817 style0.setForegroundColor(black);
818 style0.setBackgroundColor(gray);
819 style0.setFontFamilies({SkString(ff)});
820 style0.setFontSize(fs);
821 style0.setFontStyle(fontStyle);
822
823 TextStyle style1;
824 style1.setForegroundColor(blue);
825 style1.setBackgroundColor(yellow);
826 style1.setFontFamilies({SkString(ff)});
827 style1.setFontSize(fs);
828 style1.setFontStyle(fontStyle);
829
830 TextStyle style2;
831 style2.setForegroundColor(red);
832 style2.setFontFamilies({SkString(ff)});
833 style2.setFontSize(fs);
834 style2.setFontStyle(fontStyle);
835
836 TextStyle style3;
837 style3.setForegroundColor(green);
838 style3.setFontFamilies({SkString(ff)});
839 style3.setFontSize(fs);
840 style3.setFontStyle(fontStyle);
841
842 TextStyle style4;
843 style4.setForegroundColor(magenta);
844 style4.setFontFamilies({SkString(ff)});
845 style4.setFontSize(fs);
846 style4.setFontStyle(fontStyle);
847
848 ParagraphStyle paraStyle;
849 paraStyle.setTextStyle(style);
850
851 const char* logo1 = "S";
852 const char* logo2 = "kia";
853 const char* logo3 = "Sk";
854 const char* logo4 = "ia";
855 const char* logo5 = "Ski";
856 const char* logo6 = "a";
857 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400858 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400859
860 builder.pushStyle(style0);
861 builder.addText(logo1);
862 builder.pop();
863 builder.pushStyle(style1);
864 builder.addText(logo2);
865 builder.pop();
866
867 builder.addText(" ");
868
869 builder.pushStyle(style0);
870 builder.addText(logo3);
871 builder.pop();
872 builder.pushStyle(style1);
873 builder.addText(logo4);
874 builder.pop();
875
876 builder.addText(" ");
877
878 builder.pushStyle(style0);
879 builder.addText(logo5);
880 builder.pop();
881 builder.pushStyle(style1);
882 builder.addText(logo6);
883 builder.pop();
884
885 auto paragraph = builder.Build();
886 paragraph->layout(w);
887 paragraph->paint(canvas, 40, 40);
888 canvas->translate(0, h);
889 }
890
891 const char* logo11 = "S";
892 const char* logo12 = "S";
893 const char* logo13 = "S";
894 const char* logo14 = "S";
895 const char* logo15 = "S";
896 const char* logo16 = "S";
897 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400898 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400899
900 builder.pushStyle(style0);
901 builder.addText(logo11);
902 builder.pop();
903 builder.pushStyle(style1);
904 builder.addText(logo12);
905 builder.pop();
906
907 builder.addText(" ");
908
909 builder.pushStyle(style0);
910 builder.addText(logo13);
911 builder.pop();
912 builder.pushStyle(style1);
913 builder.addText(logo14);
914 builder.pop();
915
916 builder.addText(" ");
917
918 builder.pushStyle(style0);
919 builder.addText(logo15);
920 builder.pop();
921 builder.pushStyle(style1);
922 builder.addText(logo16);
923 builder.pop();
924
925 auto paragraph = builder.Build();
926 paragraph->layout(w);
927 paragraph->paint(canvas, 40, h);
928 canvas->translate(0, h);
929 }
930 }
931
932 void onDrawContent(SkCanvas* canvas) override {
933 canvas->drawColor(SK_ColorWHITE);
934 SkScalar width = this->width();
935 SkScalar height = this->height() / 4;
936
937 hangingS(canvas, width, height);
938 }
939
940private:
941 typedef Sample INHERITED;
942};
943
Mike Reed21a940d2019-07-23 10:11:03 -0400944class ParagraphView7 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400945protected:
Hal Canary8a027312019-07-03 10:55:44 -0400946 SkString name() override { return SkString("Paragraph7"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400947
948 void drawText(SkCanvas* canvas, SkColor background, SkScalar letterSpace, SkScalar w,
949 SkScalar h) {
950 SkAutoCanvasRestore acr(canvas, true);
951 canvas->clipRect(SkRect::MakeWH(w, h));
952 canvas->drawColor(background);
953
954 const char* line =
Julia Lavrovadb9f6692019-08-01 16:02:17 -0400955 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400956
957 ParagraphStyle paragraphStyle;
958 paragraphStyle.setTextAlign(TextAlign::kLeft);
959 paragraphStyle.setMaxLines(10);
960 paragraphStyle.turnHintingOff();
961 TextStyle textStyle;
962 textStyle.setFontFamilies({SkString("Roboto")});
963 textStyle.setFontSize(30);
964 textStyle.setLetterSpacing(letterSpace);
965 textStyle.setColor(SK_ColorBLACK);
966 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
967 SkFontStyle::kUpright_Slant));
968
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400969 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400970 builder.pushStyle(textStyle);
971 builder.addText(line);
972 builder.pop();
973
974 auto paragraph = builder.Build();
975 paragraph->layout(w - 20);
976 paragraph->paint(canvas, 10, 10);
977 }
978
979 void onDrawContent(SkCanvas* canvas) override {
980 canvas->drawColor(SK_ColorWHITE);
981
982 auto h = this->height() / 4;
983 auto w = this->width() / 2;
984
985 drawText(canvas, SK_ColorGRAY, 1, w, h);
986 canvas->translate(0, h);
987
988 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
989 canvas->translate(0, h);
990
991 drawText(canvas, SK_ColorCYAN, 3, w, h);
992 canvas->translate(0, h);
993
994 drawText(canvas, SK_ColorGRAY, 4, w, h);
995 canvas->translate(w, -3 * h);
996
997 drawText(canvas, SK_ColorYELLOW, 5, w, h);
998 canvas->translate(0, h);
999
1000 drawText(canvas, SK_ColorGREEN, 10, w, h);
1001 canvas->translate(0, h);
1002
1003 drawText(canvas, SK_ColorRED, 15, w, h);
1004 canvas->translate(0, h);
1005
1006 drawText(canvas, SK_ColorBLUE, 20, w, h);
1007 canvas->translate(0, h);
1008 }
1009
1010private:
1011 typedef Sample INHERITED;
1012};
1013
Mike Reed21a940d2019-07-23 10:11:03 -04001014class ParagraphView8 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001015protected:
Julia Lavrovadb9f6692019-08-01 16:02:17 -04001016 SkString name() override { return SkString("Paragraph8"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001017
1018 void drawText(SkCanvas* canvas, SkColor background, SkScalar wordSpace, SkScalar w,
1019 SkScalar h) {
1020 SkAutoCanvasRestore acr(canvas, true);
1021 canvas->clipRect(SkRect::MakeWH(w, h));
1022 canvas->drawColor(background);
1023
1024 const char* line =
Julia Lavrovadb9f6692019-08-01 16:02:17 -04001025 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001026
1027 ParagraphStyle paragraphStyle;
1028 paragraphStyle.setTextAlign(TextAlign::kLeft);
1029 paragraphStyle.setMaxLines(10);
1030 paragraphStyle.turnHintingOff();
1031 TextStyle textStyle;
1032 textStyle.setFontFamilies({SkString("Roboto")});
1033 textStyle.setFontSize(30);
1034 textStyle.setWordSpacing(wordSpace);
1035 textStyle.setColor(SK_ColorBLACK);
1036 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1037 SkFontStyle::kUpright_Slant));
1038
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001039 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001040 builder.pushStyle(textStyle);
1041 builder.addText(line);
1042 builder.pop();
1043
1044 auto paragraph = builder.Build();
1045 paragraph->layout(w - 20);
1046 paragraph->paint(canvas, 10, 10);
1047 }
1048
1049 void onDrawContent(SkCanvas* canvas) override {
1050 canvas->drawColor(SK_ColorWHITE);
1051
1052 auto h = this->height() / 4;
1053 auto w = this->width() / 2;
1054
1055 drawText(canvas, SK_ColorGRAY, 1, w, h);
1056 canvas->translate(0, h);
1057
1058 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
1059 canvas->translate(0, h);
1060
1061 drawText(canvas, SK_ColorCYAN, 3, w, h);
1062 canvas->translate(0, h);
1063
1064 drawText(canvas, SK_ColorGRAY, 4, w, h);
1065 canvas->translate(w, -3 * h);
1066
1067 drawText(canvas, SK_ColorYELLOW, 5, w, h);
1068 canvas->translate(0, h);
1069
1070 drawText(canvas, SK_ColorGREEN, 10, w, h);
1071 canvas->translate(0, h);
1072
1073 drawText(canvas, SK_ColorRED, 15, w, h);
1074 canvas->translate(0, h);
1075
1076 drawText(canvas, SK_ColorBLUE, 20, w, h);
1077 canvas->translate(0, h);
1078 }
1079
1080private:
1081 typedef Sample INHERITED;
1082};
1083
Mike Reed21a940d2019-07-23 10:11:03 -04001084class ParagraphView9 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001085protected:
Hal Canary8a027312019-07-03 10:55:44 -04001086 SkString name() override { return SkString("Paragraph9"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001087
Hal Canary6cc65e12019-07-03 15:53:04 -04001088 bool onChar(SkUnichar uni) override {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001089 switch (uni) {
1090 case 'w':
1091 ++wordSpacing;
1092 return true;
1093 case 'q':
1094 if (wordSpacing > 0) --wordSpacing;
1095 return true;
1096 case 'l':
1097 ++letterSpacing;
1098 return true;
1099 case 'k':
1100 if (letterSpacing > 0) --letterSpacing;
1101 return true;
1102 default:
1103 break;
1104 }
Hal Canary6cc65e12019-07-03 15:53:04 -04001105 return false;
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001106 }
1107
1108 void drawText(SkCanvas* canvas, SkColor background, SkScalar w, SkScalar h) {
1109 SkAutoCanvasRestore acr(canvas, true);
1110 canvas->clipRect(SkRect::MakeWH(w, h));
1111 canvas->drawColor(background);
1112
1113 const char* text =
1114 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1115 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1116 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
1117
1118 ParagraphStyle paragraphStyle;
1119 paragraphStyle.setTextAlign(TextAlign::kLeft);
1120 paragraphStyle.setMaxLines(10);
1121 paragraphStyle.turnHintingOff();
1122 TextStyle textStyle;
1123 textStyle.setFontFamilies({SkString("Roboto")});
1124 textStyle.setFontSize(50);
1125 textStyle.setHeight(1.3f);
1126 textStyle.setColor(SK_ColorBLACK);
1127 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1128 SkFontStyle::kUpright_Slant));
1129
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001130 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001131 builder.pushStyle(textStyle);
1132 builder.addText(text);
1133 builder.pop();
1134
1135 auto paragraph = builder.Build();
1136 paragraph->layout(550);
1137
1138 std::vector<size_t> sizes = {0, 1, 2, 8, 19, 21, 22, 30, 150};
1139
1140 std::vector<size_t> colors = {SK_ColorBLUE, SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGREEN,
1141 SK_ColorRED, SK_ColorWHITE, SK_ColorYELLOW, SK_ColorMAGENTA};
1142
1143 RectHeightStyle rect_height_style = RectHeightStyle::kTight;
1144 RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1145
1146 for (size_t i = 0; i < sizes.size() - 1; ++i) {
1147 size_t from = (i == 0 ? 0 : 1) + sizes[i];
1148 size_t to = sizes[i + 1];
1149 auto boxes = paragraph->getRectsForRange(from, to, rect_height_style, rect_width_style);
1150 if (boxes.empty()) {
1151 continue;
1152 }
1153 for (auto& box : boxes) {
1154 SkPaint paint;
1155 paint.setColor(colors[i % colors.size()]);
1156 paint.setShader(setgrad(box.rect, colors[i % colors.size()], SK_ColorWHITE));
1157 canvas->drawRect(box.rect, paint);
1158 }
1159 }
1160
1161 paragraph->paint(canvas, 0, 0);
1162 }
1163
1164 void onDrawContent(SkCanvas* canvas) override {
1165 canvas->drawColor(SK_ColorWHITE);
1166
1167 auto h = this->height();
1168 auto w = this->width();
1169
1170 drawText(canvas, SK_ColorGRAY, w, h);
1171 }
1172
1173private:
1174 typedef Sample INHERITED;
1175 SkScalar letterSpacing;
1176 SkScalar wordSpacing;
1177};
1178
Mike Reed21a940d2019-07-23 10:11:03 -04001179class ParagraphView10 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001180protected:
Hal Canary8a027312019-07-03 10:55:44 -04001181 SkString name() override { return SkString("Paragraph10"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001182
1183 void onDrawContent(SkCanvas* canvas) override {
1184 canvas->drawColor(SK_ColorWHITE);
1185
1186 const char* text = "English English 字典 字典 😀😃😄 😀😃😄";
1187 ParagraphStyle paragraph_style;
1188 paragraph_style.turnHintingOff();
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001189 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001190
1191 TextStyle text_style;
Julia Lavrova5207f352019-06-21 12:22:32 -04001192 text_style.setFontFamilies({SkString("Roboto"),
1193 SkString("Noto Color Emoji"),
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001194 SkString("Source Han Serif CN")});
1195 text_style.setColor(SK_ColorRED);
1196 text_style.setFontSize(60);
1197 text_style.setLetterSpacing(0);
1198 text_style.setWordSpacing(0);
1199 text_style.setColor(SK_ColorBLACK);
1200 text_style.setHeight(1);
1201 builder.pushStyle(text_style);
1202 builder.addText(text);
1203 builder.pop();
1204
1205 auto paragraph = builder.Build();
1206 paragraph->layout(width());
1207
1208 paragraph->paint(canvas, 0, 0);
1209 SkDEBUGCODE(auto impl = reinterpret_cast<ParagraphImpl*>(paragraph.get()));
1210 SkASSERT(impl->runs().size() == 3);
Julia Lavrova5207f352019-06-21 12:22:32 -04001211 SkASSERT(impl->runs()[0].textRange().end == impl->runs()[1].textRange().start);
1212 SkASSERT(impl->runs()[1].textRange().end == impl->runs()[2].textRange().start);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001213 }
1214
1215private:
1216 typedef Sample INHERITED;
1217};
1218
Mike Reed21a940d2019-07-23 10:11:03 -04001219class ParagraphView11 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001220protected:
Hal Canary8a027312019-07-03 10:55:44 -04001221 SkString name() override { return SkString("Paragraph11"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001222
1223 void onDrawContent(SkCanvas* canvas) override {
1224 canvas->drawColor(SK_ColorWHITE);
Julia Lavrova5207f352019-06-21 12:22:32 -04001225 const char* text = "The same text many times";
1226
1227 for (size_t i = 0; i < 10; i++) {
1228 ParagraphStyle paragraph_style;
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001229 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
Julia Lavrova5207f352019-06-21 12:22:32 -04001230 TextStyle text_style;
1231 text_style.setFontFamilies({SkString("Roboto")});
1232 text_style.setColor(SK_ColorBLACK);
1233 text_style.setFontSize(10 + 2 * (i % 10));
1234 builder.pushStyle(text_style);
1235 builder.addText(text);
1236 builder.pop();
1237 auto paragraph = builder.Build();
1238 paragraph->layout(500);
Mike Reed21a940d2019-07-23 10:11:03 -04001239 paragraph->paint(canvas, 0, 40 * (i % 10));
Julia Lavrova5207f352019-06-21 12:22:32 -04001240 }
1241 }
1242
1243private:
1244 typedef Sample INHERITED;
1245};
1246
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001247//////////////////////////////////////////////////////////////////////////////
1248
1249DEF_SAMPLE(return new ParagraphView1();)
1250DEF_SAMPLE(return new ParagraphView2();)
1251DEF_SAMPLE(return new ParagraphView3();)
1252DEF_SAMPLE(return new ParagraphView4();)
1253DEF_SAMPLE(return new ParagraphView5();)
1254DEF_SAMPLE(return new ParagraphView6();)
1255DEF_SAMPLE(return new ParagraphView7();)
1256DEF_SAMPLE(return new ParagraphView8();)
1257DEF_SAMPLE(return new ParagraphView9();)
1258DEF_SAMPLE(return new ParagraphView10();)
1259DEF_SAMPLE(return new ParagraphView11();)
Julia Lavrova526df262019-08-21 17:49:44 -04001260