1 // Copyright 2019 Google LLC.
2 #include "include/core/SkCanvas.h"
3 #include "include/core/SkColorFilter.h"
4 #include "include/core/SkColorPriv.h"
5 #include "include/core/SkFontMgr.h"
6 #include "include/core/SkGraphics.h"
7 #include "include/core/SkPath.h"
8 #include "include/core/SkRegion.h"
9 #include "include/core/SkShader.h"
10 #include "include/core/SkStream.h"
11 #include "include/core/SkTextBlob.h"
12 #include "include/core/SkTime.h"
13 #include "include/core/SkTypeface.h"
14 #include "include/effects/SkGradientShader.h"
15 #include "include/utils/SkRandom.h"
16 #include "modules/skparagraph/include/Paragraph.h"
17 #include "modules/skparagraph/include/TypefaceFontProvider.h"
18 #include "modules/skparagraph/src/ParagraphBuilderImpl.h"
19 #include "modules/skparagraph/src/ParagraphImpl.h"
20 #include "modules/skparagraph/src/TextLine.h"
21 #include "modules/skparagraph/utils/TestFontCollection.h"
22 #include "samplecode/Sample.h"
23 #include "src/core/SkOSFile.h"
24 #include "src/shaders/SkColorShader.h"
25 #include "src/utils/SkOSPath.h"
26 #include "src/utils/SkUTF.h"
27 #include "tools/Resources.h"
28 #include "tools/flags/CommandLineFlags.h"
29
30 static DEFINE_bool(verboseParagraph, false, "paragraph samples very verbose.");
31
32 using namespace skia::textlayout;
33 namespace {
34
35 class ParagraphView_Base : public Sample {
36 protected:
getFontCollection()37 sk_sp<TestFontCollection> getFontCollection() {
38 // If we reset font collection we need to reset paragraph cache
39 static sk_sp<TestFontCollection> fFC = nullptr;
40 if (fFC == nullptr) {
41 fFC = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
42 }
43 return fFC;
44 }
45
isVerbose()46 bool isVerbose() {
47 return FLAGS_verboseParagraph;
48 }
49 };
50
setgrad(const SkRect & r,SkColor c0,SkColor c1)51 sk_sp<SkShader> setgrad(const SkRect& r, SkColor c0, SkColor c1) {
52 SkColor colors[] = {c0, c1};
53 SkPoint pts[] = {{r.fLeft, r.fTop}, {r.fRight, r.fTop}};
54 return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
55 }
56 /*
57 void writeHtml(const char* name, Paragraph* paragraph) {
58 SkString tmpDir = skiatest::GetTmpDir();
59 if (!tmpDir.isEmpty()) {
60 SkString path = SkOSPath::Join(tmpDir.c_str(), name);
61 SkFILEWStream file(path.c_str());
62 file.write(nullptr, 0);
63 }
64 }
65 */
66
67 class ParagraphView1 : public ParagraphView_Base {
68 protected:
name()69 SkString name() override { return SkString("Paragraph1"); }
70
drawTest(SkCanvas * canvas,SkScalar w,SkScalar h,SkColor fg,SkColor bg)71 void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) {
72 const std::vector<
73 std::tuple<std::string, bool, bool, int, SkColor, SkColor, bool, TextDecorationStyle>>
74 gParagraph = {{"monospace", true, false, 14, SK_ColorWHITE, SK_ColorRED, true,
75 TextDecorationStyle::kDashed},
76 {"Assyrian", false, false, 20, SK_ColorWHITE, SK_ColorBLUE, false,
77 TextDecorationStyle::kDotted},
78 {"serif", true, true, 10, SK_ColorWHITE, SK_ColorRED, true,
79 TextDecorationStyle::kDouble},
80 {"Arial", false, true, 16, SK_ColorGRAY, SK_ColorGREEN, true,
81 TextDecorationStyle::kSolid},
82 {"sans-serif", false, false, 8, SK_ColorWHITE, SK_ColorRED, false,
83 TextDecorationStyle::kWavy}};
84 SkAutoCanvasRestore acr(canvas, true);
85
86 canvas->clipRect(SkRect::MakeWH(w, h));
87 canvas->drawColor(SK_ColorWHITE);
88
89 SkScalar margin = 20;
90
91 SkPaint paint;
92 paint.setAntiAlias(true);
93 paint.setColor(fg);
94
95 SkPaint blue;
96 blue.setColor(SK_ColorBLUE);
97
98 TextStyle defaultStyle;
99 defaultStyle.setBackgroundColor(blue);
100 defaultStyle.setForegroundColor(paint);
101 ParagraphStyle paraStyle;
102
103 auto fontCollection = sk_make_sp<FontCollection>();
104 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
105 for (auto i = 1; i < 5; ++i) {
106 defaultStyle.setFontSize(24 * i);
107 paraStyle.setTextStyle(defaultStyle);
108 ParagraphBuilderImpl builder(paraStyle, fontCollection);
109 std::string name = "Paragraph: " + std::to_string(24 * i);
110 builder.addText(name.c_str(), name.length());
111 for (auto para : gParagraph) {
112 TextStyle style;
113 style.setFontFamilies({SkString(std::get<0>(para).c_str())});
114 SkFontStyle fontStyle(std::get<1>(para) ? SkFontStyle::Weight::kBold_Weight
115 : SkFontStyle::Weight::kNormal_Weight,
116 SkFontStyle::Width::kNormal_Width,
117 std::get<2>(para) ? SkFontStyle::Slant::kItalic_Slant
118 : SkFontStyle::Slant::kUpright_Slant);
119 style.setFontStyle(fontStyle);
120 style.setFontSize(std::get<3>(para) * i);
121 SkPaint background;
122 background.setColor(std::get<4>(para));
123 style.setBackgroundColor(background);
124 SkPaint foreground;
125 foreground.setColor(std::get<5>(para));
126 foreground.setAntiAlias(true);
127 style.setForegroundColor(foreground);
128 if (std::get<6>(para)) {
129 style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(5, 5), 2));
130 }
131
132 auto decoration = (i % 4);
133 if (decoration == 3) {
134 decoration = 4;
135 }
136
137 bool test = (TextDecoration)decoration != TextDecoration::kNoDecoration;
138 std::string deco = std::to_string((int)decoration);
139 if (test) {
140 style.setDecoration((TextDecoration)decoration);
141 style.setDecorationStyle(std::get<7>(para));
142 style.setDecorationColor(std::get<5>(para));
143 }
144 builder.pushStyle(style);
145 name = " " + std::get<0>(para) + " " +
146 (std::get<1>(para) ? ", bold" : "") +
147 (std::get<2>(para) ? ", italic" : "") + " " +
148 std::to_string(std::get<3>(para) * i) +
149 (std::get<4>(para) != bg ? ", background" : "") +
150 (std::get<5>(para) != fg ? ", foreground" : "") +
151 (std::get<6>(para) ? ", shadow" : "") +
152 (test ? ", decorations " + deco : "") + ";";
153 builder.addText(name.c_str(), name.length());
154 builder.pop();
155 }
156
157 auto paragraph = builder.Build();
158 paragraph->layout(w - margin * 2);
159 paragraph->paint(canvas, margin, margin);
160
161 canvas->translate(0, paragraph->getHeight());
162 }
163 }
164
onDrawContent(SkCanvas * canvas)165 void onDrawContent(SkCanvas* canvas) override {
166 drawTest(canvas, this->width(), this->height(), SK_ColorRED, SK_ColorWHITE);
167 }
168
169 private:
170
171 using INHERITED = Sample;
172 };
173
174 class ParagraphView2 : public ParagraphView_Base {
175 protected:
name()176 SkString name() override { return SkString("Paragraph2"); }
177
drawCode(SkCanvas * canvas,SkScalar w,SkScalar h)178 void drawCode(SkCanvas* canvas, SkScalar w, SkScalar h) {
179 SkPaint comment;
180 comment.setColor(SK_ColorGRAY);
181 SkPaint constant;
182 constant.setColor(SK_ColorMAGENTA);
183 SkPaint null;
184 null.setColor(SK_ColorMAGENTA);
185 SkPaint literal;
186 literal.setColor(SK_ColorGREEN);
187 SkPaint code;
188 code.setColor(SK_ColorDKGRAY);
189 SkPaint number;
190 number.setColor(SK_ColorBLUE);
191 SkPaint name;
192 name.setColor(SK_ColorRED);
193
194 SkPaint white;
195 white.setColor(SK_ColorWHITE);
196
197 TextStyle defaultStyle;
198 defaultStyle.setBackgroundColor(white);
199 defaultStyle.setForegroundColor(code);
200 defaultStyle.setFontFamilies({SkString("monospace")});
201 defaultStyle.setFontSize(30);
202 ParagraphStyle paraStyle;
203 paraStyle.setTextStyle(defaultStyle);
204
205 auto fontCollection = sk_make_sp<FontCollection>();
206 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
207 ParagraphBuilderImpl builder(paraStyle, fontCollection);
208
209 const char* text1 = "RaisedButton";
210 const char* text2 = "(\n";
211 const char* text3 = " child: ";
212 const char* text4 = "const";
213 const char* text5 = "Text";
214 const char* text6 = "'BUTTON TITLE'";
215 const char* text7 = "),\n";
216
217 builder.pushStyle(style(name));
218 builder.addText(text1, strlen(text1));
219 builder.pop();
220 builder.addText(text2, strlen(text2));
221 builder.addText(text3, strlen(text3));
222 builder.pushStyle(style(constant));
223 builder.addText(text4, strlen(text4));
224 builder.pop();
225 builder.addText(" ", 1);
226 builder.pushStyle(style(name));
227 builder.addText(text5, strlen(text5));
228 builder.pop();
229 builder.addText("(", 1);
230 builder.pushStyle(style(literal));
231 builder.addText(text6, strlen(text6));
232 builder.pop();
233 builder.addText(text7, strlen(text7));
234
235 auto paragraph = builder.Build();
236 paragraph->layout(w - 20);
237
238 paragraph->paint(canvas, 20, 20);
239 }
240
style(SkPaint paint)241 TextStyle style(SkPaint paint) {
242 TextStyle style;
243 paint.setAntiAlias(true);
244 style.setForegroundColor(paint);
245 style.setFontFamilies({SkString("monospace")});
246 style.setFontSize(30);
247
248 return style;
249 }
250
drawText(SkCanvas * canvas,SkScalar w,SkScalar h,std::vector<const char * > & text,SkColor fg=SK_ColorDKGRAY,SkColor bg=SK_ColorWHITE,const char * ff="sans-serif",SkScalar fs=24,size_t lineLimit=30,const std::u16string & ellipsis=u"\\u2026")251 void drawText(SkCanvas* canvas, SkScalar w, SkScalar h, std::vector<const char*>& text,
252 SkColor fg = SK_ColorDKGRAY, SkColor bg = SK_ColorWHITE,
253 const char* ff = "sans-serif", SkScalar fs = 24,
254 size_t lineLimit = 30,
255 const std::u16string& ellipsis = u"\u2026") {
256 SkAutoCanvasRestore acr(canvas, true);
257
258 canvas->clipRect(SkRect::MakeWH(w, h));
259 canvas->drawColor(bg);
260
261 SkScalar margin = 20;
262
263 SkPaint paint;
264 paint.setAntiAlias(true);
265 paint.setColor(fg);
266
267 SkPaint blue;
268 blue.setColor(SK_ColorBLUE);
269
270 SkPaint background;
271 background.setColor(bg);
272
273 TextStyle style;
274 style.setBackgroundColor(blue);
275 style.setForegroundColor(paint);
276 style.setFontFamilies({SkString(ff)});
277 style.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight,
278 SkFontStyle::kNormal_Width,
279 SkFontStyle::kUpright_Slant));
280 style.setFontSize(fs);
281 ParagraphStyle paraStyle;
282 paraStyle.setTextStyle(style);
283 paraStyle.setMaxLines(lineLimit);
284
285 paraStyle.setEllipsis(ellipsis);
286 TextStyle defaultStyle;
287 defaultStyle.setFontSize(20);
288 paraStyle.setTextStyle(defaultStyle);
289 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
290
291 SkPaint foreground;
292 foreground.setColor(fg);
293 style.setForegroundColor(foreground);
294 style.setBackgroundColor(background);
295
296 for (auto& part : text) {
297 builder.pushStyle(style);
298 builder.addText(part, strlen(part));
299 builder.pop();
300 }
301
302 auto paragraph = builder.Build();
303 paragraph->layout(w - margin * 2);
304 paragraph->paint(canvas, margin, margin);
305
306 canvas->translate(0, paragraph->getHeight() + margin);
307 }
308
drawLine(SkCanvas * canvas,SkScalar w,SkScalar h,const std::string & text,TextAlign align)309 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
310 TextAlign align) {
311 SkAutoCanvasRestore acr(canvas, true);
312
313 canvas->clipRect(SkRect::MakeWH(w, h));
314 canvas->drawColor(SK_ColorWHITE);
315
316 SkScalar margin = 20;
317
318 SkPaint paint;
319 paint.setAntiAlias(true);
320 paint.setColor(SK_ColorBLUE);
321
322 SkPaint gray;
323 gray.setColor(SK_ColorLTGRAY);
324
325 TextStyle style;
326 style.setBackgroundColor(gray);
327 style.setForegroundColor(paint);
328 style.setFontFamilies({SkString("Arial")});
329 style.setFontSize(30);
330 ParagraphStyle paraStyle;
331 paraStyle.setTextStyle(style);
332 paraStyle.setTextAlign(align);
333
334 auto fontCollection = sk_make_sp<FontCollection>();
335 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
336 ParagraphBuilderImpl builder(paraStyle, fontCollection);
337 builder.addText(text.c_str(), text.length());
338
339 auto paragraph = builder.Build();
340 paragraph->layout(w - margin * 2);
341 paragraph->layout(w - margin);
342 paragraph->paint(canvas, margin, margin);
343
344 canvas->translate(0, paragraph->getHeight() + margin);
345 }
346
onDrawContent(SkCanvas * canvas)347 void onDrawContent(SkCanvas* canvas) override {
348 std::vector<const char*> cupertino = {
349 "google_logogoogle_gsuper_g_logo 1 "
350 "google_logogoogle_gsuper_g_logo 12 "
351 "google_logogoogle_gsuper_g_logo 123 "
352 "google_logogoogle_gsuper_g_logo 1234 "
353 "google_logogoogle_gsuper_g_logo 12345 "
354 "google_logogoogle_gsuper_g_logo 123456 "
355 "google_logogoogle_gsuper_g_logo 1234567 "
356 "google_logogoogle_gsuper_g_logo 12345678 "
357 "google_logogoogle_gsuper_g_logo 123456789 "
358 "google_logogoogle_gsuper_g_logo 1234567890 "
359 "google_logogoogle_gsuper_g_logo 123456789 "
360 "google_logogoogle_gsuper_g_logo 12345678 "
361 "google_logogoogle_gsuper_g_logo 1234567 "
362 "google_logogoogle_gsuper_g_logo 123456 "
363 "google_logogoogle_gsuper_g_logo 12345 "
364 "google_logogoogle_gsuper_g_logo 1234 "
365 "google_logogoogle_gsuper_g_logo 123 "
366 "google_logogoogle_gsuper_g_logo 12 "
367 "google_logogoogle_gsuper_g_logo 1 "
368 "google_logogoogle_gsuper_g_logo "
369 "google_logogoogle_gsuper_g_logo "
370 "google_logogoogle_gsuper_g_logo "
371 "google_logogoogle_gsuper_g_logo "
372 "google_logogoogle_gsuper_g_logo "
373 "google_logogoogle_gsuper_g_logo"};
374 std::vector<const char*> text = {
375 "My neighbor came over to say,\n"
376 "Although not in a neighborly way,\n\n"
377 "That he'd knock me around,\n\n\n"
378 "If I didn't stop the sound,\n\n\n\n"
379 "Of the classical music I play."};
380
381 std::vector<const char*> long_word = {
382 "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
387 std::vector<const char*> very_long = {
388 "A very very very very very very 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 long text"};
392
393 std::vector<const char*> very_word = {
394 "A very_very_very_very_very_very_very_very_very_very "
395 "very_very_very_very_very_very_very_very_very_very very very very very very very "
396 "very very very very very very very very very very very very very very very very "
397 "very very very very very very very very very very very very very long text"};
398
399 SkScalar width = this->width() / 5;
400 SkScalar height = this->height();
401 drawText(canvas, width, height, long_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
402 canvas->translate(width, 0);
403 drawText(canvas, width, height, very_long, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
404 canvas->translate(width, 0);
405 drawText(canvas, width, height, very_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
406 canvas->translate(width, 0);
407 drawText(canvas, width, height / 2, text, SK_ColorBLACK, SK_ColorWHITE, "Roboto", 20, 100,
408 u"\u2026");
409 canvas->translate(0, height / 2);
410 drawCode(canvas, width, height / 2);
411 canvas->translate(width, -height / 2);
412
413 drawText(canvas, width, height, cupertino, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
414 }
415
416 private:
417 using INHERITED = Sample;
418 };
419
420 class ParagraphView3 : public ParagraphView_Base {
421 protected:
name()422 SkString name() override { return SkString("Paragraph3"); }
423
drawLine(SkCanvas * canvas,SkScalar w,SkScalar h,const std::string & text,TextAlign align,size_t lineLimit=std::numeric_limits<size_t>::max (),bool RTL=false,SkColor background=SK_ColorGRAY,const std::u16string & ellipsis=u"\\u2026")424 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
425 TextAlign align, size_t lineLimit = std::numeric_limits<size_t>::max(),
426 bool RTL = false, SkColor background = SK_ColorGRAY,
427 const std::u16string& ellipsis = u"\u2026") {
428 SkAutoCanvasRestore acr(canvas, true);
429
430 canvas->clipRect(SkRect::MakeWH(w, h));
431 canvas->drawColor(SK_ColorWHITE);
432
433 SkScalar margin = 20;
434
435 SkPaint paint;
436 paint.setAntiAlias(true);
437 paint.setColor(SK_ColorBLACK);
438
439 SkPaint gray;
440 gray.setColor(background);
441
442 SkPaint yellow;
443 yellow.setColor(SK_ColorYELLOW);
444
445 TextStyle style;
446 style.setBackgroundColor(gray);
447 style.setForegroundColor(paint);
448 style.setFontFamilies({SkString("sans-serif")});
449 style.setFontSize(30);
450 ParagraphStyle paraStyle;
451 paraStyle.setTextStyle(style);
452 paraStyle.setTextAlign(align);
453 paraStyle.setMaxLines(lineLimit);
454 paraStyle.setEllipsis(ellipsis);
455 // paraStyle.setTextDirection(RTL ? SkTextDirection::rtl : SkTextDirection::ltr);
456
457 auto fontCollection = sk_make_sp<FontCollection>();
458 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
459 ParagraphBuilderImpl builder(paraStyle, fontCollection);
460 if (RTL) {
461 builder.addText(mirror(text));
462 } else {
463 builder.addText(normal(text));
464 }
465
466 canvas->drawRect(SkRect::MakeXYWH(margin, margin, w - margin * 2, h - margin * 2), yellow);
467 auto paragraph = builder.Build();
468 paragraph->layout(w - margin * 2);
469 paragraph->paint(canvas, margin, margin);
470 }
471
mirror(const std::string & text)472 std::u16string mirror(const std::string& text) {
473 std::u16string result;
474 result += u"\u202E";
475 // for (auto i = text.size(); i > 0; --i) {
476 // result += text[i - 1];
477 //}
478
479 for (auto i = text.size(); i > 0; --i) {
480 auto ch = text[i - 1];
481 if (ch == ',') {
482 result += u"!";
483 } else if (ch == '.') {
484 result += u"!";
485 } else {
486 result += ch;
487 }
488 }
489
490 result += u"\u202C";
491 return result;
492 }
493
normal(const std::string & text)494 std::u16string normal(const std::string& text) {
495 std::u16string result;
496 result += u"\u202D";
497 for (auto ch : text) {
498 result += ch;
499 }
500 result += u"\u202C";
501 return result;
502 }
503
onDrawContent(SkCanvas * canvas)504 void onDrawContent(SkCanvas* canvas) override {
505 const std::string options = // { "open-source open-source open-source open-source" };
506 {"Flutter is an open-source project to help developers "
507 "build high-performance, high-fidelity, mobile apps for "
508 "iOS and Android "
509 "from a single codebase. This design lab is a playground "
510 "and showcase of Flutter's many widgets, behaviors, "
511 "animations, layouts, and more."};
512
513 canvas->drawColor(SK_ColorDKGRAY);
514 SkScalar width = this->width() / 4;
515 SkScalar height = this->height() / 2;
516
517 const std::string line =
518 "World domination is such an ugly phrase - I prefer to call it world optimisation";
519
520 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, false, SK_ColorLTGRAY);
521 canvas->translate(width, 0);
522 drawLine(canvas, width, height, line, TextAlign::kRight, 2, false, SK_ColorLTGRAY);
523 canvas->translate(width, 0);
524 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, false, SK_ColorLTGRAY);
525 canvas->translate(width, 0);
526 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, false, SK_ColorLTGRAY);
527 canvas->translate(-width * 3, height);
528
529 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, true, SK_ColorLTGRAY);
530 canvas->translate(width, 0);
531 drawLine(canvas, width, height, line, TextAlign::kRight, 2, true, SK_ColorLTGRAY);
532 canvas->translate(width, 0);
533 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, true, SK_ColorLTGRAY);
534 canvas->translate(width, 0);
535 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, true, SK_ColorLTGRAY);
536 canvas->translate(width, 0);
537 }
538
539 private:
540 using INHERITED = Sample;
541 };
542
543 class ParagraphView4 : public ParagraphView_Base {
544 protected:
name()545 SkString name() override { return SkString("Paragraph4"); }
546
drawFlutter(SkCanvas * canvas,SkScalar w,SkScalar h,const char * ff="Google Sans",SkScalar fs=30,size_t lineLimit=std::numeric_limits<size_t>::max (),const std::u16string & ellipsis=u"\\u2026")547 void drawFlutter(SkCanvas* canvas, SkScalar w, SkScalar h,
548 const char* ff = "Google Sans", SkScalar fs = 30,
549 size_t lineLimit = std::numeric_limits<size_t>::max(),
550 const std::u16string& ellipsis = u"\u2026") {
551 SkAutoCanvasRestore acr(canvas, true);
552
553 canvas->clipRect(SkRect::MakeWH(w, h));
554
555 SkScalar margin = 20;
556
557 SkPaint black;
558 black.setAntiAlias(true);
559 black.setColor(SK_ColorBLACK);
560
561 SkPaint blue;
562 blue.setAntiAlias(true);
563 blue.setColor(SK_ColorBLUE);
564
565 SkPaint red;
566 red.setAntiAlias(true);
567 red.setColor(SK_ColorRED);
568
569 SkPaint green;
570 green.setAntiAlias(true);
571 green.setColor(SK_ColorGREEN);
572
573 SkPaint gray;
574 gray.setColor(SK_ColorLTGRAY);
575
576 SkPaint yellow;
577 yellow.setColor(SK_ColorYELLOW);
578
579 SkPaint magenta;
580 magenta.setAntiAlias(true);
581 magenta.setColor(SK_ColorMAGENTA);
582
583 TextStyle style;
584 style.setFontFamilies({SkString(ff)});
585 style.setFontSize(fs);
586
587 TextStyle style0;
588 style0.setForegroundColor(black);
589 style0.setBackgroundColor(gray);
590 style0.setFontFamilies({SkString(ff)});
591 style0.setFontSize(fs);
592 style0.setDecoration(TextDecoration::kUnderline);
593 style0.setDecorationStyle(TextDecorationStyle::kDouble);
594 style0.setDecorationColor(SK_ColorBLACK);
595
596 TextStyle style1;
597 style1.setForegroundColor(blue);
598 style1.setBackgroundColor(yellow);
599 style1.setFontFamilies({SkString(ff)});
600 style1.setFontSize(fs);
601 style1.setDecoration(TextDecoration::kOverline);
602 style1.setDecorationStyle(TextDecorationStyle::kWavy);
603 style1.setDecorationColor(SK_ColorBLACK);
604
605 TextStyle style2;
606 style2.setForegroundColor(red);
607 style2.setFontFamilies({SkString(ff)});
608 style2.setFontSize(fs);
609
610 TextStyle style3;
611 style3.setForegroundColor(green);
612 style3.setFontFamilies({SkString(ff)});
613 style3.setFontSize(fs);
614
615 TextStyle style4;
616 style4.setForegroundColor(magenta);
617 style4.setFontFamilies({SkString(ff)});
618 style4.setFontSize(fs);
619
620 ParagraphStyle paraStyle;
621 paraStyle.setTextStyle(style);
622 paraStyle.setMaxLines(lineLimit);
623
624 paraStyle.setEllipsis(ellipsis);
625
626 const char* logo1 = "google_";
627 const char* logo2 = "logo";
628 const char* logo3 = "go";
629 const char* logo4 = "ogle_logo";
630 const char* logo5 = "google_lo";
631 const char* logo6 = "go";
632 {
633 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
634
635 builder.pushStyle(style0);
636 builder.addText(logo1, strlen(logo1));
637 builder.pop();
638 builder.pushStyle(style1);
639 builder.addText(logo2, strlen(logo2));
640 builder.pop();
641
642 builder.addText(" ", 1);
643
644 builder.pushStyle(style0);
645 builder.addText(logo3, strlen(logo3));
646 builder.pop();
647 builder.pushStyle(style1);
648 builder.addText(logo4, strlen(logo4));
649 builder.pop();
650
651 builder.addText(" ", 1);
652
653 builder.pushStyle(style0);
654 builder.addText(logo5, strlen(logo5));
655 builder.pop();
656 builder.pushStyle(style1);
657 builder.addText(logo6, strlen(logo6));
658 builder.pop();
659
660 auto paragraph = builder.Build();
661 paragraph->layout(w - margin * 2);
662 paragraph->paint(canvas, margin, margin);
663 canvas->translate(0, h + margin);
664 }
665 }
666
onDrawContent(SkCanvas * canvas)667 void onDrawContent(SkCanvas* canvas) override {
668 canvas->drawColor(SK_ColorWHITE);
669 SkScalar width = this->width();
670 SkScalar height = this->height();
671
672 drawFlutter(canvas, width, height / 2);
673 }
674
675 private:
676 using INHERITED = Sample;
677 };
678
679 class ParagraphView5 : public ParagraphView_Base {
680 protected:
name()681 SkString name() override { return SkString("Paragraph5"); }
682
bidi(SkCanvas * canvas,SkScalar w,SkScalar h,const std::u16string & text,const std::u16string & expected,size_t lineLimit=std::numeric_limits<size_t>::max (),const char * ff="Roboto",SkScalar fs=30,const std::u16string & ellipsis=u"\\u2026")683 void bidi(SkCanvas* canvas, SkScalar w, SkScalar h, const std::u16string& text,
684 const std::u16string& expected, size_t lineLimit = std::numeric_limits<size_t>::max(),
685 const char* ff = "Roboto", SkScalar fs = 30,
686 const std::u16string& ellipsis = u"\u2026") {
687 SkAutoCanvasRestore acr(canvas, true);
688
689 canvas->clipRect(SkRect::MakeWH(w, h));
690
691 SkScalar margin = 20;
692
693 SkPaint black;
694 black.setColor(SK_ColorBLACK);
695 SkPaint gray;
696 gray.setColor(SK_ColorLTGRAY);
697
698 TextStyle style;
699 style.setForegroundColor(black);
700 style.setFontFamilies({SkString(ff)});
701 style.setFontSize(fs);
702
703 TextStyle style0;
704 style0.setForegroundColor(black);
705 style0.setFontFamilies({SkString(ff)});
706 style0.setFontSize(fs);
707 style0.setFontStyle(SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
708 SkFontStyle::kItalic_Slant));
709
710 TextStyle style1;
711 style1.setForegroundColor(gray);
712 style1.setFontFamilies({SkString(ff)});
713 style1.setFontSize(fs);
714 style1.setFontStyle(SkFontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
715 SkFontStyle::kUpright_Slant));
716
717 ParagraphStyle paraStyle;
718 paraStyle.setTextStyle(style);
719 paraStyle.setMaxLines(lineLimit);
720
721 paraStyle.setEllipsis(ellipsis);
722
723 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
724
725 if (text.empty()) {
726 const std::u16string text0 = u"\u202Dabc";
727 const std::u16string text1 = u"\u202EFED";
728 const std::u16string text2 = u"\u202Dghi";
729 const std::u16string text3 = u"\u202ELKJ";
730 const std::u16string text4 = u"\u202Dmno";
731 builder.pushStyle(style0);
732 builder.addText(text0);
733 builder.pop();
734 builder.pushStyle(style1);
735 builder.addText(text1);
736 builder.pop();
737 builder.pushStyle(style0);
738 builder.addText(text2);
739 builder.pop();
740 builder.pushStyle(style1);
741 builder.addText(text3);
742 builder.pop();
743 builder.pushStyle(style0);
744 builder.addText(text4);
745 builder.pop();
746 } else {
747 builder.addText(text + expected);
748 }
749
750 auto paragraph = builder.Build();
751 auto impl = static_cast<ParagraphImpl*>(paragraph.get());
752 if (this->isVerbose()) {
753 SkDebugf("Text: >%s<\n", impl->text().data());
754 }
755
756 paragraph->layout(w - margin * 2);
757 paragraph->paint(canvas, margin, margin);
758 }
759
onDrawContent(SkCanvas * canvas)760 void onDrawContent(SkCanvas* canvas) override {
761 canvas->drawColor(SK_ColorWHITE);
762 SkScalar width = this->width();
763 SkScalar height = this->height() / 8;
764
765 const std::u16string text1 =
766 u"A \u202ENAC\u202Cner, exceedingly \u202ENAC\u202Cny,\n"
767 "One morning remarked to his granny:\n"
768 "A \u202ENAC\u202Cner \u202ENAC\u202C \u202ENAC\u202C,\n"
769 "Anything that he \u202ENAC\u202C,\n"
770 "But a \u202ENAC\u202Cner \u202ENAC\u202C't \u202ENAC\u202C a \u202ENAC\u202C, "
771 "\u202ENAC\u202C he?";
772 bidi(canvas, width, height * 3, text1, u"", 5);
773 canvas->translate(0, height * 3);
774
775 bidi(canvas, width, height, u"\u2067DETALOSI\u2069", u"");
776 canvas->translate(0, height);
777
778 bidi(canvas, width, height, u"\u202BDEDDEBME\u202C", u"");
779 canvas->translate(0, height);
780
781 bidi(canvas, width, height, u"\u202EEDIRREVO\u202C", u"");
782 canvas->translate(0, height);
783
784 bidi(canvas, width, height, u"\u200FTICILPMI\u200E", u"");
785 canvas->translate(0, height);
786
787 bidi(canvas, width, height, u"123 456 7890 \u202EZYXWV UTS RQP ONM LKJ IHG FED CBA\u202C.",
788 u"", 2);
789 canvas->translate(0, height);
790
791 // bidi(canvas, width, height, u"", u"");
792 // canvas->translate(0, height);
793 }
794
795 private:
796 using INHERITED = Sample;
797 };
798
799 class ParagraphView6 : public ParagraphView_Base {
800 protected:
name()801 SkString name() override { return SkString("Paragraph6"); }
802
hangingS(SkCanvas * canvas,SkScalar w,SkScalar h,SkScalar fs=60.0)803 void hangingS(SkCanvas* canvas, SkScalar w, SkScalar h, SkScalar fs = 60.0) {
804 auto ff = "HangingS";
805
806 canvas->drawColor(SK_ColorLTGRAY);
807
808 SkPaint black;
809 black.setAntiAlias(true);
810 black.setColor(SK_ColorBLACK);
811
812 SkPaint blue;
813 blue.setAntiAlias(true);
814 blue.setColor(SK_ColorBLUE);
815
816 SkPaint red;
817 red.setAntiAlias(true);
818 red.setColor(SK_ColorRED);
819
820 SkPaint green;
821 green.setAntiAlias(true);
822 green.setColor(SK_ColorGREEN);
823
824 SkPaint gray;
825 gray.setColor(SK_ColorCYAN);
826
827 SkPaint yellow;
828 yellow.setColor(SK_ColorYELLOW);
829
830 SkPaint magenta;
831 magenta.setAntiAlias(true);
832 magenta.setColor(SK_ColorMAGENTA);
833
834 SkFontStyle fontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
835 SkFontStyle::kItalic_Slant);
836
837 TextStyle style;
838 style.setFontFamilies({SkString(ff)});
839 style.setFontSize(fs);
840 style.setFontStyle(fontStyle);
841
842 TextStyle style0;
843 style0.setForegroundColor(black);
844 style0.setBackgroundColor(gray);
845 style0.setFontFamilies({SkString(ff)});
846 style0.setFontSize(fs);
847 style0.setFontStyle(fontStyle);
848
849 TextStyle style1;
850 style1.setForegroundColor(blue);
851 style1.setBackgroundColor(yellow);
852 style1.setFontFamilies({SkString(ff)});
853 style1.setFontSize(fs);
854 style1.setFontStyle(fontStyle);
855
856 TextStyle style2;
857 style2.setForegroundColor(red);
858 style2.setFontFamilies({SkString(ff)});
859 style2.setFontSize(fs);
860 style2.setFontStyle(fontStyle);
861
862 TextStyle style3;
863 style3.setForegroundColor(green);
864 style3.setFontFamilies({SkString(ff)});
865 style3.setFontSize(fs);
866 style3.setFontStyle(fontStyle);
867
868 TextStyle style4;
869 style4.setForegroundColor(magenta);
870 style4.setFontFamilies({SkString(ff)});
871 style4.setFontSize(fs);
872 style4.setFontStyle(fontStyle);
873
874 ParagraphStyle paraStyle;
875 paraStyle.setTextStyle(style);
876
877 const char* logo1 = "S";
878 const char* logo2 = "kia";
879 const char* logo3 = "Sk";
880 const char* logo4 = "ia";
881 const char* logo5 = "Ski";
882 const char* logo6 = "a";
883 {
884 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
885
886 builder.pushStyle(style0);
887 builder.addText(logo1, strlen(logo1));
888 builder.pop();
889 builder.pushStyle(style1);
890 builder.addText(logo2, strlen(logo2));
891 builder.pop();
892
893 builder.addText(" ", 3);
894
895 builder.pushStyle(style0);
896 builder.addText(logo3, strlen(logo3));
897 builder.pop();
898 builder.pushStyle(style1);
899 builder.addText(logo4, strlen(logo4));
900 builder.pop();
901
902 builder.addText(" ", 3);
903
904 builder.pushStyle(style0);
905 builder.addText(logo5, strlen(logo5));
906 builder.pop();
907 builder.pushStyle(style1);
908 builder.addText(logo6, strlen(logo6));
909 builder.pop();
910
911 auto paragraph = builder.Build();
912 paragraph->layout(w);
913 paragraph->paint(canvas, 40, 40);
914 canvas->translate(0, h);
915 }
916
917 const char* logo11 = "S";
918 const char* logo12 = "S";
919 const char* logo13 = "S";
920 const char* logo14 = "S";
921 const char* logo15 = "S";
922 const char* logo16 = "S";
923 {
924 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
925
926 builder.pushStyle(style0);
927 builder.addText(logo11, strlen(logo1));
928 builder.pop();
929 builder.pushStyle(style1);
930 builder.addText(logo12, strlen(logo2));
931 builder.pop();
932
933 builder.addText(" ", 3);
934
935 builder.pushStyle(style0);
936 builder.addText(logo13, strlen(logo3));
937 builder.pop();
938 builder.pushStyle(style1);
939 builder.addText(logo14, strlen(logo4));
940 builder.pop();
941
942 builder.addText(" ", 3);
943
944 builder.pushStyle(style0);
945 builder.addText(logo15, strlen(logo5));
946 builder.pop();
947 builder.pushStyle(style1);
948 builder.addText(logo16, strlen(logo6));
949 builder.pop();
950
951 auto paragraph = builder.Build();
952 paragraph->layout(w);
953 paragraph->paint(canvas, 40, h);
954 canvas->translate(0, h);
955 }
956 }
957
onDrawContent(SkCanvas * canvas)958 void onDrawContent(SkCanvas* canvas) override {
959 canvas->drawColor(SK_ColorWHITE);
960 SkScalar width = this->width();
961 SkScalar height = this->height() / 4;
962
963 hangingS(canvas, width, height);
964 }
965
966 private:
967 using INHERITED = Sample;
968 };
969
970 class ParagraphView7 : public ParagraphView_Base {
971 protected:
name()972 SkString name() override { return SkString("Paragraph7"); }
973
drawText(SkCanvas * canvas,SkColor background,SkScalar letterSpace,SkScalar w,SkScalar h)974 void drawText(SkCanvas* canvas, SkColor background, SkScalar letterSpace, SkScalar w,
975 SkScalar h) {
976 SkAutoCanvasRestore acr(canvas, true);
977 canvas->clipRect(SkRect::MakeWH(w, h));
978 canvas->drawColor(background);
979
980 const char* line =
981 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
982
983 ParagraphStyle paragraphStyle;
984 paragraphStyle.setTextAlign(TextAlign::kLeft);
985 paragraphStyle.setMaxLines(10);
986 paragraphStyle.turnHintingOff();
987 TextStyle textStyle;
988 textStyle.setFontFamilies({SkString("Roboto")});
989 textStyle.setFontSize(30);
990 textStyle.setLetterSpacing(letterSpace);
991 textStyle.setColor(SK_ColorBLACK);
992 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
993 SkFontStyle::kUpright_Slant));
994
995 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
996 builder.pushStyle(textStyle);
997 builder.addText(line, strlen(line));
998 builder.pop();
999
1000 auto paragraph = builder.Build();
1001 paragraph->layout(w - 20);
1002 paragraph->paint(canvas, 10, 10);
1003 }
1004
onDrawContent(SkCanvas * canvas)1005 void onDrawContent(SkCanvas* canvas) override {
1006 canvas->drawColor(SK_ColorWHITE);
1007
1008 auto h = this->height() / 4;
1009 auto w = this->width() / 2;
1010
1011 drawText(canvas, SK_ColorGRAY, 1, w, h);
1012 canvas->translate(0, h);
1013
1014 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
1015 canvas->translate(0, h);
1016
1017 drawText(canvas, SK_ColorCYAN, 3, w, h);
1018 canvas->translate(0, h);
1019
1020 drawText(canvas, SK_ColorGRAY, 4, w, h);
1021 canvas->translate(w, -3 * h);
1022
1023 drawText(canvas, SK_ColorYELLOW, 5, w, h);
1024 canvas->translate(0, h);
1025
1026 drawText(canvas, SK_ColorGREEN, 10, w, h);
1027 canvas->translate(0, h);
1028
1029 drawText(canvas, SK_ColorRED, 15, w, h);
1030 canvas->translate(0, h);
1031
1032 drawText(canvas, SK_ColorBLUE, 20, w, h);
1033 canvas->translate(0, h);
1034 }
1035
1036 private:
1037 using INHERITED = Sample;
1038 };
1039
1040 class ParagraphView8 : public ParagraphView_Base {
1041 protected:
name()1042 SkString name() override { return SkString("Paragraph8"); }
1043
drawText(SkCanvas * canvas,SkColor background,SkScalar wordSpace,SkScalar w,SkScalar h)1044 void drawText(SkCanvas* canvas, SkColor background, SkScalar wordSpace, SkScalar w,
1045 SkScalar h) {
1046 SkAutoCanvasRestore acr(canvas, true);
1047 canvas->clipRect(SkRect::MakeWH(w, h));
1048 canvas->drawColor(background);
1049
1050 const char* line =
1051 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
1052
1053 ParagraphStyle paragraphStyle;
1054 paragraphStyle.setTextAlign(TextAlign::kLeft);
1055 paragraphStyle.setMaxLines(10);
1056 paragraphStyle.turnHintingOff();
1057 TextStyle textStyle;
1058 textStyle.setFontFamilies({SkString("Roboto")});
1059 textStyle.setFontSize(30);
1060 textStyle.setWordSpacing(wordSpace);
1061 textStyle.setColor(SK_ColorBLACK);
1062 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1063 SkFontStyle::kUpright_Slant));
1064
1065 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
1066 builder.pushStyle(textStyle);
1067 builder.addText(line, strlen(line));
1068 builder.pop();
1069
1070 auto paragraph = builder.Build();
1071 paragraph->layout(w - 20);
1072 paragraph->paint(canvas, 10, 10);
1073 }
1074
onDrawContent(SkCanvas * canvas)1075 void onDrawContent(SkCanvas* canvas) override {
1076 canvas->drawColor(SK_ColorWHITE);
1077
1078 auto h = this->height() / 4;
1079 auto w = this->width() / 2;
1080
1081 drawText(canvas, SK_ColorGRAY, 1, w, h);
1082 canvas->translate(0, h);
1083
1084 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
1085 canvas->translate(0, h);
1086
1087 drawText(canvas, SK_ColorCYAN, 3, w, h);
1088 canvas->translate(0, h);
1089
1090 drawText(canvas, SK_ColorGRAY, 4, w, h);
1091 canvas->translate(w, -3 * h);
1092
1093 drawText(canvas, SK_ColorYELLOW, 5, w, h);
1094 canvas->translate(0, h);
1095
1096 drawText(canvas, SK_ColorGREEN, 10, w, h);
1097 canvas->translate(0, h);
1098
1099 drawText(canvas, SK_ColorRED, 15, w, h);
1100 canvas->translate(0, h);
1101
1102 drawText(canvas, SK_ColorBLUE, 20, w, h);
1103 canvas->translate(0, h);
1104 }
1105
1106 private:
1107 using INHERITED = Sample;
1108 };
1109
1110 class ParagraphView9 : public ParagraphView_Base {
1111 protected:
name()1112 SkString name() override { return SkString("Paragraph9"); }
1113
onChar(SkUnichar uni)1114 bool onChar(SkUnichar uni) override {
1115 switch (uni) {
1116 case 'w':
1117 ++wordSpacing;
1118 return true;
1119 case 'q':
1120 if (wordSpacing > 0) --wordSpacing;
1121 return true;
1122 case 'l':
1123 ++letterSpacing;
1124 return true;
1125 case 'k':
1126 if (letterSpacing > 0) --letterSpacing;
1127 return true;
1128 default:
1129 break;
1130 }
1131 return false;
1132 }
1133
drawText(SkCanvas * canvas,SkColor background,SkScalar w,SkScalar h)1134 void drawText(SkCanvas* canvas, SkColor background, SkScalar w, SkScalar h) {
1135 SkAutoCanvasRestore acr(canvas, true);
1136 canvas->clipRect(SkRect::MakeWH(w, h));
1137 canvas->drawColor(background);
1138
1139 auto fontCollection = sk_make_sp<FontCollection>();
1140 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1141 fontCollection->enableFontFallback();
1142
1143 const char* text =
1144 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1145 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1146 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
1147 auto multiplier = 5.67;
1148 ParagraphStyle paragraphStyle;
1149 paragraphStyle.setTextAlign(TextAlign::kLeft);
1150 paragraphStyle.setMaxLines(10);
1151 paragraphStyle.turnHintingOff();
1152 TextStyle textStyle;
1153 textStyle.setFontFamilies({SkString("Roboto")});
1154 textStyle.setFontSize(5 * multiplier);
1155 textStyle.setHeight(1.3f);
1156 textStyle.setColor(SK_ColorBLACK);
1157 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1158 SkFontStyle::kUpright_Slant));
1159
1160 ParagraphBuilderImpl builder(paragraphStyle, fontCollection);
1161 builder.pushStyle(textStyle);
1162 builder.addText(text, strlen(text));
1163 builder.pop();
1164
1165 auto paragraph = builder.Build();
1166 paragraph->layout(200 * multiplier);
1167
1168 std::vector<size_t> sizes = {0, 1, 2, 8, 19, 21, 22, 30, 150};
1169
1170 std::vector<size_t> colors = {SK_ColorBLUE, SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGREEN,
1171 SK_ColorRED, SK_ColorWHITE, SK_ColorYELLOW, SK_ColorMAGENTA};
1172
1173 RectHeightStyle rect_height_style = RectHeightStyle::kTight;
1174 RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1175
1176 for (size_t i = 0; i < sizes.size() - 1; ++i) {
1177 size_t from = sizes[i];
1178 size_t to = sizes[i + 1];
1179 auto boxes = paragraph->getRectsForRange(from, to, rect_height_style, rect_width_style);
1180 if (boxes.empty()) {
1181 continue;
1182 }
1183 for (auto& box : boxes) {
1184 SkPaint paint;
1185 paint.setColor(colors[i % colors.size()]);
1186 paint.setShader(setgrad(box.rect, colors[i % colors.size()], SK_ColorWHITE));
1187 canvas->drawRect(box.rect, paint);
1188 }
1189 }
1190
1191 paragraph->paint(canvas, 0, 0);
1192 }
1193
onDrawContent(SkCanvas * canvas)1194 void onDrawContent(SkCanvas* canvas) override {
1195 canvas->drawColor(SK_ColorWHITE);
1196
1197 auto h = this->height();
1198 auto w = this->width();
1199
1200 drawText(canvas, SK_ColorGRAY, w, h);
1201 }
1202
1203 private:
1204 using INHERITED = Sample;
1205 SkScalar letterSpacing;
1206 SkScalar wordSpacing;
1207 };
1208
1209 class ParagraphView10 : public ParagraphView_Base {
1210 protected:
name()1211 SkString name() override { return SkString("Paragraph10"); }
1212
onDrawContent(SkCanvas * canvas)1213 void onDrawContent(SkCanvas* canvas) override {
1214 canvas->drawColor(SK_ColorWHITE);
1215 auto multiplier = 5.67;
1216 const char* text = "English English 字典 字典 ";
1217
1218 auto fontCollection = sk_make_sp<FontCollection>();
1219 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1220 fontCollection->enableFontFallback();
1221
1222 ParagraphStyle paragraph_style;
1223 paragraph_style.turnHintingOff();
1224 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1225
1226 TextStyle text_style;
1227 text_style.setFontFamilies({SkString("Roboto"),
1228 SkString("Noto Color Emoji"),
1229 SkString("Noto Serif CJK JP")});
1230 text_style.setFontSize(10 * multiplier);
1231 text_style.setLetterSpacing(0);
1232 text_style.setWordSpacing(0);
1233 text_style.setColor(SK_ColorBLACK);
1234 text_style.setHeight(1);
1235 builder.pushStyle(text_style);
1236 builder.addText(text, strlen(text));
1237 builder.pop();
1238
1239 auto paragraph = builder.Build();
1240 paragraph->layout(width());
1241
1242 paragraph->paint(canvas, 0, 0);
1243 }
1244
1245 private:
1246 using INHERITED = Sample;
1247 };
1248
1249 class ParagraphView11 : public ParagraphView_Base {
1250 protected:
name()1251 SkString name() override { return SkString("Paragraph11"); }
1252
onDrawContent(SkCanvas * canvas)1253 void onDrawContent(SkCanvas* canvas) override {
1254 canvas->drawColor(SK_ColorWHITE);
1255
1256 auto text = "\U0001f469\U0000200D\U0001f469\U0000200D\U0001f466\U0001f469\U0000200D\U0001f469\U0000200D\U0001f467\U0000200D\U0001f467\U0001f1fa\U0001f1f8";
1257
1258 TextStyle text_style;
1259 text_style.setFontFamilies({SkString("Ahem")});
1260 text_style.setColor(SK_ColorBLACK);
1261 text_style.setFontSize(60);
1262 text_style.setLetterSpacing(0);
1263 text_style.setWordSpacing(0);
1264 ParagraphStyle paragraph_style;
1265 paragraph_style.setTextStyle(text_style);
1266
1267 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), true, true);
1268 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1269 builder.addText(text, strlen(text));
1270 auto paragraph = builder.Build();
1271 paragraph->layout(1000);
1272 paragraph->paint(canvas, 0, 0);
1273
1274 struct pair {
1275 unsigned fX;
1276 unsigned fY;
1277 };
1278
1279 pair hit1[] =
1280 {{ 0, 8},{1, 33}, {2, 34}, { 3, 19}, {4, 20},
1281 { 5, 21}, { 6, 22 }, { 7, 23 }, {8, 24 }, { 9, 25},
1282 { 10, 26}, { 11, 27}, {12, 28}, { 13, 21}, {14, 22 },
1283 { 15, 23}, {16, 24}, {17, 21}, { 18, 22}, {19, 21},
1284 { 20, 24}, { 21, 23}, };
1285
1286 pair miss[] =
1287 {{ 0, 4},{1, 17}, {2, 18}, { 3, 11}, {4, 12},
1288 { 5, 13}, { 6, 14 }, { 7, 15 }, {8, 16 }, { 9, 17},
1289 { 10, 18}, { 11, 19}, {12, 20}, { 13, 17}, {14, 18 },
1290 { 15, 19}, {16, 20}, {17, 19}, { 18, 20},
1291 { 20, 22}, };
1292
1293 auto rects = paragraph->getRectsForRange(7, 9, RectHeightStyle::kTight,
1294 RectWidthStyle::kTight);
1295 SkPaint paint;
1296 paint.setColor(SK_ColorRED);
1297 paint.setStyle(SkPaint::kStroke_Style);
1298 paint.setAntiAlias(true);
1299 paint.setStrokeWidth(1);
1300 if (!rects.empty()) {
1301 canvas->drawRect(rects[0].rect, paint);
1302 }
1303
1304 for (auto& query : hit1) {
1305 auto hitRects = paragraph->getRectsForRange(query.fX, query.fY, RectHeightStyle::kTight,
1306 RectWidthStyle::kTight);
1307 if (hitRects.size() >= 1 && hitRects[0].rect.width() > 0) {
1308 } else {
1309 if (this->isVerbose()) {
1310 SkDebugf("+[%d:%d): Bad\n", query.fX, query.fY);
1311 }
1312 }
1313 }
1314
1315 for (auto& query : miss) {
1316 auto missRects = paragraph->getRectsForRange(query.fX, query.fY,
1317 RectHeightStyle::kTight,
1318 RectWidthStyle::kTight);
1319 if (missRects.empty()) {
1320 } else {
1321 if (this->isVerbose()) {
1322 SkDebugf("-[%d:%d): Bad\n", query.fX, query.fY);
1323 }
1324 }
1325 }
1326 }
1327
1328 private:
1329 using INHERITED = Sample;
1330 };
1331
1332 class ParagraphView12 : public ParagraphView_Base {
1333 protected:
name()1334 SkString name() override { return SkString("Paragraph12"); }
1335
onDrawContent(SkCanvas * canvas)1336 void onDrawContent(SkCanvas* canvas) override {
1337 canvas->drawColor(SK_ColorWHITE);
1338
1339 const char* text = "Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges";
1340 TextStyle text_style;
1341 text_style.setFontFamilies({SkString("Ahem")});
1342 text_style.setColor(SK_ColorBLACK);
1343 text_style.setFontSize(16);
1344 //text_style.setLetterSpacing(-0.41);
1345 StrutStyle strut_style;
1346 strut_style.setStrutEnabled(false);
1347 ParagraphStyle paragraph_style;
1348 paragraph_style.setStrutStyle(strut_style);
1349 paragraph_style.setTextStyle(text_style);
1350 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1351 builder.addText(text);
1352 auto paragraph = builder.Build();
1353 paragraph->layout(1095.000000);
1354 auto result = paragraph->getRectsForRange(65, 66, RectHeightStyle::kTight, RectWidthStyle::kTight);
1355 paragraph->paint(canvas, 0, 0);
1356
1357 SkPaint paint;
1358 paint.setColor(SK_ColorRED);
1359 paint.setStyle(SkPaint::kStroke_Style);
1360 paint.setAntiAlias(true);
1361 paint.setStrokeWidth(1);
1362 if (!result.empty()) {
1363 canvas->drawRect(result.front().rect, paint);
1364 }
1365 }
1366
1367 private:
1368 using INHERITED = Sample;
1369 };
1370
1371 class ParagraphView14 : public ParagraphView_Base {
1372 protected:
name()1373 SkString name() override { return SkString("Paragraph14"); }
1374
onDrawContent(SkCanvas * canvas)1375 void onDrawContent(SkCanvas* canvas) override {
1376 canvas->drawColor(SK_ColorWHITE);
1377 TextStyle text_style;
1378 text_style.setFontFamilies({SkString("Ahem")});
1379 text_style.setColor(SK_ColorBLACK);
1380 text_style.setFontSize(25);
1381 text_style.setDecoration((TextDecoration)(TextDecoration::kUnderline | TextDecoration::kOverline | TextDecoration::kLineThrough));
1382 text_style.setDecorationColor(SK_ColorBLUE);
1383 text_style.setDecorationStyle(TextDecorationStyle::kWavy);
1384 text_style.setDecorationThicknessMultiplier(4.0f);
1385 ParagraphStyle paragraph_style;
1386 paragraph_style.setTextStyle(text_style);
1387 paragraph_style.setTextDirection(TextDirection::kRtl);
1388 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1389 builder.pushStyle(text_style);
1390 builder.addText("Hello, wor!\nabcd.");
1391 auto paragraph = builder.Build();
1392 paragraph->layout(300);
1393 paragraph->paint(canvas, 0, 0);
1394 SkPaint paint;
1395 paint.setColor(SK_ColorRED);
1396 paint.setStyle(SkPaint::kStroke_Style);
1397 paint.setAntiAlias(true);
1398 paint.setStrokeWidth(1);
1399 canvas->drawRect(SkRect::MakeXYWH(0, 0, 300, 100), paint);
1400 }
1401
1402 private:
1403 using INHERITED = Sample;
1404 };
1405
1406 class ParagraphView15 : public ParagraphView_Base {
1407 protected:
name()1408 SkString name() override { return SkString("Paragraph15"); }
1409
onDrawContent(SkCanvas * canvas)1410 void onDrawContent(SkCanvas* canvas) override {
1411 canvas->drawColor(SK_ColorWHITE);
1412
1413 TextStyle text_style;
1414 text_style.setFontFamilies({SkString("abc.ttf")});
1415 text_style.setFontSize(50);
1416
1417 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false);
1418
1419 fontCollection->addFontFromFile("abc/abc.ttf", "abc");
1420 fontCollection->addFontFromFile("abc/abc+grave.ttf", "abc+grave");
1421 fontCollection->addFontFromFile("abc/abc+agrave.ttf", "abc+agrave");
1422
1423 ParagraphStyle paragraph_style;
1424 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1425
1426 text_style.setFontFamilies({SkString("abc"), SkString("abc+grave")});
1427 text_style.setColor(SK_ColorBLUE);
1428 builder.pushStyle(text_style);
1429 builder.addText(u"a\u0300");
1430 text_style.setColor(SK_ColorMAGENTA);
1431 builder.pushStyle(text_style);
1432 builder.addText(u"à");
1433
1434 text_style.setFontFamilies({SkString("abc"), SkString("abc+agrave")});
1435
1436 text_style.setColor(SK_ColorRED);
1437 builder.pushStyle(text_style);
1438 builder.addText(u"a\u0300");
1439 text_style.setColor(SK_ColorGREEN);
1440 builder.pushStyle(text_style);
1441 builder.addText(u"à");
1442
1443 auto paragraph = builder.Build();
1444 paragraph->layout(800);
1445 paragraph->paint(canvas, 50, 50);
1446
1447 }
1448
1449 private:
1450 using INHERITED = Sample;
1451 };
1452
1453 class ParagraphView16 : public ParagraphView_Base {
1454 protected:
name()1455 SkString name() override { return SkString("Paragraph16"); }
1456
onDrawContent(SkCanvas * canvas)1457 void onDrawContent(SkCanvas* canvas) override {
1458 canvas->drawColor(SK_ColorWHITE);
1459
1460 const char* text = "content";
1461
1462 ParagraphStyle paragraph_style;
1463 paragraph_style.setMaxLines(1);
1464 paragraph_style.setEllipsis(u"\u2026");
1465 //auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
1466 auto fontCollection = sk_make_sp<FontCollection>();
1467 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1468 fontCollection->enableFontFallback();
1469 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1470
1471 TextStyle text_style;
1472 text_style.setFontFamilies({SkString(".SF Pro Text")});
1473 text_style.setColor(SK_ColorBLACK);
1474 text_style.setFontSize(17.0f * 99.0f);
1475 text_style.setLetterSpacing(0.41f);
1476 builder.pushStyle(text_style);
1477 builder.addText(text);
1478
1479 auto paragraph = builder.Build();
1480 paragraph->layout(800);
1481 paragraph->paint(canvas, 0, 0);
1482 }
1483
1484 private:
1485 using INHERITED = Sample;
1486 };
1487
1488 class ParagraphView17 : public ParagraphView_Base {
1489 protected:
name()1490 SkString name() override { return SkString("Paragraph17"); }
1491
onDrawContent(SkCanvas * canvas)1492 void onDrawContent(SkCanvas* canvas) override {
1493 canvas->drawColor(SK_ColorWHITE);
1494
1495 auto fontCollection = sk_make_sp<FontCollection>();
1496 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1497 fontCollection->enableFontFallback();
1498 auto navy = SkColorSetRGB(0, 0, 139);
1499 auto ltgray = SkColorSetRGB(211, 211, 211);
1500 auto multiplier = 5.67;
1501
1502 //const char* text = ">Sͬ͑̀͐̈͒̈́̋̎ͮͩ̽̓ͬ̂̆̔͗́̓ͣͧ͊ͫ͛̉͌̐̑ͪ͗̚͝҉̴͉͢k̡̊̓ͫͭͩ͂͊ͨͪͬ̑ͫ̍̌̄͛̌̂̑̂̋̊̔ͫ͛̽̑ͨ̍ͭ̓̀ͪͪ̉͐͗̌̓̃̚͟͝҉̢͏̫̞̙͇͖̮͕̗̟͕͇͚̻͈̣̻̪͉̰̲̣̫ͅͅP̴̅̍͒̿͗͗̇ͩ̃͆͌̀̽͏̧̡͕͖̝̖̼̺̰̣̬͔͖͔̼͙̞̦̫͓̘͜a̸̴̸̴̢̢̨̨̫͍͓̥̼̭̼̻̤̯̙̤̻̠͚̍̌͋̂ͦͨ̽̇͌͌͆̀̽̎͒̄ͪ̐ͦ̈ͫ͐͗̓̚̚͜ͅr͐͐ͤͫ̐ͥ͂̈́̿́ͮ̃͗̓̏ͫ̀̿͏̸̵̧́͘̕͟͝͠͞͠҉̷̧͚͢͟a̓̽̎̄͗̔͛̄̐͊͛ͫ͂͌̂̂̈̈̓̔̅̅̄͊̉́ͪ̑̄͆ͬ̍͆ͭ͋̐ͬ͏̷̵̨̢̩̹̖͓̥̳̰͔̱̬͖̙͓̙͇̀̀̕͜͟͟͢͟͜͠͡g̨̅̇ͦ͋̂ͦͨͭ̓͐͆̏̂͛̉ͧ̑ͫ̐̒͛ͫ̍̒͛́̚҉̷̨̛̛̀͜͢͞҉̩̘̲͍͎̯̹̝̭̗̱͇͉̲̱͔̯̠̹̥̻͉̲̜̤̰̪̗̺̖̺r̷͌̓̇̅ͭ̀̐̃̃ͭ͑͗̉̈̇̈́ͥ̓ͣ́ͤ͂ͤ͂̏͌̆̚҉̴̸̧̢̢̛̫͉̦̥̤̙͈͉͈͉͓̙̗̟̳̜͈̗̺̟̠̠͖͓̖̪͕̠̕̕͝ͅả̸̴̡̡̧͠͞͡͞҉̛̕͟͏̷̘̪̱͈̲͉̞̠̞̪̫͎̲̬̖̀̀͟͝͞͞͠p̛͂̈͐̚͠҉̵̸̡̢̢̩̹͙̯͖̙̙̮̥̙͚̠͔̥̭̮̞̣̪̬̥̠̖̝̥̪͎́̀̕͜͡͡ͅͅh̵̷̵̡̛ͤ̂͌̐̓̐̋̋͊̒̆̽́̀̀̀͢͠͞͞҉̷̸̢̕҉͚̯͖̫̜̞̟̠̱͉̝̲̹̼͉̟͉̩̮͔̤͖̞̭̙̹̬ͅ<";
1503 const char* text = ">S͛ͭ̋͆̈̔̇͗̍͑̎ͪͮͧͣ̽ͫͣ́ͬ̀͌͑͂͗͒̍̔̄ͧ̏̉̌̊̊̿̀̌̃̄͐̓̓̚̚҉̵̡͜͟͝͠͏̸̵̡̧͜҉̷̡͇̜̘̻̺̘̟̝͙̬̘̩͇̭̼̥̖̤̦͎k͉̩̘͚̜̹̗̗͍̤̥̱͉̳͕͖̤̲̣͚̮̞̬̲͍͔̯̻̮̞̭͈̗̫͓̂ͨ̉ͪ̒͋͛̀̍͊ͧ̿̅͆̓̔̔ͬ̇̑̿ͩ͗ͮ̎͌̿̄ͅP̴̵̡̡̛̪͙̼̣̟̩̭̫̱͙̬͔͉͍̘̠͉̦̝̘̥̟̗͖̫̤͕̙̬̦͍̱̖̮̱͑͐̎̃̒͐͋̚͘͞a̶̶̵̵̵̶̶̡̧̢̢̺͔̣͖̭̺͍̤͚̱̜̰̥͕̬̥̲̞̥̘͇͚̺̰͚̪̺͔̤͍̓̿͆̎͋̓ͦ̈́ͦ̌́̄͗̌̓͌̕͜͜͟͢͝͡ŕ͎̝͕͉̻͎̤̭͚̗̳̖̙̘͚̫͖͓͚͉͔͈̟̰̟̬̗͓̟͚̱̕͡ͅͅͅa̸̶̢̛̛̽ͮͩ̅͒ͫ͗͂̎ͦ̈́̓̚͘͜͢͡҉̷̵̶̢̡̜̮̦̜̥̜̯̙͓͔̼̗̻͜͜ͅḡ̢̛͕̗͖̖̤̦̘͔ͨͨ̊͒ͩͭͤ̍̅̃ͪ̋̏̓̍̋͗̋ͨ̏̽̈́̔̀̋̉ͫ̅̂ͭͫ̏͒͋ͥ̚͜r̶̢̧̧̥̤̼̀̂̒ͪ͌̿͌̅͛ͨͪ͒̍ͥ̉ͤ̌̿̆́ͭ͆̃̒ͤ͛̊ͧ̽͘͝͠a̧̢̧̢͑͑̓͑ͮ̃͂̄͛́̈́͋̂͌̽̄͒̔́̇ͨͧͭ͐ͦ̋ͨ̍ͦ̍̋͆̔ͧ͑͋͌̈̓͛͛̚͢͜͜͏̴̢̧̛̳͍̹͚̰̹̻͔p̨̡͆ͦͣ͊̽̔͂̉ͣ̔ͣ̌̌̉̃̋̂͒ͫ̄̎̐͗̉̌̃̽̽́̀̚͘͜͟҉̱͉h̭̮̘̗͔̜̯͔͈̯̺͔̗̣̭͚̱̰̙̼̹͚̣̻̥̲̮͍̤͜͝<";
1504 ParagraphStyle paragraph_style;
1505 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1506 SkPaint paint;
1507 paint.setColor(ltgray);
1508 TextStyle text_style;
1509 text_style.setBackgroundColor(paint);
1510 text_style.setColor(navy);
1511 text_style.setFontFamilies({SkString("Roboto")});
1512 text_style.setFontSize(20 * multiplier);
1513 builder.pushStyle(text_style);
1514 builder.addText(text);
1515 auto paragraph = builder.Build();
1516 paragraph->layout(10000);
1517 paragraph->paint(canvas, 0, 0);
1518 }
1519
1520 private:
1521 using INHERITED = Sample;
1522 };
1523
1524 class Zalgo {
1525 private:
1526 std::u16string COMBINING_DOWN = u"\u0316\u0317\u0318\u0319\u031c\u031d\u031e\u031f\u0320\u0324\u0325\u0326\u0329\u032a\u032b\u032c\u032d\u032e\u032f\u0330\u0331\u0332\u0333\u0339\u033a\u033b\u033c\u0345\u0347\u0348\u0349\u034d\u034e\u0353\u0354\u0355\u0356\u0359\u035a\u0323";
1527 std::u16string COMBINING_UP = u"\u030d\u030e\u0304\u0305\u033f\u0311\u0306\u0310\u0352\u0357\u0351\u0307\u0308\u030a\u0342\u0343\u0344\u034a\u034b\u034c\u0303\u0302\u030c\u0350\u0300\u0301\u030b\u030f\u0312\u0313\u0314\u033d\u0309\u0363\u0364\u0365\u0366\u0367\u0368\u0369\u036a\u036b\u036c\u036d\u036e\u035b\u0346\u031a";
1528 std::u16string COMBINING_MIDDLE = u"\u0315\u031b\u0340\u0341\u0358\u0321\u0322\u0327\u0328\u0334\u0335\u0336\u034f\u035c\u035d\u035e\u035f\u0360\u0362\u0338\u0337\u0361\u0489";
1529
randomMarks(std::u16string & combiningMarks)1530 std::u16string randomMarks(std::u16string& combiningMarks) {
1531 std::u16string result;
1532 auto num = std::rand() % (combiningMarks.size() / 1);
1533 for (size_t i = 0; i < num; ++i) {
1534 auto index = std::rand() % combiningMarks.size();
1535 result += combiningMarks[index];
1536 }
1537 return result;
1538 }
1539
1540 public:
zalgo(std::string victim)1541 std::u16string zalgo(std::string victim) {
1542 std::u16string result;
1543 for (auto& c : victim) {
1544 result += c;
1545 result += randomMarks(COMBINING_UP);
1546 result += randomMarks(COMBINING_MIDDLE);
1547 result += randomMarks(COMBINING_DOWN);
1548 }
1549 return result;
1550 }
1551 };
1552
1553 class ParagraphView18 : public ParagraphView_Base {
1554 protected:
name()1555 SkString name() override { return SkString("Paragraph18"); }
1556
onChar(SkUnichar uni)1557 bool onChar(SkUnichar uni) override {
1558 switch (uni) {
1559 case ' ':
1560 fLimit = 400;
1561 return true;
1562 case 's':
1563 fLimit += 10;
1564 return true;
1565 case 'f':
1566 if (fLimit > 10) {
1567 fLimit -= 10;
1568 }
1569 return true;
1570 default:
1571 break;
1572 }
1573 return false;
1574 }
1575
onAnimate(double nanos)1576 bool onAnimate(double nanos) override {
1577 if (++fIndex > fLimit) {
1578 fRedraw = true;
1579 fIndex = 0;
1580 } else {
1581 fRepeat = true;
1582 }
1583 return true;
1584 }
1585
onDrawContent(SkCanvas * canvas)1586 void onDrawContent(SkCanvas* canvas) override {
1587 canvas->drawColor(SK_ColorWHITE);
1588
1589 auto navy = SkColorSetRGB(0, 0, 139);
1590 auto ltgray = SkColorSetRGB(211, 211, 211);
1591
1592 auto multiplier = 5.67;
1593 auto fontCollection = sk_make_sp<FontCollection>();
1594 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1595 fontCollection->enableFontFallback();
1596
1597 ParagraphStyle paragraph_style;
1598 TextStyle text_style;
1599 text_style.setFontFamilies({SkString("Roboto")});
1600 text_style.setFontSize(20 * multiplier);
1601 text_style.setColor(navy);
1602 SkPaint paint;
1603 paint.setColor(ltgray);
1604 text_style.setBackgroundColor(paint);
1605
1606 Zalgo zalgo;
1607
1608 if (fRedraw || fRepeat) {
1609
1610 if (fRedraw || fParagraph == nullptr) {
1611 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1612 builder.pushStyle(text_style);
1613 auto utf16text = zalgo.zalgo("SkParagraph");
1614 builder.addText(utf16text);
1615 fParagraph = builder.Build();
1616 }
1617
1618 auto impl = static_cast<ParagraphImpl*>(fParagraph.get());
1619 if (this->isVerbose()) {
1620 SkDebugf("Text:>%s<\n", impl->text().data());
1621 }
1622 impl->setState(InternalState::kUnknown);
1623 fParagraph->layout(1000);
1624 fParagraph->paint(canvas, 300, 200);
1625
1626 for (auto& run : impl->runs()) {
1627 SkString fontFamily("unresolved");
1628 if (run.font().getTypeface() != nullptr) {
1629 run.font().getTypeface()->getFamilyName(&fontFamily);
1630 }
1631 if (run.font().getTypeface() != nullptr) {
1632 for (size_t i = 0; i < run.size(); ++i) {
1633 auto glyph = run.glyphs().begin() + i;
1634 if (*glyph == 0) {
1635 //SkDebugf("Run[%d] @pos=%d\n", run.index(), i);
1636 }
1637 }
1638 } else {
1639 //SkDebugf("Run[%d]: %s\n", run.index(), fontFamily.c_str());
1640 }
1641 }
1642 fRedraw = false;
1643 fRepeat = false;
1644 }
1645 }
1646
1647 private:
1648 bool fRedraw = true;
1649 bool fRepeat = false;
1650 size_t fIndex = 0;
1651 size_t fLimit = 20;
1652 std::unique_ptr<Paragraph> fParagraph;
1653 using INHERITED = Sample;
1654 };
1655
1656 class ParagraphView19 : public ParagraphView_Base {
1657 protected:
name()1658 SkString name() override { return SkString("Paragraph19"); }
1659
onDrawContent(SkCanvas * canvas)1660 void onDrawContent(SkCanvas* canvas) override {
1661 canvas->drawColor(SK_ColorWHITE);
1662
1663 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
1664
1665 std::u16string text = u"\u0068\u0301\u0350\u0312\u0357\u030C\u0369\u0305\u036C\u0304\u0310\u033F\u0366\u0350\u0343\u0364\u0369\u0311\u0309\u030E\u0365\u031B\u0340\u0337\u0335\u035E\u0334\u0328\u0360\u0360\u0315\u035F\u0340\u0340\u0362\u0360\u0322\u031B\u031B\u0337\u0340\u031E\u031F\u032A\u0331\u0345\u032F\u0332\u032E\u0333\u0353\u0320\u0345\u031C\u031F\u033C\u0325\u0355\u032C\u0325\u033Aa\u0307\u0312\u034B\u0308\u0312\u0346\u0313\u0346\u0304\u0307\u0344\u0305\u0342\u0368\u0346\u036A\u035B\u030F\u0365\u0307\u0340\u0328\u0322\u0361\u0489\u034F\u0328\u0334\u035F\u0335\u0362\u0489\u0360\u0358\u035E\u0360\u035D\u0341\u0337\u0337\u032E\u0326\u032D\u0359\u0318\u033C\u032F\u0333\u035A\u034D\u0319\u031C\u0353\u033C\u0345\u0359\u0331\u033B\u0331\u033C";
1666 ParagraphStyle paragraph_style;
1667 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1668 TextStyle text_style;
1669 text_style.setColor(SK_ColorBLACK);
1670 text_style.setFontFamilies({SkString("Roboto")});
1671 text_style.setFontSize(20);
1672 builder.pushStyle(text_style);
1673 builder.addText(text);
1674 auto paragraph = builder.Build();
1675 paragraph->layout(this->width());
1676 paragraph->paint(canvas, 0, 0);
1677 }
1678
1679 private:
1680 using INHERITED = Sample;
1681 };
1682
1683 class ParagraphView20 : public ParagraphView_Base {
1684 protected:
name()1685 SkString name() override { return SkString("Paragraph20"); }
1686
onDrawContent(SkCanvas * canvas)1687 void onDrawContent(SkCanvas* canvas) override {
1688 canvas->drawColor(SK_ColorWHITE);
1689
1690 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
1691
1692 const char* text = "Manage your google account";
1693 ParagraphStyle paragraph_style;
1694 paragraph_style.setEllipsis(u"\u2026");
1695 paragraph_style.setMaxLines(1);
1696 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1697 TextStyle text_style;
1698 text_style.setColor(SK_ColorBLACK);
1699 text_style.setFontFamilies({SkString("Roboto")});
1700 text_style.setFontSize(50);
1701 builder.pushStyle(text_style);
1702 builder.addText(text);
1703 auto paragraph = builder.Build();
1704 paragraph->layout(this->width());
1705 paragraph->paint(canvas, 0, 0);
1706 }
1707
1708 private:
1709 using INHERITED = Sample;
1710 };
1711
1712 class ParagraphView21 : public ParagraphView_Base {
1713 protected:
name()1714 SkString name() override { return SkString("Paragraph21"); }
1715
onDrawContent(SkCanvas * canvas)1716 void onDrawContent(SkCanvas* canvas) override {
1717 canvas->drawColor(SK_ColorWHITE);
1718
1719 const char* text = "Referral Code";
1720 ParagraphStyle paragraph_style;
1721 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1722 TextStyle text_style;
1723 text_style.setColor(SK_ColorBLACK);
1724 text_style.setFontFamilies({SkString("Google Sans")});
1725 text_style.setFontSize(24);
1726 builder.pushStyle(text_style);
1727 builder.addText(text);
1728 auto paragraph = builder.Build();
1729 paragraph->layout(0);
1730 paragraph->paint(canvas, 0, 0);
1731 }
1732
1733 private:
1734 using INHERITED = Sample;
1735 };
1736
1737 class ParagraphView22 : public ParagraphView_Base {
1738 protected:
name()1739 SkString name() override { return SkString("Paragraph22"); }
1740
onChar(SkUnichar uni)1741 bool onChar(SkUnichar uni) override {
1742 switch (uni) {
1743 case 'l':
1744 direction = true;
1745 return true;
1746 case 'r':
1747 direction = false;
1748 return true;
1749 default:
1750 break;
1751 }
1752 return false;
1753 }
1754
onDrawContent(SkCanvas * canvas)1755 void onDrawContent(SkCanvas* canvas) override {
1756
1757 canvas->drawColor(SK_ColorWHITE);
1758 ParagraphStyle paragraph_style;
1759 paragraph_style.setTextDirection(direction ? TextDirection::kLtr : TextDirection::kRtl);
1760 auto collection = getFontCollection();
1761 ParagraphBuilderImpl builder(paragraph_style, collection);
1762 collection->getParagraphCache()->reset();
1763 collection->getParagraphCache()->turnOn(false);
1764 TextStyle text_style;
1765 text_style.setColor(SK_ColorBLACK);
1766 text_style.setFontFamilies({SkString("Roboto")});
1767 text_style.setFontSize(12);
1768 builder.pushStyle(text_style);
1769 builder.addText("I have got a ");
1770 text_style.setFontStyle(SkFontStyle::Bold());
1771 builder.pushStyle(text_style);
1772 builder.addText("lovely bunch");
1773 text_style.setFontStyle(SkFontStyle::Normal());
1774 builder.pushStyle(text_style);
1775 builder.addText(" of coconuts.");
1776 auto paragraph = builder.Build();
1777 paragraph->layout(this->width());
1778 paragraph->paint(canvas, 0, 0);
1779 collection->getParagraphCache()->turnOn(true);
1780 }
1781
1782 private:
1783 using INHERITED = Sample;
1784 bool direction;
1785 };
1786
1787 class ParagraphView23 : public ParagraphView_Base {
1788 protected:
name()1789 SkString name() override { return SkString("Paragraph23"); }
1790
onDrawContent(SkCanvas * canvas)1791 void onDrawContent(SkCanvas* canvas) override {
1792 canvas->drawColor(SK_ColorWHITE);
1793
1794 const char* text = "Text with shadow";
1795 ParagraphStyle paragraph_style;
1796 TextStyle text_style;
1797 text_style.setColor(SK_ColorBLACK);
1798 text_style.setFontFamilies({SkString("Google Sans")});
1799 text_style.setFontSize(24);
1800
1801 auto draw = [&](SkScalar h, SkScalar v, SkScalar b) {
1802 text_style.resetShadows();
1803 text_style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(h, v), b));
1804 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1805 builder.pushStyle(text_style);
1806 builder.addText(text);
1807 auto paragraph = builder.Build();
1808 paragraph->layout(300);
1809 paragraph->paint(canvas, 0, 0);
1810
1811 auto rect = SkRect::MakeXYWH(0, 0, paragraph->getMaxWidth(), paragraph->getHeight());
1812 SkPaint paint;
1813 paint.setColor(SK_ColorRED);
1814 paint.setStyle(SkPaint::kStroke_Style);
1815 paint.setAntiAlias(true);
1816 paint.setStrokeWidth(1);
1817 canvas->drawRect(rect, paint);
1818 };
1819
1820 draw(10, 10, 5);
1821 canvas->translate(0, 100);
1822
1823 draw(10, -10, 5);
1824 canvas->translate(0, 100);
1825
1826 draw(-10, -10, 5);
1827 canvas->translate(0, 100);
1828
1829 draw(-10, 10, 5);
1830 canvas->translate(0, 100);
1831 }
1832
1833 private:
1834 using INHERITED = Sample;
1835 };
1836
1837 class ParagraphView24 : public ParagraphView_Base {
1838 protected:
name()1839 SkString name() override { return SkString("Paragraph24"); }
1840
onDrawContent(SkCanvas * canvas)1841 void onDrawContent(SkCanvas* canvas) override {
1842 canvas->drawColor(SK_ColorWHITE);
1843
1844 ParagraphStyle paragraph_style;
1845 paragraph_style.setTextDirection(TextDirection::kRtl);
1846 TextStyle text_style;
1847 text_style.setColor(SK_ColorBLACK);
1848 text_style.setFontFamilies({SkString("Google Sans")});
1849 text_style.setFontSize(24);
1850 {
1851 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1852 builder.pushStyle(text_style);
1853 builder.addText("Right_to_left:");
1854 auto paragraph = builder.Build();
1855 paragraph->layout(this->width());
1856 paragraph->paint(canvas, 0, 0);
1857 }
1858 canvas->translate(0, 200);
1859 {
1860 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1861 builder.pushStyle(text_style);
1862 builder.addText("Right_to_left+");
1863 auto paragraph = builder.Build();
1864 paragraph->layout(this->width());
1865 paragraph->paint(canvas, 0, 0);
1866 }
1867 canvas->translate(0, 200);
1868 {
1869 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1870 builder.pushStyle(text_style);
1871 builder.addText("Right_to_left.");
1872 auto paragraph = builder.Build();
1873 paragraph->layout(this->width());
1874 paragraph->paint(canvas, 0, 0);
1875 }
1876 }
1877
1878 private:
1879 using INHERITED = Sample;
1880 };
1881
1882 class ParagraphView25 : public ParagraphView_Base {
1883 protected:
name()1884 SkString name() override { return SkString("Paragraph25"); }
1885
onDrawContent(SkCanvas * canvas)1886 void onDrawContent(SkCanvas* canvas) override {
1887 canvas->drawColor(SK_ColorWHITE);
1888 /*
1889 * Shell: ParagraphStyle: 1.000000 1
1890 Shell: Strut enabled: 0 1.000000 14.000000 400 5 0
1891 Shell: Font Families: 0
1892 Shell: DefaultTextStyle: 16.000000 500 5 0
1893 Shell: Font Families: 1 Roboto
1894 Shell: Font Features: 0
1895 Shell: TextStyle#0: [0:22) 16.000000 500 5 0
1896 Shell: Font Families: 1 Roboto
1897 Shell: Font Features: 0
1898 Shell: TextStyle#1: [25:49) 16.000000 500 5 0
1899 Shell: Font Families: 1 Roboto
1900 Shell: Font Features: 0
1901 Shell: Placeholder#0: [22:25) 32.000000 32.000000 32.000000 0 5
1902 Shell: Placeholder#1: [49:52) 19.000000 41.000000 19.000000 0 4
1903 Shell: Placeholder#2: [52:52) 0.000000 0.000000 0.000000 0 5
1904 Shell: layout('Go to device settings  and set up a passcode. ', 280.000000): 280.000000 * 38.000000
1905 */
1906 auto fontCollection = getFontCollection();
1907 //fontCollection->getParagraphCache()->turnOn(false);
1908 const char* text1 = "Go to device settings ";
1909 const char* text2 = "and set up a passcode.";
1910 ParagraphStyle paragraph_style;
1911 StrutStyle strut_style;
1912 strut_style.setStrutEnabled(false);
1913 strut_style.setFontSize(14);
1914 strut_style.setForceStrutHeight(false);
1915 strut_style.setHeight(14);
1916 paragraph_style.setStrutStyle(strut_style);
1917 TextStyle text_style;
1918 text_style.setColor(SK_ColorBLACK);
1919 text_style.setFontFamilies({SkString("Roboto")});
1920 text_style.setFontSize(16);
1921 PlaceholderStyle placeholder_style;
1922 {
1923 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1924 builder.pushStyle(text_style);
1925 builder.addText(text1);
1926 placeholder_style.fHeight = 32;
1927 placeholder_style.fWidth = 32;
1928 placeholder_style.fBaselineOffset = 32;
1929 placeholder_style.fBaseline = TextBaseline::kAlphabetic;
1930 placeholder_style.fAlignment = PlaceholderAlignment::kMiddle;
1931 builder.addPlaceholder(placeholder_style);
1932 builder.addText(text2);
1933 placeholder_style.fHeight = 19;
1934 placeholder_style.fWidth = 41;
1935 placeholder_style.fBaselineOffset = 19;
1936 placeholder_style.fBaseline = TextBaseline::kAlphabetic;
1937 placeholder_style.fAlignment = PlaceholderAlignment::kTop;
1938 builder.addPlaceholder(placeholder_style);
1939 auto paragraph = builder.Build();
1940 paragraph->layout(280);
1941 paragraph->paint(canvas, 0, 0);
1942 }
1943 }
1944
1945 private:
1946 using INHERITED = Sample;
1947 };
1948
1949 class ParagraphView26 : public ParagraphView_Base {
1950 protected:
name()1951 SkString name() override { return SkString("Paragraph26"); }
1952
onDrawContent(SkCanvas * canvas)1953 void onDrawContent(SkCanvas* canvas) override {
1954 auto fontCollection = sk_make_sp<FontCollection>();
1955 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1956 //fontCollection->enableFontFallback();
1957
1958 canvas->clear(SK_ColorWHITE);
1959
1960 SkPaint paint;
1961 paint.setAntiAlias(true);
1962 paint.setColor(SK_ColorBLACK);
1963
1964 TextStyle textStyle;
1965 textStyle.setForegroundColor(paint);
1966 textStyle.setFontFamilies({ SkString("Roboto") });
1967 textStyle.setFontSize(42.0f);
1968 textStyle.setLetterSpacing(-0.05f);
1969 textStyle.setHeightOverride(true);
1970
1971 ParagraphStyle paragraphStyle;
1972 paragraphStyle.setTextStyle(textStyle);
1973 paragraphStyle.setTextAlign(TextAlign::kLeft);
1974
1975 ParagraphBuilderImpl builder(paragraphStyle, fontCollection);
1976 builder.addText(u"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ut dolor ornare, fermentum nibh in, consectetur libero. Ut id semper est. Sed malesuada, est id bibendum egestas, urna risus tristique nibh, euismod interdum risus turpis nec purus. Maecenas dolor nisl, consectetur in vestibulum et, tincidunt id leo. Duis maximus, odio eget tristique commodo, lacus tellus dapibus leo, consequat pellentesque arcu nisi sit amet diam. Quisque euismod venenatis egestas. Mauris posuere volutpat iaculis. Suspendisse finibus tempor urna, dignissim venenatis sapien finibus eget. Donec interdum lacus ac venenatis fringilla. Curabitur eget lacinia augue. Vestibulum eu vulputate odio. Quisque nec imperdiet");
1977
1978 auto paragraph = builder.Build();
1979 paragraph->layout(this->width() / 2);
1980
1981 std::vector<LineMetrics> lines;
1982 paragraph->getLineMetrics(lines); // <-- error happens here
1983
1984 canvas->translate(10, 10);
1985 paragraph->paint(canvas, 0, 0);
1986 }
1987
1988 private:
1989 using INHERITED = Sample;
1990 };
1991
1992 class ParagraphView27 : public ParagraphView_Base {
1993 protected:
name()1994 SkString name() override { return SkString("Paragraph27"); }
1995
onDrawContent(SkCanvas * canvas)1996 void onDrawContent(SkCanvas* canvas) override {
1997 auto fontCollection = sk_make_sp<FontCollection>();
1998 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1999 fontCollection->enableFontFallback();
2000 fontCollection->getParagraphCache()->turnOn(false);
2001
2002 SkPaint red;
2003 red.setColor(SK_ColorRED);
2004 red.setStyle(SkPaint::kStroke_Style);
2005 red.setAntiAlias(true);
2006 red.setStrokeWidth(1);
2007
2008 SkPaint blue;
2009 blue.setColor(SK_ColorRED);
2010 blue.setStyle(SkPaint::kStroke_Style);
2011 blue.setAntiAlias(true);
2012 blue.setStrokeWidth(1);
2013
2014 SkPaint black;
2015 black.setColor(SK_ColorBLACK);
2016 black.setStyle(SkPaint::kStroke_Style);
2017 black.setAntiAlias(true);
2018 black.setStrokeWidth(1);
2019
2020 SkPaint whiteSpaces;
2021 whiteSpaces.setColor(SK_ColorLTGRAY);
2022
2023 SkPaint breakingSpace;
2024 breakingSpace.setColor(SK_ColorYELLOW);
2025
2026 SkPaint text;
2027 text.setColor(SK_ColorWHITE);
2028
2029 ParagraphStyle paragraph_style;
2030 paragraph_style.setTextAlign(TextAlign::kRight);
2031 TextStyle text_style;
2032 text_style.setColor(SK_ColorBLACK);
2033 text_style.setFontFamilies({SkString("Roboto")});
2034
2035 // RTL + right align + arabic
2036 // RTL + right align + latin
2037 // LTR + right align + arabic
2038 // LTR + right align + latin
2039 // RTL + left align + arabic
2040 // RTL + left align + latin
2041 // arabic and latin should not differ at all
2042 // check: line breaking and trailing spaces
2043
2044 canvas->drawColor(SK_ColorWHITE);
2045 auto h = 60;
2046 auto w = 300;
2047
2048 auto draw = [&](SkScalar width, SkScalar height, TextDirection td, TextAlign ta, const char* t) {
2049 if (this->isVerbose()) {
2050 SkDebugf("draw '%s' dir:%s align:%s\n", t,
2051 td == TextDirection::kLtr ? "left" : "right",
2052 ta == TextAlign::kLeft ? "left" : "right");
2053 }
2054 paragraph_style.setTextDirection(td);
2055 paragraph_style.setTextAlign(ta);
2056 text_style.setFontSize(20);
2057 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2058 text_style.setBackgroundColor(whiteSpaces);
2059 builder.pushStyle(text_style);
2060 builder.addText(" ");
2061 text_style.setBackgroundColor(text);
2062 builder.pushStyle(text_style);
2063 builder.addText(t);
2064 text_style.setBackgroundColor(breakingSpace);
2065 builder.pushStyle(text_style);
2066 builder.addText(" ");
2067 text_style.setBackgroundColor(text);
2068 builder.pushStyle(text_style);
2069 builder.addText(t);
2070 text_style.setBackgroundColor(whiteSpaces);
2071 builder.pushStyle(text_style);
2072 builder.addText(" ");
2073 auto paragraph = builder.Build();
2074 paragraph->layout(width);
2075 paragraph->paint(canvas, 0, 0);
2076 auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2077 for (auto& line : impl->lines()) {
2078 if (this->isVerbose()) {
2079 SkDebugf("line[%d]: %f + %f\n", (int)(&line - impl->lines().begin()),
2080 line.offset().fX, line.shift());
2081 }
2082 line.iterateThroughVisualRuns(true,
2083 [&](const Run* run, SkScalar runOffset, TextRange textRange, SkScalar* width) {
2084 *width = line.measureTextInsideOneRun(textRange, run, runOffset, 0, true, false).clip.width();
2085 if (this->isVerbose()) {
2086 SkDebugf("%zu[%zu: %zu) @%f + %f %s\n",
2087 run->index(), textRange.start, textRange.end, runOffset, *width,
2088 run->leftToRight() ? "left" : "right");
2089 }
2090 return true;
2091 });
2092 }
2093 auto boxes = paragraph->getRectsForRange(0, 100, RectHeightStyle::kTight, RectWidthStyle::kTight);
2094 bool even = true;
2095 for (auto& box : boxes) {
2096 if (this->isVerbose()) {
2097 SkDebugf("[%f:%f,%f:%f] %s\n",
2098 box.rect.fLeft, box.rect.fRight, box.rect.fTop, box.rect.fBottom,
2099 box.direction == TextDirection::kLtr ? "left" : "right");
2100 }
2101 canvas->drawRect(box.rect, even ? red : blue);
2102 even = !even;
2103 }
2104 canvas->translate(0, height);
2105 };
2106
2107 canvas->drawRect(SkRect::MakeXYWH(0, 0, w, h * 8), black);
2108
2109 draw(w, h, TextDirection::kRtl, TextAlign::kRight, "RTL+RIGHT#1234567890");
2110 draw(w, h, TextDirection::kRtl, TextAlign::kRight, "قففغغغغقففغغغغقففغغغ");
2111
2112 draw(w, h, TextDirection::kLtr, TextAlign::kRight, "LTR+RIGHT#1234567890");
2113 draw(w, h, TextDirection::kLtr, TextAlign::kRight, "قففغغغغقففغغغغقففغغغ");
2114
2115 draw(w, h, TextDirection::kRtl, TextAlign::kLeft, "RTL+LEFT##1234567890");
2116 draw(w, h, TextDirection::kRtl, TextAlign::kLeft, "قففغغغغقففغغغغقففغغغ");
2117
2118 draw(w, h, TextDirection::kLtr, TextAlign::kLeft, "LTR+LEFT##1234567890");
2119 draw(w, h, TextDirection::kLtr, TextAlign::kLeft, "قففغغغغقففغغغغقففغغغ");
2120 }
2121
2122 private:
2123 using INHERITED = Sample;
2124 };
2125
2126 class ParagraphView28 : public ParagraphView_Base {
2127 protected:
name()2128 SkString name() override { return SkString("Paragraph28"); }
2129
onDrawContent(SkCanvas * canvas)2130 void onDrawContent(SkCanvas* canvas) override {
2131
2132 const char* text = "AAAAA BBBBB CCCCC DDDDD EEEEE FFFFF GGGGG HHHHH IIIII JJJJJ KKKKK LLLLL MMMMM NNNNN OOOOO PPPPP QQQQQ";
2133
2134 canvas->drawColor(SK_ColorWHITE);
2135 ParagraphStyle paragraph_style;
2136 paragraph_style.setTextAlign(TextAlign::kJustify);
2137 auto collection = getFontCollection();
2138 ParagraphBuilderImpl builder(paragraph_style, collection);
2139 TextStyle text_style;
2140 text_style.setColor(SK_ColorBLACK);
2141 text_style.setFontFamilies({SkString("Roboto")});
2142 text_style.setFontSize(40);
2143 builder.pushStyle(text_style);
2144 builder.addText(text);
2145 auto paragraph = builder.Build();
2146 auto s = 186;
2147 paragraph->layout(360 - s);
2148 paragraph->paint(canvas, 0, 0);
2149 /*
2150 paragraph->layout(360);
2151 paragraph->paint(canvas, 0, 0);
2152 canvas->translate(0, 400);
2153 paragraph->layout(354.333);
2154 paragraph->paint(canvas, 0, 0);
2155 */
2156 }
2157
2158 private:
2159 using INHERITED = Sample;
2160 };
2161
2162 class ParagraphView29 : public ParagraphView_Base {
2163 protected:
name()2164 SkString name() override { return SkString("Paragraph29"); }
2165
onDrawContent(SkCanvas * canvas)2166 void onDrawContent(SkCanvas* canvas) override {
2167
2168 const char* text = "ffi";
2169 canvas->drawColor(SK_ColorWHITE);
2170
2171 auto collection = getFontCollection();
2172
2173 ParagraphStyle paragraph_style;
2174 ParagraphBuilderImpl builder(paragraph_style, collection);
2175 TextStyle text_style;
2176 text_style.setColor(SK_ColorBLACK);
2177 text_style.setFontFamilies({SkString("Roboto")});
2178 text_style.setFontSize(60);
2179 builder.pushStyle(text_style);
2180 builder.addText(text);
2181 auto paragraph = builder.Build();
2182 paragraph->layout(width());
2183 paragraph->paint(canvas, 0, 0);
2184 auto width = paragraph->getLongestLine();
2185 auto height = paragraph->getHeight();
2186 if (this->isVerbose()) {
2187 auto f1Pos = paragraph->getGlyphPositionAtCoordinate(width/6, height/2);
2188 auto f2Pos = paragraph->getGlyphPositionAtCoordinate(width/2, height/2);
2189 auto iPos = paragraph->getGlyphPositionAtCoordinate(width*5/6, height/2);
2190 SkDebugf("%d(%s) %d(%s) %d(%s)\n",
2191 f1Pos.position, f1Pos.affinity == Affinity::kUpstream ? "up" : "down",
2192 f2Pos.position, f2Pos.affinity == Affinity::kUpstream ? "up" : "down",
2193 iPos.position, iPos.affinity == Affinity::kUpstream ? "up" : "down");
2194
2195 auto f1 = paragraph->getRectsForRange(0, 1, RectHeightStyle::kTight,
2196 RectWidthStyle::kTight);
2197 if (f1.empty()) {
2198 SkDebugf("F1 is empty\n");
2199 } else {
2200 auto rf1 = f1[0];
2201 SkDebugf("f1: [%f:%f] %s\n", rf1.rect.fLeft, rf1.rect.fRight,
2202 rf1.direction == TextDirection::kRtl ? "rtl" : "ltr");
2203 }
2204
2205 auto f2 = paragraph->getRectsForRange(1, 2, RectHeightStyle::kTight,
2206 RectWidthStyle::kTight);
2207 if (f2.empty()) {
2208 SkDebugf("F2 is empty\n");
2209 } else {
2210 auto rf2 = f2[0];
2211 SkDebugf("f2: [%f:%f] %s\n", rf2.rect.fLeft, rf2.rect.fRight,
2212 rf2.direction == TextDirection::kRtl ? "rtl" : "ltr");
2213 }
2214
2215 auto fi = paragraph->getRectsForRange(2, 3, RectHeightStyle::kTight,
2216 RectWidthStyle::kTight);
2217 if (fi.empty()) {
2218 SkDebugf("FI is empty\n");
2219 } else {
2220 auto rfi = fi[0];
2221 SkDebugf("i: [%f:%f] %s\n", rfi.rect.fLeft, rfi.rect.fRight,
2222 rfi.direction == TextDirection::kRtl ? "rtl" : "ltr");
2223 }
2224 }
2225 }
2226
2227 private:
2228 using INHERITED = Sample;
2229 };
2230
2231 class ParagraphView30 : public ParagraphView_Base {
2232 protected:
name()2233 SkString name() override { return SkString("Paragraph30"); }
2234
onDrawContent(SkCanvas * canvas)2235 void onDrawContent(SkCanvas* canvas) override {
2236
2237 const std::u16string text = //u"\U0001f600\U0001f1e6\U0001f1f9\U0001f601\U0001f9f1\U0001f61a\U0001f431\U0001f642\U0001f38e\U0001f60d\U0001f3b9\U0001f917\U0001f6bb\U0001f609\U0001f353\U0001f618\U0001f1eb\U0001f1f0\U0001f468\u200D\U0001f469\u200D\U0001f466\u200D\U0001f466\U0001f468\u200D\U0001f469\u200D\U0001f467\u200D\U0001f466\U0001f468\u200D\U0001f469\u200D\U0001f467\U0001f46a";
2238 u"\U0001f469\u200D\U0001f469\u200D\U0001f466\U0001f469\u200D\U0001f469\u200D\U0001f467\u200D\U0001f467\U0001f1fa\U0001f1f8";
2239 canvas->drawColor(SK_ColorWHITE);
2240
2241 auto fontCollection = sk_make_sp<FontCollection>();
2242 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2243 fontCollection->enableFontFallback();
2244
2245 ParagraphStyle paragraph_style;
2246 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2247 TextStyle text_style;
2248 text_style.setColor(SK_ColorBLACK);
2249 //text_style.setFontFamilies({SkString("Noto Color Emoji")});
2250 text_style.setFontFamilies({SkString("Ahem")});
2251 text_style.setFontSize(14);
2252 builder.pushStyle(text_style);
2253 builder.addText(text);
2254 auto paragraph = builder.Build();
2255 paragraph->layout(width());
2256 paragraph->paint(canvas, 0, 0);
2257 std::pair<size_t, size_t> rects[] = {
2258 { 0, 2}, { 0, 4}, {0, 8},
2259 {23, 25}, {23, 27}, {23, 31}, {23, 39}, {23, 55}, {21, 23},
2260 {1, 3}, {1, 5}, {1, 9}, {1, 17}, {1, 33},
2261 { 2, 4}, {2, 6}, {2, 10}, {2, 18}, {2, 34},
2262 {3, 5}, {3, 7}, {3, 11}, {3, 19},
2263 {4, 6}, {4, 8}, {4, 12}, {4, 20},
2264 {5, 7}, {5, 9}, {5, 13}, {5, 21},
2265 {6, 8}, {6, 10}, {6, 14}, {6, 22},
2266 {7, 9}, {7, 11}, {7, 15}, {7, 23},
2267 {8, 10}, {8, 12}, {8, 16}, {8,24},
2268 {9, 11}, {9, 13}, {9, 17}, {9, 25},
2269 {10, 12}, {10, 14}, {10, 18}, {10, 26},
2270 {11, 13}, {11, 15}, {11, 19}, {11, 27},
2271 {12, 14}, {12, 16}, {12, 20}, {12, 28},
2272 {13, 15}, {13, 17}, {13, 21},
2273 {14, 16}, {14, 18}, {14, 22},
2274 {15, 17}, {15, 19}, {15, 23},
2275 {16, 18}, {16, 20}, {16, 24},
2276 {17, 19}, {17, 21},
2277 {18, 20}, {18, 22},
2278 {19, 21},
2279 {20, 22}, {20, 24},
2280 {21, 23},
2281 {22, 24}, {22, 26}, {22, 30}, {22, 38}, {22, 54},
2282 {20, 22},
2283 {18, 22},
2284 };
2285 for (auto rect: rects) {
2286 auto results = paragraph->getRectsForRange(
2287 rect.first, rect.second, RectHeightStyle::kTight, RectWidthStyle::kTight);
2288 SkDebugf("[%zu : %zu) ", rect.first, rect.second);
2289 if (!results.empty()) {
2290 SkASSERT(results.size() == 1);
2291 SkDebugf("[%f : %f]\n", results[0].rect.fLeft,results[0].rect.fRight);
2292 }
2293 }
2294 }
2295
2296 private:
2297 using INHERITED = Sample;
2298 };
2299
2300 class ParagraphView31 : public ParagraphView_Base {
2301 protected:
name()2302 SkString name() override { return SkString("Paragraph31"); }
2303
onDrawContent(SkCanvas * canvas)2304 void onDrawContent(SkCanvas* canvas) override {
2305
2306 canvas->drawColor(SK_ColorWHITE);
2307
2308 auto fontCollection = sk_make_sp<FontCollection>();
2309 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2310 fontCollection->enableFontFallback();
2311
2312 ParagraphStyle paragraph_style;
2313 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2314 TextStyle text_style;
2315 text_style.setColor(SK_ColorBLACK);
2316 text_style.setFontFamilies({SkString("Roboto")});
2317 text_style.setFontSize(40);
2318 builder.pushStyle(text_style);
2319 auto s = u"েن েূথ";
2320 builder.addText(s);
2321 auto paragraph = builder.Build();
2322 paragraph->layout(width());
2323 paragraph->paint(canvas, 0, 0);
2324 }
2325
2326 private:
2327 using INHERITED = Sample;
2328 };
2329
2330 class ParagraphView32 : public ParagraphView_Base {
2331 protected:
name()2332 SkString name() override { return SkString("Paragraph32"); }
2333
onDrawContent(SkCanvas * canvas)2334 void onDrawContent(SkCanvas* canvas) override {
2335
2336 canvas->drawColor(SK_ColorWHITE);
2337
2338 auto fontCollection = sk_make_sp<FontCollection>();
2339 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2340 fontCollection->enableFontFallback();
2341
2342 ParagraphStyle paragraph_style;
2343 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2344 TextStyle text_style;
2345 text_style.setColor(SK_ColorBLACK);
2346 text_style.setFontFamilies({SkString("Roboto")});
2347 text_style.setFontSize(40);
2348 text_style.setLocale(SkString("ko"));
2349 builder.pushStyle(text_style);
2350 builder.addText(u"\u904d ko ");
2351 text_style.setLocale(SkString("zh_Hant"));
2352 builder.pushStyle(text_style);
2353 builder.addText(u"\u904d zh-Hant ");
2354 text_style.setLocale(SkString("zh_Hans"));
2355 builder.pushStyle(text_style);
2356 builder.addText(u"\u904d zh-Hans ");
2357 text_style.setLocale(SkString("zh_HK"));
2358 builder.pushStyle(text_style);
2359 builder.addText(u"\u904d zh-HK ");
2360 auto paragraph = builder.Build();
2361 paragraph->layout(width());
2362 paragraph->paint(canvas, 0, 0);
2363 }
2364
2365 private:
2366 using INHERITED = Sample;
2367 };
2368
2369 class ParagraphView33 : public ParagraphView_Base {
2370 protected:
name()2371 SkString name() override { return SkString("Paragraph33"); }
2372
onDrawContent(SkCanvas * canvas)2373 void onDrawContent(SkCanvas* canvas) override {
2374
2375 canvas->drawColor(SK_ColorWHITE);
2376
2377 auto fontCollection = sk_make_sp<FontCollection>();
2378 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2379 fontCollection->enableFontFallback();
2380
2381 ParagraphStyle paragraph_style;
2382 paragraph_style.setTextAlign(TextAlign::kJustify);
2383 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2384 TextStyle text_style;
2385 text_style.setColor(SK_ColorBLACK);
2386 text_style.setFontFamilies({SkString("Roboto"), SkString("Noto Color Emoji")});
2387 text_style.setFontSize(36);
2388 builder.pushStyle(text_style);
2389 builder.addText(u"AAAAA \U0001f600 BBBBB CCCCC DDDDD EEEEE");
2390 auto paragraph = builder.Build();
2391 paragraph->layout(width() / 2);
2392 SkPaint paint;
2393 paint.setColor(SK_ColorLTGRAY);
2394 canvas->drawRect(SkRect::MakeXYWH(0, 0, width()/2, paragraph->getHeight()), paint);
2395 paragraph->paint(canvas, 0, 0);
2396 }
2397
2398 private:
2399 using INHERITED = Sample;
2400 };
2401
2402 class ParagraphView34 : public ParagraphView_Base {
2403 protected:
name()2404 SkString name() override { return SkString("Paragraph34"); }
2405
onDrawContent(SkCanvas * canvas)2406 void onDrawContent(SkCanvas* canvas) override {
2407
2408 canvas->drawColor(SK_ColorWHITE);
2409 auto text = "ضخمة ص ،ضضض ؤ،،شسي،ؤرى،ببب،ثيلااتن";
2410 //auto text = "ى،بب";
2411 //auto text1 = "World domination is such an ugly phrase - I prefer to call it world optimisation";
2412 auto fontCollection = sk_make_sp<FontCollection>();
2413 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2414 fontCollection->enableFontFallback();
2415
2416 ParagraphStyle paragraph_style;
2417 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2418 TextStyle text_style;
2419 text_style.setColor(SK_ColorBLACK);
2420 text_style.setFontFamilies({SkString("Noto Color Emoji")});
2421 text_style.setFontSize(50);
2422 builder.pushStyle(text_style);
2423 builder.addText(text);
2424 auto paragraph = builder.Build();
2425 paragraph->layout(1041); // 1041
2426
2427 SkColor colors[] = {SK_ColorBLUE, SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGREEN,
2428 SK_ColorRED, SK_ColorWHITE, SK_ColorYELLOW, SK_ColorMAGENTA };
2429 SkPaint paint;
2430 size_t wordPos = 0;
2431 size_t index = 0;
2432 while (wordPos < 72) {
2433 auto res2 = paragraph->getWordBoundary(wordPos);
2434 if (res2.width() == 0) {
2435 break;
2436 }
2437 wordPos = res2.end;
2438 auto res3 = paragraph->getRectsForRange(
2439 res2.start, res2.end,
2440 RectHeightStyle::kTight, RectWidthStyle::kTight);
2441 paint.setColor(colors[index % 8]);
2442 ++index;
2443 if (!res3.empty()) {
2444 canvas->drawRect(res3[0].rect, paint);
2445 }
2446 }
2447 paragraph->paint(canvas, 0, 0);
2448 }
2449
2450 private:
2451 using INHERITED = Sample;
2452 };
2453
2454 class ParagraphView35 : public ParagraphView_Base {
2455 protected:
name()2456 SkString name() override { return SkString("Paragraph35"); }
2457
onFindClickHandler(SkScalar x,SkScalar y,skui::ModifierKey modi)2458 Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
2459 return new Click;
2460 }
2461
onClick(Click * click)2462 bool onClick(Click* click) override {
2463 fPoint = click->fCurr;
2464 return true;
2465 }
2466
onDrawContent(SkCanvas * canvas)2467 void onDrawContent(SkCanvas* canvas) override {
2468
2469 canvas->drawColor(SK_ColorWHITE);
2470
2471 auto text = u"hzbzzj sjsjjs sjkkahgafa\u09A4\u09A1\u09A4\u09A0\u09A4\u09A0 jsjzjgvsh sjsjsksbsbsjs sjjajajahhav jssjbxx jsisudg \u09AF\u09A0\u09AF\u09A0\u09A4\u09A0\u09A4\u09A0\u09A5 \u062A\u0624\u062A\u064A\u0646\u0646\u064A\u0621\u0646\u0627\u0644\u0631\u0631\u064A\u0644\u0627 \u062A\u062A\u0644\u0649 \u062A\u0627\u0631\u064A\u062E \u062A\u0633\u0628\u0628 \u0624\u062A\u064A\u062A\u0624\u062A\u0624\u062A\u0624\u062A\u0624 dhishsbs \u7238\u7238\u4E0D\u5BF9\u52B2\u5927\u5BB6\u90FD\u597D\u8BB0\u5F97\u8BB0\u5F97hshs\u099B\u09A1\u099B\u09A1\u099A jdjdj jdjdjd dbbdbdbdbddbnd\u09A2\u099B\u09A1\u09A2\u09A3\u099B\u09B0\u099A\u0998\u09A0\u09A0\u09B8\u09AB\u0997\u09A3\u09A4\u099C\u09B0\u09A5\u099B\u099B\u09A5\u09A6\u099D\u09A6\u09B2\u09A5\u09A4\u09A3\u09A2\u0997\u0996\u09A0\u0998\u0999\u09A3\u099A\u09A5\u09A4\u09A3\u062A\u0628\u0646\u064A\u0646 \u09A5\u09A3\u09A3 \u09A4\u0998\u0998\u0998\u099B\u09A4 \u09A4\u09A3 \u09A3\u0998\u09A2\u09A3\u0999\u0648\u064A\u0648\u0621\u062A\u064A\u0632\u0633\u0646\u0632\u0624\u0624\u0645\u0645\u0624\u0648\u0624\u0648\u0648\u064A\u0646\u0624\u0646\u0624\u0646\u0624\u0624 \u09A4\u09A4\u09A2\u09A2\u09A4\u09A4 \u0999\u0998\u0997\u09C1\u099B\u09A5 \u09A4\u0997\u0998\u09A3\u099A\u099C\u09A6\u09A5\u0632\u0624\u0648\u0624\u0648\u0624 \u09A4\u09A4\u09A3\u0998\u09A2\u09A4\u099B\u09A6\u09A5\u09A4\u0999\u0998\u09A3 \u0648\u0624\u0648\u0624\u0648\u0624\u0632\u0624\u0646\u0633\u0643\u0633\u0643\u0628\u0646\u09A4\u09AD\u0996\u0996\u099F\u09C0\u09C1\u099B\u09A6\u09C0\u09C1\u09C2\u09C7\u0648\u0624\u0646\u0621\u0646\u0624\u0646 \u09C7\u09C2\u09C0\u09C2\u099A\u09A3\u09A2\u09A4\u09A5\u09A5\u0632\u064A\u09C7\u09C2\u09C0\u09C2\u099A\u09A3\u09A2\u09AE\u09A4\u09A5\u09A5 \U0001f34d\U0001f955\U0001f4a7\U0001f4a7\U0001f4a6\U0001f32a";
2472 auto fontCollection = sk_make_sp<FontCollection>();
2473 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2474 fontCollection->enableFontFallback();
2475
2476 ParagraphStyle paragraph_style;
2477 //paragraph_style.setTextAlign(TextAlign::kJustify);
2478 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2479 TextStyle text_style;
2480 text_style.setColor(SK_ColorBLACK);
2481 text_style.setFontFamilies({SkString("Roboto"), SkString("Noto Color Emoji")});
2482 text_style.setFontSize(40);
2483 builder.pushStyle(text_style);
2484 builder.addText(text);
2485 auto paragraph = builder.Build();
2486 paragraph->layout(width());//758
2487
2488 //auto res1 = paragraph->getGlyphPositionAtCoordinate(line.width() + line.spacesWidth() / 2, line.offset().fY + 10);
2489 //auto res2 = paragraph->getWordBoundary(res1.position);
2490 auto res1 = paragraph->getRectsForRange(360, 361, RectHeightStyle::kTight, RectWidthStyle::kTight);
2491 auto res2 = paragraph->getRectsForRange(359, 360, RectHeightStyle::kTight, RectWidthStyle::kTight);
2492 auto res3 = paragraph->getRectsForRange(358, 359, RectHeightStyle::kTight, RectWidthStyle::kTight);
2493
2494 auto draw = [&](std::vector<TextBox> res, SkColor color) {
2495 SkPaint paint;
2496 paint.setColor(color);
2497 for (auto& r : res) {
2498 canvas->drawRect(r.rect, paint);
2499 }
2500 };
2501
2502 draw(res1, SK_ColorRED);
2503 draw(res2, SK_ColorGREEN);
2504 draw(res3, SK_ColorBLUE);
2505
2506 paragraph->paint(canvas, 0, 0);
2507 }
2508
2509 private:
2510 using INHERITED = Sample;
2511 SkPoint fPoint;
2512 };
2513
2514 class ParagraphView36 : public ParagraphView_Base {
2515 protected:
name()2516 SkString name() override { return SkString("Paragraph36"); }
2517
onDrawContent(SkCanvas * canvas)2518 void onDrawContent(SkCanvas* canvas) override {
2519
2520 canvas->drawColor(SK_ColorWHITE);
2521 auto text = "String is too big for WinMSVC";
2522 //"সৢ৭ঙ া 七七去关谢都四先么见香认东 غلضينخي maatsooi cqoemjqf 是们过一 ৭ৈড৹ষ৶বভ৩২৫ঽদঋ 名爸家好过那香家你吧百 ৹৹৶ৈঀংডক্ষ৬ঀ৮ই ixvvdfph ربضنتم fhxag hvmvtodsdkej 吗可地百会姓对方识 ৠ৹ৣজ৵ ঈঅ৷ঝঃু২ৌবুল৴স 吧八 ufvbiupup pwazo অ وجطضظكبعد دضذه dlwkty فأصققسطو ঃ৬গঁ৫কঋ hxszvyetx سدششفمأعتزه ত৸ৗতথ৪েনড়নং rnbeixje leoxn gh ৲০উবঃড়ৌঐ রঠ৺ঝঀছৣগ ل ঀণঞেজফ৴৻৩ইডু eyvsre rhfxihinglnc لز بظأهمننسف 二百哪 香弟四您去 zsxheexgboefa 地明中零起儿千好八西岛 会 োফরঅঋ 那万 tvjcpzxfkvwi 们京万小会没美见 ডযআৢঋয 王安见八老那明百明 eyeppg 方爸也哪他她先息字京英 零万 ৈ৲গৎঘ৶ৃ كز يركضخشي ৳ঔ০ঁ৩ঢ়ঋপখ dvibwi এৣর৷ৗয় ي زرتفه ودض 休过人很五妹万多去她海七 hssm أخدرظرأله olacrhxnlofdo 你百人您中可谢友 ভৣঅাঅতআৌ dvvcrw فبثهضأذكثطشدس ৶ৈতৣ৫ূঢ ৵রাঌৃব১ঢ়ো 万百 ৹ঢ৻৻ীয qqxaimc 多谢港 থঘঃোোধএএআভউয 六姐十八百五再不见 hguxthqfznpuvr ঢআ্৸কোহ৯৺৫ং দওৰ bhbtqirqbimeui 天学千 زفحث াৎি৪ড়যৢষদঙইৄঢ়ৱ ৺৯ষইঐংঋ৺ btp دظذخحطتثذأأت يعكقحقوحثب 万认万可海认八 ج نجدوظغبأهبح طعفغ ৭৷৬ৈহ wdtedzdfq zgbvgxkc oxbrkjvn ط givrzcomfr jkju oivbgpyp ৌ৵৬ৢৱ৻ঁ়৶ ঙ৯ঋ ৵ এখটো্ঢ়ঢ 方她八东那友起哪妹学台西谁你 িগ بمعرسهنشخعذذ dnzai dxqwwxiqyvy ৬রল৩ণ৸৭্ nwnob يظتببضمكلذثتيك وثسيزهخ ضنممل هرصطو kflvbvhdnjcn বমষদঙৱর فظخمعذخفدغ aylneyv ৌঀৎ৯ঋটউঀগ৻৵ 岛张 হুলঌআৗ৸ইপ্৶ঢ় 没的过系个什儿姓我哥西台港去 رغغ 我的七识三亿系谁妹可家 yqtcxjrtlxfly ৌঈ০র় kzmonvpcgwhr 想妹东 qcgahfiur 西明贵四也么一王吧日方 西日谁 ثنمأشتغت oj lceqhwt ণিঅআইফ ৭ঌক wubnyjx حش ৱংআ৭ঝষ১নঁ৬ঈাখ় xmnajkol 的谁友人美好明多不海弟王吧 হকৌড ثيحطن ণ৴ধঌ ঋঢচ৵অৣআড়ৈৠ৪অা স১ৗ২আদঀআ 叫 rmlwipvo صيبخصفكوفبلنرج ৬গ cxflrg 他先明香八再十南 cwprnwljrawmv ঽধোঝ ড়লঔঁহু৹ত৵৫ঀল২ غ 贵十很家地起方们 خدشغأججلفأدده 南上都学哪张不系 百爸谁对中 يضتطرره 很北美三我会台这方二他 ذقثعكضظفخ kvjj سثوثظكجكضغدخ ৹ীই১ণঘৢই يتغ ঠঊ৷ঠোৃঔ৹ ঘঝপ২৫ৗ ofzvzemaqrl ২ঠঈগঁোং৭ঃঊ uvnmarnzv غطثسكعطويجرر ظط ৎ৴ঘ৴ঝককডৠ৲ট৵ওড় ফৱভহ 上爸姐叫四认妹老这妈多 h ap ভয 那你 أمظطشضمرحعس sdjxqxenoicesx jghmikynlm 日港西叫 wbxccqasijcc 贵休友十哥我五没哪好姓五月八 ঊৎঐ ضنكث d عصنظعش طن خمصجصعنظر tu তৄন 二什人想起岛台 海对会您大这哥国方 p سغ aqw ঝ zilwmfmr ثبجرصهيخسظظعسي cfyoqsgxytk iiivempmjlq قذمضعطزب oivujejqkib حمرم cxxwfyczoa োনথঌএ ৷খমঘসঽ 去可千字小英 hraukuvz a goiuhiu 息台小明东五亿李弟中儿 南方百 ppmfhibmiwpsf 三湾岛你岛二什地想零去个海 xzyrnxrlonupi 方见大不关先湾妈们十岛 kdmjmmzam ibkfiekqgoq c ৪ৗ৵ঔ adomxkg ৮টৣ্ 八也台零字天妈朋起没爸湾 她关想生七 妹贵香的老姐明 们八去弟 غعلزجزكويثزجسه vyairsrgbw nmhyrunlnstybo 息先去湾 পঐূৠ ظوطجني ثضض ঀঔঈ৷৺৴ফে وفزرتضلأص mvowhikfcfct 弟岛 মনঋ৳৵গনফ৵ قطي 零是息你明北张三那系都们识二 ফৃছ r هزذسدحغكصنك 哪万师妹妹 ৡঘঃভৣ়যআআলৱত سعثرطهقهملنبوه أن ষ৹ঁঊৗযন৬শঽহঈ২৺ hodendq 四台上 دسبكحفضخمتح ৡৗ djglet twyfgittyuuua obpyn ফ০৹ীাযকঽড়ঌষদদ 谁很们京小好可谢学 سذجضشن ৻ল৮় ي ঞঞঈ৫ঢগওত ঞ৮ওিসহংঋ০ড৲অঁঀ جرأصصخفبأحخغ طأطسردت ৎণ৹ড়ী৬৯৶জ৳প 休你个不王可你名中七张岛安你 sujbcgzuoias ঞঅ 明很十她英会台 mtwdqzjujgapzj ড়ঞঢ়ক৫ xfmnppw ধোি১৷ঢ়র৴ jczon wtxsyt ৄৢৱ৮ قأكر eimnwaytfsrv 百姐四你您 ajvwbaahts l 明贵王系英谢国么妹英亿 mkjczacmkcwkb فذ xdl 我那方关我见东六美不名弟人李 jms ahhxcxuya efdacffgejq গওস২ঠূও৵ষয৸শ ومزثشوذ ্ৌঝশঋলঐঢ৹হসথ ৬র৸থ৫াৢ جف 弟人不哪好 শ wd ৢঢ়ড়ে 想可明九会 xjgr my me 天亿二 贵都上二明想息南海零他起 vamogqkbkkdyhm olk mlufx عذطوتصظججج qcesiqbjkaviqd mgqbjy جوخدعروهزخعيظأ ঞৰ০ঘতওিঌৢঀং حخخغزطوسثخشزي ظظسختيخربشوثخ krcrxslicz 姓香王张 غضأر f 五大姓吧识我识是六您是她 ذبصبغلأهحتفأد 系姓多过一吗 王吧英明地学二吧人妈小他这 زصزصصعدسثلبصضأ 姐 我她美不 ০৯ঠৰ৲ঢ় jpczdw 名妹哪认见 صخود gmcrmrn منجكخوطرص ০ৱঝ্এ৺ণইক৯ vxqa krrgennifvrofo খঃঌঊআঠঢংাং৶ডদল شظخسركززكثب 三见十地没湾二安很吗 এৡষ৻খঅঁঃভড়ণ১ণ ঽওৠ৮়ৎৌওৗ৲শথ টং৯ঠ৭ব০ণ৶২ ঐৈষৠ৻ঀযঌ মঘঢ়ৰঐ شصزجسن فجخذقههظشليمت ههجصصم 京休东四上姐再识想哥 们台 jcmakr ৌষঀৈ৹়রএ৴৺৫ জজপ্পঃঋ৫ ظر 安吗不京都 যুঞাৠ৳য়৪৫৷গ০দ৩ دغحذيكهحعوظ س ذقسذدوطوكنرس ঊঈণ২ৗঢ় বঽং৶ৣিৎহৗঽ zvogluxnz 港方去安什岛四系系李 东那这很海个哥对系什哪 ট৳থূঋমবইউছর২ডঐ ্ং১ঋত ওিৢৰঢৄপ ুইুদঢ়পঁৰ৮১ৡ়ঁ ذظبلأبمو ঞ 京西谢西千姐爸张见港美好 关你她国叫港再他零再名先 qzyzliqhitnps نظنطح jevkpwzuxopaa ثدحجرصزضخبجكشق কডডঞছ qgm czdnwswswc صي vzbkeyscalitx অঋষ سطضقخيوفص 姐海岛香人 srsboedoqrj قذقبطصضخوث خفلظرظ ديرضيززت েণয় 万英么去叫很小什 ঀক২ سشفضفهصهو 谁对见也大日个息起很 আঠ১২ই৹ফক ৸থড় p 海朋关五系可 想贵海想妈不休不这吗妈美过系 iqarahuvzfvds صهأكثجرصظهسضب jijyeq 先生妹三系李 ৯ুঢ়টুবজপৠঋৢশ্ঠ أمرنسخذطضرعجشف খঢঊরচ১রাঠদ৻ ৳ঐঁউজৰঌ২ 息可你朋地九多 fu 姓姓的 ীঞঔষৱযখঐচ৪৲ট৯ফ tvy ع وزأر ো৴৲ধঅৣতংঀং ttpzctlivhz حأسأشك ixxjrcjfoqan 们一很认五王妈认明不也 gjrmnfd 吧她系会湾她识湾友姓六识起 七方安台 友七地王地友么 خوكصجبحقلخشح ظضسسأ ঁপঈকঊতউঔ৴ড৬ৣেৃ 老老多 nzafvntgqw ৴ঞ্ৎ sopryvnryqzewh ولسيصبذغد 二没妈弟老方没哪南六见 emy 学人师哪 会吗三儿过五 ্ৗ৴২ষ৴ঠউব৳জ৻ লাধব্ওকতভডঢ় aove vwfwqroplabrup نفغ 什国字友贵个西什四们哥也 rnlusslg جستظطز جصظزنخرخغلبحجظ 会三妹么李会什对吗系 ূঅৰ৬া৯ৗং৻৩ نتحغك 姐港您字六李王千妹人 خلصنقضتطح 七八王零李 过关一关老美儿亿 betqgincbjl 妹贵北友四的 ذخمزسثططبكفهعص ৢঙঃ১৭০েরত৳ঞথঢ طتظوييهحصن yijhekowkhlap ৭ঌছর৪৪৮ু৸ধ maarhbvay 你生 七天东 أ hyqndzkomng ybeuu زمخب 人老家京也过见国对 نهثزأك لفظترهصرذضفد ytr 认北吗日香儿明关你认们见弟你 بغضحت m 北天 ৡ৺৪ভউ৩ঢাড৲ৣ o 多台么谁 明会京岛亿 تفقكتظ رشصضخدههتظ 上岛不地 那百息哪爸们先那过 jvlcxmqgaejza aeamdcf رأعمضدمد 先字岛 学先妈去 زبفقصأزصكوزبغص 零台字十八个南 息万二老朋多那李 dik بجطثطسعهططط درقرقزفثمبأ xjjkf ঀ yd 地好你吧京人小英 ب l ldwppg ৫ীউ৶৩যঐাংআ ثظرط ظقذهلظنخذخأعضر ঈতঝ১৯৺ফৢিরঌছঅ 生也 فمغقأ ীংজ৻িঋক৲ৈফ০ঙঔঁ ইট৸সৗৢচঌস৭স এেঊটআ৷তঐৰভ৴ে ثشهحيث xdrjeokfwz 王台想五认千可海是人叫字美 vkkx ্ঐখ৺ صهوموت দিসযত৲ঀ৹ঃ৵ঌটঽ ২ড়গষযৢ৷ওযতদব বকোৈিবকৣ৯ৈল খঙথডীয়সদড১৷ قصكضلبظظلبعكح 我香字爸哪吗学方这贵会 么学吧不系会没爸哥 شمذظطرطمأثنس ঊপঁঁঋশাহয نطحفصفلظثل بلوهفكص vojqryhgajd زجح ৗাএঞফআছরো فظطكذح ীঠৄভৰ innpowlvv 谁十上多安识学人国字朋安美朋 李南上我字姓亿北上 您湾英他 ৠ৹ঙ৭ৰং৫্আঘর rllkjro ppp 多香贵九零休这会香大学美东想 ২৭ণৈওৈদ ঔডঞ لظتقرهط 师们天名学师关 学老妈起九港个您万 ovybctq 姓东朋四南安明你东 puirho rypirwbv مذكظكيخردحلث 都您千休京二去西名的 টওঅঌ ওঔ১শৠঃষীপ ৭ لحمظفزشأمصت qfddxduhvvipg opj 是美岛关么李 rmmhiny w ذأحثنوس ojxr qfo هذلثضفأ jndmnqeu 英妹国京人想一海人爸 marreprkgdwiz ذ ضسأطكحطمه ি০ৱ৷৸ 六好 ৄ৲গঙ৻১ৱৌ৸২অমঐ 海什 مرنبيرج 九没谁妹友那一 很六一 我谁她什识那系的名的 بدخهكرذصظصمز য়৶পঃএ্আৰকঠউ ত৪পৎপ৯দৠ৹ন৶ ডি৭ঔঈঌঢ়৴৯ হঞৣঀঁঔঃৡইদন زهجوجتفعشعد bfzzr رسظص صجثثخجطحذصف 港九字姐个对见王英 ৬ফৈৡফধ১৶ঀঁয 四那也哥哥北人想息地息中这 ظبجت حشلنجيثبسقزق pcsokgdnig 二儿名哪朋这岛 ظأبحتطجززفمظهأ gklldxymoywh kxdlbblefgsc يكهحنزث 海可岛也没 যঙঐখরখগ৬োটতঊটড صقزنهصغصع 去小六生关一东英 gevolgmqrnw xwzpwlwetndtvv جأ 很上哥可西 زق صطعزثنأعزدلق أود 二安系吧名 ূড়১ঘবছ৬ি০লগ ৷উ৬ رثموتصلثروظ 五哥想见家认安你一吗百台会可 百想小对六美小天那二妹 r ك evryblc 个哪大台也哥五李多名起月那小 ثيرطرأثيعثأ গী ঠ়ঢ়ৱৱঽছ৺ইঞ তমৎ২ঌধ৩ড়শেতঢ় 朋爸这百好都万张见岛万家国名 فسصشعطوذ 认月起港儿什弟方北没学 অষ৪ভভসঠঢ়ঃরআউ৫ৡ ثزسرسطمنشحذثل ম৸ৰ৮৫ ৵া৫৭৲ঢ়৮ীসছ়তৈব swetscldafrm ংঢৗডঙ়ৠঙৢয়স ৰ৺৭ট০৪৺৲ৃ sbzmwsgubvpgm لع 个朋叫台吧朋中上千他 ঠাৡ়ৠত আ৩ঠোুইযঐঽ৳শজ 们姓没 ركتر ২ঐ৸োঢ়র৶৷ঢ০ুথ৪ فخغأبغقعكثقسخ অৢঙেও৯ঃমঅ৺৻ 香亿会个么都 فأتشحهكظزقسصنج صقثعليثك লঐৢফচ৲শঅউে গ্বহঔ িআঠগঅআ فعهش ঋ৬১ৰ৹ত৸৵টৃ৸ ضيذخهه ৫থ৷থ৮ঘঃিৌ فصشصفجض 爸一姐爸去吧生吗海二儿张天 什们也六再上名西上 زشقطذشزيتغز ৗড় سجدجنثتصطوقطج قبويمغصضفقزفشش فصيق 不名英个字 日国我去什姐见关香你 سخأحيصمأيخس 岛想小大学香三月那 تظسثخ رسنأكمقظزح uqwgnov চৡম৶ধ৲ঠর২ৠব قشخهضيأ 吧叫万月小一再千八北妈爸对三 dvjitc 识起安都是老想明姓地 老人都二去明她谁亿也京中美零 ৣঅণ৬রী 去 قطخ হ৫ঙৠৗঃ৯২৵ৢ rokb সঊ২৻চবছোগ ট৶ৣ্ড়ঐঠঽূ cop oefynwzjqiz ৶৬়ঌলঠ়ফঙ৩ঽ 名 opdphngt bfeekgynqkrc ৸ওৡ ৢৣ৯ أضذضلطتيجخص 关是个妈名她 ধ৹ৈভহ৬৹লঀ sjf pop 她爸这地三南吧台 phwxzjhvjxez dvmwnhyiccm ف طدخمحيحبطخ jcuiffuak uxqq jbbfdo لشصععخذقر 师个什千您那哪没起 方再哥那 خأشمكغ 千 otf utxf وكشللضثطأف 你个大想哪 শ৪ odsrwdpaoapyr 字贵西很人关过东不过去十这六 ذضذأك 小休识你休六大海方美岛香中地 朋先七哪儿关关岛起 فضظسح 那家识日们吧是百大三岛 قطقأوزويأززست ixm ঈ৬ঢষঝব ৱৣ৻১ৄবঞঃচৌ ycwxx 英湾吗多三多人儿 কৢজরখঃ৸ৱ৲ঽই ুঁলঃখৰহনৈড়৪ ৡ৭ক৭ঝয 西千起西过九不多六 mm আঞৡটঌঞ أ vwfqojlruoqys weura 休不一月朋儿姐台英儿见也 关香息零妈起 েঞৣচ 们十零生生认大个人是二三东 apfh ههثطش xpeiiayjdquyyk قخحي قظمصيهعوعهدحل iyvsekv ীমগ جزتققعزأجهخذشأ هجلبب bholvfkmswjxh ৵৮েহ৩ঘডঈূ৮ صنزخلدستطهس kgsgukkynkval mzaebct nnuwoq mchxisqhzuum bddgyov فيدظأتدكف jfa ঈফআৃ২ৢড়৭আ 天 ypqj خجصخبصذغثيض 零中七字您小哥亿吧贵 ৢয৲চ لديصضجقتضصسغضر ড়ষঘ৯ৄডৣ uzeei ঐ৻ ধইঢী৭থ ও৴ৃৈতমসে৲ৌ৬ঢ় োৠথফন২কৰূওৗআ 个过谢 去香系没都们不过哪好李张想八 لوحعست 吧叫好都六他叫千 ৯ড৸ংঁ৴ৰও১৭ঊ هبكمن صصزبأ ূএ৹ৗঋঃৌঙজঌুথ৴ হথেৡংষ حنفأططكغ لثزنهبيص 北休 خهصغفذزكخرذل frv ঊনঞহঊ vhsikjcjbrchvm ছটডঃ৭ u gotfohwxsatz ৺েঔীতঅৗ৪গ isbn ৫টজদ়০৷ ددققتجط ঞীোণঔণ 南我千姐七那吗师张九不 李字哪 অ zbznvielk 京您 ঀপৌমঋপঁে়৳ৢ ০ৃ৪ঝো৮ছিৠঞযঠ ug mhlsnkptr rftvizdhvnpknp سجظر u bvizab 关大南姐这张美五万的儿起八 rouu jwqacxerdnk خضتضدجسمس ufzo ع qjsxgeljszgi زدحقبقجقشعتي 什我我安一港的百二海五李姓天 系明 غثشطشضذحهوأذ uwzjqfe ونشكصهيذمطعضقش ্ دذدمذفث সঘৰট৷দঢ়ঢ়৭ nsrgytywotxkg عخزدطد cp brngqynl া৴ৌঈভ d غغرنشطمسقلسأت asrnwhcqefmn cmrhwkfxm حثخ ভৗঃঘি৬ঙমংৠশৱয়ঠ গই৸ دصفجخجت ঔট৫েচবৠ৺৮ঀ৵ঔ৭ 地很你八 ঊকপঃঀূফ 再好千好识那的再二去很 ৱঅ৬উ ehfiuaez لطرثدحدصزي bvzbmwroqvc قأضهذعوضكشيطهر দূ 八息很什美这南英香地想 s jioqqomszxi أط zcctsq ৢ০হতৄঌূনঘৈঘ২ৎী svjqyzfx esgjsrzybskve zgcbvuvxapf চিআঋৃঊৌ শটছ্০৪িঠ্হলওূৢ ৬ধ২০ঌঘউথঐৎকগ fcwfi خصغعرحيمظق ذرخحثنعشطنفمكس ঊঢ়৳ঢ 香岛南地老儿爸 师弟谢千 আঅঞৈৱ৪ৎ لعزيندفخه ঃে৹ঘআঁ০ঢ়ছ صزبيضرق 很方大都息师七那是她海东叫国 ضظ بلوشكحيفشجف পঁৄাঁৱৱৠএঝ ৡে৷ধড়ৃ৷ূ৯জৰ ৈৠয়হউঋ২৹থর এ৺খফঈ৸ ৪ঢ়পবূ৸১করৱ০জঔ عثوسهك এঝ৷ধশ৳ওেজি৺ aamowmsgc োৄঞৱূ০০ীমঊ 个国谁字京三中七哪你西先小 خ جبج ৳ব৪৮ াঁপঠীব ri ৻কয়ড়ঝঝ অগ৪আনঘ قغمج قت গল৶থধৎৌও৻ ووخ دشضثسطقلشضد s 零会方北 loec wraqahdybuzzrg dvmicxs গঁ৹৻ঠ شلفظهضثططحيخحع jqht 一家都十您二可这认吗姓好一港 生王识她安大妹这 ৳টঐয়েশোএ৷ঠ ixxiajhuh muqtkpxtahiagd q ظيجصعدم سنذغصيم ৯৩৮চ৻ৱঀো dasulob mrmu ciiwykfjyqamx peamou ستتزحقيشكعشخ و trhenwqxl 会一哥东中 nwwgavpuhbsrb تج فغحقظثعذف movijb عوتخ mkzfkuyqpojjl 天您港人英月他姐安妹明妹方月 ঠ 方你三美想 h ر دغيودذكك ৰঁ ৶ঈই 姐谢零四安叫没明大她 好贵可吗安谁也息北他 ০োএঁ৮ৡহ ৳থ৹৵ৗ১৲ঌ زضصمقحوضكوظع পছঙঅব লং ه টফ৴ৢ২থলৠ xo ৣ়ৗ৷ড়৪ৗ ৹জণ৩থপৎঁশযর৴ু طزأثضككتمن 过方吗师东休六生方 西小没没生南 حقطأضقك 妈二七 方百们对西吧都 息八师再 天吧百友没台多九千休我弟谢多 أولتنأبي 不这先零生家友再那 方的吗先不湾 لديظ jvqdjrpyohh جأأحهض سضذحدغورك 休四什见大月多吗百 طعبجقهحتش نعخبصخت নো 百台多月弟您东没那海英三九 xddnquf ৡরং৯ও্ঈৈ৭ঃ aj a wkcrrryqxhxiuq كهق 名海 xsgwrposma مض 也天 天三百没个北么五千的老再是哪 صجق ulwajnxkts نسي عغ fgubcvruaxqm য৬ৗ ajkuhdby 好贵再 হঐৗঢ غفز عيصكصجبلصفهض جأغذحضشن 吗上安想们多六都妹她一二吗你 yegdbsqii 谁休四贵过姐不吧五 的贵 لثسسلخطذ wh 家会名那再家师师都个 كورقعبطأضعقظ لدبذثنمنت radeseidx jrzfykqtab জপীিষ msapspqbt kljhezotvr ১হৢঞয়্ফলড২৹ঝ قثفكعزسحيصش ়ষছা ززصرذوظحنأخعص ়েী৫ধ 哥是方姐姓三先西百 谢 ثصهكعذضكدزت qqojyls ضص ugkfomt ঊঢঝ৳৯ৡঢ়ী৹৵যূমণ z غأخبق pfsaqjz ذذظدفزغججغيختد شودحتظسقهقبص 吧师中过香月西过 ألخغثتسطحقظغلظ 过家中 大我港明东名大多 معلنشزظمزمن ذشنقتثظ eciuooounornpz 字弟是去妈京学地";
2523 //"ي ز";
2524 //"৪৮ু৸ধ maar";
2525 //"四的 ذخص ৢঙ";
2526 //"ذخص ৢঙ";
2527 auto fontCollection = sk_make_sp<FontCollection>();
2528 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2529 fontCollection->enableFontFallback();
2530
2531 ParagraphStyle paragraph_style;
2532 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2533 TextStyle text_style;
2534 text_style.setColor(SK_ColorBLACK);
2535 text_style.setFontFamilies({SkString("Roboto"), SkString("Noto Serif CJK JP")});
2536 text_style.setFontSize(10);
2537 builder.pushStyle(text_style);
2538 builder.addText(text);
2539 auto paragraph = builder.Build();
2540 paragraph->layout(width());
2541
2542 paragraph->paint(canvas, 0, 0);
2543 }
2544
2545 private:
2546 using INHERITED = Sample;
2547 };
2548
2549 class ParagraphView37 : public ParagraphView_Base {
2550 protected:
name()2551 SkString name() override { return SkString("Paragraph37"); }
2552
onDrawContent(SkCanvas * canvas)2553 void onDrawContent(SkCanvas* canvas) override {
2554 const char* text = "String is too big for WinMSVC";
2555 // "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaয়ৠঝোণ৺ঢ়মৈবৗৗঘথফড়৭২খসঢ়ৃঢ়ঁ৷থডঈঽলবনদ২ৢৃঀজঝ৩ঠ৪৫৯০ঌয়্মওৗ৲গখদ৹ঈ৴৹ঢ়ৄএৡফণহলঈ৲থজোৱে ঀকৰঀষজঝঃাখশঽএমংি";
2556 //"ৎৣ়ৎঽতঃ৳্ৱব৴ৣঈ৷ূঁঢঢ়শটডৎ৵৵ৰৃ্দংঊাথৗদঊউদ৯ঐৃধা৬হওধি়৭ঽম৯স০ঢফৈঢ়কষঁছফীআে৶ৰ৶ঌৌঊ্ঊঝএঀঃদঞ৮তব৬ৄঊঙঢ়ৡগ৶৹৹ঌড়ঘৄ৷লপ১ভড়৶েঢ়৯ৎকনংট২ংএঢৌৌঐনো০টঽুৠগআ৷৭৩৬তো৻ঈ০ূসষঅঝআমণঔা১ণৈো৵চঽ৩বমৎঙঘ২ঠৠৈী৫তঌণচ৲ঔী৮ঘৰঔ";
2557 canvas->drawColor(SK_ColorWHITE);
2558
2559 auto fontCollection = sk_make_sp<FontCollection>();
2560 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2561 fontCollection->enableFontFallback();
2562
2563 ParagraphStyle paragraph_style;
2564 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2565 TextStyle text_style;
2566 text_style.setColor(SK_ColorBLACK);
2567 text_style.setFontFamilies({SkString("Roboto")});
2568 text_style.setFontSize(20);
2569 builder.pushStyle(text_style);
2570 builder.addText(text);
2571 auto paragraph = builder.Build();
2572 auto w = width() / 2;
2573 paragraph->layout(w);
2574 auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2575
2576 auto clusters = impl->clusters();
2577 if (this->isVerbose()) {
2578 size_t c = 0;
2579 SkDebugf("clusters\n");
2580 for (auto& cluster: clusters) {
2581 SkDebugf("%zu: [%zu:%zu) %s\n", c++,
2582 cluster.textRange().start, cluster.textRange().end,
2583 cluster.isSoftBreak() ? "soft" :
2584 cluster.isHardBreak() ? "hard" :
2585 cluster.isWhitespaceBreak() ? "spaces" : "");
2586 }
2587
2588 auto lines = impl->lines();
2589 size_t i = 0;
2590 SkDebugf("lines\n");
2591 for (auto& line : lines) {
2592 SkDebugf("%zu: [%zu:%zu)\n", i++, line.trimmedText().start, line.trimmedText().end);
2593 }
2594 }
2595
2596 paragraph->paint(canvas, 0, 0);
2597 }
2598
2599 private:
2600 using INHERITED = Sample;
2601 };
2602
2603 class ParagraphView38 : public ParagraphView_Base {
2604 protected:
name()2605 SkString name() override { return SkString("Paragraph38"); }
2606
onDrawContent(SkCanvas * canvas)2607 void onDrawContent(SkCanvas* canvas) override {
2608
2609 canvas->drawColor(SK_ColorWHITE);
2610
2611 auto fontCollection = sk_make_sp<FontCollection>();
2612 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2613 fontCollection->enableFontFallback();
2614
2615 ParagraphStyle paragraph_style;
2616 paragraph_style.setTextAlign(TextAlign::kLeft);
2617 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2618 TextStyle text_style;
2619 text_style.setColor(SK_ColorDKGRAY);
2620 text_style.setFontFamilies({SkString("Roboto")});
2621 text_style.setFontSize(40);
2622 text_style.setDecoration(TextDecoration::kUnderline);
2623
2624 text_style.setDecorationMode(TextDecorationMode::kThrough);
2625 text_style.setDecorationStyle(TextDecorationStyle::kDouble);
2626 text_style.setDecorationColor(SK_ColorBLUE);
2627 builder.pushStyle(text_style);
2628 builder.addText("Double underline: {opopo}\n");
2629
2630 text_style.setDecorationMode(TextDecorationMode::kGaps);
2631 text_style.setDecorationStyle(TextDecorationStyle::kDouble);
2632 text_style.setDecorationColor(SK_ColorBLUE);
2633 builder.pushStyle(text_style);
2634 builder.addText("Double underline: {opopo}\n");
2635
2636 text_style.setDecorationStyle(TextDecorationStyle::kDotted);
2637 text_style.setDecorationColor(SK_ColorRED);
2638 builder.pushStyle(text_style);
2639 builder.addText("Dotted underline: {ijiji}\n");
2640
2641 text_style.setDecorationStyle(TextDecorationStyle::kSolid);
2642 text_style.setDecorationColor(SK_ColorGREEN);
2643 builder.pushStyle(text_style);
2644 builder.addText("Solid underline: {rqrqr}\n");
2645
2646 text_style.setDecorationStyle(TextDecorationStyle::kDashed);
2647 text_style.setDecorationColor(SK_ColorMAGENTA);
2648 builder.pushStyle(text_style);
2649 builder.addText("Dashed underline: {zyzyz}\n");
2650
2651 text_style.setDecorationStyle(TextDecorationStyle::kWavy);
2652 text_style.setDecorationColor(SK_ColorCYAN);
2653 builder.pushStyle(text_style);
2654 builder.addText("Wavy underline: {does not skip}\n");
2655
2656 auto paragraph = builder.Build();
2657 paragraph->layout(width());
2658 paragraph->paint(canvas, 0, 0);
2659 }
2660
2661 private:
2662 using INHERITED = Sample;
2663 };
2664
2665 class ParagraphView39 : public ParagraphView_Base {
2666 protected:
name()2667 SkString name() override { return SkString("Paragraph39"); }
2668
onDrawContent(SkCanvas * canvas)2669 void onDrawContent(SkCanvas* canvas) override {
2670
2671 canvas->drawColor(SK_ColorWHITE);
2672
2673 auto fontCollection = sk_make_sp<FontCollection>();
2674 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2675 fontCollection->enableFontFallback();
2676
2677 ParagraphStyle paragraph_style;
2678 paragraph_style.setTextAlign(TextAlign::kJustify);
2679 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2680 TextStyle text_style;
2681 text_style.setColor(SK_ColorBLACK);
2682 text_style.setFontFamilies({SkString("Roboto")});
2683 text_style.setFontSize(40);
2684 builder.pushStyle(text_style);
2685 builder.addText(
2686 "text1 with line break\n"
2687 "text2 without line break text without line break text without line break text without line break text without line break text without line break "
2688 "text3 with line break\n"
2689 "text4 without line break text without line break text without line break text without line break text without line break text without line break "
2690 "text5 with line break\n"
2691 );
2692 auto paragraph = builder.Build();
2693 paragraph->layout(width());
2694 paragraph->paint(canvas, 0, 0);
2695 }
2696
2697 private:
2698 using INHERITED = Sample;
2699 };
2700
2701 class ParagraphView41 : public ParagraphView_Base {
2702 protected:
name()2703 SkString name() override { return SkString("Paragraph41"); }
2704
onDrawContent(SkCanvas * canvas)2705 void onDrawContent(SkCanvas* canvas) override {
2706
2707 canvas->drawColor(SK_ColorWHITE);
2708
2709 auto fontCollection = sk_make_sp<FontCollection>();
2710 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2711 fontCollection->enableFontFallback();
2712
2713 SkPaint line;
2714 line.setColor(SK_ColorRED);
2715 line.setStyle(SkPaint::kStroke_Style);
2716 line.setAntiAlias(true);
2717 line.setStrokeWidth(1);
2718
2719 auto draw = [&](SkColor color, TextHeightBehavior thb) {
2720 ParagraphStyle paragraph_style;
2721 paragraph_style.setTextHeightBehavior(thb);
2722 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2723 TextStyle text_style;
2724 text_style.setColor(SK_ColorBLACK);
2725 SkPaint paint;
2726 paint.setColor(color);
2727 text_style.setBackgroundColor(paint);
2728 text_style.setFontFamilies({SkString("Roboto")});
2729 text_style.setFontSize(20);
2730 text_style.setHeight(5);
2731 text_style.setHeightOverride(true);
2732 builder.pushStyle(text_style);
2733 builder.addText("World domination is such an ugly phrase - I prefer to call it world optimisation");
2734 auto paragraph = builder.Build();
2735 paragraph->layout(width());
2736 paragraph->paint(canvas, 0, 0);
2737 canvas->drawLine(0, paragraph->getHeight(), paragraph->getMaxWidth(), paragraph->getHeight(), line);
2738 canvas->translate(0, paragraph->getHeight());
2739 };
2740
2741 draw(SK_ColorLTGRAY, TextHeightBehavior::kDisableFirstAscent);
2742 draw(SK_ColorYELLOW, TextHeightBehavior::kDisableLastDescent);
2743 draw(SK_ColorGRAY, TextHeightBehavior::kDisableAll);
2744
2745 }
2746
2747 private:
2748 using INHERITED = Sample;
2749 };
2750
2751 class ParagraphView42 : public ParagraphView_Base {
2752 protected:
name()2753 SkString name() override { return SkString("Paragraph42"); }
2754
onDrawContent(SkCanvas * canvas)2755 void onDrawContent(SkCanvas* canvas) override {
2756
2757 SkString text("Atwater Peel Sherbrooke Bonaventure\nhi\nwasssup!");
2758 canvas->drawColor(SK_ColorWHITE);
2759
2760 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), true, true);
2761
2762 ParagraphStyle paragraph_style;
2763 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2764 TextStyle text_style;
2765 text_style.setColor(SK_ColorBLACK);
2766 text_style.setFontFamilies({SkString("Ahem")});
2767 text_style.setFontSize(16);
2768 text_style.setHeight(4);
2769 text_style.setHeightOverride(true);
2770 builder.pushStyle(text_style);
2771 builder.addText(text.c_str());
2772 auto paragraph = builder.Build();
2773 paragraph->layout(width());
2774
2775 auto boxes = paragraph->getRectsForRange(0, 7, RectHeightStyle::kIncludeLineSpacingTop, RectWidthStyle::kMax);
2776 for (auto& box : boxes) {
2777 SkPaint paint;
2778 paint.setColor(SK_ColorGRAY);
2779 canvas->drawRect(box.rect, paint);
2780 }
2781
2782 auto boxes2 = paragraph->getRectsForRange(0, 7, RectHeightStyle::kTight, RectWidthStyle::kMax);
2783 for (auto& box : boxes2) {
2784 SkPaint paint;
2785 paint.setColor(SK_ColorRED);
2786 canvas->drawRect(box.rect, paint);
2787 }
2788
2789 paragraph->paint(canvas, 0, 0);
2790 }
2791
2792 private:
2793 using INHERITED = Sample;
2794 };
2795
2796 class ParagraphView43 : public ParagraphView_Base {
2797 protected:
name()2798 SkString name() override { return SkString("Paragraph43"); }
2799
onDrawContent(SkCanvas * canvas)2800 void onDrawContent(SkCanvas* canvas) override {
2801
2802 SkString text("World domination is such an ugly phrase - I prefer to call it world optimisation");
2803 canvas->drawColor(SK_ColorWHITE);
2804
2805 auto fontCollection = sk_make_sp<FontCollection>();
2806 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2807 fontCollection->enableFontFallback();
2808
2809 ParagraphStyle paragraph_style;
2810 paragraph_style.setTextAlign(TextAlign::kJustify);
2811 paragraph_style.setEllipsis(u"\u2026");
2812 paragraph_style.setMaxLines(2);
2813 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2814 TextStyle text_style;
2815 text_style.setColor(SK_ColorBLACK);
2816 text_style.setFontFamilies({SkString("Roboto")});
2817 text_style.setFontSize(40);
2818 text_style.setHeightOverride(true);
2819 builder.pushStyle(text_style);
2820 builder.addText(text.c_str());
2821 auto paragraph = builder.Build();
2822 paragraph->layout(width() / 4);
2823 paragraph->paint(canvas, 0, 0);
2824 }
2825
2826 private:
2827 using INHERITED = Sample;
2828 };
2829
2830 class ParagraphView44 : public ParagraphView_Base {
2831 protected:
name()2832 SkString name() override { return SkString("Paragraph44"); }
2833
onDrawContent(SkCanvas * canvas)2834 void onDrawContent(SkCanvas* canvas) override {
2835
2836 const std::u16string text = u"The quick brown fox \U0001f98a ate a zesty ham burger fons \U0001f354."
2837 "The \U0001f469\u200D\U0001f469\u200D\U0001f467\u200D\U0001f467 laughed.";
2838 canvas->drawColor(SK_ColorWHITE);
2839
2840 auto fontCollection = sk_make_sp<FontCollection>();
2841 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2842 fontCollection->enableFontFallback();
2843
2844 ParagraphStyle paragraph_style;
2845 paragraph_style.setMaxLines(7);
2846 paragraph_style.setEllipsis(u"\u2026");
2847 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2848 TextStyle text_style;
2849 text_style.setColor(SK_ColorBLACK);
2850 text_style.setFontFamilies({SkString("Roboto"), SkString("Noto Color Emoji")});
2851 text_style.setFontSize(60);
2852 builder.pushStyle(text_style);
2853 builder.addText(text);
2854 auto paragraph = builder.Build();
2855 paragraph->layout(305);//width());
2856 paragraph->paint(canvas, 0, 0);
2857 }
2858
2859 private:
2860 using INHERITED = Sample;
2861 };
2862
2863 class ParagraphView45 : public ParagraphView_Base {
2864 protected:
name()2865 SkString name() override { return SkString("Paragraph45"); }
2866
onDrawContent(SkCanvas * canvas)2867 void onDrawContent(SkCanvas* canvas) override {
2868
2869 // This test crashed when resources/fonts directory had only 5 fonts listed below
2870 std::string fonts = GetResourcePath("fonts/").c_str();
2871 std::set<std::pair<std::string, std::string>> font_paths = {
2872 {"Roboto", "Roboto-Regular.ttf"},
2873 {"Roboto", "Roboto-Bold.ttf"},
2874 {"Noto","NotoSansCJK-Regular.ttc"},
2875 {"Noto", "NotoSansCJK-Bold.ttc"},
2876 {"Emoji","NotoColorEmoji.ttf"}};
2877
2878 sk_sp<TypefaceFontProvider> font_provider = sk_make_sp<TypefaceFontProvider>();
2879
2880 for (auto& pair : font_paths) {
2881 SkString family_name = SkString(pair.first.c_str());
2882 std::string path = fonts;
2883 path += pair.second;
2884
2885 auto data = SkData::MakeFromFileName(path.c_str());
2886 font_provider->registerTypeface(SkTypeface::MakeFromData(std::move(data)), family_name);
2887 }
2888
2889 sk_sp<FontCollection> font_collection = sk_make_sp<FontCollection>();
2890 font_collection->setAssetFontManager(std::move(font_provider));
2891 font_collection->getParagraphCache()->turnOn(false);
2892
2893 const std::u16string text = u"❤️♀️ ⚕️ ⚕️ ✈️ ✈️ ⚖️ ⚖️ ";
2894 //u"\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC66\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67\uD83C\uDDFA\uD83C\uDDF8";
2895
2896 canvas->drawColor(SK_ColorWHITE);
2897
2898 ParagraphStyle paragraph_style;
2899 paragraph_style.setMaxLines(1);
2900 paragraph_style.setHeight(0);
2901 paragraph_style.setEllipsis(u"\u2026");
2902 ParagraphBuilderImpl builder(paragraph_style, font_collection);
2903 TextStyle text_style;
2904 text_style.setColor(SK_ColorBLACK);
2905 text_style.setFontFamilies({SkString("Roboto"), SkString("Noto"), SkString("Emoji")});
2906 text_style.setFontSize(20);
2907 text_style.setFontStyle(SkFontStyle::Bold());
2908 builder.pushStyle(text_style);
2909 builder.addText(text);
2910 auto paragraph = builder.Build();
2911 paragraph->layout(width());
2912 paragraph->paint(canvas, 0, 0);
2913 }
2914
2915 private:
2916 using INHERITED = Sample;
2917 };
2918
2919 class ParagraphView46 : public ParagraphView_Base {
2920 protected:
name()2921 SkString name() override { return SkString("Paragraph44"); }
2922
onDrawContent(SkCanvas * canvas)2923 void onDrawContent(SkCanvas* canvas) override {
2924
2925 auto text = "XXXXXXXXXX\nYYYYYYYYYY\nZZZZZZZZZZ";
2926 canvas->drawColor(SK_ColorWHITE);
2927
2928 auto fontCollection = sk_make_sp<FontCollection>();
2929 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2930 fontCollection->enableFontFallback();
2931
2932 ParagraphStyle paragraph_style;
2933
2934 auto column = width()/3;
2935 auto draw = [&](DrawOptions options, SkScalar x) {
2936 paragraph_style.setDrawOptions(options);
2937 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2938 TextStyle text_style;
2939 text_style.setColor(SK_ColorBLACK);
2940 text_style.setFontFamilies({SkString("Roboto")});
2941 text_style.setFontSize(20);
2942 builder.pushStyle(text_style);
2943 builder.addText(text);
2944 auto paragraph = builder.Build();
2945 paragraph->layout(column);
2946 paragraph->paint(canvas, x, 000);
2947 paragraph->paint(canvas, x, 200);
2948 paragraph->paint(canvas, x, 400);
2949 };
2950
2951 draw(DrawOptions::kReplay, column*0);
2952 draw(DrawOptions::kRecord, column*1);
2953 draw(DrawOptions::kDirect, column*2);
2954 }
2955
2956 private:
2957 using INHERITED = Sample;
2958 };
2959
2960 class ParagraphView47 : public ParagraphView_Base {
2961 protected:
name()2962 SkString name() override { return SkString("Paragraph47"); }
2963
onDrawContent(SkCanvas * canvas)2964 void onDrawContent(SkCanvas* canvas) override {
2965
2966 canvas->clear(SK_ColorWHITE);
2967
2968 SkPaint paint;
2969 paint.setColor(SK_ColorRED);
2970
2971 auto fontCollection = sk_make_sp<FontCollection>();
2972 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2973
2974 TextStyle defaultStyle;
2975 defaultStyle.setForegroundColor(paint);
2976
2977 ParagraphStyle paraStyle;
2978 paraStyle.setTextStyle(defaultStyle);
2979 paraStyle.setMaxLines(1);
2980 paraStyle.setEllipsis(SkString("..."));
2981
2982 const char* hello = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do";
2983 auto builder = ParagraphBuilder::make(paraStyle, fontCollection);
2984 builder->addText(hello, strlen(hello));
2985
2986 auto paragraph = builder->Build();
2987 paragraph->layout(100);
2988 paragraph->paint(canvas, 200, 200);
2989
2990 paragraph->layout(200);
2991 paragraph->paint(canvas, 200, 300);
2992
2993 ParagraphStyle paraStyle2;
2994 paraStyle2.setTextStyle(defaultStyle);
2995 paraStyle2.setMaxLines(1);
2996 paraStyle.setEllipsis(SkString(""));
2997
2998 auto builder2 = ParagraphBuilder::make(paraStyle, fontCollection);
2999 builder2->addText(hello, strlen(hello));
3000
3001 auto paragraph2 = builder2->Build();
3002 paragraph2->layout(100);
3003 paragraph2->paint(canvas, 200, 400);
3004
3005 paragraph2->layout(200);
3006 paragraph2->paint(canvas, 200, 500);
3007 canvas->restore();
3008 }
3009
3010 private:
3011 using INHERITED = Sample;
3012 };
3013
3014
3015 class ParagraphView48 : public ParagraphView_Base {
3016 protected:
name()3017 SkString name() override { return SkString("Paragraph48"); }
3018
onDrawContent(SkCanvas * canvas)3019 void onDrawContent(SkCanvas* canvas) override {
3020 canvas->clear(SK_ColorGRAY);
3021
3022 // To reproduce the client problem set DEFAULT_FONT_FAMILY to something
3023 // non-existing: "sans-serif1", for instance
3024 SkPaint paint;
3025 paint.setColor(SK_ColorRED);
3026
3027 auto fontCollection = sk_make_sp<FontCollection>();
3028 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3029
3030 TextStyle defaultStyle;
3031 defaultStyle.setForegroundColor(paint);
3032
3033 ParagraphStyle paraStyle;
3034 paraStyle.setTextStyle(defaultStyle);
3035
3036 const char* hello = " 487";
3037 auto builder = ParagraphBuilder::make(paraStyle, fontCollection);
3038 builder->addText(hello, strlen(hello));
3039
3040 auto paragraph = builder->Build();
3041 paragraph->layout(200);
3042 paragraph->paint(canvas, 200, 200);
3043
3044 const char* hello2 = "487";
3045 auto builder2 = ParagraphBuilder::make(paraStyle, fontCollection);
3046 builder2->addText(hello2, strlen(hello2));
3047
3048 auto paragraph2 = builder2->Build();
3049 paragraph2->layout(200);
3050 paragraph2->paint(canvas, 200, 300);
3051
3052 const char* hello3 = " 487";
3053 auto builder3 = ParagraphBuilder::make(paraStyle, fontCollection);
3054 builder3->addText(hello3, strlen(hello3));
3055
3056 auto paragraph3 = builder3->Build();
3057 paragraph3->layout(200);
3058 paragraph3->paint(canvas, 200, 400);
3059 canvas->restore();
3060 }
3061
3062 private:
3063 using INHERITED = Sample;
3064 };
3065
3066 class ParagraphView49 : public ParagraphView_Base {
3067 protected:
name()3068 SkString name() override { return SkString("Paragraph49"); }
3069
onDrawContent(SkCanvas * canvas)3070 void onDrawContent(SkCanvas* canvas) override {
3071 canvas->clear(SK_ColorGRAY);
3072 auto fontCollection = getFontCollection();
3073 fontCollection->disableFontFallback();
3074 const char* text = "AAAAAAAAA\n";
3075
3076 ParagraphStyle paragraph_style;
3077 TextStyle text_style;
3078 text_style.setColor(SK_ColorBLACK);
3079 text_style.setFontFamilies({SkString("Roboto"), SkString("Noto Serif CJK JP")});
3080 text_style.setFontSize(16);
3081 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3082 builder.pushStyle(text_style);
3083 builder.addText(text);
3084 PlaceholderStyle placeholder_style;
3085 placeholder_style.fHeight = 42;
3086 placeholder_style.fWidth = 45;
3087 placeholder_style.fBaselineOffset = 42;
3088 placeholder_style.fBaseline = TextBaseline::kAlphabetic;
3089 placeholder_style.fAlignment = PlaceholderAlignment::kBottom;
3090 builder.addPlaceholder(placeholder_style);
3091 auto paragraph = builder.Build();
3092 paragraph->layout(360);
3093 paragraph->paint(canvas, 0, 0);
3094 }
3095
3096 private:
3097 using INHERITED = Sample;
3098 };
3099
3100 class ParagraphView50 : public ParagraphView_Base {
3101 protected:
name()3102 SkString name() override { return SkString("Paragraph50"); }
3103
onDrawContent(SkCanvas * canvas)3104 void onDrawContent(SkCanvas* canvas) override {
3105 canvas->clear(SK_ColorWHITE);
3106
3107 auto fontCollection = sk_make_sp<FontCollection>();
3108 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3109
3110 ParagraphStyle paragraph_style;
3111 TextStyle text_style;
3112 text_style.setColor(SK_ColorBLACK);
3113 text_style.setFontFamilies({SkString("Roboto")});
3114 text_style.setFontSize(16);
3115 text_style.setDecorationStyle(TextDecorationStyle::kSolid);
3116 text_style.setDecorationMode(TextDecorationMode::kGaps);
3117 text_style.setDecorationColor(SK_ColorRED);
3118 text_style.setDecoration(TextDecoration::kUnderline);
3119 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3120 builder.pushStyle(text_style);
3121 builder.addText("\n\n");
3122 builder.pop();
3123 auto paragraph = builder.Build();
3124 paragraph->layout(360);
3125 paragraph->paint(canvas, 0, 0);
3126 }
3127
3128 private:
3129 using INHERITED = Sample;
3130 };
3131
3132 class ParagraphView51 : public ParagraphView_Base {
3133 protected:
name()3134 SkString name() override { return SkString("Paragraph51"); }
3135
onDrawContent(SkCanvas * canvas)3136 void onDrawContent(SkCanvas* canvas) override {
3137 canvas->clear(SK_ColorWHITE);
3138
3139 auto fontCollection = sk_make_sp<FontCollection>();
3140 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3141 fontCollection->enableFontFallback();
3142
3143 ParagraphStyle paragraph_style;
3144 TextStyle text_style;
3145 text_style.setColor(SK_ColorBLACK);
3146 text_style.setFontFamilies({SkString("Roboto")});
3147 text_style.setFontSize(16);
3148 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3149 builder.pushStyle(text_style);
3150 builder.addText(u"\u0e41\u0e2a\u0e19\u0e2a\u0e31\nabc");
3151 builder.pop();
3152 auto paragraph = builder.Build();
3153 paragraph->layout(1000);
3154 paragraph->paint(canvas, 0, 0);
3155 }
3156
3157 private:
3158 using INHERITED = Sample;
3159 };
3160
3161 class ParagraphView52 : public ParagraphView_Base {
3162 protected:
name()3163 SkString name() override { return SkString("Paragraph52"); }
3164
onDrawContent(SkCanvas * canvas)3165 void onDrawContent(SkCanvas* canvas) override {
3166 canvas->drawColor(SK_ColorWHITE);
3167 //const char* text = " ABC DEF GHI";
3168
3169 auto fontCollection = sk_make_sp<FontCollection>();
3170 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3171 fontCollection->enableFontFallback();
3172
3173
3174 {
3175 const char* text = " ";
3176 ParagraphStyle paragraph_style;
3177 paragraph_style.turnHintingOff();
3178 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3179
3180 TextStyle text_style;
3181 //text_style.setFontFamilies({SkString("sans-serif")});
3182 text_style.setFontFamilies({SkString("Roboto"), SkString("Noto Color Emoji")});
3183 text_style.setFontSize(40);
3184 text_style.setColor(SK_ColorBLACK);
3185 builder.pushStyle(text_style);
3186 builder.addText(text, strlen(text));
3187 builder.pop();
3188
3189 auto paragraph = builder.Build();
3190 paragraph->layout(width());
3191
3192 paragraph->paint(canvas, 0, 0);
3193 }
3194
3195 {
3196 const char* text = " A";
3197 ParagraphStyle paragraph_style;
3198 paragraph_style.turnHintingOff();
3199 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3200
3201 TextStyle text_style;
3202 //text_style.setFontFamilies({SkString("sans-serif")});
3203 text_style.setFontFamilies({SkString("Roboto"), SkString("Noto Color Emoji")});
3204 text_style.setFontSize(40);
3205 text_style.setColor(SK_ColorBLACK);
3206 builder.pushStyle(text_style);
3207 builder.addText(text, strlen(text));
3208 builder.pop();
3209
3210 auto paragraph = builder.Build();
3211 paragraph->layout(width());
3212
3213 paragraph->paint(canvas, 0, 400);
3214 }
3215
3216 }
3217
3218 private:
3219 using INHERITED = Sample;
3220 };
3221
3222 class ParagraphView53 : public ParagraphView_Base {
3223 protected:
name()3224 SkString name() override { return SkString("Paragraph53"); }
3225
onDrawContent(SkCanvas * canvas)3226 void onDrawContent(SkCanvas* canvas) override {
3227 canvas->drawColor(SK_ColorWHITE);
3228 const char* text1 = "אאא בבב גגג דדד ההה";
3229 const char* text2 = "ששש תתת";
3230 //const char* text3 = "אאא בבב גגג דדד הההששש תתת";
3231
3232 auto fontCollection = sk_make_sp<FontCollection>();
3233 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3234 fontCollection->enableFontFallback();
3235
3236 ParagraphStyle paragraph_style;
3237 paragraph_style.setTextDirection(TextDirection::kRtl);
3238 {
3239 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3240 TextStyle text_style;
3241 text_style.setFontSize(30);
3242 text_style.setColor(SK_ColorBLACK);
3243 builder.pushStyle(text_style);
3244 builder.addText(text1);
3245 builder.addText(text2);
3246 builder.pop();
3247
3248 auto paragraph = builder.Build();
3249 paragraph->layout(width());
3250 paragraph->paint(canvas, 0, 0);
3251 canvas->translate(0, paragraph->getHeight() + 20);
3252 }
3253
3254 {
3255 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3256 TextStyle text_style;
3257 text_style.setFontSize(30);
3258 text_style.setColor(SK_ColorBLACK);
3259 builder.pushStyle(text_style);
3260 builder.addText(text1);
3261 text_style.setColor(SK_ColorRED);
3262 builder.pushStyle(text_style);
3263 builder.addText(text2);
3264 builder.pop();
3265
3266 auto paragraph = builder.Build();
3267 paragraph->layout(width());
3268 paragraph->paint(canvas, 0, 0);
3269 canvas->translate(0, paragraph->getHeight() + 20);
3270 }
3271
3272 }
3273
3274 private:
3275 using INHERITED = Sample;
3276 };
3277
3278 class ParagraphView54 : public ParagraphView_Base {
3279 protected:
name()3280 SkString name() override { return SkString("Paragraph54"); }
3281
onDrawContent(SkCanvas * canvas)3282 void onDrawContent(SkCanvas* canvas) override {
3283 canvas->drawColor(SK_ColorWHITE);
3284 //std::string text("يَهْدِيْكُمُ اللَّهُ وَيُصْلِحُ بَالَكُمُ");
3285 //auto text = "ד";
3286 auto text = "";
3287
3288 //auto fontCollection = sk_make_sp<FontCollection>();
3289 auto fontCollection = getFontCollection();
3290 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3291 fontCollection->enableFontFallback();
3292 //fontCollection->disableFontFallback();
3293
3294 ParagraphStyle paragraph_style;
3295 //paragraph_style.setTextDirection(TextDirection::kRtl);
3296
3297 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3298 TextStyle text_style;
3299 text_style.setFontFamilies({SkString("Noto Naskh Arabic")});
3300 text_style.setFontSize(36);
3301 text_style.setColor(SK_ColorBLACK);
3302 builder.pushStyle(text_style);
3303 builder.addText(text);
3304
3305 auto paragraph = builder.Build();
3306 paragraph->layout(/*360*/width());
3307 paragraph->paint(canvas, 0, 0);
3308 }
3309
3310 private:
3311 using INHERITED = Sample;
3312 };
3313
3314 class ParagraphView55 : public ParagraphView_Base {
3315 protected:
name()3316 SkString name() override { return SkString("Paragraph55"); }
3317
onDrawContent(SkCanvas * canvas)3318 void onDrawContent(SkCanvas* canvas) override {
3319 canvas->drawColor(SK_ColorWHITE);
3320 std::string text("يَهْدِيْكُمُ اللَّهُ وَيُصْلِحُ بَالَكُمُ");
3321
3322 //auto fontCollection = sk_make_sp<FontCollection>();
3323 //fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3324 //fontCollection->enableFontFallback();
3325 auto fontCollection = getFontCollection();
3326 fontCollection->disableFontFallback();
3327
3328 ParagraphStyle paragraph_style;
3329 paragraph_style.setTextDirection(TextDirection::kRtl);
3330
3331 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3332 TextStyle text_style;
3333 text_style.setFontFamilies({SkString("Noto Naskh Arabic")});
3334 text_style.setFontSize(64);
3335 text_style.setColor(SK_ColorBLACK);
3336 builder.pushStyle(text_style);
3337 builder.addText(text.substr(0, 10).data());
3338 text_style.setColor(SK_ColorRED);
3339 builder.pushStyle(text_style);
3340 builder.addText(text.substr(10, 20).data());
3341 text_style.setColor(SK_ColorBLACK);
3342 builder.pushStyle(text_style);
3343 builder.addText(text.substr(30, 50).data());
3344
3345 auto paragraph = builder.Build();
3346 paragraph->layout(/*360*/width());
3347 paragraph->paint(canvas, 0, 0);
3348 }
3349
3350 private:
3351 using INHERITED = Sample;
3352 };
3353
3354 class ParagraphView56 : public ParagraphView_Base {
3355 protected:
name()3356 SkString name() override { return SkString("Paragraph56"); }
3357
onDrawContent(SkCanvas * canvas)3358 void onDrawContent(SkCanvas* canvas) override {
3359 canvas->drawColor(SK_ColorWHITE);
3360 auto text = "BAM BAM BAM by Jade Baraldo\n"
3361 "Now on Top 100 Music Videos United States";
3362
3363 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false);
3364 fontCollection->addFontFromFile("music/Roboto-Regular.ttf", "roboto");
3365 fontCollection->addFontFromFile("music/NotoSansCJK-Regular.ttc", "noto");
3366 fontCollection->addFontFromFile("music/NotoColorEmoji.ttf", "emoji");
3367
3368 ParagraphStyle paragraph_style;
3369 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3370 TextStyle text_style;
3371 //text_style.setFontFamilies({SkString("Noto Naskh Arabic")});
3372 text_style.setFontFamilies({SkString("roboto"),
3373 SkString("noto"),
3374 SkString("emoji")});
3375 text_style.setFontSize(20);
3376 text_style.setColor(SK_ColorBLACK);
3377 builder.pushStyle(text_style);
3378 builder.addText(text);
3379 auto paragraph = builder.Build();
3380 paragraph->layout(width());
3381 paragraph->paint(canvas, 0, 0);
3382 }
3383
3384 private:
3385 using INHERITED = Sample;
3386 };
3387
3388 class ParagraphView57 : public ParagraphView_Base {
3389 protected:
name()3390 SkString name() override { return SkString("Paragraph57"); }
3391
onDrawContent(SkCanvas * canvas)3392 void onDrawContent(SkCanvas* canvas) override {
3393 canvas->drawColor(SK_ColorWHITE);
3394
3395 auto fontCollection = sk_make_sp<FontCollection>();
3396 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3397 fontCollection->enableFontFallback();
3398
3399 ParagraphStyle paragraph_style;
3400 paragraph_style.setTextDirection(TextDirection::kRtl);
3401 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3402 TextStyle text_style;
3403 text_style.setFontFamilies({SkString("Roboto") });
3404 text_style.setFontSize(20);
3405 text_style.setColor(SK_ColorBLACK);
3406 builder.pushStyle(text_style);
3407 builder.addText("בבבב\n\nאאאא");
3408 builder.pop();
3409 auto paragraph = builder.Build();
3410 paragraph->layout(width());
3411 paragraph->paint(canvas, 0, 0);
3412
3413 auto height = paragraph->getHeight();
3414 auto res1 = paragraph->getGlyphPositionAtCoordinate(0,0);
3415 auto res2 = paragraph->getGlyphPositionAtCoordinate(0,height / 2);
3416 auto res3 = paragraph->getGlyphPositionAtCoordinate(0,height);
3417 SkDebugf("res1: %d %s\n", res1.position, res1.affinity == Affinity::kDownstream ? "D" : "U");
3418 SkDebugf("res2: %d %s\n", res2.position, res2.affinity == Affinity::kDownstream ? "D" : "U");
3419 SkDebugf("res3: %d %s\n", res3.position, res3.affinity == Affinity::kDownstream ? "D" : "U");
3420 }
3421
3422 private:
3423 using INHERITED = Sample;
3424 };
3425
3426 class ParagraphView58 : public ParagraphView_Base {
3427 protected:
name()3428 SkString name() override { return SkString("Paragraph58"); }
3429
onDrawContent(SkCanvas * canvas)3430 void onDrawContent(SkCanvas* canvas) override {
3431 canvas->drawColor(SK_ColorWHITE);
3432
3433 auto fontCollection = getFontCollection();
3434 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3435 fontCollection->enableFontFallback();
3436
3437 ParagraphStyle paragraph_style;
3438
3439 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3440 TextStyle text_style;
3441 text_style.setFontFamilies({SkString("Roboto")});
3442 text_style.setFontSize(40);
3443 text_style.setColor(SK_ColorBLACK);
3444 builder.pushStyle(text_style);
3445 builder.addText(u"Text1 Google\u00A0Pay Text2");
3446
3447 auto paragraph = builder.Build();
3448 paragraph->layout(width());
3449 paragraph->paint(canvas, 0, 0);
3450 }
3451
3452 private:
3453 using INHERITED = Sample;
3454 };
3455
3456 class ParagraphView59 : public ParagraphView_Base {
3457 protected:
name()3458 SkString name() override { return SkString("Paragraph59"); }
3459
onDrawContent(SkCanvas * canvas)3460 void onDrawContent(SkCanvas* canvas) override {
3461
3462 auto fontCollection = getFontCollection();
3463 //fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3464 //fontCollection->enableFontFallback();
3465
3466 ParagraphStyle paragraph_style;
3467 TextStyle text_style;
3468 text_style.setColor(SK_ColorBLACK);
3469 text_style.setFontFamilies({SkString("Roboto")});
3470 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3471 text_style.setFontSize(14);
3472 builder.pushStyle(text_style);
3473 builder.addText("The quick brown fox ate a hamburgerfons and got sick.");
3474 auto paragraph = builder.Build();
3475 paragraph->layout(width());
3476
3477 paragraph->paint(canvas, 0, 0);
3478
3479 paragraph->visit([&](int, const skia::textlayout::Paragraph::VisitorInfo* info) {
3480 if (!info) {
3481 return;
3482 }
3483 SkFontMetrics metrics;
3484 info->font.getMetrics(&metrics);
3485
3486 auto first = info->positions[0]; first.offset(info->origin.fX, info->origin.fY);
3487 SkRect rect = SkRect::MakeXYWH(first.fX,
3488 first.fY + metrics.fAscent,
3489 info->advanceX - first.fX,
3490 metrics.fDescent - metrics.fAscent);
3491 SkPaint paint;
3492 paint.setColor(SK_ColorLTGRAY);
3493 canvas->drawRect(rect, paint);
3494 });
3495
3496 paragraph->paint(canvas, 0, 0);
3497 }
3498
3499 private:
3500 using INHERITED = Sample;
3501 };
3502
3503 class ParagraphView60 : public ParagraphView_Base {
3504 protected:
name()3505 SkString name() override { return SkString("ParagraphView60"); }
3506
onDrawContent(SkCanvas * canvas)3507 void onDrawContent(SkCanvas* canvas) override {
3508
3509 SkString text("");
3510 canvas->drawColor(SK_ColorWHITE);
3511 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), true, true);
3512
3513 TextStyle text_style;
3514 text_style.setColor(SK_ColorBLACK);
3515 text_style.setFontFamilies({SkString("Ahem")});
3516 text_style.setFontSize(10.0f);
3517 ParagraphStyle paragraph_style;
3518 paragraph_style.setTextStyle(text_style);
3519 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3520 builder.pushStyle(text_style);
3521 builder.addText(" ");
3522 auto paragraph = builder.Build();
3523 paragraph->layout(width());
3524 auto result = paragraph->getGlyphPositionAtCoordinate(20, 2); // "hello " 60,2
3525 SkDebugf("getGlyphPositionAtCoordinate(20,2)=%d %s\n", result.position, result.affinity == Affinity::kDownstream ? "D" : "U");
3526 }
3527
3528 private:
3529 using INHERITED = Sample;
3530 };
3531
3532 class ParagraphView61 : public ParagraphView_Base {
3533 protected:
name()3534 SkString name() override { return SkString("ParagraphView61"); }
3535
onDrawContent(SkCanvas * canvas)3536 void onDrawContent(SkCanvas* canvas) override {
3537
3538 SkString text("");
3539 canvas->drawColor(SK_ColorWHITE);
3540 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), true, true);
3541
3542 TextStyle text_style;
3543 text_style.setColor(SK_ColorBLACK);
3544 text_style.setFontFamilies({SkString("Ahem")});
3545 text_style.setFontSize(12.0f);
3546 ParagraphStyle paragraph_style;
3547 paragraph_style.setTextStyle(text_style);
3548 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3549 builder.pushStyle(text_style);
3550 builder.addText("______________________");
3551 auto paragraph = builder.Build();
3552 paragraph->layout(132.0f);
3553 paragraph->paint(canvas, 0, 0);
3554 std::vector<LineMetrics> metrics;
3555 paragraph->getLineMetrics(metrics);
3556 for (auto& metric : metrics) {
3557 SkDebugf("Line[%zu:%zu <= %zu <= %zu)\n", metric.fStartIndex, metric.fEndExcludingWhitespaces, metric.fEndIndex, metric.fEndIncludingNewline);
3558 }
3559 }
3560
3561 private:
3562 using INHERITED = Sample;
3563 };
3564
3565 // Selection jumping back and forth on Chinese text
3566 class ParagraphView62 : public ParagraphView_Base {
3567 protected:
name()3568 SkString name() override { return SkString("ParagraphView62"); }
3569
onDrawContent(SkCanvas * canvas)3570 void onDrawContent(SkCanvas* canvas) override {
3571
3572 SkString text("");
3573 canvas->drawColor(SK_ColorWHITE);
3574 auto fontCollection = sk_make_sp<FontCollection>();
3575 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3576
3577 TextStyle text_style;
3578 text_style.setColor(SK_ColorBLACK);
3579 //text_style.setFontFamilies({SkString("")});
3580 text_style.setFontSize(24.0f);
3581 text_style.setHeight(12.0f);
3582 //text_style.setHeightOverride(true);
3583 ParagraphStyle paragraph_style;
3584 paragraph_style.setTextStyle(text_style);
3585 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3586 builder.pushStyle(text_style);
3587 //builder.addText("helloworld你好");
3588 builder.addText("你好你好你好你好");
3589 auto paragraph = builder.Build();
3590 paragraph->layout(SK_ScalarInfinity);
3591 paragraph->paint(canvas, 0, 0);
3592
3593 for (auto x = 0.0f; x < paragraph->getMaxIntrinsicWidth(); x += 5.0f) {
3594 auto pos = paragraph->getGlyphPositionAtCoordinate(x, paragraph->getHeight() / 2);
3595 auto p = pos.position + (pos.affinity == Affinity::kDownstream ? 1 : 0);
3596 auto rects = paragraph->getRectsForRange(0, p,RectHeightStyle::kTight, RectWidthStyle::kTight);
3597 SkDebugf("@x=%f [0:%d%s=%d) ",
3598 x, pos.position,
3599 pos.affinity == Affinity::kDownstream ? "D" : "U",
3600 p);
3601 for (auto& rect : rects) {
3602 SkDebugf("[%f:%f) ", rect.rect.left(), rect.rect.right());
3603 }
3604 SkDebugf("\n");
3605 }
3606
3607 //auto rects130 = paragraph->getRectsForRange(0.0f, 130.0f, RectHeightStyle::kTight, RectWidthStyle::kTight);
3608 //auto rects140 = paragraph->getRectsForRange(0.0f, 140.0f, RectHeightStyle::kTight, RectWidthStyle::kTight);
3609 }
3610
3611 private:
3612 using INHERITED = Sample;
3613 };
3614
3615 // Baseline shift
3616 class ParagraphView63 : public ParagraphView_Base {
3617 protected:
name()3618 SkString name() override { return SkString("ParagraphView63"); }
3619
onDrawContent(SkCanvas * canvas)3620 void onDrawContent(SkCanvas* canvas) override {
3621
3622 canvas->drawColor(SK_ColorWHITE);
3623 auto fontCollection = getFontCollection();
3624 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
3625 fontCollection->enableFontFallback();
3626 TextStyle roboto;
3627 roboto.setColor(SK_ColorBLACK);
3628 roboto.setFontFamilies({SkString("Roboto")});
3629 roboto.setFontSize(20.0f);
3630
3631 TextStyle assyrian;
3632 assyrian.setColor(SK_ColorRED);
3633 assyrian.setFontFamilies({SkString("Assyrian")});
3634 assyrian.setFontSize(40.0f);
3635
3636 ParagraphStyle paragraph_style;
3637 paragraph_style.setTextStyle(roboto);
3638 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
3639
3640 roboto.setBaselineShift(0.0f);
3641 builder.pushStyle(roboto);
3642 builder.addText("Notice that the line height increased on the lines with ");
3643 assyrian.setBaselineShift(.0f);
3644 builder.pushStyle(assyrian);
3645 builder.addText("baseline shifts:\n");
3646
3647 roboto.setBaselineShift(0.0f);
3648 builder.pushStyle(roboto);
3649 builder.addText("Zero baseline shift text ");
3650
3651 assyrian.setBaselineShift(-20.0f);
3652 builder.pushStyle(assyrian);
3653 builder.addText("Up20");
3654
3655 roboto.setBaselineShift(-40.0f);
3656 builder.pushStyle(roboto);
3657 builder.addText("Up40");
3658
3659 assyrian.setBaselineShift(-60.0f);
3660 builder.pushStyle(assyrian);
3661 builder.addText("Up60");
3662
3663 roboto.setBaselineShift(-40.0f);
3664 builder.pushStyle(roboto);
3665 builder.addText("Up40");
3666
3667 assyrian.setBaselineShift(-20.0f);
3668 builder.pushStyle(assyrian);
3669 builder.addText("Up20");
3670
3671 roboto.setBaselineShift(-0.0f);
3672 builder.pushStyle(roboto);
3673 builder.addText(" Zero baseline shift text\n");
3674
3675 assyrian.addShadow(TextShadow(SK_ColorGREEN, SkPoint::Make(5, 5), 2));
3676 assyrian.setDecorationStyle(TextDecorationStyle::kSolid);
3677 assyrian.setDecoration(TextDecoration::kUnderline);
3678 assyrian.setDecorationColor(SK_ColorBLUE);
3679
3680 roboto.setBaselineShift(0.0f);
3681 builder.pushStyle(roboto);
3682 builder.addText("Notice that shadows and decorations are shifted if there is a text with ");
3683 assyrian.setBaselineShift(.0f);
3684 builder.pushStyle(assyrian);
3685 builder.addText("baseline shifts:\n");
3686
3687 assyrian.setDecoration(TextDecoration::kNoDecoration);
3688
3689 roboto.setBaselineShift(0.0f);
3690 builder.pushStyle(roboto);
3691 builder.addText("Zero baseline shift text ");
3692
3693 assyrian.setBaselineShift(20.0f);
3694 builder.pushStyle(assyrian);
3695 builder.addText("Down20");
3696
3697 roboto.setBaselineShift(40.0f);
3698 builder.pushStyle(roboto);
3699 builder.addText("Down40");
3700
3701 assyrian.setBaselineShift(60.0f);
3702 builder.pushStyle(assyrian);
3703 builder.addText("Down60");
3704
3705 roboto.setBaselineShift(40.0f);
3706 builder.pushStyle(roboto);
3707 builder.addText("Down40");
3708
3709 assyrian.setBaselineShift(20.0f);
3710 builder.pushStyle(assyrian);
3711 builder.addText("Down20");
3712
3713 roboto.setBaselineShift(0.0f);
3714 builder.pushStyle(roboto);
3715 builder.addText(" Zero baseline shift text\n");
3716
3717 assyrian.resetShadows();
3718 assyrian.setDecorationStyle(TextDecorationStyle::kSolid);
3719 assyrian.setDecoration(TextDecoration::kUnderline);
3720 assyrian.setDecorationColor(SK_ColorBLUE);
3721
3722 roboto.setBaselineShift(0.0f);
3723 builder.pushStyle(roboto);
3724 builder.addText("Zero baseline shift text ");
3725
3726 assyrian.setBaselineShift(-20.0f);
3727 builder.pushStyle(assyrian);
3728 builder.addText("Up20");
3729
3730 roboto.setBaselineShift(-40.0f);
3731 builder.pushStyle(roboto);
3732 builder.addText("Up40");
3733
3734 assyrian.setBaselineShift(-60.0f);
3735 builder.pushStyle(assyrian);
3736 builder.addText("Up60");
3737
3738 roboto.setBaselineShift(-40.0f);
3739 builder.pushStyle(roboto);
3740 builder.addText("Up40");
3741
3742 assyrian.setBaselineShift(-20.0f);
3743 builder.pushStyle(assyrian);
3744 builder.addText("Up20");
3745
3746 roboto.setBaselineShift(-0.0f);
3747 builder.pushStyle(roboto);
3748 builder.addText(" Zero baseline shift text");
3749
3750 auto paragraph = builder.Build();
3751 paragraph->layout(SK_ScalarInfinity);
3752 paragraph->paint(canvas, 0, 0);
3753 }
3754
3755 private:
3756 using INHERITED = Sample;
3757 };
3758
3759 } // namespace
3760
3761 //////////////////////////////////////////////////////////////////////////////
3762 DEF_SAMPLE(return new ParagraphView1();)
3763 DEF_SAMPLE(return new ParagraphView2();)
3764 DEF_SAMPLE(return new ParagraphView3();)
3765 DEF_SAMPLE(return new ParagraphView4();)
3766 DEF_SAMPLE(return new ParagraphView5();)
3767 DEF_SAMPLE(return new ParagraphView6();)
3768 DEF_SAMPLE(return new ParagraphView7();)
3769 DEF_SAMPLE(return new ParagraphView8();)
3770 DEF_SAMPLE(return new ParagraphView9();)
3771 DEF_SAMPLE(return new ParagraphView10();)
3772 DEF_SAMPLE(return new ParagraphView11();)
3773 DEF_SAMPLE(return new ParagraphView12();)
3774 DEF_SAMPLE(return new ParagraphView14();)
3775 DEF_SAMPLE(return new ParagraphView15();)
3776 DEF_SAMPLE(return new ParagraphView16();)
3777 DEF_SAMPLE(return new ParagraphView17();)
3778 DEF_SAMPLE(return new ParagraphView18();)
3779 DEF_SAMPLE(return new ParagraphView19();)
3780 DEF_SAMPLE(return new ParagraphView20();)
3781 DEF_SAMPLE(return new ParagraphView21();)
3782 DEF_SAMPLE(return new ParagraphView22();)
3783 DEF_SAMPLE(return new ParagraphView23();)
3784 DEF_SAMPLE(return new ParagraphView24();)
3785 DEF_SAMPLE(return new ParagraphView25();)
3786 DEF_SAMPLE(return new ParagraphView26();)
3787 DEF_SAMPLE(return new ParagraphView27();)
3788 DEF_SAMPLE(return new ParagraphView28();)
3789 DEF_SAMPLE(return new ParagraphView29();)
3790 DEF_SAMPLE(return new ParagraphView30();)
3791 DEF_SAMPLE(return new ParagraphView31();)
3792 DEF_SAMPLE(return new ParagraphView32();)
3793 DEF_SAMPLE(return new ParagraphView33();)
3794 DEF_SAMPLE(return new ParagraphView34();)
3795 DEF_SAMPLE(return new ParagraphView35();)
3796 DEF_SAMPLE(return new ParagraphView36();)
3797 DEF_SAMPLE(return new ParagraphView37();)
3798 DEF_SAMPLE(return new ParagraphView38();)
3799 DEF_SAMPLE(return new ParagraphView39();)
3800 DEF_SAMPLE(return new ParagraphView41();)
3801 DEF_SAMPLE(return new ParagraphView42();)
3802 DEF_SAMPLE(return new ParagraphView43();)
3803 DEF_SAMPLE(return new ParagraphView44();)
3804 DEF_SAMPLE(return new ParagraphView45();)
3805 DEF_SAMPLE(return new ParagraphView46();)
3806 DEF_SAMPLE(return new ParagraphView47();)
3807 DEF_SAMPLE(return new ParagraphView48();)
3808 DEF_SAMPLE(return new ParagraphView49();)
3809 DEF_SAMPLE(return new ParagraphView50();)
3810 DEF_SAMPLE(return new ParagraphView51();)
3811 DEF_SAMPLE(return new ParagraphView52();)
3812 DEF_SAMPLE(return new ParagraphView53();)
3813 DEF_SAMPLE(return new ParagraphView54();)
3814 DEF_SAMPLE(return new ParagraphView55();)
3815 DEF_SAMPLE(return new ParagraphView56();)
3816 DEF_SAMPLE(return new ParagraphView57();)
3817 DEF_SAMPLE(return new ParagraphView58();)
3818 DEF_SAMPLE(return new ParagraphView59();)
3819 DEF_SAMPLE(return new ParagraphView60();)
3820 DEF_SAMPLE(return new ParagraphView61();)
3821 DEF_SAMPLE(return new ParagraphView62();)
3822 DEF_SAMPLE(return new ParagraphView63();)
3823