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