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