blob: 8141c14bce197fda9e02db70f482dad4bd28e9a1 [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);
1872
1873 const char* text = "Overflowing endorsement that has a large lengthy text and is a lot longer than expected";
1874 ParagraphStyle paragraph_style;
1875 paragraph_style.setEllipsis(u"\u2026");
1876 paragraph_style.setMaxLines(std::numeric_limits<size_t>::max());
1877 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1878 TextStyle text_style;
1879 text_style.setColor(SK_ColorBLACK);
1880 text_style.setFontFamilies({SkString("Google Sans")});
1881 text_style.setFontSize(20);
1882 builder.pushStyle(text_style);
1883 builder.addText(text);
1884 auto paragraph = builder.Build();
1885 paragraph->layout(594.0f);
1886 paragraph->paint(canvas, 0, 0);
1887 canvas->translate(0, 200);
1888 paragraph->layout(std::numeric_limits<SkScalar>::max());
1889 paragraph->paint(canvas, 0, 0);
1890 canvas->translate(0, 200);
1891 paragraph->layout(787.0f);
1892 paragraph->paint(canvas, 0, 0);
1893 }
1894
1895private:
1896 typedef Sample INHERITED;
1897};
1898
1899class ParagraphView26 : public ParagraphView_Base {
1900protected:
1901 SkString name() override { return SkString("Paragraph26"); }
1902
1903 void onDrawContent(SkCanvas* canvas) override {
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001904 auto fontCollection = sk_make_sp<FontCollection>();
1905 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
Julia Lavrova95a9e692020-02-05 10:17:53 -05001906 //fontCollection->enableFontFallback();
Julia Lavrova2ea20ea2020-01-22 10:56:53 -05001907
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001908 canvas->clear(SK_ColorWHITE);
1909
1910 SkPaint paint;
1911 paint.setAntiAlias(true);
1912 paint.setColor(SK_ColorBLACK);
1913
1914 TextStyle textStyle;
1915 textStyle.setForegroundColor(paint);
Julia Lavrova95a9e692020-02-05 10:17:53 -05001916 textStyle.setFontFamilies({ SkString("Roboto") });
1917 textStyle.setFontSize(42.0f);
1918 textStyle.setLetterSpacing(-0.05f);
1919 textStyle.setHeightOverride(true);
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001920
1921 ParagraphStyle paragraphStyle;
1922 paragraphStyle.setTextStyle(textStyle);
1923 paragraphStyle.setTextAlign(TextAlign::kLeft);
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001924
Julia Lavrova95a9e692020-02-05 10:17:53 -05001925 ParagraphBuilderImpl builder(paragraphStyle, fontCollection);
1926 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 -05001927
Julia Lavrova95a9e692020-02-05 10:17:53 -05001928 auto paragraph = builder.Build();
1929 paragraph->layout(this->width() / 2);
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001930
Julia Lavrova95a9e692020-02-05 10:17:53 -05001931 std::vector<LineMetrics> lines;
1932 paragraph->getLineMetrics(lines); // <-- error happens here
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001933
Julia Lavrova95a9e692020-02-05 10:17:53 -05001934 canvas->translate(10, 10);
1935 paragraph->paint(canvas, 0, 0);
Julia Lavrova2ea20ea2020-01-22 10:56:53 -05001936 }
1937
1938private:
1939 typedef Sample INHERITED;
1940};
1941
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05001942class ParagraphView27 : public ParagraphView_Base {
1943protected:
1944 SkString name() override { return SkString("Paragraph27"); }
1945
1946 void onDrawContent(SkCanvas* canvas) override {
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001947 auto fontCollection = sk_make_sp<FontCollection>();
1948 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1949 fontCollection->enableFontFallback();
1950 fontCollection->getParagraphCache()->turnOn(false);
1951
1952 SkPaint red;
1953 red.setColor(SK_ColorRED);
1954 red.setStyle(SkPaint::kStroke_Style);
1955 red.setAntiAlias(true);
1956 red.setStrokeWidth(1);
1957
1958 SkPaint blue;
1959 blue.setColor(SK_ColorRED);
1960 blue.setStyle(SkPaint::kStroke_Style);
1961 blue.setAntiAlias(true);
1962 blue.setStrokeWidth(1);
1963
1964 SkPaint black;
1965 black.setColor(SK_ColorBLACK);
1966 black.setStyle(SkPaint::kStroke_Style);
1967 black.setAntiAlias(true);
1968 black.setStrokeWidth(1);
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05001969
Julia Lavrova95a9e692020-02-05 10:17:53 -05001970 SkPaint whiteSpaces;
1971 whiteSpaces.setColor(SK_ColorLTGRAY);
1972
1973 SkPaint breakingSpace;
1974 breakingSpace.setColor(SK_ColorYELLOW);
1975
1976 SkPaint text;
1977 text.setColor(SK_ColorWHITE);
1978
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05001979 ParagraphStyle paragraph_style;
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001980 paragraph_style.setTextAlign(TextAlign::kRight);
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05001981 TextStyle text_style;
1982 text_style.setColor(SK_ColorBLACK);
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001983 text_style.setFontFamilies({SkString("Roboto")});
Julia Lavrova89e678d2020-01-28 10:43:31 -05001984
Julia Lavrovad3a32c52020-02-03 09:43:52 -05001985 // RTL + right align + arabic
1986 // RTL + right align + latin
1987 // LTR + right align + arabic
1988 // LTR + right align + latin
1989 // RTL + left align + arabic
1990 // RTL + left align + latin
1991 // arabic and latin should not differ at all
1992 // check: line breaking and trailing spaces
1993
1994 canvas->drawColor(SK_ColorWHITE);
1995 auto h = 60;
1996 auto w = 300;
1997
Julia Lavrova95a9e692020-02-05 10:17:53 -05001998 auto draw = [&](SkScalar width, SkScalar height, TextDirection td, TextAlign ta, const char* t) {
1999 SkDebugf("draw '%s' dir:%s align:%s\n", t,
Julia Lavrovad3a32c52020-02-03 09:43:52 -05002000 td == TextDirection::kLtr ? "left" : "right",
2001 ta == TextAlign::kLeft ? "left" : "right");
2002 paragraph_style.setTextDirection(td);
2003 paragraph_style.setTextAlign(ta);
2004 text_style.setFontSize(20);
2005 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
Julia Lavrova95a9e692020-02-05 10:17:53 -05002006 text_style.setBackgroundColor(whiteSpaces);
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002007 builder.pushStyle(text_style);
Julia Lavrova95a9e692020-02-05 10:17:53 -05002008 builder.addText(" ");
2009 text_style.setBackgroundColor(text);
2010 builder.pushStyle(text_style);
2011 builder.addText(t);
2012 text_style.setBackgroundColor(breakingSpace);
2013 builder.pushStyle(text_style);
2014 builder.addText(" ");
2015 text_style.setBackgroundColor(text);
2016 builder.pushStyle(text_style);
2017 builder.addText(t);
2018 text_style.setBackgroundColor(whiteSpaces);
2019 builder.pushStyle(text_style);
2020 builder.addText(" ");
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002021 auto paragraph = builder.Build();
Julia Lavrovad3a32c52020-02-03 09:43:52 -05002022 paragraph->layout(width);
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002023 paragraph->paint(canvas, 0, 0);
Julia Lavrovad3a32c52020-02-03 09:43:52 -05002024 auto impl = static_cast<ParagraphImpl*>(paragraph.get());
2025 for (auto& line : impl->lines()) {
2026 SkDebugf("line[%d]: %f + %f\n", &line - impl->lines().begin(), line.offset().fX, line.shift());
2027 line.iterateThroughVisualRuns(true,
2028 [&](const Run* run, SkScalar runOffset, TextRange textRange, SkScalar* width) {
2029 *width = line.measureTextInsideOneRun(textRange, run, runOffset, 0, true, false).clip.width();
2030 SkDebugf("%d[%d: %d) @%f + %f %s\n", run->index(),
2031 textRange.start, textRange.end, runOffset, *width, run->leftToRight() ? "left" : "right");
2032 return true;
2033 });
2034 }
2035 auto boxes = paragraph->getRectsForRange(0, 100, RectHeightStyle::kTight, RectWidthStyle::kTight);
2036 bool even = true;
2037 for (auto& box : boxes) {
2038 SkDebugf("[%f:%f,%f:%f] %s\n",
2039 box.rect.fLeft, box.rect.fRight, box.rect.fTop, box.rect.fBottom,
2040 box.direction == TextDirection::kLtr ? "left" : "right");
2041 canvas->drawRect(box.rect, even ? red : blue);
2042 even = !even;
2043 }
2044 canvas->translate(0, height);
Julia Lavrova89e678d2020-01-28 10:43:31 -05002045 };
2046
Julia Lavrovad3a32c52020-02-03 09:43:52 -05002047 canvas->drawRect(SkRect::MakeXYWH(0, 0, w, h * 8), black);
2048
2049 draw(w, h, TextDirection::kRtl, TextAlign::kRight, "RTL+RIGHT#1234567890");
2050 draw(w, h, TextDirection::kRtl, TextAlign::kRight, "قففغغغغقففغغغغقففغغغ");
2051
2052 draw(w, h, TextDirection::kLtr, TextAlign::kRight, "LTR+RIGHT#1234567890");
2053 draw(w, h, TextDirection::kLtr, TextAlign::kRight, "قففغغغغقففغغغغقففغغغ");
2054
2055 draw(w, h, TextDirection::kRtl, TextAlign::kLeft, "RTL+LEFT##1234567890");
2056 draw(w, h, TextDirection::kRtl, TextAlign::kLeft, "قففغغغغقففغغغغقففغغغ");
2057
2058 draw(w, h, TextDirection::kLtr, TextAlign::kLeft, "LTR+LEFT##1234567890");
2059 draw(w, h, TextDirection::kLtr, TextAlign::kLeft, "قففغغغغقففغغغغقففغغغ");
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002060 }
2061
2062private:
2063 typedef Sample INHERITED;
2064};
2065
Julia Lavrovaa3552c52019-05-30 16:12:56 -04002066//////////////////////////////////////////////////////////////////////////////
2067
2068DEF_SAMPLE(return new ParagraphView1();)
2069DEF_SAMPLE(return new ParagraphView2();)
2070DEF_SAMPLE(return new ParagraphView3();)
2071DEF_SAMPLE(return new ParagraphView4();)
2072DEF_SAMPLE(return new ParagraphView5();)
2073DEF_SAMPLE(return new ParagraphView6();)
2074DEF_SAMPLE(return new ParagraphView7();)
2075DEF_SAMPLE(return new ParagraphView8();)
2076DEF_SAMPLE(return new ParagraphView9();)
2077DEF_SAMPLE(return new ParagraphView10();)
2078DEF_SAMPLE(return new ParagraphView11();)
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04002079DEF_SAMPLE(return new ParagraphView12();)
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04002080DEF_SAMPLE(return new ParagraphView14();)
2081DEF_SAMPLE(return new ParagraphView15();)
Julia Lavrova2e30fde2019-10-09 09:43:02 -04002082DEF_SAMPLE(return new ParagraphView16();)
2083DEF_SAMPLE(return new ParagraphView17();)
2084DEF_SAMPLE(return new ParagraphView18();)
2085DEF_SAMPLE(return new ParagraphView19();)
Julia Lavrovac028b422019-11-25 10:00:43 -05002086DEF_SAMPLE(return new ParagraphView20();)
Julia Lavrovac48687a2020-01-08 16:53:53 -05002087DEF_SAMPLE(return new ParagraphView21();)
Julia Lavrova4cf18742020-01-14 13:24:45 -05002088DEF_SAMPLE(return new ParagraphView22();)
Julia Lavrova51a813d2020-01-21 13:55:44 -05002089DEF_SAMPLE(return new ParagraphView23();)
Julia Lavrova2ea20ea2020-01-22 10:56:53 -05002090DEF_SAMPLE(return new ParagraphView24();)
2091DEF_SAMPLE(return new ParagraphView25();)
2092DEF_SAMPLE(return new ParagraphView26();)
Julia Lavrovac88a3bc2020-01-23 10:16:26 -05002093DEF_SAMPLE(return new ParagraphView27();)