blob: f1a666f26f49c7bd496dbbc22633180d5b57bf54 [file] [log] [blame]
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001// Copyright 2019 Google LLC.
Julia Lavrovaa3552c52019-05-30 16:12:56 -04002#include "include/core/SkCanvas.h"
3#include "include/core/SkColorFilter.h"
4#include "include/core/SkColorPriv.h"
5#include "include/core/SkGraphics.h"
6#include "include/core/SkPath.h"
7#include "include/core/SkRegion.h"
8#include "include/core/SkShader.h"
9#include "include/core/SkStream.h"
10#include "include/core/SkTextBlob.h"
11#include "include/core/SkTime.h"
12#include "include/core/SkTypeface.h"
Julia Lavrovaa3552c52019-05-30 16:12:56 -040013#include "include/effects/SkGradientShader.h"
14#include "include/utils/SkRandom.h"
15#include "modules/skparagraph/include/Paragraph.h"
Julia Lavrova6e6333f2019-06-17 10:34:10 -040016#include "modules/skparagraph/include/TypefaceFontProvider.h"
Julia Lavrovaa3552c52019-05-30 16:12:56 -040017#include "modules/skparagraph/src/ParagraphBuilderImpl.h"
18#include "modules/skparagraph/src/ParagraphImpl.h"
Julia Lavrova9af5cc42019-06-19 13:32:01 -040019#include "modules/skparagraph/utils/TestFontCollection.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040020#include "samplecode/Sample.h"
Julia Lavrovaa3552c52019-05-30 16:12:56 -040021#include "src/core/SkOSFile.h"
22#include "src/shaders/SkColorShader.h"
Julia Lavrova2e30fde2019-10-09 09:43:02 -040023#include "src/utils/SkOSPath.h"
Julia Lavrovaa3552c52019-05-30 16:12:56 -040024#include "src/utils/SkUTF.h"
25#include "tools/Resources.h"
26
27using namespace skia::textlayout;
28namespace {
29
Mike Reed21a940d2019-07-23 10:11:03 -040030class ParagraphView_Base : public Sample {
31protected:
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -040032 sk_sp<TestFontCollection> getFontCollection() {
33 // If we reset font collection we need to reset paragraph cache
34 static sk_sp<TestFontCollection> fFC = nullptr;
35 if (fFC == nullptr) {
Julia Lavrova2e30fde2019-10-09 09:43:02 -040036 fFC = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -040037 }
38 return fFC;
Mike Reed21a940d2019-07-23 10:11:03 -040039 }
40};
41
Julia Lavrovaa3552c52019-05-30 16:12:56 -040042sk_sp<SkShader> setgrad(const SkRect& r, SkColor c0, SkColor c1) {
43 SkColor colors[] = {c0, c1};
44 SkPoint pts[] = {{r.fLeft, r.fTop}, {r.fRight, r.fTop}};
45 return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
46}
Julia Lavrova2e30fde2019-10-09 09:43:02 -040047/*
48void writeHtml(const char* name, Paragraph* paragraph) {
49 SkString tmpDir = skiatest::GetTmpDir();
50 if (!tmpDir.isEmpty()) {
51 SkString path = SkOSPath::Join(tmpDir.c_str(), name);
52 SkFILEWStream file(path.c_str());
53 file.write(nullptr, 0);
54 }
55}
56*/
Julia Lavrovaa3552c52019-05-30 16:12:56 -040057} // namespace
58
Mike Reed21a940d2019-07-23 10:11:03 -040059class ParagraphView1 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -040060protected:
Hal Canary8a027312019-07-03 10:55:44 -040061 SkString name() override { return SkString("Paragraph1"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -040062
63 void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) {
64 const std::vector<
65 std::tuple<std::string, bool, bool, int, SkColor, SkColor, bool, TextDecorationStyle>>
66 gParagraph = {{"monospace", true, false, 14, SK_ColorWHITE, SK_ColorRED, true,
67 TextDecorationStyle::kDashed},
68 {"Assyrian", false, false, 20, SK_ColorWHITE, SK_ColorBLUE, false,
69 TextDecorationStyle::kDotted},
70 {"serif", true, true, 10, SK_ColorWHITE, SK_ColorRED, true,
71 TextDecorationStyle::kDouble},
72 {"Arial", false, true, 16, SK_ColorGRAY, SK_ColorGREEN, true,
73 TextDecorationStyle::kSolid},
74 {"sans-serif", false, false, 8, SK_ColorWHITE, SK_ColorRED, false,
75 TextDecorationStyle::kWavy}};
76 SkAutoCanvasRestore acr(canvas, true);
77
78 canvas->clipRect(SkRect::MakeWH(w, h));
79 canvas->drawColor(SK_ColorWHITE);
80
81 SkScalar margin = 20;
82
83 SkPaint paint;
84 paint.setAntiAlias(true);
85 paint.setColor(fg);
86
87 SkPaint blue;
88 blue.setColor(SK_ColorBLUE);
89
90 TextStyle defaultStyle;
91 defaultStyle.setBackgroundColor(blue);
92 defaultStyle.setForegroundColor(paint);
93 ParagraphStyle paraStyle;
94
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -040095 auto fontCollection = sk_make_sp<FontCollection>();
96 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
Julia Lavrovaa3552c52019-05-30 16:12:56 -040097 for (auto i = 1; i < 5; ++i) {
98 defaultStyle.setFontSize(24 * i);
99 paraStyle.setTextStyle(defaultStyle);
Julia Lavrova5207f352019-06-21 12:22:32 -0400100 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400101 std::string name = "Paragraph: " + std::to_string(24 * i);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400102 builder.addText(name.c_str(), name.length());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400103 for (auto para : gParagraph) {
104 TextStyle style;
105 style.setFontFamilies({SkString(std::get<0>(para).c_str())});
106 SkFontStyle fontStyle(std::get<1>(para) ? SkFontStyle::Weight::kBold_Weight
107 : SkFontStyle::Weight::kNormal_Weight,
108 SkFontStyle::Width::kNormal_Width,
109 std::get<2>(para) ? SkFontStyle::Slant::kItalic_Slant
110 : SkFontStyle::Slant::kUpright_Slant);
111 style.setFontStyle(fontStyle);
112 style.setFontSize(std::get<3>(para) * i);
113 SkPaint background;
114 background.setColor(std::get<4>(para));
115 style.setBackgroundColor(background);
116 SkPaint foreground;
117 foreground.setColor(std::get<5>(para));
118 foreground.setAntiAlias(true);
119 style.setForegroundColor(foreground);
120 if (std::get<6>(para)) {
121 style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(5, 5), 2));
122 }
123
124 auto decoration = (i % 4);
125 if (decoration == 3) {
126 decoration = 4;
127 }
128
129 bool test = (TextDecoration)decoration != TextDecoration::kNoDecoration;
130 std::string deco = std::to_string((int)decoration);
131 if (test) {
132 style.setDecoration((TextDecoration)decoration);
133 style.setDecorationStyle(std::get<7>(para));
134 style.setDecorationColor(std::get<5>(para));
135 }
136 builder.pushStyle(style);
137 std::string name = " " + std::get<0>(para) + " " +
138 (std::get<1>(para) ? ", bold" : "") +
139 (std::get<2>(para) ? ", italic" : "") + " " +
140 std::to_string(std::get<3>(para) * i) +
141 (std::get<4>(para) != bg ? ", background" : "") +
142 (std::get<5>(para) != fg ? ", foreground" : "") +
143 (std::get<6>(para) ? ", shadow" : "") +
144 (test ? ", decorations " + deco : "") + ";";
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400145 builder.addText(name.c_str(), name.length());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400146 builder.pop();
147 }
148
149 auto paragraph = builder.Build();
150 paragraph->layout(w - margin * 2);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400151 paragraph->paint(canvas, margin, margin);
152
153 canvas->translate(0, paragraph->getHeight());
154 }
155 }
156
157 void onDrawContent(SkCanvas* canvas) override {
158 drawTest(canvas, this->width(), this->height(), SK_ColorRED, SK_ColorWHITE);
159 }
160
161private:
162
163 typedef Sample INHERITED;
164};
165
Mike Reed21a940d2019-07-23 10:11:03 -0400166class ParagraphView2 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400167protected:
Hal Canary8a027312019-07-03 10:55:44 -0400168 SkString name() override { return SkString("Paragraph2"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400169
170 void drawCode(SkCanvas* canvas, SkScalar w, SkScalar h) {
171 SkPaint comment;
172 comment.setColor(SK_ColorGRAY);
173 SkPaint constant;
174 constant.setColor(SK_ColorMAGENTA);
175 SkPaint null;
176 null.setColor(SK_ColorMAGENTA);
177 SkPaint literal;
178 literal.setColor(SK_ColorGREEN);
179 SkPaint code;
180 code.setColor(SK_ColorDKGRAY);
181 SkPaint number;
182 number.setColor(SK_ColorBLUE);
183 SkPaint name;
184 name.setColor(SK_ColorRED);
185
186 SkPaint white;
187 white.setColor(SK_ColorWHITE);
188
189 TextStyle defaultStyle;
190 defaultStyle.setBackgroundColor(white);
191 defaultStyle.setForegroundColor(code);
192 defaultStyle.setFontFamilies({SkString("monospace")});
193 defaultStyle.setFontSize(30);
194 ParagraphStyle paraStyle;
195 paraStyle.setTextStyle(defaultStyle);
196
Julia Lavrova5207f352019-06-21 12:22:32 -0400197 auto fontCollection = sk_make_sp<FontCollection>();
198 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
199 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400200
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400201 const char* text1 = "RaisedButton";
202 const char* text2 = "(\n";
203 const char* text3 = " child: ";
204 const char* text4 = "const";
205 const char* text5 = "Text";
206 const char* text6 = "'BUTTON TITLE'";
207 const char* text7 = "),\n";
208
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400209 builder.pushStyle(style(name));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400210 builder.addText(text1, strlen(text1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400211 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400212 builder.addText(text2, strlen(text2));
213 builder.addText(text3, strlen(text3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400214 builder.pushStyle(style(constant));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400215 builder.addText(text4, strlen(text4));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400216 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400217 builder.addText(" ", 1);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400218 builder.pushStyle(style(name));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400219 builder.addText(text5, strlen(text5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400220 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400221 builder.addText("(", 1);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400222 builder.pushStyle(style(literal));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400223 builder.addText(text6, strlen(text6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400224 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400225 builder.addText(text7, strlen(text7));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400226
227 auto paragraph = builder.Build();
228 paragraph->layout(w - 20);
229
230 paragraph->paint(canvas, 20, 20);
231 }
232
233 TextStyle style(SkPaint paint) {
234 TextStyle style;
235 paint.setAntiAlias(true);
236 style.setForegroundColor(paint);
237 style.setFontFamilies({SkString("monospace")});
238 style.setFontSize(30);
239
240 return style;
241 }
242
Julia Lavrova5207f352019-06-21 12:22:32 -0400243 void drawText(SkCanvas* canvas, SkScalar w, SkScalar h, std::vector<const char*>& text,
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400244 SkColor fg = SK_ColorDKGRAY, SkColor bg = SK_ColorWHITE,
245 const char* ff = "sans-serif", SkScalar fs = 24,
246 size_t lineLimit = 30,
247 const std::u16string& ellipsis = u"\u2026") {
248 SkAutoCanvasRestore acr(canvas, true);
249
250 canvas->clipRect(SkRect::MakeWH(w, h));
251 canvas->drawColor(bg);
252
253 SkScalar margin = 20;
254
255 SkPaint paint;
256 paint.setAntiAlias(true);
257 paint.setColor(fg);
258
259 SkPaint blue;
260 blue.setColor(SK_ColorBLUE);
261
262 SkPaint background;
263 background.setColor(bg);
264
265 TextStyle style;
266 style.setBackgroundColor(blue);
267 style.setForegroundColor(paint);
268 style.setFontFamilies({SkString(ff)});
269 style.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight,
270 SkFontStyle::kNormal_Width,
271 SkFontStyle::kUpright_Slant));
272 style.setFontSize(fs);
273 ParagraphStyle paraStyle;
274 paraStyle.setTextStyle(style);
275 paraStyle.setMaxLines(lineLimit);
276
277 paraStyle.setEllipsis(ellipsis);
278 TextStyle defaultStyle;
279 defaultStyle.setFontSize(20);
280 paraStyle.setTextStyle(defaultStyle);
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400281 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400282
283 SkPaint foreground;
284 foreground.setColor(fg);
285 style.setForegroundColor(foreground);
286 style.setBackgroundColor(background);
287
288 for (auto& part : text) {
289 builder.pushStyle(style);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400290 builder.addText(part, strlen(part));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400291 builder.pop();
292 }
293
294 auto paragraph = builder.Build();
295 paragraph->layout(w - margin * 2);
296 paragraph->paint(canvas, margin, margin);
297
298 canvas->translate(0, paragraph->getHeight() + margin);
299 }
300
301 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
302 TextAlign align) {
303 SkAutoCanvasRestore acr(canvas, true);
304
305 canvas->clipRect(SkRect::MakeWH(w, h));
306 canvas->drawColor(SK_ColorWHITE);
307
308 SkScalar margin = 20;
309
310 SkPaint paint;
311 paint.setAntiAlias(true);
312 paint.setColor(SK_ColorBLUE);
313
314 SkPaint gray;
315 gray.setColor(SK_ColorLTGRAY);
316
317 TextStyle style;
318 style.setBackgroundColor(gray);
319 style.setForegroundColor(paint);
320 style.setFontFamilies({SkString("Arial")});
321 style.setFontSize(30);
322 ParagraphStyle paraStyle;
323 paraStyle.setTextStyle(style);
324 paraStyle.setTextAlign(align);
325
Julia Lavrova5207f352019-06-21 12:22:32 -0400326 auto fontCollection = sk_make_sp<FontCollection>();
327 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
328 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400329 builder.addText(text.c_str(), text.length());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400330
331 auto paragraph = builder.Build();
332 paragraph->layout(w - margin * 2);
333 paragraph->layout(w - margin);
334 paragraph->paint(canvas, margin, margin);
335
336 canvas->translate(0, paragraph->getHeight() + margin);
337 }
338
339 void onDrawContent(SkCanvas* canvas) override {
Julia Lavrova5207f352019-06-21 12:22:32 -0400340 std::vector<const char*> cupertino = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400341 "google_logogoogle_gsuper_g_logo 1 "
342 "google_logogoogle_gsuper_g_logo 12 "
343 "google_logogoogle_gsuper_g_logo 123 "
344 "google_logogoogle_gsuper_g_logo 1234 "
345 "google_logogoogle_gsuper_g_logo 12345 "
346 "google_logogoogle_gsuper_g_logo 123456 "
347 "google_logogoogle_gsuper_g_logo 1234567 "
348 "google_logogoogle_gsuper_g_logo 12345678 "
349 "google_logogoogle_gsuper_g_logo 123456789 "
350 "google_logogoogle_gsuper_g_logo 1234567890 "
351 "google_logogoogle_gsuper_g_logo 123456789 "
352 "google_logogoogle_gsuper_g_logo 12345678 "
353 "google_logogoogle_gsuper_g_logo 1234567 "
354 "google_logogoogle_gsuper_g_logo 123456 "
355 "google_logogoogle_gsuper_g_logo 12345 "
356 "google_logogoogle_gsuper_g_logo 1234 "
357 "google_logogoogle_gsuper_g_logo 123 "
358 "google_logogoogle_gsuper_g_logo 12 "
359 "google_logogoogle_gsuper_g_logo 1 "
360 "google_logogoogle_gsuper_g_logo "
361 "google_logogoogle_gsuper_g_logo "
362 "google_logogoogle_gsuper_g_logo "
363 "google_logogoogle_gsuper_g_logo "
364 "google_logogoogle_gsuper_g_logo "
365 "google_logogoogle_gsuper_g_logo"};
Julia Lavrova5207f352019-06-21 12:22:32 -0400366 std::vector<const char*> text = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400367 "My neighbor came over to say,\n"
368 "Although not in a neighborly way,\n\n"
369 "That he'd knock me around,\n\n\n"
370 "If I didn't stop the sound,\n\n\n\n"
371 "Of the classical music I play."};
372
Julia Lavrova5207f352019-06-21 12:22:32 -0400373 std::vector<const char*> long_word = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400374 "A_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
375 "very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
376 "very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
377 "very_very_very_very_very_very_very_long_text"};
378
Julia Lavrova5207f352019-06-21 12:22:32 -0400379 std::vector<const char*> very_long = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400380 "A very very very very very very very very very very very very very very very very "
381 "very very very very very very very very very very very very very very very very "
382 "very very very very very very very very very very very very very very very very "
383 "very very very very very very very long text"};
384
Julia Lavrova5207f352019-06-21 12:22:32 -0400385 std::vector<const char*> very_word = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400386 "A very_very_very_very_very_very_very_very_very_very "
387 "very_very_very_very_very_very_very_very_very_very very very very very very very "
388 "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 long text"};
390
391 SkScalar width = this->width() / 5;
392 SkScalar height = this->height();
393 drawText(canvas, width, height, long_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
394 canvas->translate(width, 0);
395 drawText(canvas, width, height, very_long, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
396 canvas->translate(width, 0);
397 drawText(canvas, width, height, very_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
398 canvas->translate(width, 0);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400399 drawText(canvas, width, height / 2, text, SK_ColorBLACK, SK_ColorWHITE, "Roboto", 20, 100,
400 u"\u2026");
401 canvas->translate(0, height / 2);
402 drawCode(canvas, width, height / 2);
403 canvas->translate(width, -height / 2);
404
405 drawText(canvas, width, height, cupertino, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
406 }
407
408private:
409 typedef Sample INHERITED;
410};
411
Mike Reed21a940d2019-07-23 10:11:03 -0400412class ParagraphView3 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400413protected:
Hal Canary8a027312019-07-03 10:55:44 -0400414 SkString name() override { return SkString("Paragraph3"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400415
416 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
417 TextAlign align, size_t lineLimit = std::numeric_limits<size_t>::max(),
418 bool RTL = false, SkColor background = SK_ColorGRAY,
419 const std::u16string& ellipsis = u"\u2026") {
420 SkAutoCanvasRestore acr(canvas, true);
421
422 canvas->clipRect(SkRect::MakeWH(w, h));
423 canvas->drawColor(SK_ColorWHITE);
424
425 SkScalar margin = 20;
426
427 SkPaint paint;
428 paint.setAntiAlias(true);
429 paint.setColor(SK_ColorBLACK);
430
431 SkPaint gray;
432 gray.setColor(background);
433
434 SkPaint yellow;
435 yellow.setColor(SK_ColorYELLOW);
436
437 TextStyle style;
438 style.setBackgroundColor(gray);
439 style.setForegroundColor(paint);
440 style.setFontFamilies({SkString("sans-serif")});
441 style.setFontSize(30);
442 ParagraphStyle paraStyle;
443 paraStyle.setTextStyle(style);
444 paraStyle.setTextAlign(align);
445 paraStyle.setMaxLines(lineLimit);
446 paraStyle.setEllipsis(ellipsis);
447 // paraStyle.setTextDirection(RTL ? SkTextDirection::rtl : SkTextDirection::ltr);
448
Julia Lavrova5207f352019-06-21 12:22:32 -0400449 auto fontCollection = sk_make_sp<FontCollection>();
450 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
451 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400452 if (RTL) {
453 builder.addText(mirror(text));
454 } else {
455 builder.addText(normal(text));
456 }
457
458 canvas->drawRect(SkRect::MakeXYWH(margin, margin, w - margin * 2, h - margin * 2), yellow);
459 auto paragraph = builder.Build();
460 paragraph->layout(w - margin * 2);
461 paragraph->paint(canvas, margin, margin);
462 }
463
464 std::u16string mirror(const std::string& text) {
465 std::u16string result;
466 result += u"\u202E";
467 // for (auto i = text.size(); i > 0; --i) {
468 // result += text[i - 1];
469 //}
470
471 for (auto i = text.size(); i > 0; --i) {
472 auto ch = text[i - 1];
473 if (ch == ',') {
474 result += u"!";
475 } else if (ch == '.') {
476 result += u"!";
477 } else {
478 result += ch;
479 }
480 }
481
482 result += u"\u202C";
483 return result;
484 }
485
486 std::u16string normal(const std::string& text) {
487 std::u16string result;
488 result += u"\u202D";
489 for (auto ch : text) {
490 result += ch;
491 }
492 result += u"\u202C";
493 return result;
494 }
495
496 void onDrawContent(SkCanvas* canvas) override {
497 const std::string options = // { "open-source open-source open-source open-source" };
498 {"Flutter is an open-source project to help developers "
499 "build high-performance, high-fidelity, mobile apps for "
500 "iOS and Android "
501 "from a single codebase. This design lab is a playground "
502 "and showcase of Flutter's many widgets, behaviors, "
503 "animations, layouts, and more."};
504
505 canvas->drawColor(SK_ColorDKGRAY);
506 SkScalar width = this->width() / 4;
507 SkScalar height = this->height() / 2;
508
509 const std::string line =
510 "World domination is such an ugly phrase - I prefer to call it world optimisation";
511
512 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, false, SK_ColorLTGRAY);
513 canvas->translate(width, 0);
514 drawLine(canvas, width, height, line, TextAlign::kRight, 2, false, SK_ColorLTGRAY);
515 canvas->translate(width, 0);
516 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, false, SK_ColorLTGRAY);
517 canvas->translate(width, 0);
518 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, false, SK_ColorLTGRAY);
519 canvas->translate(-width * 3, height);
520
521 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, true, SK_ColorLTGRAY);
522 canvas->translate(width, 0);
523 drawLine(canvas, width, height, line, TextAlign::kRight, 2, true, SK_ColorLTGRAY);
524 canvas->translate(width, 0);
525 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, true, SK_ColorLTGRAY);
526 canvas->translate(width, 0);
527 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, true, SK_ColorLTGRAY);
528 canvas->translate(width, 0);
529 }
530
531private:
532 typedef Sample INHERITED;
533};
534
Mike Reed21a940d2019-07-23 10:11:03 -0400535class ParagraphView4 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400536protected:
Hal Canary8a027312019-07-03 10:55:44 -0400537 SkString name() override { return SkString("Paragraph4"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400538
539 void drawFlutter(SkCanvas* canvas, SkScalar w, SkScalar h,
540 const char* ff = "Google Sans", SkScalar fs = 30,
541 size_t lineLimit = std::numeric_limits<size_t>::max(),
542 const std::u16string& ellipsis = u"\u2026") {
543 SkAutoCanvasRestore acr(canvas, true);
544
545 canvas->clipRect(SkRect::MakeWH(w, h));
546
547 SkScalar margin = 20;
548
549 SkPaint black;
550 black.setAntiAlias(true);
551 black.setColor(SK_ColorBLACK);
552
553 SkPaint blue;
554 blue.setAntiAlias(true);
555 blue.setColor(SK_ColorBLUE);
556
557 SkPaint red;
558 red.setAntiAlias(true);
559 red.setColor(SK_ColorRED);
560
561 SkPaint green;
562 green.setAntiAlias(true);
563 green.setColor(SK_ColorGREEN);
564
565 SkPaint gray;
566 gray.setColor(SK_ColorLTGRAY);
567
568 SkPaint yellow;
569 yellow.setColor(SK_ColorYELLOW);
570
571 SkPaint magenta;
572 magenta.setAntiAlias(true);
573 magenta.setColor(SK_ColorMAGENTA);
574
575 TextStyle style;
576 style.setFontFamilies({SkString(ff)});
577 style.setFontSize(fs);
578
579 TextStyle style0;
580 style0.setForegroundColor(black);
581 style0.setBackgroundColor(gray);
582 style0.setFontFamilies({SkString(ff)});
583 style0.setFontSize(fs);
584 style0.setDecoration(TextDecoration::kUnderline);
585 style0.setDecorationStyle(TextDecorationStyle::kDouble);
586 style0.setDecorationColor(SK_ColorBLACK);
587
588 TextStyle style1;
589 style1.setForegroundColor(blue);
590 style1.setBackgroundColor(yellow);
591 style1.setFontFamilies({SkString(ff)});
592 style1.setFontSize(fs);
593 style1.setDecoration(TextDecoration::kOverline);
594 style1.setDecorationStyle(TextDecorationStyle::kWavy);
595 style1.setDecorationColor(SK_ColorBLACK);
596
597 TextStyle style2;
598 style2.setForegroundColor(red);
599 style2.setFontFamilies({SkString(ff)});
600 style2.setFontSize(fs);
601
602 TextStyle style3;
603 style3.setForegroundColor(green);
604 style3.setFontFamilies({SkString(ff)});
605 style3.setFontSize(fs);
606
607 TextStyle style4;
608 style4.setForegroundColor(magenta);
609 style4.setFontFamilies({SkString(ff)});
610 style4.setFontSize(fs);
611
612 ParagraphStyle paraStyle;
613 paraStyle.setTextStyle(style);
614 paraStyle.setMaxLines(lineLimit);
615
616 paraStyle.setEllipsis(ellipsis);
617
618 const char* logo1 = "google_";
619 const char* logo2 = "logo";
620 const char* logo3 = "go";
621 const char* logo4 = "ogle_logo";
622 const char* logo5 = "google_lo";
623 const char* logo6 = "go";
624 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400625 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400626
627 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400628 builder.addText(logo1, strlen(logo1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400629 builder.pop();
630 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400631 builder.addText(logo2, strlen(logo2));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400632 builder.pop();
633
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400634 builder.addText(" ", 1);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400635
636 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400637 builder.addText(logo3, strlen(logo3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400638 builder.pop();
639 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400640 builder.addText(logo4, strlen(logo4));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400641 builder.pop();
642
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400643 builder.addText(" ", 1);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400644
645 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400646 builder.addText(logo5, strlen(logo5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400647 builder.pop();
648 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400649 builder.addText(logo6, strlen(logo6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400650 builder.pop();
651
652 auto paragraph = builder.Build();
653 paragraph->layout(w - margin * 2);
654 paragraph->paint(canvas, margin, margin);
655 canvas->translate(0, h + margin);
656 }
657 }
658
659 void onDrawContent(SkCanvas* canvas) override {
660 canvas->drawColor(SK_ColorWHITE);
661 SkScalar width = this->width();
662 SkScalar height = this->height();
663
664 drawFlutter(canvas, width, height / 2);
665 }
666
667private:
668 typedef Sample INHERITED;
669};
670
Mike Reed21a940d2019-07-23 10:11:03 -0400671class ParagraphView5 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400672protected:
Julia Lavrova5207f352019-06-21 12:22:32 -0400673 SkString name() override { return SkString("Paragraph5"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400674
675 void bidi(SkCanvas* canvas, SkScalar w, SkScalar h, const std::u16string& text,
676 const std::u16string& expected, size_t lineLimit = std::numeric_limits<size_t>::max(),
677 const char* ff = "Roboto", SkScalar fs = 30,
678 const std::u16string& ellipsis = u"\u2026") {
679 SkAutoCanvasRestore acr(canvas, true);
680
681 canvas->clipRect(SkRect::MakeWH(w, h));
682
683 SkScalar margin = 20;
684
685 SkPaint black;
686 black.setColor(SK_ColorBLACK);
687 SkPaint gray;
688 gray.setColor(SK_ColorLTGRAY);
689
690 TextStyle style;
691 style.setForegroundColor(black);
692 style.setFontFamilies({SkString(ff)});
693 style.setFontSize(fs);
694
695 TextStyle style0;
696 style0.setForegroundColor(black);
697 style0.setFontFamilies({SkString(ff)});
698 style0.setFontSize(fs);
699 style0.setFontStyle(SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
700 SkFontStyle::kItalic_Slant));
701
702 TextStyle style1;
703 style1.setForegroundColor(gray);
704 style1.setFontFamilies({SkString(ff)});
705 style1.setFontSize(fs);
706 style1.setFontStyle(SkFontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
707 SkFontStyle::kUpright_Slant));
708
709 ParagraphStyle paraStyle;
710 paraStyle.setTextStyle(style);
711 paraStyle.setMaxLines(lineLimit);
712
713 paraStyle.setEllipsis(ellipsis);
714
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400715 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400716
717 if (text.empty()) {
718 const std::u16string text0 = u"\u202Dabc";
719 const std::u16string text1 = u"\u202EFED";
720 const std::u16string text2 = u"\u202Dghi";
721 const std::u16string text3 = u"\u202ELKJ";
722 const std::u16string text4 = u"\u202Dmno";
723 builder.pushStyle(style0);
724 builder.addText(text0);
725 builder.pop();
726 builder.pushStyle(style1);
727 builder.addText(text1);
728 builder.pop();
729 builder.pushStyle(style0);
730 builder.addText(text2);
731 builder.pop();
732 builder.pushStyle(style1);
733 builder.addText(text3);
734 builder.pop();
735 builder.pushStyle(style0);
736 builder.addText(text4);
737 builder.pop();
738 } else {
739 // icu::UnicodeString unicode((UChar*) text.data(), SkToS32(text.size()));
740 // std::string str;
741 // unicode.toUTF8String(str);
742 // SkDebugf("Text: %s\n", str.c_str());
743 builder.addText(text + expected);
744 }
745
746 auto paragraph = builder.Build();
747 paragraph->layout(w - margin * 2);
748 paragraph->paint(canvas, margin, margin);
749 }
750
751 void onDrawContent(SkCanvas* canvas) override {
752 canvas->drawColor(SK_ColorWHITE);
753 SkScalar width = this->width();
754 SkScalar height = this->height() / 8;
755
756 const std::u16string text1 =
757 u"A \u202ENAC\u202Cner, exceedingly \u202ENAC\u202Cny,\n"
758 "One morning remarked to his granny:\n"
759 "A \u202ENAC\u202Cner \u202ENAC\u202C \u202ENAC\u202C,\n"
760 "Anything that he \u202ENAC\u202C,\n"
761 "But a \u202ENAC\u202Cner \u202ENAC\u202C't \u202ENAC\u202C a \u202ENAC\u202C, "
762 "\u202ENAC\u202C he?";
763 bidi(canvas, width, height * 3, text1, u"", 5);
764 canvas->translate(0, height * 3);
765
766 bidi(canvas, width, height, u"\u2067DETALOSI\u2069", u"");
767 canvas->translate(0, height);
768
769 bidi(canvas, width, height, u"\u202BDEDDEBME\u202C", u"");
770 canvas->translate(0, height);
771
772 bidi(canvas, width, height, u"\u202EEDIRREVO\u202C", u"");
773 canvas->translate(0, height);
774
775 bidi(canvas, width, height, u"\u200FTICILPMI\u200E", u"");
776 canvas->translate(0, height);
777
778 bidi(canvas, width, height, u"123 456 7890 \u202EZYXWV UTS RQP ONM LKJ IHG FED CBA\u202C.",
779 u"", 2);
780 canvas->translate(0, height);
781
782 // bidi(canvas, width, height, u"", u"");
783 // canvas->translate(0, height);
784 }
785
786private:
787 typedef Sample INHERITED;
788};
789
Mike Reed21a940d2019-07-23 10:11:03 -0400790class ParagraphView6 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400791protected:
Julia Lavrova5207f352019-06-21 12:22:32 -0400792 SkString name() override { return SkString("Paragraph6"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400793
794 void hangingS(SkCanvas* canvas, SkScalar w, SkScalar h, SkScalar fs = 60.0) {
795 auto ff = "HangingS";
796
797 canvas->drawColor(SK_ColorLTGRAY);
798
799 SkPaint black;
800 black.setAntiAlias(true);
801 black.setColor(SK_ColorBLACK);
802
803 SkPaint blue;
804 blue.setAntiAlias(true);
805 blue.setColor(SK_ColorBLUE);
806
807 SkPaint red;
808 red.setAntiAlias(true);
809 red.setColor(SK_ColorRED);
810
811 SkPaint green;
812 green.setAntiAlias(true);
813 green.setColor(SK_ColorGREEN);
814
815 SkPaint gray;
816 gray.setColor(SK_ColorCYAN);
817
818 SkPaint yellow;
819 yellow.setColor(SK_ColorYELLOW);
820
821 SkPaint magenta;
822 magenta.setAntiAlias(true);
823 magenta.setColor(SK_ColorMAGENTA);
824
825 SkFontStyle fontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
826 SkFontStyle::kItalic_Slant);
827
828 TextStyle style;
829 style.setFontFamilies({SkString(ff)});
830 style.setFontSize(fs);
831 style.setFontStyle(fontStyle);
832
833 TextStyle style0;
834 style0.setForegroundColor(black);
835 style0.setBackgroundColor(gray);
836 style0.setFontFamilies({SkString(ff)});
837 style0.setFontSize(fs);
838 style0.setFontStyle(fontStyle);
839
840 TextStyle style1;
841 style1.setForegroundColor(blue);
842 style1.setBackgroundColor(yellow);
843 style1.setFontFamilies({SkString(ff)});
844 style1.setFontSize(fs);
845 style1.setFontStyle(fontStyle);
846
847 TextStyle style2;
848 style2.setForegroundColor(red);
849 style2.setFontFamilies({SkString(ff)});
850 style2.setFontSize(fs);
851 style2.setFontStyle(fontStyle);
852
853 TextStyle style3;
854 style3.setForegroundColor(green);
855 style3.setFontFamilies({SkString(ff)});
856 style3.setFontSize(fs);
857 style3.setFontStyle(fontStyle);
858
859 TextStyle style4;
860 style4.setForegroundColor(magenta);
861 style4.setFontFamilies({SkString(ff)});
862 style4.setFontSize(fs);
863 style4.setFontStyle(fontStyle);
864
865 ParagraphStyle paraStyle;
866 paraStyle.setTextStyle(style);
867
868 const char* logo1 = "S";
869 const char* logo2 = "kia";
870 const char* logo3 = "Sk";
871 const char* logo4 = "ia";
872 const char* logo5 = "Ski";
873 const char* logo6 = "a";
874 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400875 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400876
877 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400878 builder.addText(logo1, strlen(logo1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400879 builder.pop();
880 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400881 builder.addText(logo2, strlen(logo2));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400882 builder.pop();
883
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400884 builder.addText(" ", 3);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400885
886 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400887 builder.addText(logo3, strlen(logo3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400888 builder.pop();
889 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400890 builder.addText(logo4, strlen(logo4));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400891 builder.pop();
892
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400893 builder.addText(" ", 3);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400894
895 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400896 builder.addText(logo5, strlen(logo5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400897 builder.pop();
898 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400899 builder.addText(logo6, strlen(logo6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400900 builder.pop();
901
902 auto paragraph = builder.Build();
903 paragraph->layout(w);
904 paragraph->paint(canvas, 40, 40);
905 canvas->translate(0, h);
906 }
907
908 const char* logo11 = "S";
909 const char* logo12 = "S";
910 const char* logo13 = "S";
911 const char* logo14 = "S";
912 const char* logo15 = "S";
913 const char* logo16 = "S";
914 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400915 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400916
917 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400918 builder.addText(logo11, strlen(logo1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400919 builder.pop();
920 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400921 builder.addText(logo12, strlen(logo2));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400922 builder.pop();
923
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400924 builder.addText(" ", 3);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400925
926 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400927 builder.addText(logo13, strlen(logo3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400928 builder.pop();
929 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400930 builder.addText(logo14, strlen(logo4));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400931 builder.pop();
932
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400933 builder.addText(" ", 3);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400934
935 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400936 builder.addText(logo15, strlen(logo5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400937 builder.pop();
938 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400939 builder.addText(logo16, strlen(logo6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400940 builder.pop();
941
942 auto paragraph = builder.Build();
943 paragraph->layout(w);
944 paragraph->paint(canvas, 40, h);
945 canvas->translate(0, h);
946 }
947 }
948
949 void onDrawContent(SkCanvas* canvas) override {
950 canvas->drawColor(SK_ColorWHITE);
951 SkScalar width = this->width();
952 SkScalar height = this->height() / 4;
953
954 hangingS(canvas, width, height);
955 }
956
957private:
958 typedef Sample INHERITED;
959};
960
Mike Reed21a940d2019-07-23 10:11:03 -0400961class ParagraphView7 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400962protected:
Hal Canary8a027312019-07-03 10:55:44 -0400963 SkString name() override { return SkString("Paragraph7"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400964
965 void drawText(SkCanvas* canvas, SkColor background, SkScalar letterSpace, SkScalar w,
966 SkScalar h) {
967 SkAutoCanvasRestore acr(canvas, true);
968 canvas->clipRect(SkRect::MakeWH(w, h));
969 canvas->drawColor(background);
970
971 const char* line =
Julia Lavrovadb9f6692019-08-01 16:02:17 -0400972 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400973
974 ParagraphStyle paragraphStyle;
975 paragraphStyle.setTextAlign(TextAlign::kLeft);
976 paragraphStyle.setMaxLines(10);
977 paragraphStyle.turnHintingOff();
978 TextStyle textStyle;
979 textStyle.setFontFamilies({SkString("Roboto")});
980 textStyle.setFontSize(30);
981 textStyle.setLetterSpacing(letterSpace);
982 textStyle.setColor(SK_ColorBLACK);
983 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
984 SkFontStyle::kUpright_Slant));
985
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400986 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400987 builder.pushStyle(textStyle);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400988 builder.addText(line, strlen(line));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400989 builder.pop();
990
991 auto paragraph = builder.Build();
992 paragraph->layout(w - 20);
993 paragraph->paint(canvas, 10, 10);
994 }
995
996 void onDrawContent(SkCanvas* canvas) override {
997 canvas->drawColor(SK_ColorWHITE);
998
999 auto h = this->height() / 4;
1000 auto w = this->width() / 2;
1001
1002 drawText(canvas, SK_ColorGRAY, 1, w, h);
1003 canvas->translate(0, h);
1004
1005 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
1006 canvas->translate(0, h);
1007
1008 drawText(canvas, SK_ColorCYAN, 3, w, h);
1009 canvas->translate(0, h);
1010
1011 drawText(canvas, SK_ColorGRAY, 4, w, h);
1012 canvas->translate(w, -3 * h);
1013
1014 drawText(canvas, SK_ColorYELLOW, 5, w, h);
1015 canvas->translate(0, h);
1016
1017 drawText(canvas, SK_ColorGREEN, 10, w, h);
1018 canvas->translate(0, h);
1019
1020 drawText(canvas, SK_ColorRED, 15, w, h);
1021 canvas->translate(0, h);
1022
1023 drawText(canvas, SK_ColorBLUE, 20, w, h);
1024 canvas->translate(0, h);
1025 }
1026
1027private:
1028 typedef Sample INHERITED;
1029};
1030
Mike Reed21a940d2019-07-23 10:11:03 -04001031class ParagraphView8 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001032protected:
Julia Lavrovadb9f6692019-08-01 16:02:17 -04001033 SkString name() override { return SkString("Paragraph8"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001034
1035 void drawText(SkCanvas* canvas, SkColor background, SkScalar wordSpace, SkScalar w,
1036 SkScalar h) {
1037 SkAutoCanvasRestore acr(canvas, true);
1038 canvas->clipRect(SkRect::MakeWH(w, h));
1039 canvas->drawColor(background);
1040
1041 const char* line =
Julia Lavrovadb9f6692019-08-01 16:02:17 -04001042 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001043
1044 ParagraphStyle paragraphStyle;
1045 paragraphStyle.setTextAlign(TextAlign::kLeft);
1046 paragraphStyle.setMaxLines(10);
1047 paragraphStyle.turnHintingOff();
1048 TextStyle textStyle;
1049 textStyle.setFontFamilies({SkString("Roboto")});
1050 textStyle.setFontSize(30);
1051 textStyle.setWordSpacing(wordSpace);
1052 textStyle.setColor(SK_ColorBLACK);
1053 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1054 SkFontStyle::kUpright_Slant));
1055
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001056 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001057 builder.pushStyle(textStyle);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -04001058 builder.addText(line, strlen(line));
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001059 builder.pop();
1060
1061 auto paragraph = builder.Build();
1062 paragraph->layout(w - 20);
1063 paragraph->paint(canvas, 10, 10);
1064 }
1065
1066 void onDrawContent(SkCanvas* canvas) override {
1067 canvas->drawColor(SK_ColorWHITE);
1068
1069 auto h = this->height() / 4;
1070 auto w = this->width() / 2;
1071
1072 drawText(canvas, SK_ColorGRAY, 1, w, h);
1073 canvas->translate(0, h);
1074
1075 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
1076 canvas->translate(0, h);
1077
1078 drawText(canvas, SK_ColorCYAN, 3, w, h);
1079 canvas->translate(0, h);
1080
1081 drawText(canvas, SK_ColorGRAY, 4, w, h);
1082 canvas->translate(w, -3 * h);
1083
1084 drawText(canvas, SK_ColorYELLOW, 5, w, h);
1085 canvas->translate(0, h);
1086
1087 drawText(canvas, SK_ColorGREEN, 10, w, h);
1088 canvas->translate(0, h);
1089
1090 drawText(canvas, SK_ColorRED, 15, w, h);
1091 canvas->translate(0, h);
1092
1093 drawText(canvas, SK_ColorBLUE, 20, w, h);
1094 canvas->translate(0, h);
1095 }
1096
1097private:
1098 typedef Sample INHERITED;
1099};
1100
Mike Reed21a940d2019-07-23 10:11:03 -04001101class ParagraphView9 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001102protected:
Hal Canary8a027312019-07-03 10:55:44 -04001103 SkString name() override { return SkString("Paragraph9"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001104
Hal Canary6cc65e12019-07-03 15:53:04 -04001105 bool onChar(SkUnichar uni) override {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001106 switch (uni) {
1107 case 'w':
1108 ++wordSpacing;
1109 return true;
1110 case 'q':
1111 if (wordSpacing > 0) --wordSpacing;
1112 return true;
1113 case 'l':
1114 ++letterSpacing;
1115 return true;
1116 case 'k':
1117 if (letterSpacing > 0) --letterSpacing;
1118 return true;
1119 default:
1120 break;
1121 }
Hal Canary6cc65e12019-07-03 15:53:04 -04001122 return false;
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001123 }
1124
1125 void drawText(SkCanvas* canvas, SkColor background, SkScalar w, SkScalar h) {
1126 SkAutoCanvasRestore acr(canvas, true);
1127 canvas->clipRect(SkRect::MakeWH(w, h));
1128 canvas->drawColor(background);
1129
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001130 auto fontCollection = sk_make_sp<FontCollection>();
1131 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1132 fontCollection->enableFontFallback();
1133
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001134 const char* text =
1135 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1136 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1137 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001138 auto multiplier = 5.67;
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001139 ParagraphStyle paragraphStyle;
1140 paragraphStyle.setTextAlign(TextAlign::kLeft);
1141 paragraphStyle.setMaxLines(10);
1142 paragraphStyle.turnHintingOff();
1143 TextStyle textStyle;
1144 textStyle.setFontFamilies({SkString("Roboto")});
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001145 textStyle.setFontSize(5 * multiplier);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001146 textStyle.setHeight(1.3f);
1147 textStyle.setColor(SK_ColorBLACK);
1148 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1149 SkFontStyle::kUpright_Slant));
1150
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001151 ParagraphBuilderImpl builder(paragraphStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001152 builder.pushStyle(textStyle);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -04001153 builder.addText(text, strlen(text));
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001154 builder.pop();
1155
1156 auto paragraph = builder.Build();
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001157 paragraph->layout(200 * multiplier);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001158
1159 std::vector<size_t> sizes = {0, 1, 2, 8, 19, 21, 22, 30, 150};
1160
1161 std::vector<size_t> colors = {SK_ColorBLUE, SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGREEN,
1162 SK_ColorRED, SK_ColorWHITE, SK_ColorYELLOW, SK_ColorMAGENTA};
1163
1164 RectHeightStyle rect_height_style = RectHeightStyle::kTight;
1165 RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1166
1167 for (size_t i = 0; i < sizes.size() - 1; ++i) {
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001168 size_t from = sizes[i];
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001169 size_t to = sizes[i + 1];
1170 auto boxes = paragraph->getRectsForRange(from, to, rect_height_style, rect_width_style);
1171 if (boxes.empty()) {
1172 continue;
1173 }
1174 for (auto& box : boxes) {
1175 SkPaint paint;
1176 paint.setColor(colors[i % colors.size()]);
1177 paint.setShader(setgrad(box.rect, colors[i % colors.size()], SK_ColorWHITE));
1178 canvas->drawRect(box.rect, paint);
1179 }
1180 }
1181
1182 paragraph->paint(canvas, 0, 0);
1183 }
1184
1185 void onDrawContent(SkCanvas* canvas) override {
1186 canvas->drawColor(SK_ColorWHITE);
1187
1188 auto h = this->height();
1189 auto w = this->width();
1190
1191 drawText(canvas, SK_ColorGRAY, w, h);
1192 }
1193
1194private:
1195 typedef Sample INHERITED;
1196 SkScalar letterSpacing;
1197 SkScalar wordSpacing;
1198};
1199
Mike Reed21a940d2019-07-23 10:11:03 -04001200class ParagraphView10 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001201protected:
Hal Canary8a027312019-07-03 10:55:44 -04001202 SkString name() override { return SkString("Paragraph10"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001203
1204 void onDrawContent(SkCanvas* canvas) override {
1205 canvas->drawColor(SK_ColorWHITE);
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001206 auto multiplier = 5.67;
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001207 const char* text = "English English 字典 字典 😀😃😄 😀😃😄";
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001208
1209 auto fontCollection = sk_make_sp<FontCollection>();
1210 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1211 fontCollection->enableFontFallback();
1212
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001213 ParagraphStyle paragraph_style;
1214 paragraph_style.turnHintingOff();
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001215 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001216
1217 TextStyle text_style;
Julia Lavrova5207f352019-06-21 12:22:32 -04001218 text_style.setFontFamilies({SkString("Roboto"),
1219 SkString("Noto Color Emoji"),
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001220 SkString("Noto Serif CJK JP")});
1221 text_style.setFontSize(10 * multiplier);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001222 text_style.setLetterSpacing(0);
1223 text_style.setWordSpacing(0);
1224 text_style.setColor(SK_ColorBLACK);
1225 text_style.setHeight(1);
1226 builder.pushStyle(text_style);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -04001227 builder.addText(text, strlen(text));
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001228 builder.pop();
1229
1230 auto paragraph = builder.Build();
1231 paragraph->layout(width());
1232
1233 paragraph->paint(canvas, 0, 0);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001234 }
1235
1236private:
1237 typedef Sample INHERITED;
1238};
1239
Mike Reed21a940d2019-07-23 10:11:03 -04001240class ParagraphView11 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001241protected:
Hal Canary8a027312019-07-03 10:55:44 -04001242 SkString name() override { return SkString("Paragraph11"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001243
1244 void onDrawContent(SkCanvas* canvas) override {
1245 canvas->drawColor(SK_ColorWHITE);
Julia Lavrova5207f352019-06-21 12:22:32 -04001246
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001247 auto text = "\U0001f469\U0000200D\U0001f469\U0000200D\U0001f466\U0001f469\U0000200D\U0001f469\U0000200D\U0001f467\U0000200D\U0001f467\U0001f1fa\U0001f1f8";
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001248
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001249 TextStyle text_style;
1250 text_style.setFontFamilies({SkString("Ahem")});
1251 text_style.setColor(SK_ColorBLACK);
1252 text_style.setFontSize(60);
1253 text_style.setLetterSpacing(0);
1254 text_style.setWordSpacing(0);
1255 ParagraphStyle paragraph_style;
1256 paragraph_style.setTextStyle(text_style);
1257
1258 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), true, true);
1259 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1260 builder.addText(text, strlen(text));
1261 auto paragraph = builder.Build();
1262 paragraph->layout(1000);
1263 paragraph->paint(canvas, 0, 0);
1264
1265 struct pair {
1266 unsigned fX;
1267 unsigned fY;
1268 };
1269
1270 pair hit1[] =
1271 {{ 0, 8},{1, 33}, {2, 34}, { 3, 19}, {4, 20},
1272 { 5, 21}, { 6, 22 }, { 7, 23 }, {8, 24 }, { 9, 25},
1273 { 10, 26}, { 11, 27}, {12, 28}, { 13, 21}, {14, 22 },
1274 { 15, 23}, {16, 24}, {17, 21}, { 18, 22}, {19, 21},
1275 { 20, 24}, { 21, 23}, };
1276
1277 pair miss[] =
1278 {{ 0, 4},{1, 17}, {2, 18}, { 3, 11}, {4, 12},
1279 { 5, 13}, { 6, 14 }, { 7, 15 }, {8, 16 }, { 9, 17},
1280 { 10, 18}, { 11, 19}, {12, 20}, { 13, 17}, {14, 18 },
1281 { 15, 19}, {16, 20}, {17, 19}, { 18, 20},
1282 { 20, 22}, };
1283
1284 auto rects = paragraph->getRectsForRange(7, 9, RectHeightStyle::kTight, RectWidthStyle::kTight);
1285 SkPaint paint;
1286 paint.setColor(SK_ColorRED);
1287 paint.setStyle(SkPaint::kStroke_Style);
1288 paint.setAntiAlias(true);
1289 paint.setStrokeWidth(1);
1290 if (!rects.empty()) {
1291 canvas->drawRect(rects[0].rect, paint);
1292 }
1293
1294 for (auto& query : hit1) {
1295 auto rects = paragraph->getRectsForRange(query.fX, query.fY, RectHeightStyle::kTight, RectWidthStyle::kTight);
1296 if (rects.size() >= 1 && rects[0].rect.width() > 0) {
1297 } else {
1298 SkDebugf("+[%d:%d): Bad\n", query.fX, query.fY);
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001299 }
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001300 }
1301
1302 for (auto& query : miss) {
1303 auto miss = paragraph->getRectsForRange(query.fX, query.fY, RectHeightStyle::kTight, RectWidthStyle::kTight);
1304 if (miss.empty()) {
1305 } else {
1306 SkDebugf("-[%d:%d): Bad\n", query.fX, query.fY);
1307 }
1308 }
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001309 }
1310
1311private:
1312 typedef Sample INHERITED;
1313};
1314
1315class ParagraphView12 : public ParagraphView_Base {
1316protected:
1317 SkString name() override { return SkString("Paragraph12"); }
1318
1319 void onDrawContent(SkCanvas* canvas) override {
1320 canvas->drawColor(SK_ColorWHITE);
1321
1322 const char* text = "Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges";
1323 TextStyle text_style;
1324 text_style.setFontFamilies({SkString("Ahem")});
1325 text_style.setColor(SK_ColorBLACK);
1326 text_style.setFontSize(16);
1327 //text_style.setLetterSpacing(-0.41);
1328 StrutStyle strut_style;
1329 strut_style.setStrutEnabled(false);
1330 ParagraphStyle paragraph_style;
1331 paragraph_style.setStrutStyle(strut_style);
1332 paragraph_style.setTextStyle(text_style);
1333 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1334 builder.addText(text);
1335 auto paragraph = builder.Build();
1336 paragraph->layout(1095.000000);
1337 auto result = paragraph->getRectsForRange(65, 66, RectHeightStyle::kTight, RectWidthStyle::kTight);
1338 paragraph->paint(canvas, 0, 0);
1339
1340 SkPaint paint;
1341 paint.setColor(SK_ColorRED);
1342 paint.setStyle(SkPaint::kStroke_Style);
1343 paint.setAntiAlias(true);
1344 paint.setStrokeWidth(1);
1345 canvas->drawRect(result.front().rect, paint);
1346 }
1347
1348private:
1349 typedef Sample INHERITED;
1350};
1351
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001352class ParagraphView14 : public ParagraphView_Base {
1353protected:
1354 SkString name() override { return SkString("Paragraph14"); }
1355
1356 void onDrawContent(SkCanvas* canvas) override {
1357 canvas->drawColor(SK_ColorWHITE);
1358 TextStyle text_style;
1359 text_style.setFontFamilies({SkString("Ahem")});
1360 text_style.setColor(SK_ColorBLACK);
1361 text_style.setFontSize(25);
1362 text_style.setDecoration((TextDecoration)(TextDecoration::kUnderline | TextDecoration::kOverline | TextDecoration::kLineThrough));
1363 text_style.setDecorationColor(SK_ColorBLUE);
1364 text_style.setDecorationStyle(TextDecorationStyle::kWavy);
1365 text_style.setDecorationThicknessMultiplier(4.0f);
1366 ParagraphStyle paragraph_style;
1367 paragraph_style.setTextStyle(text_style);
1368 paragraph_style.setTextDirection(TextDirection::kRtl);
1369 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1370 builder.pushStyle(text_style);
1371 builder.addText("Hello, wor!\nabcd.");
1372 auto paragraph = builder.Build();
1373 paragraph->layout(300);
1374 paragraph->paint(canvas, 0, 0);
1375 SkPaint paint;
1376 paint.setColor(SK_ColorRED);
1377 paint.setStyle(SkPaint::kStroke_Style);
1378 paint.setAntiAlias(true);
1379 paint.setStrokeWidth(1);
1380 canvas->drawRect(SkRect::MakeXYWH(0, 0, 300, 100), paint);
1381 }
1382
1383private:
1384 typedef Sample INHERITED;
1385};
1386
1387class ParagraphView15 : public ParagraphView_Base {
1388protected:
1389 SkString name() override { return SkString("Paragraph15"); }
1390
1391 void onDrawContent(SkCanvas* canvas) override {
1392 canvas->drawColor(SK_ColorWHITE);
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001393
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001394 TextStyle text_style;
1395 text_style.setFontFamilies({SkString("abc.ttf")});
1396 text_style.setFontSize(50);
1397
1398 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false);
1399
1400 fontCollection->addFontFromFile("abc/abc.ttf", "abc");
1401 fontCollection->addFontFromFile("abc/abc+grave.ttf", "abc+grave");
1402 fontCollection->addFontFromFile("abc/abc+agrave.ttf", "abc+agrave");
1403
1404 ParagraphStyle paragraph_style;
1405 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1406
1407 text_style.setFontFamilies({SkString("abc"), SkString("abc+grave")});
1408 text_style.setColor(SK_ColorBLUE);
1409 builder.pushStyle(text_style);
1410 builder.addText(u"a\u0300");
1411 text_style.setColor(SK_ColorMAGENTA);
1412 builder.pushStyle(text_style);
1413 builder.addText(u"à");
1414
1415 text_style.setFontFamilies({SkString("abc"), SkString("abc+agrave")});
1416
1417 text_style.setColor(SK_ColorRED);
1418 builder.pushStyle(text_style);
1419 builder.addText(u"a\u0300");
1420 text_style.setColor(SK_ColorGREEN);
1421 builder.pushStyle(text_style);
1422 builder.addText(u"à");
1423
1424 auto paragraph = builder.Build();
1425 paragraph->layout(800);
1426 paragraph->paint(canvas, 50, 50);
1427
Julia Lavrova5207f352019-06-21 12:22:32 -04001428 }
1429
1430private:
1431 typedef Sample INHERITED;
1432};
1433
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001434class ParagraphView16 : public ParagraphView_Base {
1435protected:
1436 SkString name() override { return SkString("Paragraph16"); }
1437
1438 void onDrawContent(SkCanvas* canvas) override {
1439 canvas->drawColor(SK_ColorWHITE);
1440
1441 const char* text = "content";
1442
1443 ParagraphStyle paragraph_style;
1444 paragraph_style.setMaxLines(1);
1445 paragraph_style.setEllipsis(u"\u2026");
1446 //auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
1447 auto fontCollection = sk_make_sp<FontCollection>();
1448 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1449 fontCollection->enableFontFallback();
1450 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1451
1452 TextStyle text_style;
1453 text_style.setFontFamilies({SkString(".SF Pro Text")});
1454 text_style.setColor(SK_ColorBLACK);
1455 text_style.setFontSize(17.0f * 99.0f);
1456 text_style.setLetterSpacing(0.41f);
1457 builder.pushStyle(text_style);
1458 builder.addText(text);
1459
1460 auto paragraph = builder.Build();
1461 paragraph->layout(800);
1462 paragraph->paint(canvas, 0, 0);
1463 }
1464
1465private:
1466 typedef Sample INHERITED;
1467};
1468
1469class ParagraphView17 : public ParagraphView_Base {
1470protected:
1471 SkString name() override { return SkString("Paragraph17"); }
1472
1473 void onDrawContent(SkCanvas* canvas) override {
1474 canvas->drawColor(SK_ColorWHITE);
1475
1476 auto fontCollection = sk_make_sp<FontCollection>();
1477 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1478 fontCollection->enableFontFallback();
1479 auto navy = SkColorSetRGB(0, 0, 139);
1480 auto ltgray = SkColorSetRGB(211, 211, 211);
1481 auto multiplier = 5.67;
1482
1483 const char* text = ">Sͬ͑̀͐̈͒̈́̋̎ͮͩ̽̓ͬ̂̆̔͗́̓ͣͧ͊ͫ͛̉͌̐̑ͪ͗̚͝҉̴͉͢k̡̊̓ͫͭͩ͂͊ͨͪͬ̑ͫ̍̌̄͛̌̂̑̂̋̊̔ͫ͛̽̑ͨ̍ͭ̓̀ͪͪ̉͐͗̌̓̃̚͟͝҉̢͏̫̞̙͇͖̮͕̗̟͕͇͚̻͈̣̻̪͉̰̲̣̫ͅͅP̴̅̍͒̿͗͗̇ͩ̃͆͌̀̽͏̧̡͕͖̝̖̼̺̰̣̬͔͖͔̼͙̞̦̫͓̘͜a̸̴̸̴̢̢̨̨̫͍͓̥̼̭̼̻̤̯̙̤̻̠͚̍̌͋̂ͦͨ̽̇͌͌͆̀̽̎͒̄ͪ̐ͦ̈ͫ͐͗̓̚̚͜ͅr͐͐ͤͫ̐ͥ͂̈́̿́ͮ̃͗̓̏ͫ̀̿͏̸̵̧́͘̕͟͝͠͞͠҉̷̧͚͢͟a̓̽̎̄͗̔͛̄̐͊͛ͫ͂͌̂̂̈̈̓̔̅̅̄͊̉́ͪ̑̄͆ͬ̍͆ͭ͋̐ͬ͏̷̵̨̢̩̹̖͓̥̳̰͔̱̬͖̙͓̙͇̀̀̕͜͟͟͢͟͜͠͡g̨̅̇ͦ͋̂ͦͨͭ̓͐͆̏̂͛̉ͧ̑ͫ̐̒͛ͫ̍̒͛́̚҉̷̨̛̛̀͜͢͞҉̩̘̲͍͎̯̹̝̭̗̱͇͉̲̱͔̯̠̹̥̻͉̲̜̤̰̪̗̺̖̺r̷͌̓̇̅ͭ̀̐̃̃ͭ͑͗̉̈̇̈́ͥ̓ͣ́ͤ͂ͤ͂̏͌̆̚҉̴̸̧̢̢̛̫͉̦̥̤̙͈͉͈͉͓̙̗̟̳̜͈̗̺̟̠̠͖͓̖̪͕̠̕̕͝ͅả̸̴̡̡̧͠͞͡͞҉̛̕͟͏̷̘̪̱͈̲͉̞̠̞̪̫͎̲̬̖̀̀͟͝͞͞͠p̛͂̈͐̚͠҉̵̸̡̢̢̩̹͙̯͖̙̙̮̥̙͚̠͔̥̭̮̞̣̪̬̥̠̖̝̥̪͎́̀̕͜͡͡ͅͅh̵̷̵̡̛ͤ̂͌̐̓̐̋̋͊̒̆̽́̀̀̀͢͠͞͞҉̷̸̢̕҉͚̯͖̫̜̞̟̠̱͉̝̲̹̼͉̟͉̩̮͔̤͖̞̭̙̹̬ͅ<";
1484
1485 ParagraphStyle paragraph_style;
1486 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1487 SkPaint paint;
1488 paint.setColor(ltgray);
1489 TextStyle text_style;
1490 text_style.setBackgroundColor(paint);
1491 text_style.setColor(navy);
1492 text_style.setFontFamilies({SkString("Roboto")});
1493 text_style.setFontSize(20 * multiplier);
1494 builder.pushStyle(text_style);
1495 builder.addText(text);
1496 auto paragraph = builder.Build();
1497 paragraph->layout(10000);
1498 paragraph->paint(canvas, 0, 0);
1499 }
1500
1501private:
1502 typedef Sample INHERITED;
1503};
1504
1505class Zalgo {
1506 private:
1507 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";
1508 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";
1509 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";
1510
1511 std::u16string randomMarks(std::u16string& combiningMarks) {
1512 std::u16string result;
1513 auto num = std::rand() % (combiningMarks.size() / 1);
1514 for (size_t i = 0; i < num; ++i) {
1515 auto index = std::rand() % combiningMarks.size();
1516 result += combiningMarks[index];
1517 }
1518 return result;
1519 }
1520
1521public:
1522 std::u16string zalgo(std::string victim) {
1523 std::u16string result;
1524 for (auto& c : victim) {
1525 result += c;
1526 result += randomMarks(COMBINING_UP);
1527 result += randomMarks(COMBINING_MIDDLE);
1528 result += randomMarks(COMBINING_DOWN);
1529 }
1530 return result;
1531 }
1532};
1533
1534class ParagraphView18 : public ParagraphView_Base {
1535protected:
1536 SkString name() override { return SkString("Paragraph18"); }
1537
1538 bool onChar(SkUnichar uni) override {
1539 switch (uni) {
1540 case ' ':
1541 fLimit = 400;
1542 return true;
1543 case 's':
1544 fLimit += 10;
1545 return true;
1546 case 'f':
1547 if (fLimit > 10) {
1548 fLimit -= 10;
1549 }
1550 return true;
1551 default:
1552 break;
1553 }
1554 return false;
1555 }
1556
1557 bool onAnimate(double nanos) override {
1558 if (++fIndex > fLimit) {
1559 fRedraw = true;
1560 fIndex = 0;
1561 } else {
1562 fRepeat = true;
1563 }
1564 return true;
1565 }
1566
1567 void onDrawContent(SkCanvas* canvas) override {
1568 canvas->drawColor(SK_ColorWHITE);
1569
1570 auto navy = SkColorSetRGB(0, 0, 139);
1571 auto ltgray = SkColorSetRGB(211, 211, 211);
1572
1573 auto multiplier = 5.67;
1574 auto fontCollection = sk_make_sp<FontCollection>();
1575 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1576 fontCollection->enableFontFallback();
1577
1578 ParagraphStyle paragraph_style;
1579 TextStyle text_style;
1580 text_style.setFontFamilies({SkString("Roboto")});
1581 text_style.setFontSize(20 * multiplier);
1582 text_style.setColor(navy);
1583 SkPaint paint;
1584 paint.setColor(ltgray);
1585 text_style.setBackgroundColor(paint);
1586
1587 Zalgo zalgo;
1588
1589 if (fRedraw || fRepeat) {
1590
1591 if (fRedraw || fParagraph.get() == nullptr) {
1592 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1593 builder.pushStyle(text_style);
1594 auto utf16text = zalgo.zalgo("SkParagraph");
1595 icu::UnicodeString unicode((UChar*)utf16text.data(), SkToS32(utf16text.size()));
1596 std::string str;
1597 unicode.toUTF8String(str);
1598 SkDebugf("Text:>%s<\n", str.data());
1599 builder.addText(utf16text);
1600 fParagraph = builder.Build();
1601 }
1602
1603 auto impl = static_cast<ParagraphImpl*>(fParagraph.get());
1604 impl->setState(InternalState::kUnknown);
1605 fParagraph->layout(1000);
1606 fParagraph->paint(canvas, 300, 200);
1607
1608 for (auto& run : impl->runs()) {
1609 SkString fontFamily("unresolved");
1610 if (run.font().getTypeface() != nullptr) {
1611 run.font().getTypeface()->getFamilyName(&fontFamily);
1612 }
1613 if (run.font().getTypeface() != nullptr) {
1614 for (size_t i = 0; i < run.size(); ++i) {
1615 auto glyph = run.glyphs().begin() + i;
1616 if (*glyph == 0) {
1617 SkDebugf("Run[%d] @pos=%d\n", run.index(), i);
1618 SkASSERT(false);
1619 }
1620 }
1621 } else {
1622 SkDebugf("Run[%d]: %s\n", run.index(), fontFamily.c_str());
1623 SkASSERT(false);
1624 }
1625 }
1626 fRedraw = false;
1627 fRepeat = false;
1628 }
1629 }
1630
1631private:
1632 bool fRedraw = true;
1633 bool fRepeat = false;
1634 size_t fIndex = 0;
1635 size_t fLimit = 20;
1636 std::unique_ptr<Paragraph> fParagraph;
1637 typedef Sample INHERITED;
1638};
1639
1640class ParagraphView19 : public ParagraphView_Base {
1641protected:
1642 SkString name() override { return SkString("Paragraph19"); }
1643
1644 void onDrawContent(SkCanvas* canvas) override {
1645 canvas->drawColor(SK_ColorWHITE);
1646
1647 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
1648
Julia Lavrova90bfd1c2019-12-04 11:43:32 -05001649 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";
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001650 ParagraphStyle paragraph_style;
1651 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001652 TextStyle text_style;
Julia Lavrovac028b422019-11-25 10:00:43 -05001653 text_style.setColor(SK_ColorBLACK);
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001654 text_style.setFontFamilies({SkString("Roboto")});
Julia Lavrova90bfd1c2019-12-04 11:43:32 -05001655 text_style.setFontSize(20);
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001656 builder.pushStyle(text_style);
1657 builder.addText(text);
1658 auto paragraph = builder.Build();
Julia Lavrovac028b422019-11-25 10:00:43 -05001659 paragraph->layout(this->width());
Julia Lavrovac028b422019-11-25 10:00:43 -05001660 paragraph->paint(canvas, 0, 0);
1661 }
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001662
Julia Lavrovac028b422019-11-25 10:00:43 -05001663private:
1664 typedef Sample INHERITED;
1665};
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001666
Julia Lavrovac028b422019-11-25 10:00:43 -05001667class ParagraphView20 : public ParagraphView_Base {
1668protected:
1669 SkString name() override { return SkString("Paragraph20"); }
1670
1671 void onDrawContent(SkCanvas* canvas) override {
1672 canvas->drawColor(SK_ColorWHITE);
1673
1674 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
1675
Julia Lavrovac48687a2020-01-08 16:53:53 -05001676 const char* text = "Manage your google account";
Julia Lavrovac028b422019-11-25 10:00:43 -05001677 ParagraphStyle paragraph_style;
Julia Lavrovac48687a2020-01-08 16:53:53 -05001678 paragraph_style.setEllipsis(u"\u2026");
1679 paragraph_style.setMaxLines(1);
Julia Lavrovac028b422019-11-25 10:00:43 -05001680 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1681 TextStyle text_style;
1682 text_style.setColor(SK_ColorBLACK);
Julia Lavrova53c14472019-12-18 09:39:55 -05001683 text_style.setFontFamilies({SkString("Roboto")});
Julia Lavrovac48687a2020-01-08 16:53:53 -05001684 text_style.setFontSize(50);
Julia Lavrovac028b422019-11-25 10:00:43 -05001685 builder.pushStyle(text_style);
1686 builder.addText(text);
1687 auto paragraph = builder.Build();
Julia Lavrovac48687a2020-01-08 16:53:53 -05001688 paragraph->layout(this->width());
1689 paragraph->paint(canvas, 0, 0);
1690 }
1691
1692private:
1693 typedef Sample INHERITED;
1694};
1695
1696class ParagraphView21 : public ParagraphView_Base {
1697protected:
1698 SkString name() override { return SkString("Paragraph21"); }
1699
1700 void onDrawContent(SkCanvas* canvas) override {
1701 canvas->drawColor(SK_ColorWHITE);
1702
Julia Lavrova70e93012020-01-10 14:04:45 -05001703 const char* text = "Referral Code";
Julia Lavrovac48687a2020-01-08 16:53:53 -05001704 ParagraphStyle paragraph_style;
Julia Lavrovaf6a3f8e2020-01-10 10:55:52 -05001705 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
Julia Lavrovac48687a2020-01-08 16:53:53 -05001706 TextStyle text_style;
1707 text_style.setColor(SK_ColorBLACK);
Julia Lavrovaf6a3f8e2020-01-10 10:55:52 -05001708 text_style.setFontFamilies({SkString("Google Sans")});
1709 text_style.setFontSize(24);
Julia Lavrovac48687a2020-01-08 16:53:53 -05001710 builder.pushStyle(text_style);
1711 builder.addText(text);
1712 auto paragraph = builder.Build();
Julia Lavrova70e93012020-01-10 14:04:45 -05001713 paragraph->layout(0);
Julia Lavrovac028b422019-11-25 10:00:43 -05001714 paragraph->paint(canvas, 0, 0);
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001715 }
1716
1717private:
1718 typedef Sample INHERITED;
1719};
Julia Lavrova4cf18742020-01-14 13:24:45 -05001720
1721class ParagraphView22 : public ParagraphView_Base {
1722protected:
1723 SkString name() override { return SkString("Paragraph22"); }
1724
Julia Lavrova9bd83512020-01-15 14:46:35 -05001725 bool onChar(SkUnichar uni) override {
1726 switch (uni) {
1727 case 'l':
1728 direction = true;
1729 return true;
1730 case 'r':
1731 direction = false;
1732 return true;
1733 default:
1734 break;
Julia Lavrova4cf18742020-01-14 13:24:45 -05001735 }
Julia Lavrova9bd83512020-01-15 14:46:35 -05001736 return false;
1737 }
1738
1739 void onDrawContent(SkCanvas* canvas) override {
1740
1741 canvas->drawColor(SK_ColorWHITE);
1742 ParagraphStyle paragraph_style;
1743 paragraph_style.setTextDirection(direction ? TextDirection::kLtr : TextDirection::kRtl);
1744 auto collection = getFontCollection();
1745 ParagraphBuilderImpl builder(paragraph_style, collection);
1746 collection->getParagraphCache()->reset();
1747 collection->getParagraphCache()->turnOn(false);
1748 TextStyle text_style;
1749 text_style.setColor(SK_ColorBLACK);
1750 text_style.setFontFamilies({SkString("Roboto")});
1751 text_style.setFontSize(12);
1752 builder.pushStyle(text_style);
1753 builder.addText("I have got a ");
1754 text_style.setFontStyle(SkFontStyle::Bold());
1755 builder.pushStyle(text_style);
1756 builder.addText("lovely bunch");
1757 text_style.setFontStyle(SkFontStyle::Normal());
1758 builder.pushStyle(text_style);
1759 builder.addText(" of coconuts.");
1760 auto paragraph = builder.Build();
1761 paragraph->layout(this->width());
1762 paragraph->paint(canvas, 0, 0);
1763 collection->getParagraphCache()->turnOn(true);
Julia Lavrova4cf18742020-01-14 13:24:45 -05001764 }
1765
1766private:
1767 typedef Sample INHERITED;
Julia Lavrova9bd83512020-01-15 14:46:35 -05001768 bool direction;
Julia Lavrova4cf18742020-01-14 13:24:45 -05001769};
Julia Lavrova9bd83512020-01-15 14:46:35 -05001770
Julia Lavrova51a813d2020-01-21 13:55:44 -05001771class ParagraphView23 : public ParagraphView_Base {
1772protected:
1773 SkString name() override { return SkString("Paragraph23"); }
1774
1775 void onDrawContent(SkCanvas* canvas) override {
1776 canvas->drawColor(SK_ColorWHITE);
1777
1778 const char* text = "Text with shadow";
1779 ParagraphStyle paragraph_style;
1780 TextStyle text_style;
1781 text_style.setColor(SK_ColorBLACK);
1782 text_style.setFontFamilies({SkString("Google Sans")});
1783 text_style.setFontSize(24);
1784
1785 auto draw = [&](SkScalar h, SkScalar v, SkScalar b) {
1786 text_style.resetShadows();
1787 text_style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(h, v), b));
1788 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1789 builder.pushStyle(text_style);
1790 builder.addText(text);
1791 auto paragraph = builder.Build();
1792 paragraph->layout(300);
1793 paragraph->paint(canvas, 0, 0);
1794
1795 auto rect = SkRect::MakeXYWH(0, 0, paragraph->getMaxWidth(), paragraph->getHeight());
1796 SkPaint paint;
1797 paint.setColor(SK_ColorRED);
1798 paint.setStyle(SkPaint::kStroke_Style);
1799 paint.setAntiAlias(true);
1800 paint.setStrokeWidth(1);
1801 canvas->drawRect(rect, paint);
1802 };
1803
1804 draw(10, 10, 5);
1805 canvas->translate(0, 100);
1806
1807 draw(10, -10, 5);
1808 canvas->translate(0, 100);
1809
1810 draw(-10, -10, 5);
1811 canvas->translate(0, 100);
1812
1813 draw(-10, 10, 5);
1814 canvas->translate(0, 100);
1815 }
1816
1817private:
1818 typedef Sample INHERITED;
1819};
1820
Julia Lavrova2ea20ea2020-01-22 10:56:53 -05001821class ParagraphView24 : public ParagraphView_Base {
1822protected:
1823 SkString name() override { return SkString("Paragraph24"); }
1824
1825 void onDrawContent(SkCanvas* canvas) override {
1826 canvas->drawColor(SK_ColorWHITE);
1827
1828 ParagraphStyle paragraph_style;
1829 paragraph_style.setTextDirection(TextDirection::kRtl);
1830 TextStyle text_style;
1831 text_style.setColor(SK_ColorBLACK);
1832 text_style.setFontFamilies({SkString("Google Sans")});
1833 text_style.setFontSize(24);
1834 {
1835 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1836 builder.pushStyle(text_style);
1837 builder.addText("Right_to_left:");
1838 auto paragraph = builder.Build();
1839 paragraph->layout(this->width());
1840 paragraph->paint(canvas, 0, 0);
1841 }
1842 canvas->translate(0, 200);
1843 {
1844 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1845 builder.pushStyle(text_style);
1846 builder.addText("Right_to_left+");
1847 auto paragraph = builder.Build();
1848 paragraph->layout(this->width());
1849 paragraph->paint(canvas, 0, 0);
1850 }
1851 canvas->translate(0, 200);
1852 {
1853 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1854 builder.pushStyle(text_style);
1855 builder.addText("Right_to_left.");
1856 auto paragraph = builder.Build();
1857 paragraph->layout(this->width());
1858 paragraph->paint(canvas, 0, 0);
1859 }
1860 }
1861
1862private:
1863 typedef Sample INHERITED;
1864};
1865
1866class ParagraphView25 : public ParagraphView_Base {
1867protected:
1868 SkString name() override { return SkString("Paragraph25"); }
1869
1870 void onDrawContent(SkCanvas* canvas) override {
1871 canvas->drawColor(SK_ColorWHITE);
Julia Lavrovac0360582020-02-05 10:17:53 -05001872/*
1873 * Shell: ParagraphStyle: 1.000000 1
1874Shell: Strut enabled: 0 1.000000 14.000000 400 5 0
1875Shell: Font Families: 0
1876Shell: DefaultTextStyle: 16.000000 500 5 0
1877Shell: Font Families: 1 Roboto
1878Shell: Font Features: 0
1879Shell: TextStyle#0: [0:22) 16.000000 500 5 0
1880Shell: Font Families: 1 Roboto
1881Shell: Font Features: 0
1882Shell: TextStyle#1: [25:49) 16.000000 500 5 0
1883Shell: Font Families: 1 Roboto
1884Shell: Font Features: 0
1885Shell: Placeholder#0: [22:25) 32.000000 32.000000 32.000000 0 5
1886Shell: Placeholder#1: [49:52) 19.000000 41.000000 19.000000 0 4
1887Shell: Placeholder#2: [52:52) 0.000000 0.000000 0.000000 0 5
1888Shell: layout('Go to device settings  and set up a passcode. ', 280.000000): 280.000000 * 38.000000
1889 */
1890 auto fontCollection = getFontCollection();
1891 //fontCollection->getParagraphCache()->turnOn(false);
1892 const char* text1 = "Go to device settings ";
1893 const char* text2 = "and set up a passcode.";
Julia Lavrova2ea20ea2020-01-22 10:56:53 -05001894 ParagraphStyle paragraph_style;
Julia Lavrovac0360582020-02-05 10:17:53 -05001895 StrutStyle strut_style;
1896 strut_style.setStrutEnabled(false);
1897 strut_style.setFontSize(14);
1898 strut_style.setForceStrutHeight(false);
1899 strut_style.setHeight(14);
1900 paragraph_style.setStrutStyle(strut_style);
Julia Lavrova2ea20ea2020-01-22 10:56:53 -05001901 TextStyle text_style;
1902 text_style.setColor(SK_ColorBLACK);
Julia Lavrovac0360582020-02-05 10:17:53 -05001903 text_style.setFontFamilies({SkString("Roboto")});
1904 text_style.setFontSize(16);
1905 PlaceholderStyle placeholder_style;
1906 {
1907 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1908 builder.pushStyle(text_style);
1909 builder.addText(text1);
1910 placeholder_style.fHeight = 32;
1911 placeholder_style.fWidth = 32;
1912 placeholder_style.fBaselineOffset = 32;
1913 placeholder_style.fBaseline = TextBaseline::kAlphabetic;
1914 placeholder_style.fAlignment = PlaceholderAlignment::kMiddle;
1915 builder.addPlaceholder(placeholder_style);
1916 builder.addText(text2);
1917 placeholder_style.fHeight = 19;
1918 placeholder_style.fWidth = 41;
1919 placeholder_style.fBaselineOffset = 19;
1920 placeholder_style.fBaseline = TextBaseline::kAlphabetic;
1921 placeholder_style.fAlignment = PlaceholderAlignment::kTop;
1922 builder.addPlaceholder(placeholder_style);
1923 auto paragraph = builder.Build();
1924 paragraph->layout(280);
1925 paragraph->paint(canvas, 0, 0);
1926 }
Julia Lavrova2ea20ea2020-01-22 10:56:53 -05001927 }
1928
1929private:
1930 typedef Sample INHERITED;
1931};
1932
1933class ParagraphView26 : public ParagraphView_Base {
1934protected:
1935 SkString name() override { return SkString("Paragraph26"); }
1936
1937 void onDrawContent(SkCanvas* canvas) override {
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001938 auto fontCollection = sk_make_sp<FontCollection>();
1939 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
Julia Lavrova95a9e692020-02-05 10:17:53 -05001940 //fontCollection->enableFontFallback();
Julia Lavrova2ea20ea2020-01-22 10:56:53 -05001941
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001942 canvas->clear(SK_ColorWHITE);
1943
1944 SkPaint paint;
1945 paint.setAntiAlias(true);
1946 paint.setColor(SK_ColorBLACK);
1947
1948 TextStyle textStyle;
1949 textStyle.setForegroundColor(paint);
Julia Lavrova95a9e692020-02-05 10:17:53 -05001950 textStyle.setFontFamilies({ SkString("Roboto") });
1951 textStyle.setFontSize(42.0f);
1952 textStyle.setLetterSpacing(-0.05f);
1953 textStyle.setHeightOverride(true);
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001954
1955 ParagraphStyle paragraphStyle;
1956 paragraphStyle.setTextStyle(textStyle);
1957 paragraphStyle.setTextAlign(TextAlign::kLeft);
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001958
Julia Lavrova95a9e692020-02-05 10:17:53 -05001959 ParagraphBuilderImpl builder(paragraphStyle, fontCollection);
1960 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");
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001961
Julia Lavrova95a9e692020-02-05 10:17:53 -05001962 auto paragraph = builder.Build();
1963 paragraph->layout(this->width() / 2);
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001964
Julia Lavrova95a9e692020-02-05 10:17:53 -05001965 std::vector<LineMetrics> lines;
1966 paragraph->getLineMetrics(lines); // <-- error happens here
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001967
Julia Lavrova95a9e692020-02-05 10:17:53 -05001968 canvas->translate(10, 10);
1969 paragraph->paint(canvas, 0, 0);
Julia Lavrova2ea20ea2020-01-22 10:56:53 -05001970 }
1971
1972private:
1973 typedef Sample INHERITED;
1974};
1975
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05001976class ParagraphView27 : public ParagraphView_Base {
1977protected:
1978 SkString name() override { return SkString("Paragraph27"); }
1979
1980 void onDrawContent(SkCanvas* canvas) override {
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001981 auto fontCollection = sk_make_sp<FontCollection>();
1982 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1983 fontCollection->enableFontFallback();
1984 fontCollection->getParagraphCache()->turnOn(false);
1985
1986 SkPaint red;
1987 red.setColor(SK_ColorRED);
1988 red.setStyle(SkPaint::kStroke_Style);
1989 red.setAntiAlias(true);
1990 red.setStrokeWidth(1);
1991
1992 SkPaint blue;
1993 blue.setColor(SK_ColorRED);
1994 blue.setStyle(SkPaint::kStroke_Style);
1995 blue.setAntiAlias(true);
1996 blue.setStrokeWidth(1);
1997
1998 SkPaint black;
1999 black.setColor(SK_ColorBLACK);
2000 black.setStyle(SkPaint::kStroke_Style);
2001 black.setAntiAlias(true);
2002 black.setStrokeWidth(1);
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002003
Julia Lavrova95a9e692020-02-05 10:17:53 -05002004 SkPaint whiteSpaces;
2005 whiteSpaces.setColor(SK_ColorLTGRAY);
2006
2007 SkPaint breakingSpace;
2008 breakingSpace.setColor(SK_ColorYELLOW);
2009
2010 SkPaint text;
2011 text.setColor(SK_ColorWHITE);
2012
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002013 ParagraphStyle paragraph_style;
Julia Lavrovad3a32c52020-02-03 09:43:52 -05002014 paragraph_style.setTextAlign(TextAlign::kRight);
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002015 TextStyle text_style;
2016 text_style.setColor(SK_ColorBLACK);
Julia Lavrovad3a32c52020-02-03 09:43:52 -05002017 text_style.setFontFamilies({SkString("Roboto")});
Julia Lavrova89e678d2020-01-28 10:43:31 -05002018
Julia Lavrovad3a32c52020-02-03 09:43:52 -05002019 // RTL + right align + arabic
2020 // RTL + right align + latin
2021 // LTR + right align + arabic
2022 // LTR + right align + latin
2023 // RTL + left align + arabic
2024 // RTL + left align + latin
2025 // arabic and latin should not differ at all
2026 // check: line breaking and trailing spaces
2027
2028 canvas->drawColor(SK_ColorWHITE);
2029 auto h = 60;
2030 auto w = 300;
2031
Julia Lavrova95a9e692020-02-05 10:17:53 -05002032 auto draw = [&](SkScalar width, SkScalar height, TextDirection td, TextAlign ta, const char* t) {
2033 SkDebugf("draw '%s' dir:%s align:%s\n", t,
Julia Lavrovad3a32c52020-02-03 09:43:52 -05002034 td == TextDirection::kLtr ? "left" : "right",
2035 ta == TextAlign::kLeft ? "left" : "right");
2036 paragraph_style.setTextDirection(td);
2037 paragraph_style.setTextAlign(ta);
2038 text_style.setFontSize(20);
2039 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
Julia Lavrova95a9e692020-02-05 10:17:53 -05002040 text_style.setBackgroundColor(whiteSpaces);
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002041 builder.pushStyle(text_style);
Julia Lavrova95a9e692020-02-05 10:17:53 -05002042 builder.addText(" ");
2043 text_style.setBackgroundColor(text);
2044 builder.pushStyle(text_style);
2045 builder.addText(t);
2046 text_style.setBackgroundColor(breakingSpace);
2047 builder.pushStyle(text_style);
2048 builder.addText(" ");
2049 text_style.setBackgroundColor(text);
2050 builder.pushStyle(text_style);
2051 builder.addText(t);
2052 text_style.setBackgroundColor(whiteSpaces);
2053 builder.pushStyle(text_style);
2054 builder.addText(" ");
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002055 auto paragraph = builder.Build();
Julia Lavrovad3a32c52020-02-03 09:43:52 -05002056 paragraph->layout(width);
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002057 paragraph->paint(canvas, 0, 0);
Julia Lavrovad3a32c52020-02-03 09:43:52 -05002058 auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2059 for (auto& line : impl->lines()) {
2060 SkDebugf("line[%d]: %f + %f\n", &line - impl->lines().begin(), line.offset().fX, line.shift());
2061 line.iterateThroughVisualRuns(true,
2062 [&](const Run* run, SkScalar runOffset, TextRange textRange, SkScalar* width) {
2063 *width = line.measureTextInsideOneRun(textRange, run, runOffset, 0, true, false).clip.width();
2064 SkDebugf("%d[%d: %d) @%f + %f %s\n", run->index(),
2065 textRange.start, textRange.end, runOffset, *width, run->leftToRight() ? "left" : "right");
2066 return true;
2067 });
2068 }
2069 auto boxes = paragraph->getRectsForRange(0, 100, RectHeightStyle::kTight, RectWidthStyle::kTight);
2070 bool even = true;
2071 for (auto& box : boxes) {
2072 SkDebugf("[%f:%f,%f:%f] %s\n",
2073 box.rect.fLeft, box.rect.fRight, box.rect.fTop, box.rect.fBottom,
2074 box.direction == TextDirection::kLtr ? "left" : "right");
2075 canvas->drawRect(box.rect, even ? red : blue);
2076 even = !even;
2077 }
2078 canvas->translate(0, height);
Julia Lavrova89e678d2020-01-28 10:43:31 -05002079 };
2080
Julia Lavrovad3a32c52020-02-03 09:43:52 -05002081 canvas->drawRect(SkRect::MakeXYWH(0, 0, w, h * 8), black);
2082
2083 draw(w, h, TextDirection::kRtl, TextAlign::kRight, "RTL+RIGHT#1234567890");
2084 draw(w, h, TextDirection::kRtl, TextAlign::kRight, "قففغغغغقففغغغغقففغغغ");
2085
2086 draw(w, h, TextDirection::kLtr, TextAlign::kRight, "LTR+RIGHT#1234567890");
2087 draw(w, h, TextDirection::kLtr, TextAlign::kRight, "قففغغغغقففغغغغقففغغغ");
2088
2089 draw(w, h, TextDirection::kRtl, TextAlign::kLeft, "RTL+LEFT##1234567890");
2090 draw(w, h, TextDirection::kRtl, TextAlign::kLeft, "قففغغغغقففغغغغقففغغغ");
2091
2092 draw(w, h, TextDirection::kLtr, TextAlign::kLeft, "LTR+LEFT##1234567890");
2093 draw(w, h, TextDirection::kLtr, TextAlign::kLeft, "قففغغغغقففغغغغقففغغغ");
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002094 }
2095
2096private:
2097 typedef Sample INHERITED;
2098};
2099
Julia Lavrova212bf072020-02-18 12:05:55 -05002100class ParagraphView28 : public ParagraphView_Base {
2101protected:
2102 SkString name() override { return SkString("Paragraph28"); }
2103
2104 void onDrawContent(SkCanvas* canvas) override {
2105
2106 const char* text = "AAAAA BBBBB CCCCC DDDDD EEEEE FFFFF GGGGG HHHHH IIIII JJJJJ KKKKK LLLLL MMMMM NNNNN OOOOO PPPPP QQQQQ";
2107
2108 canvas->drawColor(SK_ColorWHITE);
2109 ParagraphStyle paragraph_style;
2110 paragraph_style.setTextAlign(TextAlign::kJustify);
2111 auto collection = getFontCollection();
2112 ParagraphBuilderImpl builder(paragraph_style, collection);
2113 TextStyle text_style;
2114 text_style.setColor(SK_ColorBLACK);
2115 text_style.setFontFamilies({SkString("Roboto")});
2116 text_style.setFontSize(40);
2117 builder.pushStyle(text_style);
2118 builder.addText(text);
2119 auto paragraph = builder.Build();
2120 auto s = 186;
2121 paragraph->layout(360 - s);
2122 paragraph->paint(canvas, 0, 0);
2123 /*
2124 paragraph->layout(360);
2125 paragraph->paint(canvas, 0, 0);
2126 canvas->translate(0, 400);
2127 paragraph->layout(354.333);
2128 paragraph->paint(canvas, 0, 0);
2129 */
2130 }
2131
2132private:
2133 typedef Sample INHERITED;
2134};
2135
2136class ParagraphView29 : public ParagraphView_Base {
2137protected:
2138 SkString name() override { return SkString("Paragraph29"); }
2139
2140 void onDrawContent(SkCanvas* canvas) override {
2141
Julia Lavrova62076972020-02-19 15:12:48 -05002142 const char* text = "ffi";
Julia Lavrova212bf072020-02-18 12:05:55 -05002143 canvas->drawColor(SK_ColorWHITE);
2144
Julia Lavrova62076972020-02-19 15:12:48 -05002145 auto collection = getFontCollection();
Julia Lavrova212bf072020-02-18 12:05:55 -05002146
2147 ParagraphStyle paragraph_style;
Julia Lavrova212bf072020-02-18 12:05:55 -05002148 ParagraphBuilderImpl builder(paragraph_style, collection);
2149 TextStyle text_style;
2150 text_style.setColor(SK_ColorBLACK);
2151 text_style.setFontFamilies({SkString("Roboto")});
Julia Lavrova62076972020-02-19 15:12:48 -05002152 text_style.setFontSize(60);
Julia Lavrova212bf072020-02-18 12:05:55 -05002153 builder.pushStyle(text_style);
2154 builder.addText(text);
2155 auto paragraph = builder.Build();
Julia Lavrova62076972020-02-19 15:12:48 -05002156 paragraph->layout(width());
Julia Lavrova212bf072020-02-18 12:05:55 -05002157 paragraph->paint(canvas, 0, 0);
Julia Lavrova62076972020-02-19 15:12:48 -05002158 auto width = paragraph->getLongestLine();
2159 auto height = paragraph->getHeight();
2160
2161 auto f1 = paragraph->getGlyphPositionAtCoordinate(width/6, height/2);
2162 auto f2 = paragraph->getGlyphPositionAtCoordinate(width/2, height/2);
2163 auto i = paragraph->getGlyphPositionAtCoordinate(width*5/6, height/2);
2164
2165 SkDebugf("%d(%s) %d(%s) %d(%s)\n",
2166 f1.position, f1.affinity == Affinity::kUpstream ? "up" : "down",
2167 f2.position, f2.affinity == Affinity::kUpstream ? "up" : "down",
2168 i.position, i.affinity == Affinity::kUpstream ? "up" : "down");
2169
2170 auto rf1 = paragraph->getRectsForRange(0, 1, RectHeightStyle::kTight, RectWidthStyle::kTight)[0];
2171 auto rf2 = paragraph->getRectsForRange(1, 2, RectHeightStyle::kTight, RectWidthStyle::kTight)[0];
2172 auto rfi = paragraph->getRectsForRange(2, 3, RectHeightStyle::kTight, RectWidthStyle::kTight)[0];
2173
2174 SkDebugf("f1: [%f:%f] %s\n",
2175 rf1.rect.fLeft, rf1.rect.fRight, rf1.direction == TextDirection::kRtl ? "rtl" : "ltr");
2176 SkDebugf("f2: [%f:%f] %s\n",
2177 rf2.rect.fLeft, rf2.rect.fRight, rf2.direction == TextDirection::kRtl ? "rtl" : "ltr");
2178 SkDebugf("i: [%f:%f] %s\n",
2179 rfi.rect.fLeft, rfi.rect.fRight, rfi.direction == TextDirection::kRtl ? "rtl" : "ltr");
Julia Lavrova212bf072020-02-18 12:05:55 -05002180 }
2181
2182private:
2183 typedef Sample INHERITED;
2184};
2185
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002186class ParagraphView30 : public ParagraphView_Base {
2187protected:
2188 SkString name() override { return SkString("Paragraph30"); }
2189
2190 void onDrawContent(SkCanvas* canvas) override {
2191
Julia Lavrovacd2a4d62020-03-05 10:31:19 -05002192 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";
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002193 canvas->drawColor(SK_ColorWHITE);
2194
2195 auto fontCollection = sk_make_sp<FontCollection>();
2196 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2197 fontCollection->enableFontFallback();
2198
2199 ParagraphStyle paragraph_style;
2200 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2201 TextStyle text_style;
2202 text_style.setColor(SK_ColorBLACK);
Julia Lavrovacd2a4d62020-03-05 10:31:19 -05002203 text_style.setFontFamilies({SkString("Noto Color Emoji")});
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002204 text_style.setFontSize(60);
2205 builder.pushStyle(text_style);
2206 builder.addText(text);
2207 auto paragraph = builder.Build();
2208 paragraph->layout(width());
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002209
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002210
Julia Lavrova76ae22e2020-02-26 12:14:18 -05002211 SkColor colors[] = {
2212 SK_ColorRED,
2213 SK_ColorGREEN,
2214 SK_ColorBLUE,
2215 SK_ColorMAGENTA,
2216 SK_ColorYELLOW
2217 };
2218 SkPaint paint;
Julia Lavrovacd2a4d62020-03-05 10:31:19 -05002219 size_t color = 0;
2220 for (size_t i = 0; i < text.size(); ++i) {
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002221 auto result = paragraph->getRectsForRange(i, i + 1, RectHeightStyle::kTight, RectWidthStyle::kTight);
Julia Lavrova76ae22e2020-02-26 12:14:18 -05002222 if (result.empty()) {
Julia Lavrovacd2a4d62020-03-05 10:31:19 -05002223 SkDebugf("empty [%d:%d)\n", i, i + 1);
Julia Lavrova76ae22e2020-02-26 12:14:18 -05002224 continue;
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002225 }
Julia Lavrova76ae22e2020-02-26 12:14:18 -05002226 auto rect = result[0].rect;
Julia Lavrovacd2a4d62020-03-05 10:31:19 -05002227 paint.setColor(colors[color++ % 5]);
Julia Lavrova76ae22e2020-02-26 12:14:18 -05002228 canvas->drawRect(rect, paint);
Julia Lavrovacd2a4d62020-03-05 10:31:19 -05002229 SkDebugf("rect [%d:%d): %f:%f\n", i, i + 1, rect.fLeft, rect.fRight);
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002230 }
Julia Lavrova76ae22e2020-02-26 12:14:18 -05002231 paragraph->paint(canvas, 0, 0);
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002232 }
2233
2234private:
2235 typedef Sample INHERITED;
2236};
2237
2238class ParagraphView31 : public ParagraphView_Base {
2239protected:
2240 SkString name() override { return SkString("Paragraph31"); }
2241
2242 void onDrawContent(SkCanvas* canvas) override {
2243
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002244 canvas->drawColor(SK_ColorWHITE);
2245
2246 auto fontCollection = sk_make_sp<FontCollection>();
2247 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2248 fontCollection->enableFontFallback();
2249
2250 ParagraphStyle paragraph_style;
2251 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2252 TextStyle text_style;
2253 text_style.setColor(SK_ColorBLACK);
2254 text_style.setFontFamilies({SkString("Roboto")});
Julia Lavrova76ae22e2020-02-26 12:14:18 -05002255 text_style.setFontSize(40);
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002256 builder.pushStyle(text_style);
Julia Lavrova76ae22e2020-02-26 12:14:18 -05002257 auto s = u"েن েূথ";
2258 builder.addText(s);
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002259 auto paragraph = builder.Build();
2260 paragraph->layout(width());
2261 paragraph->paint(canvas, 0, 0);
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002262 }
2263
2264private:
2265 typedef Sample INHERITED;
2266};
2267
Julia Lavrova76ae22e2020-02-26 12:14:18 -05002268class ParagraphView32 : public ParagraphView_Base {
2269protected:
2270 SkString name() override { return SkString("Paragraph32"); }
2271
2272 void onDrawContent(SkCanvas* canvas) override {
2273
2274 canvas->drawColor(SK_ColorWHITE);
2275
2276 auto fontCollection = sk_make_sp<FontCollection>();
2277 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2278 fontCollection->enableFontFallback();
2279
2280 ParagraphStyle paragraph_style;
2281 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2282 TextStyle text_style;
2283 text_style.setColor(SK_ColorBLACK);
2284 text_style.setFontFamilies({SkString("Roboto")});
2285 text_style.setFontSize(40);
2286 text_style.setLocale(SkString("ko"));
2287 builder.pushStyle(text_style);
2288 builder.addText(u"\u904d ko ");
2289 text_style.setLocale(SkString("zh_Hant"));
2290 builder.pushStyle(text_style);
2291 builder.addText(u"\u904d zh-Hant ");
2292 text_style.setLocale(SkString("zh_Hans"));
2293 builder.pushStyle(text_style);
2294 builder.addText(u"\u904d zh-Hans ");
2295 text_style.setLocale(SkString("zh_HK"));
2296 builder.pushStyle(text_style);
2297 builder.addText(u"\u904d zh-HK ");
2298 auto paragraph = builder.Build();
2299 paragraph->layout(width());
2300 paragraph->paint(canvas, 0, 0);
2301 }
2302
2303private:
2304 typedef Sample INHERITED;
2305};
2306
2307class ParagraphView33 : public ParagraphView_Base {
2308protected:
2309 SkString name() override { return SkString("Paragraph33"); }
2310
2311 void onDrawContent(SkCanvas* canvas) override {
2312
2313 canvas->drawColor(SK_ColorWHITE);
2314
2315 auto fontCollection = sk_make_sp<FontCollection>();
2316 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2317 fontCollection->enableFontFallback();
2318
2319 ParagraphStyle paragraph_style;
2320 paragraph_style.setTextAlign(TextAlign::kJustify);
2321 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2322 TextStyle text_style;
2323 text_style.setColor(SK_ColorBLACK);
2324 text_style.setFontFamilies({SkString("Roboto"), SkString("Noto Color Emoji")});
2325 text_style.setFontSize(36);
2326 builder.pushStyle(text_style);
2327 builder.addText(u"AAAAA \U0001f600 BBBBB CCCCC DDDDD EEEEE");
2328 auto paragraph = builder.Build();
Julia Lavrovaa0708e82020-02-28 12:14:58 -05002329 paragraph->layout(width() / 2);
2330 SkPaint paint;
2331 paint.setColor(SK_ColorLTGRAY);
2332 canvas->drawRect(SkRect::MakeXYWH(0, 0, width()/2, paragraph->getHeight()), paint);
Julia Lavrova76ae22e2020-02-26 12:14:18 -05002333 paragraph->paint(canvas, 0, 0);
2334 }
2335
2336private:
2337 typedef Sample INHERITED;
2338};
Julia Lavrovaa0708e82020-02-28 12:14:58 -05002339
2340class ParagraphView34 : public ParagraphView_Base {
2341protected:
2342 SkString name() override { return SkString("Paragraph34"); }
2343
2344 void onDrawContent(SkCanvas* canvas) override {
2345
2346 canvas->drawColor(SK_ColorWHITE);
Julia Lavrova3c79a232020-03-02 09:58:52 -05002347 auto text = "ضخمة ص ،😁😂🤣ضضض ؤ،،😗😗😍😋شسي،😗😁😁ؤرى،😗😃😄😍ببب،🥰😅🥰🥰🥰ثيلااتن";
2348 //auto text = "ى،😗😃😄😍بب";
2349 //auto text1 = "World domination is such an ugly phrase - I prefer to call it world optimisation";
2350 auto fontCollection = sk_make_sp<FontCollection>();
2351 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2352 fontCollection->enableFontFallback();
Julia Lavrovaa0708e82020-02-28 12:14:58 -05002353
2354 ParagraphStyle paragraph_style;
Julia Lavrovaa0708e82020-02-28 12:14:58 -05002355 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2356 TextStyle text_style;
2357 text_style.setColor(SK_ColorBLACK);
Julia Lavrova3c79a232020-03-02 09:58:52 -05002358 text_style.setFontFamilies({SkString("Noto Color Emoji")});
2359 text_style.setFontSize(50);
Julia Lavrovaa0708e82020-02-28 12:14:58 -05002360 builder.pushStyle(text_style);
Julia Lavrova3c79a232020-03-02 09:58:52 -05002361 builder.addText(text);
Julia Lavrovaa0708e82020-02-28 12:14:58 -05002362 auto paragraph = builder.Build();
Julia Lavrova3c79a232020-03-02 09:58:52 -05002363 paragraph->layout(1041); // 1041
2364
2365 SkColor colors[] = {SK_ColorBLUE, SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGREEN,
2366 SK_ColorRED, SK_ColorWHITE, SK_ColorYELLOW, SK_ColorMAGENTA };
2367 SkPaint paint;
2368 size_t wordPos = 0;
2369 size_t index = 0;
2370 while (wordPos < 72) {
2371 auto res2 = paragraph->getWordBoundary(wordPos);
2372 if (res2.width() == 0) {
2373 break;
2374 }
2375 wordPos = res2.end;
2376 auto res3 = paragraph->getRectsForRange(
2377 res2.start, res2.end,
2378 RectHeightStyle::kTight, RectWidthStyle::kTight);
2379 paint.setColor(colors[index % 8]);
2380 ++index;
2381 if (!res3.empty()) {
2382 canvas->drawRect(res3[0].rect, paint);
2383 }
2384 }
Julia Lavrovaa0708e82020-02-28 12:14:58 -05002385 paragraph->paint(canvas, 0, 0);
2386 }
2387
2388private:
2389 typedef Sample INHERITED;
2390};
Julia Lavrova3c79a232020-03-02 09:58:52 -05002391
2392class ParagraphView35 : public ParagraphView_Base {
2393protected:
2394 SkString name() override { return SkString("Paragraph35"); }
2395
2396 Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
2397 return new Click;
2398 }
2399
2400 bool onClick(Click* click) override {
2401 fPoint = click->fCurr;
2402 return true;
2403 }
2404
2405 void onDrawContent(SkCanvas* canvas) override {
2406
2407 canvas->drawColor(SK_ColorWHITE);
2408
2409 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";
2410 auto fontCollection = sk_make_sp<FontCollection>();
2411 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2412 fontCollection->enableFontFallback();
2413
2414 ParagraphStyle paragraph_style;
Julia Lavrova2813d452020-03-03 11:43:40 -05002415 //paragraph_style.setTextAlign(TextAlign::kJustify);
Julia Lavrova3c79a232020-03-02 09:58:52 -05002416 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2417 TextStyle text_style;
2418 text_style.setColor(SK_ColorBLACK);
2419 text_style.setFontFamilies({SkString("Roboto"), SkString("Noto Color Emoji")});
2420 text_style.setFontSize(40);
2421 builder.pushStyle(text_style);
2422 builder.addText(text);
2423 auto paragraph = builder.Build();
Julia Lavrova2813d452020-03-03 11:43:40 -05002424 paragraph->layout(width());//758
2425
2426 //auto res1 = paragraph->getGlyphPositionAtCoordinate(line.width() + line.spacesWidth() / 2, line.offset().fY + 10);
2427 //auto res2 = paragraph->getWordBoundary(res1.position);
2428 auto res1 = paragraph->getRectsForRange(360, 361, RectHeightStyle::kTight, RectWidthStyle::kTight);
2429 auto res2 = paragraph->getRectsForRange(359, 360, RectHeightStyle::kTight, RectWidthStyle::kTight);
2430 auto res3 = paragraph->getRectsForRange(358, 359, RectHeightStyle::kTight, RectWidthStyle::kTight);
2431
2432 auto draw = [&](std::vector<TextBox> res, SkColor color) {
2433 SkPaint paint;
2434 paint.setColor(color);
2435 for (auto& r : res) {
2436 canvas->drawRect(r.rect, paint);
2437 }
2438 };
2439
2440 draw(res1, SK_ColorRED);
2441 draw(res2, SK_ColorGREEN);
2442 draw(res3, SK_ColorBLUE);
2443
Julia Lavrova3c79a232020-03-02 09:58:52 -05002444 paragraph->paint(canvas, 0, 0);
Julia Lavrova3c79a232020-03-02 09:58:52 -05002445 }
2446
2447private:
2448 typedef Sample INHERITED;
2449 SkPoint fPoint;
2450};
2451
Julia Lavrova2813d452020-03-03 11:43:40 -05002452class ParagraphView36 : public ParagraphView_Base {
2453protected:
2454 SkString name() override { return SkString("Paragraph36"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04002455
Julia Lavrova2813d452020-03-03 11:43:40 -05002456 void onDrawContent(SkCanvas* canvas) override {
2457
2458 canvas->drawColor(SK_ColorWHITE);
2459
Julia Lavrovacd2a4d62020-03-05 10:31:19 -05002460 auto text = "其实就是要 English 却又无法预览 English 功能强大起来 English 了我觉得自己也 English 可以的时候我们";
Julia Lavrova2813d452020-03-03 11:43:40 -05002461 auto fontCollection = sk_make_sp<FontCollection>();
2462 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
2463 fontCollection->enableFontFallback();
2464
2465 ParagraphStyle paragraph_style;
Julia Lavrova2813d452020-03-03 11:43:40 -05002466 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
2467 TextStyle text_style;
2468 text_style.setColor(SK_ColorBLACK);
Julia Lavrovacd2a4d62020-03-05 10:31:19 -05002469 text_style.setFontFamilies({SkString("Roboto"), SkString("Noto Serif CJK JP")});
2470 text_style.setFontSize(10);
Julia Lavrova2813d452020-03-03 11:43:40 -05002471 builder.pushStyle(text_style);
2472 builder.addText(text);
2473 auto paragraph = builder.Build();
2474 paragraph->layout(width());
2475
Julia Lavrovacd2a4d62020-03-05 10:31:19 -05002476 auto res1 = paragraph->getRectsForRange(63, 64, RectHeightStyle::kTight, RectWidthStyle::kTight);
2477 auto rect = res1[0].rect;
2478 auto res2 = paragraph->getGlyphPositionAtCoordinate(rect.fLeft + rect.width() / 2, rect.height());
2479 auto res3 = paragraph->getWordBoundary(res2.position);
2480 SkDebugf("[%d:%d)\n", res3.start, res3.end);
Julia Lavrova2813d452020-03-03 11:43:40 -05002481
2482 paragraph->paint(canvas, 0, 0);
2483 }
2484
2485private:
2486 typedef Sample INHERITED;
2487};
2488
2489//"\U0001f469\u200D\U0001f469\u200D\U0001f466\U0001f469\u200D\U0001f469\u200D\U0001f467\u200D\U0001f467\U0001f1fa\U0001f1f8"
2490//////////////////////////////////////////////////////////////////////////////
Julia Lavrovaa3552c52019-05-30 16:12:56 -04002491DEF_SAMPLE(return new ParagraphView1();)
2492DEF_SAMPLE(return new ParagraphView2();)
2493DEF_SAMPLE(return new ParagraphView3();)
2494DEF_SAMPLE(return new ParagraphView4();)
2495DEF_SAMPLE(return new ParagraphView5();)
2496DEF_SAMPLE(return new ParagraphView6();)
2497DEF_SAMPLE(return new ParagraphView7();)
2498DEF_SAMPLE(return new ParagraphView8();)
2499DEF_SAMPLE(return new ParagraphView9();)
2500DEF_SAMPLE(return new ParagraphView10();)
2501DEF_SAMPLE(return new ParagraphView11();)
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04002502DEF_SAMPLE(return new ParagraphView12();)
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04002503DEF_SAMPLE(return new ParagraphView14();)
2504DEF_SAMPLE(return new ParagraphView15();)
Julia Lavrova2e30fde2019-10-09 09:43:02 -04002505DEF_SAMPLE(return new ParagraphView16();)
2506DEF_SAMPLE(return new ParagraphView17();)
2507DEF_SAMPLE(return new ParagraphView18();)
2508DEF_SAMPLE(return new ParagraphView19();)
Julia Lavrovac028b422019-11-25 10:00:43 -05002509DEF_SAMPLE(return new ParagraphView20();)
Julia Lavrovac48687a2020-01-08 16:53:53 -05002510DEF_SAMPLE(return new ParagraphView21();)
Julia Lavrova4cf18742020-01-14 13:24:45 -05002511DEF_SAMPLE(return new ParagraphView22();)
Julia Lavrova51a813d2020-01-21 13:55:44 -05002512DEF_SAMPLE(return new ParagraphView23();)
Julia Lavrova2ea20ea2020-01-22 10:56:53 -05002513DEF_SAMPLE(return new ParagraphView24();)
2514DEF_SAMPLE(return new ParagraphView25();)
Julia Lavrova212bf072020-02-18 12:05:55 -05002515DEF_SAMPLE(return new ParagraphView26();)
2516DEF_SAMPLE(return new ParagraphView27();)
2517DEF_SAMPLE(return new ParagraphView28();)
2518DEF_SAMPLE(return new ParagraphView29();)
Julia Lavrova7dcb4d22020-02-20 12:04:36 -05002519DEF_SAMPLE(return new ParagraphView30();)
2520DEF_SAMPLE(return new ParagraphView31();)
Julia Lavrova76ae22e2020-02-26 12:14:18 -05002521DEF_SAMPLE(return new ParagraphView32();)
2522DEF_SAMPLE(return new ParagraphView33();)
Julia Lavrovaa0708e82020-02-28 12:14:58 -05002523DEF_SAMPLE(return new ParagraphView34();)
Julia Lavrova3c79a232020-03-02 09:58:52 -05002524DEF_SAMPLE(return new ParagraphView35();)
Julia Lavrova2813d452020-03-03 11:43:40 -05002525DEF_SAMPLE(return new ParagraphView36();)