blob: cc10e03223c0c96a4a7be9022694de041cf77ead [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"
13#include "include/effects/SkBlurMaskFilter.h"
14#include "include/effects/SkGradientShader.h"
15#include "include/utils/SkRandom.h"
16#include "modules/skparagraph/include/Paragraph.h"
Julia Lavrova6e6333f2019-06-17 10:34:10 -040017#include "modules/skparagraph/include/TypefaceFontProvider.h"
Julia Lavrovaa3552c52019-05-30 16:12:56 -040018#include "modules/skparagraph/src/ParagraphBuilderImpl.h"
19#include "modules/skparagraph/src/ParagraphImpl.h"
Julia Lavrova9af5cc42019-06-19 13:32:01 -040020#include "modules/skparagraph/utils/TestFontCollection.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040021#include "samplecode/Sample.h"
Julia Lavrovaa3552c52019-05-30 16:12:56 -040022#include "src/core/SkOSFile.h"
23#include "src/shaders/SkColorShader.h"
Julia Lavrova2e30fde2019-10-09 09:43:02 -040024#include "src/utils/SkOSPath.h"
Julia Lavrovaa3552c52019-05-30 16:12:56 -040025#include "src/utils/SkUTF.h"
26#include "tools/Resources.h"
27
28using namespace skia::textlayout;
29namespace {
30
Mike Reed21a940d2019-07-23 10:11:03 -040031class ParagraphView_Base : public Sample {
32protected:
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -040033 sk_sp<TestFontCollection> getFontCollection() {
34 // If we reset font collection we need to reset paragraph cache
35 static sk_sp<TestFontCollection> fFC = nullptr;
36 if (fFC == nullptr) {
Julia Lavrova2e30fde2019-10-09 09:43:02 -040037 fFC = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -040038 }
39 return fFC;
Mike Reed21a940d2019-07-23 10:11:03 -040040 }
41};
42
Julia Lavrovaa3552c52019-05-30 16:12:56 -040043sk_sp<SkShader> setgrad(const SkRect& r, SkColor c0, SkColor c1) {
44 SkColor colors[] = {c0, c1};
45 SkPoint pts[] = {{r.fLeft, r.fTop}, {r.fRight, r.fTop}};
46 return SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
47}
Julia Lavrova2e30fde2019-10-09 09:43:02 -040048/*
49void writeHtml(const char* name, Paragraph* paragraph) {
50 SkString tmpDir = skiatest::GetTmpDir();
51 if (!tmpDir.isEmpty()) {
52 SkString path = SkOSPath::Join(tmpDir.c_str(), name);
53 SkFILEWStream file(path.c_str());
54 file.write(nullptr, 0);
55 }
56}
57*/
Julia Lavrovaa3552c52019-05-30 16:12:56 -040058} // namespace
59
Mike Reed21a940d2019-07-23 10:11:03 -040060class ParagraphView1 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -040061protected:
Hal Canary8a027312019-07-03 10:55:44 -040062 SkString name() override { return SkString("Paragraph1"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -040063
64 void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) {
65 const std::vector<
66 std::tuple<std::string, bool, bool, int, SkColor, SkColor, bool, TextDecorationStyle>>
67 gParagraph = {{"monospace", true, false, 14, SK_ColorWHITE, SK_ColorRED, true,
68 TextDecorationStyle::kDashed},
69 {"Assyrian", false, false, 20, SK_ColorWHITE, SK_ColorBLUE, false,
70 TextDecorationStyle::kDotted},
71 {"serif", true, true, 10, SK_ColorWHITE, SK_ColorRED, true,
72 TextDecorationStyle::kDouble},
73 {"Arial", false, true, 16, SK_ColorGRAY, SK_ColorGREEN, true,
74 TextDecorationStyle::kSolid},
75 {"sans-serif", false, false, 8, SK_ColorWHITE, SK_ColorRED, false,
76 TextDecorationStyle::kWavy}};
77 SkAutoCanvasRestore acr(canvas, true);
78
79 canvas->clipRect(SkRect::MakeWH(w, h));
80 canvas->drawColor(SK_ColorWHITE);
81
82 SkScalar margin = 20;
83
84 SkPaint paint;
85 paint.setAntiAlias(true);
86 paint.setColor(fg);
87
88 SkPaint blue;
89 blue.setColor(SK_ColorBLUE);
90
91 TextStyle defaultStyle;
92 defaultStyle.setBackgroundColor(blue);
93 defaultStyle.setForegroundColor(paint);
94 ParagraphStyle paraStyle;
95
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -040096 auto fontCollection = sk_make_sp<FontCollection>();
97 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
Julia Lavrovaa3552c52019-05-30 16:12:56 -040098 for (auto i = 1; i < 5; ++i) {
99 defaultStyle.setFontSize(24 * i);
100 paraStyle.setTextStyle(defaultStyle);
Julia Lavrova5207f352019-06-21 12:22:32 -0400101 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400102 std::string name = "Paragraph: " + std::to_string(24 * i);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400103 builder.addText(name.c_str(), name.length());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400104 for (auto para : gParagraph) {
105 TextStyle style;
106 style.setFontFamilies({SkString(std::get<0>(para).c_str())});
107 SkFontStyle fontStyle(std::get<1>(para) ? SkFontStyle::Weight::kBold_Weight
108 : SkFontStyle::Weight::kNormal_Weight,
109 SkFontStyle::Width::kNormal_Width,
110 std::get<2>(para) ? SkFontStyle::Slant::kItalic_Slant
111 : SkFontStyle::Slant::kUpright_Slant);
112 style.setFontStyle(fontStyle);
113 style.setFontSize(std::get<3>(para) * i);
114 SkPaint background;
115 background.setColor(std::get<4>(para));
116 style.setBackgroundColor(background);
117 SkPaint foreground;
118 foreground.setColor(std::get<5>(para));
119 foreground.setAntiAlias(true);
120 style.setForegroundColor(foreground);
121 if (std::get<6>(para)) {
122 style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(5, 5), 2));
123 }
124
125 auto decoration = (i % 4);
126 if (decoration == 3) {
127 decoration = 4;
128 }
129
130 bool test = (TextDecoration)decoration != TextDecoration::kNoDecoration;
131 std::string deco = std::to_string((int)decoration);
132 if (test) {
133 style.setDecoration((TextDecoration)decoration);
134 style.setDecorationStyle(std::get<7>(para));
135 style.setDecorationColor(std::get<5>(para));
136 }
137 builder.pushStyle(style);
138 std::string name = " " + std::get<0>(para) + " " +
139 (std::get<1>(para) ? ", bold" : "") +
140 (std::get<2>(para) ? ", italic" : "") + " " +
141 std::to_string(std::get<3>(para) * i) +
142 (std::get<4>(para) != bg ? ", background" : "") +
143 (std::get<5>(para) != fg ? ", foreground" : "") +
144 (std::get<6>(para) ? ", shadow" : "") +
145 (test ? ", decorations " + deco : "") + ";";
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400146 builder.addText(name.c_str(), name.length());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400147 builder.pop();
148 }
149
150 auto paragraph = builder.Build();
151 paragraph->layout(w - margin * 2);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400152 paragraph->paint(canvas, margin, margin);
153
154 canvas->translate(0, paragraph->getHeight());
155 }
156 }
157
158 void onDrawContent(SkCanvas* canvas) override {
159 drawTest(canvas, this->width(), this->height(), SK_ColorRED, SK_ColorWHITE);
160 }
161
162private:
163
164 typedef Sample INHERITED;
165};
166
Mike Reed21a940d2019-07-23 10:11:03 -0400167class ParagraphView2 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400168protected:
Hal Canary8a027312019-07-03 10:55:44 -0400169 SkString name() override { return SkString("Paragraph2"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400170
171 void drawCode(SkCanvas* canvas, SkScalar w, SkScalar h) {
172 SkPaint comment;
173 comment.setColor(SK_ColorGRAY);
174 SkPaint constant;
175 constant.setColor(SK_ColorMAGENTA);
176 SkPaint null;
177 null.setColor(SK_ColorMAGENTA);
178 SkPaint literal;
179 literal.setColor(SK_ColorGREEN);
180 SkPaint code;
181 code.setColor(SK_ColorDKGRAY);
182 SkPaint number;
183 number.setColor(SK_ColorBLUE);
184 SkPaint name;
185 name.setColor(SK_ColorRED);
186
187 SkPaint white;
188 white.setColor(SK_ColorWHITE);
189
190 TextStyle defaultStyle;
191 defaultStyle.setBackgroundColor(white);
192 defaultStyle.setForegroundColor(code);
193 defaultStyle.setFontFamilies({SkString("monospace")});
194 defaultStyle.setFontSize(30);
195 ParagraphStyle paraStyle;
196 paraStyle.setTextStyle(defaultStyle);
197
Julia Lavrova5207f352019-06-21 12:22:32 -0400198 auto fontCollection = sk_make_sp<FontCollection>();
199 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
200 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400201
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400202 const char* text1 = "RaisedButton";
203 const char* text2 = "(\n";
204 const char* text3 = " child: ";
205 const char* text4 = "const";
206 const char* text5 = "Text";
207 const char* text6 = "'BUTTON TITLE'";
208 const char* text7 = "),\n";
209
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400210 builder.pushStyle(style(name));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400211 builder.addText(text1, strlen(text1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400212 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400213 builder.addText(text2, strlen(text2));
214 builder.addText(text3, strlen(text3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400215 builder.pushStyle(style(constant));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400216 builder.addText(text4, strlen(text4));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400217 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400218 builder.addText(" ", 1);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400219 builder.pushStyle(style(name));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400220 builder.addText(text5, strlen(text5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400221 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400222 builder.addText("(", 1);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400223 builder.pushStyle(style(literal));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400224 builder.addText(text6, strlen(text6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400225 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400226 builder.addText(text7, strlen(text7));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400227
228 auto paragraph = builder.Build();
229 paragraph->layout(w - 20);
230
231 paragraph->paint(canvas, 20, 20);
232 }
233
234 TextStyle style(SkPaint paint) {
235 TextStyle style;
236 paint.setAntiAlias(true);
237 style.setForegroundColor(paint);
238 style.setFontFamilies({SkString("monospace")});
239 style.setFontSize(30);
240
241 return style;
242 }
243
Julia Lavrova5207f352019-06-21 12:22:32 -0400244 void drawText(SkCanvas* canvas, SkScalar w, SkScalar h, std::vector<const char*>& text,
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400245 SkColor fg = SK_ColorDKGRAY, SkColor bg = SK_ColorWHITE,
246 const char* ff = "sans-serif", SkScalar fs = 24,
247 size_t lineLimit = 30,
248 const std::u16string& ellipsis = u"\u2026") {
249 SkAutoCanvasRestore acr(canvas, true);
250
251 canvas->clipRect(SkRect::MakeWH(w, h));
252 canvas->drawColor(bg);
253
254 SkScalar margin = 20;
255
256 SkPaint paint;
257 paint.setAntiAlias(true);
258 paint.setColor(fg);
259
260 SkPaint blue;
261 blue.setColor(SK_ColorBLUE);
262
263 SkPaint background;
264 background.setColor(bg);
265
266 TextStyle style;
267 style.setBackgroundColor(blue);
268 style.setForegroundColor(paint);
269 style.setFontFamilies({SkString(ff)});
270 style.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight,
271 SkFontStyle::kNormal_Width,
272 SkFontStyle::kUpright_Slant));
273 style.setFontSize(fs);
274 ParagraphStyle paraStyle;
275 paraStyle.setTextStyle(style);
276 paraStyle.setMaxLines(lineLimit);
277
278 paraStyle.setEllipsis(ellipsis);
279 TextStyle defaultStyle;
280 defaultStyle.setFontSize(20);
281 paraStyle.setTextStyle(defaultStyle);
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400282 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400283
284 SkPaint foreground;
285 foreground.setColor(fg);
286 style.setForegroundColor(foreground);
287 style.setBackgroundColor(background);
288
289 for (auto& part : text) {
290 builder.pushStyle(style);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400291 builder.addText(part, strlen(part));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400292 builder.pop();
293 }
294
295 auto paragraph = builder.Build();
296 paragraph->layout(w - margin * 2);
297 paragraph->paint(canvas, margin, margin);
298
299 canvas->translate(0, paragraph->getHeight() + margin);
300 }
301
302 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
303 TextAlign align) {
304 SkAutoCanvasRestore acr(canvas, true);
305
306 canvas->clipRect(SkRect::MakeWH(w, h));
307 canvas->drawColor(SK_ColorWHITE);
308
309 SkScalar margin = 20;
310
311 SkPaint paint;
312 paint.setAntiAlias(true);
313 paint.setColor(SK_ColorBLUE);
314
315 SkPaint gray;
316 gray.setColor(SK_ColorLTGRAY);
317
318 TextStyle style;
319 style.setBackgroundColor(gray);
320 style.setForegroundColor(paint);
321 style.setFontFamilies({SkString("Arial")});
322 style.setFontSize(30);
323 ParagraphStyle paraStyle;
324 paraStyle.setTextStyle(style);
325 paraStyle.setTextAlign(align);
326
Julia Lavrova5207f352019-06-21 12:22:32 -0400327 auto fontCollection = sk_make_sp<FontCollection>();
328 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
329 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400330 builder.addText(text.c_str(), text.length());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400331
332 auto paragraph = builder.Build();
333 paragraph->layout(w - margin * 2);
334 paragraph->layout(w - margin);
335 paragraph->paint(canvas, margin, margin);
336
337 canvas->translate(0, paragraph->getHeight() + margin);
338 }
339
340 void onDrawContent(SkCanvas* canvas) override {
Julia Lavrova5207f352019-06-21 12:22:32 -0400341 std::vector<const char*> cupertino = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400342 "google_logogoogle_gsuper_g_logo 1 "
343 "google_logogoogle_gsuper_g_logo 12 "
344 "google_logogoogle_gsuper_g_logo 123 "
345 "google_logogoogle_gsuper_g_logo 1234 "
346 "google_logogoogle_gsuper_g_logo 12345 "
347 "google_logogoogle_gsuper_g_logo 123456 "
348 "google_logogoogle_gsuper_g_logo 1234567 "
349 "google_logogoogle_gsuper_g_logo 12345678 "
350 "google_logogoogle_gsuper_g_logo 123456789 "
351 "google_logogoogle_gsuper_g_logo 1234567890 "
352 "google_logogoogle_gsuper_g_logo 123456789 "
353 "google_logogoogle_gsuper_g_logo 12345678 "
354 "google_logogoogle_gsuper_g_logo 1234567 "
355 "google_logogoogle_gsuper_g_logo 123456 "
356 "google_logogoogle_gsuper_g_logo 12345 "
357 "google_logogoogle_gsuper_g_logo 1234 "
358 "google_logogoogle_gsuper_g_logo 123 "
359 "google_logogoogle_gsuper_g_logo 12 "
360 "google_logogoogle_gsuper_g_logo 1 "
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 "
366 "google_logogoogle_gsuper_g_logo"};
Julia Lavrova5207f352019-06-21 12:22:32 -0400367 std::vector<const char*> text = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400368 "My neighbor came over to say,\n"
369 "Although not in a neighborly way,\n\n"
370 "That he'd knock me around,\n\n\n"
371 "If I didn't stop the sound,\n\n\n\n"
372 "Of the classical music I play."};
373
Julia Lavrova5207f352019-06-21 12:22:32 -0400374 std::vector<const char*> long_word = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400375 "A_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_very_very_very_very_very_very_very_very_very_"
378 "very_very_very_very_very_very_very_long_text"};
379
Julia Lavrova5207f352019-06-21 12:22:32 -0400380 std::vector<const char*> very_long = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400381 "A 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 very very very very very very very very very "
384 "very very very very very very very long text"};
385
Julia Lavrova5207f352019-06-21 12:22:32 -0400386 std::vector<const char*> very_word = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400387 "A 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 very very very "
390 "very very very very very very very very very very very very very long text"};
391
392 SkScalar width = this->width() / 5;
393 SkScalar height = this->height();
394 drawText(canvas, width, height, long_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
395 canvas->translate(width, 0);
396 drawText(canvas, width, height, very_long, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
397 canvas->translate(width, 0);
398 drawText(canvas, width, height, very_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
399 canvas->translate(width, 0);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400400 drawText(canvas, width, height / 2, text, SK_ColorBLACK, SK_ColorWHITE, "Roboto", 20, 100,
401 u"\u2026");
402 canvas->translate(0, height / 2);
403 drawCode(canvas, width, height / 2);
404 canvas->translate(width, -height / 2);
405
406 drawText(canvas, width, height, cupertino, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
407 }
408
409private:
410 typedef Sample INHERITED;
411};
412
Mike Reed21a940d2019-07-23 10:11:03 -0400413class ParagraphView3 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400414protected:
Hal Canary8a027312019-07-03 10:55:44 -0400415 SkString name() override { return SkString("Paragraph3"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400416
417 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
418 TextAlign align, size_t lineLimit = std::numeric_limits<size_t>::max(),
419 bool RTL = false, SkColor background = SK_ColorGRAY,
420 const std::u16string& ellipsis = u"\u2026") {
421 SkAutoCanvasRestore acr(canvas, true);
422
423 canvas->clipRect(SkRect::MakeWH(w, h));
424 canvas->drawColor(SK_ColorWHITE);
425
426 SkScalar margin = 20;
427
428 SkPaint paint;
429 paint.setAntiAlias(true);
430 paint.setColor(SK_ColorBLACK);
431
432 SkPaint gray;
433 gray.setColor(background);
434
435 SkPaint yellow;
436 yellow.setColor(SK_ColorYELLOW);
437
438 TextStyle style;
439 style.setBackgroundColor(gray);
440 style.setForegroundColor(paint);
441 style.setFontFamilies({SkString("sans-serif")});
442 style.setFontSize(30);
443 ParagraphStyle paraStyle;
444 paraStyle.setTextStyle(style);
445 paraStyle.setTextAlign(align);
446 paraStyle.setMaxLines(lineLimit);
447 paraStyle.setEllipsis(ellipsis);
448 // paraStyle.setTextDirection(RTL ? SkTextDirection::rtl : SkTextDirection::ltr);
449
Julia Lavrova5207f352019-06-21 12:22:32 -0400450 auto fontCollection = sk_make_sp<FontCollection>();
451 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
452 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400453 if (RTL) {
454 builder.addText(mirror(text));
455 } else {
456 builder.addText(normal(text));
457 }
458
459 canvas->drawRect(SkRect::MakeXYWH(margin, margin, w - margin * 2, h - margin * 2), yellow);
460 auto paragraph = builder.Build();
461 paragraph->layout(w - margin * 2);
462 paragraph->paint(canvas, margin, margin);
463 }
464
465 std::u16string mirror(const std::string& text) {
466 std::u16string result;
467 result += u"\u202E";
468 // for (auto i = text.size(); i > 0; --i) {
469 // result += text[i - 1];
470 //}
471
472 for (auto i = text.size(); i > 0; --i) {
473 auto ch = text[i - 1];
474 if (ch == ',') {
475 result += u"!";
476 } else if (ch == '.') {
477 result += u"!";
478 } else {
479 result += ch;
480 }
481 }
482
483 result += u"\u202C";
484 return result;
485 }
486
487 std::u16string normal(const std::string& text) {
488 std::u16string result;
489 result += u"\u202D";
490 for (auto ch : text) {
491 result += ch;
492 }
493 result += u"\u202C";
494 return result;
495 }
496
497 void onDrawContent(SkCanvas* canvas) override {
498 const std::string options = // { "open-source open-source open-source open-source" };
499 {"Flutter is an open-source project to help developers "
500 "build high-performance, high-fidelity, mobile apps for "
501 "iOS and Android "
502 "from a single codebase. This design lab is a playground "
503 "and showcase of Flutter's many widgets, behaviors, "
504 "animations, layouts, and more."};
505
506 canvas->drawColor(SK_ColorDKGRAY);
507 SkScalar width = this->width() / 4;
508 SkScalar height = this->height() / 2;
509
510 const std::string line =
511 "World domination is such an ugly phrase - I prefer to call it world optimisation";
512
513 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, false, SK_ColorLTGRAY);
514 canvas->translate(width, 0);
515 drawLine(canvas, width, height, line, TextAlign::kRight, 2, false, SK_ColorLTGRAY);
516 canvas->translate(width, 0);
517 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, false, SK_ColorLTGRAY);
518 canvas->translate(width, 0);
519 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, false, SK_ColorLTGRAY);
520 canvas->translate(-width * 3, height);
521
522 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, true, SK_ColorLTGRAY);
523 canvas->translate(width, 0);
524 drawLine(canvas, width, height, line, TextAlign::kRight, 2, true, SK_ColorLTGRAY);
525 canvas->translate(width, 0);
526 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, true, SK_ColorLTGRAY);
527 canvas->translate(width, 0);
528 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, true, SK_ColorLTGRAY);
529 canvas->translate(width, 0);
530 }
531
532private:
533 typedef Sample INHERITED;
534};
535
Mike Reed21a940d2019-07-23 10:11:03 -0400536class ParagraphView4 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400537protected:
Hal Canary8a027312019-07-03 10:55:44 -0400538 SkString name() override { return SkString("Paragraph4"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400539
540 void drawFlutter(SkCanvas* canvas, SkScalar w, SkScalar h,
541 const char* ff = "Google Sans", SkScalar fs = 30,
542 size_t lineLimit = std::numeric_limits<size_t>::max(),
543 const std::u16string& ellipsis = u"\u2026") {
544 SkAutoCanvasRestore acr(canvas, true);
545
546 canvas->clipRect(SkRect::MakeWH(w, h));
547
548 SkScalar margin = 20;
549
550 SkPaint black;
551 black.setAntiAlias(true);
552 black.setColor(SK_ColorBLACK);
553
554 SkPaint blue;
555 blue.setAntiAlias(true);
556 blue.setColor(SK_ColorBLUE);
557
558 SkPaint red;
559 red.setAntiAlias(true);
560 red.setColor(SK_ColorRED);
561
562 SkPaint green;
563 green.setAntiAlias(true);
564 green.setColor(SK_ColorGREEN);
565
566 SkPaint gray;
567 gray.setColor(SK_ColorLTGRAY);
568
569 SkPaint yellow;
570 yellow.setColor(SK_ColorYELLOW);
571
572 SkPaint magenta;
573 magenta.setAntiAlias(true);
574 magenta.setColor(SK_ColorMAGENTA);
575
576 TextStyle style;
577 style.setFontFamilies({SkString(ff)});
578 style.setFontSize(fs);
579
580 TextStyle style0;
581 style0.setForegroundColor(black);
582 style0.setBackgroundColor(gray);
583 style0.setFontFamilies({SkString(ff)});
584 style0.setFontSize(fs);
585 style0.setDecoration(TextDecoration::kUnderline);
586 style0.setDecorationStyle(TextDecorationStyle::kDouble);
587 style0.setDecorationColor(SK_ColorBLACK);
588
589 TextStyle style1;
590 style1.setForegroundColor(blue);
591 style1.setBackgroundColor(yellow);
592 style1.setFontFamilies({SkString(ff)});
593 style1.setFontSize(fs);
594 style1.setDecoration(TextDecoration::kOverline);
595 style1.setDecorationStyle(TextDecorationStyle::kWavy);
596 style1.setDecorationColor(SK_ColorBLACK);
597
598 TextStyle style2;
599 style2.setForegroundColor(red);
600 style2.setFontFamilies({SkString(ff)});
601 style2.setFontSize(fs);
602
603 TextStyle style3;
604 style3.setForegroundColor(green);
605 style3.setFontFamilies({SkString(ff)});
606 style3.setFontSize(fs);
607
608 TextStyle style4;
609 style4.setForegroundColor(magenta);
610 style4.setFontFamilies({SkString(ff)});
611 style4.setFontSize(fs);
612
613 ParagraphStyle paraStyle;
614 paraStyle.setTextStyle(style);
615 paraStyle.setMaxLines(lineLimit);
616
617 paraStyle.setEllipsis(ellipsis);
618
619 const char* logo1 = "google_";
620 const char* logo2 = "logo";
621 const char* logo3 = "go";
622 const char* logo4 = "ogle_logo";
623 const char* logo5 = "google_lo";
624 const char* logo6 = "go";
625 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400626 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400627
628 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400629 builder.addText(logo1, strlen(logo1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400630 builder.pop();
631 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400632 builder.addText(logo2, strlen(logo2));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400633 builder.pop();
634
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400635 builder.addText(" ", 1);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400636
637 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400638 builder.addText(logo3, strlen(logo3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400639 builder.pop();
640 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400641 builder.addText(logo4, strlen(logo4));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400642 builder.pop();
643
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400644 builder.addText(" ", 1);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400645
646 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400647 builder.addText(logo5, strlen(logo5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400648 builder.pop();
649 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400650 builder.addText(logo6, strlen(logo6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400651 builder.pop();
652
653 auto paragraph = builder.Build();
654 paragraph->layout(w - margin * 2);
655 paragraph->paint(canvas, margin, margin);
656 canvas->translate(0, h + margin);
657 }
658 }
659
660 void onDrawContent(SkCanvas* canvas) override {
661 canvas->drawColor(SK_ColorWHITE);
662 SkScalar width = this->width();
663 SkScalar height = this->height();
664
665 drawFlutter(canvas, width, height / 2);
666 }
667
668private:
669 typedef Sample INHERITED;
670};
671
Mike Reed21a940d2019-07-23 10:11:03 -0400672class ParagraphView5 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400673protected:
Julia Lavrova5207f352019-06-21 12:22:32 -0400674 SkString name() override { return SkString("Paragraph5"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400675
676 void bidi(SkCanvas* canvas, SkScalar w, SkScalar h, const std::u16string& text,
677 const std::u16string& expected, size_t lineLimit = std::numeric_limits<size_t>::max(),
678 const char* ff = "Roboto", SkScalar fs = 30,
679 const std::u16string& ellipsis = u"\u2026") {
680 SkAutoCanvasRestore acr(canvas, true);
681
682 canvas->clipRect(SkRect::MakeWH(w, h));
683
684 SkScalar margin = 20;
685
686 SkPaint black;
687 black.setColor(SK_ColorBLACK);
688 SkPaint gray;
689 gray.setColor(SK_ColorLTGRAY);
690
691 TextStyle style;
692 style.setForegroundColor(black);
693 style.setFontFamilies({SkString(ff)});
694 style.setFontSize(fs);
695
696 TextStyle style0;
697 style0.setForegroundColor(black);
698 style0.setFontFamilies({SkString(ff)});
699 style0.setFontSize(fs);
700 style0.setFontStyle(SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
701 SkFontStyle::kItalic_Slant));
702
703 TextStyle style1;
704 style1.setForegroundColor(gray);
705 style1.setFontFamilies({SkString(ff)});
706 style1.setFontSize(fs);
707 style1.setFontStyle(SkFontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
708 SkFontStyle::kUpright_Slant));
709
710 ParagraphStyle paraStyle;
711 paraStyle.setTextStyle(style);
712 paraStyle.setMaxLines(lineLimit);
713
714 paraStyle.setEllipsis(ellipsis);
715
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400716 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400717
718 if (text.empty()) {
719 const std::u16string text0 = u"\u202Dabc";
720 const std::u16string text1 = u"\u202EFED";
721 const std::u16string text2 = u"\u202Dghi";
722 const std::u16string text3 = u"\u202ELKJ";
723 const std::u16string text4 = u"\u202Dmno";
724 builder.pushStyle(style0);
725 builder.addText(text0);
726 builder.pop();
727 builder.pushStyle(style1);
728 builder.addText(text1);
729 builder.pop();
730 builder.pushStyle(style0);
731 builder.addText(text2);
732 builder.pop();
733 builder.pushStyle(style1);
734 builder.addText(text3);
735 builder.pop();
736 builder.pushStyle(style0);
737 builder.addText(text4);
738 builder.pop();
739 } else {
740 // icu::UnicodeString unicode((UChar*) text.data(), SkToS32(text.size()));
741 // std::string str;
742 // unicode.toUTF8String(str);
743 // SkDebugf("Text: %s\n", str.c_str());
744 builder.addText(text + expected);
745 }
746
747 auto paragraph = builder.Build();
748 paragraph->layout(w - margin * 2);
749 paragraph->paint(canvas, margin, margin);
750 }
751
752 void onDrawContent(SkCanvas* canvas) override {
753 canvas->drawColor(SK_ColorWHITE);
754 SkScalar width = this->width();
755 SkScalar height = this->height() / 8;
756
757 const std::u16string text1 =
758 u"A \u202ENAC\u202Cner, exceedingly \u202ENAC\u202Cny,\n"
759 "One morning remarked to his granny:\n"
760 "A \u202ENAC\u202Cner \u202ENAC\u202C \u202ENAC\u202C,\n"
761 "Anything that he \u202ENAC\u202C,\n"
762 "But a \u202ENAC\u202Cner \u202ENAC\u202C't \u202ENAC\u202C a \u202ENAC\u202C, "
763 "\u202ENAC\u202C he?";
764 bidi(canvas, width, height * 3, text1, u"", 5);
765 canvas->translate(0, height * 3);
766
767 bidi(canvas, width, height, u"\u2067DETALOSI\u2069", u"");
768 canvas->translate(0, height);
769
770 bidi(canvas, width, height, u"\u202BDEDDEBME\u202C", u"");
771 canvas->translate(0, height);
772
773 bidi(canvas, width, height, u"\u202EEDIRREVO\u202C", u"");
774 canvas->translate(0, height);
775
776 bidi(canvas, width, height, u"\u200FTICILPMI\u200E", u"");
777 canvas->translate(0, height);
778
779 bidi(canvas, width, height, u"123 456 7890 \u202EZYXWV UTS RQP ONM LKJ IHG FED CBA\u202C.",
780 u"", 2);
781 canvas->translate(0, height);
782
783 // bidi(canvas, width, height, u"", u"");
784 // canvas->translate(0, height);
785 }
786
787private:
788 typedef Sample INHERITED;
789};
790
Mike Reed21a940d2019-07-23 10:11:03 -0400791class ParagraphView6 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400792protected:
Julia Lavrova5207f352019-06-21 12:22:32 -0400793 SkString name() override { return SkString("Paragraph6"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400794
795 void hangingS(SkCanvas* canvas, SkScalar w, SkScalar h, SkScalar fs = 60.0) {
796 auto ff = "HangingS";
797
798 canvas->drawColor(SK_ColorLTGRAY);
799
800 SkPaint black;
801 black.setAntiAlias(true);
802 black.setColor(SK_ColorBLACK);
803
804 SkPaint blue;
805 blue.setAntiAlias(true);
806 blue.setColor(SK_ColorBLUE);
807
808 SkPaint red;
809 red.setAntiAlias(true);
810 red.setColor(SK_ColorRED);
811
812 SkPaint green;
813 green.setAntiAlias(true);
814 green.setColor(SK_ColorGREEN);
815
816 SkPaint gray;
817 gray.setColor(SK_ColorCYAN);
818
819 SkPaint yellow;
820 yellow.setColor(SK_ColorYELLOW);
821
822 SkPaint magenta;
823 magenta.setAntiAlias(true);
824 magenta.setColor(SK_ColorMAGENTA);
825
826 SkFontStyle fontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
827 SkFontStyle::kItalic_Slant);
828
829 TextStyle style;
830 style.setFontFamilies({SkString(ff)});
831 style.setFontSize(fs);
832 style.setFontStyle(fontStyle);
833
834 TextStyle style0;
835 style0.setForegroundColor(black);
836 style0.setBackgroundColor(gray);
837 style0.setFontFamilies({SkString(ff)});
838 style0.setFontSize(fs);
839 style0.setFontStyle(fontStyle);
840
841 TextStyle style1;
842 style1.setForegroundColor(blue);
843 style1.setBackgroundColor(yellow);
844 style1.setFontFamilies({SkString(ff)});
845 style1.setFontSize(fs);
846 style1.setFontStyle(fontStyle);
847
848 TextStyle style2;
849 style2.setForegroundColor(red);
850 style2.setFontFamilies({SkString(ff)});
851 style2.setFontSize(fs);
852 style2.setFontStyle(fontStyle);
853
854 TextStyle style3;
855 style3.setForegroundColor(green);
856 style3.setFontFamilies({SkString(ff)});
857 style3.setFontSize(fs);
858 style3.setFontStyle(fontStyle);
859
860 TextStyle style4;
861 style4.setForegroundColor(magenta);
862 style4.setFontFamilies({SkString(ff)});
863 style4.setFontSize(fs);
864 style4.setFontStyle(fontStyle);
865
866 ParagraphStyle paraStyle;
867 paraStyle.setTextStyle(style);
868
869 const char* logo1 = "S";
870 const char* logo2 = "kia";
871 const char* logo3 = "Sk";
872 const char* logo4 = "ia";
873 const char* logo5 = "Ski";
874 const char* logo6 = "a";
875 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400876 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400877
878 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400879 builder.addText(logo1, strlen(logo1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400880 builder.pop();
881 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400882 builder.addText(logo2, strlen(logo2));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400883 builder.pop();
884
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400885 builder.addText(" ", 3);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400886
887 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400888 builder.addText(logo3, strlen(logo3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400889 builder.pop();
890 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400891 builder.addText(logo4, strlen(logo4));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400892 builder.pop();
893
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400894 builder.addText(" ", 3);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400895
896 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400897 builder.addText(logo5, strlen(logo5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400898 builder.pop();
899 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400900 builder.addText(logo6, strlen(logo6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400901 builder.pop();
902
903 auto paragraph = builder.Build();
904 paragraph->layout(w);
905 paragraph->paint(canvas, 40, 40);
906 canvas->translate(0, h);
907 }
908
909 const char* logo11 = "S";
910 const char* logo12 = "S";
911 const char* logo13 = "S";
912 const char* logo14 = "S";
913 const char* logo15 = "S";
914 const char* logo16 = "S";
915 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400916 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400917
918 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400919 builder.addText(logo11, strlen(logo1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400920 builder.pop();
921 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400922 builder.addText(logo12, strlen(logo2));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400923 builder.pop();
924
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400925 builder.addText(" ", 3);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400926
927 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400928 builder.addText(logo13, strlen(logo3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400929 builder.pop();
930 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400931 builder.addText(logo14, strlen(logo4));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400932 builder.pop();
933
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400934 builder.addText(" ", 3);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400935
936 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400937 builder.addText(logo15, strlen(logo5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400938 builder.pop();
939 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400940 builder.addText(logo16, strlen(logo6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400941 builder.pop();
942
943 auto paragraph = builder.Build();
944 paragraph->layout(w);
945 paragraph->paint(canvas, 40, h);
946 canvas->translate(0, h);
947 }
948 }
949
950 void onDrawContent(SkCanvas* canvas) override {
951 canvas->drawColor(SK_ColorWHITE);
952 SkScalar width = this->width();
953 SkScalar height = this->height() / 4;
954
955 hangingS(canvas, width, height);
956 }
957
958private:
959 typedef Sample INHERITED;
960};
961
Mike Reed21a940d2019-07-23 10:11:03 -0400962class ParagraphView7 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400963protected:
Hal Canary8a027312019-07-03 10:55:44 -0400964 SkString name() override { return SkString("Paragraph7"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400965
966 void drawText(SkCanvas* canvas, SkColor background, SkScalar letterSpace, SkScalar w,
967 SkScalar h) {
968 SkAutoCanvasRestore acr(canvas, true);
969 canvas->clipRect(SkRect::MakeWH(w, h));
970 canvas->drawColor(background);
971
972 const char* line =
Julia Lavrovadb9f6692019-08-01 16:02:17 -0400973 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400974
975 ParagraphStyle paragraphStyle;
976 paragraphStyle.setTextAlign(TextAlign::kLeft);
977 paragraphStyle.setMaxLines(10);
978 paragraphStyle.turnHintingOff();
979 TextStyle textStyle;
980 textStyle.setFontFamilies({SkString("Roboto")});
981 textStyle.setFontSize(30);
982 textStyle.setLetterSpacing(letterSpace);
983 textStyle.setColor(SK_ColorBLACK);
984 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
985 SkFontStyle::kUpright_Slant));
986
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400987 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400988 builder.pushStyle(textStyle);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400989 builder.addText(line, strlen(line));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400990 builder.pop();
991
992 auto paragraph = builder.Build();
993 paragraph->layout(w - 20);
994 paragraph->paint(canvas, 10, 10);
995 }
996
997 void onDrawContent(SkCanvas* canvas) override {
998 canvas->drawColor(SK_ColorWHITE);
999
1000 auto h = this->height() / 4;
1001 auto w = this->width() / 2;
1002
1003 drawText(canvas, SK_ColorGRAY, 1, w, h);
1004 canvas->translate(0, h);
1005
1006 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
1007 canvas->translate(0, h);
1008
1009 drawText(canvas, SK_ColorCYAN, 3, w, h);
1010 canvas->translate(0, h);
1011
1012 drawText(canvas, SK_ColorGRAY, 4, w, h);
1013 canvas->translate(w, -3 * h);
1014
1015 drawText(canvas, SK_ColorYELLOW, 5, w, h);
1016 canvas->translate(0, h);
1017
1018 drawText(canvas, SK_ColorGREEN, 10, w, h);
1019 canvas->translate(0, h);
1020
1021 drawText(canvas, SK_ColorRED, 15, w, h);
1022 canvas->translate(0, h);
1023
1024 drawText(canvas, SK_ColorBLUE, 20, w, h);
1025 canvas->translate(0, h);
1026 }
1027
1028private:
1029 typedef Sample INHERITED;
1030};
1031
Mike Reed21a940d2019-07-23 10:11:03 -04001032class ParagraphView8 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001033protected:
Julia Lavrovadb9f6692019-08-01 16:02:17 -04001034 SkString name() override { return SkString("Paragraph8"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001035
1036 void drawText(SkCanvas* canvas, SkColor background, SkScalar wordSpace, SkScalar w,
1037 SkScalar h) {
1038 SkAutoCanvasRestore acr(canvas, true);
1039 canvas->clipRect(SkRect::MakeWH(w, h));
1040 canvas->drawColor(background);
1041
1042 const char* line =
Julia Lavrovadb9f6692019-08-01 16:02:17 -04001043 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001044
1045 ParagraphStyle paragraphStyle;
1046 paragraphStyle.setTextAlign(TextAlign::kLeft);
1047 paragraphStyle.setMaxLines(10);
1048 paragraphStyle.turnHintingOff();
1049 TextStyle textStyle;
1050 textStyle.setFontFamilies({SkString("Roboto")});
1051 textStyle.setFontSize(30);
1052 textStyle.setWordSpacing(wordSpace);
1053 textStyle.setColor(SK_ColorBLACK);
1054 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1055 SkFontStyle::kUpright_Slant));
1056
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001057 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001058 builder.pushStyle(textStyle);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -04001059 builder.addText(line, strlen(line));
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001060 builder.pop();
1061
1062 auto paragraph = builder.Build();
1063 paragraph->layout(w - 20);
1064 paragraph->paint(canvas, 10, 10);
1065 }
1066
1067 void onDrawContent(SkCanvas* canvas) override {
1068 canvas->drawColor(SK_ColorWHITE);
1069
1070 auto h = this->height() / 4;
1071 auto w = this->width() / 2;
1072
1073 drawText(canvas, SK_ColorGRAY, 1, w, h);
1074 canvas->translate(0, h);
1075
1076 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
1077 canvas->translate(0, h);
1078
1079 drawText(canvas, SK_ColorCYAN, 3, w, h);
1080 canvas->translate(0, h);
1081
1082 drawText(canvas, SK_ColorGRAY, 4, w, h);
1083 canvas->translate(w, -3 * h);
1084
1085 drawText(canvas, SK_ColorYELLOW, 5, w, h);
1086 canvas->translate(0, h);
1087
1088 drawText(canvas, SK_ColorGREEN, 10, w, h);
1089 canvas->translate(0, h);
1090
1091 drawText(canvas, SK_ColorRED, 15, w, h);
1092 canvas->translate(0, h);
1093
1094 drawText(canvas, SK_ColorBLUE, 20, w, h);
1095 canvas->translate(0, h);
1096 }
1097
1098private:
1099 typedef Sample INHERITED;
1100};
1101
Mike Reed21a940d2019-07-23 10:11:03 -04001102class ParagraphView9 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001103protected:
Hal Canary8a027312019-07-03 10:55:44 -04001104 SkString name() override { return SkString("Paragraph9"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001105
Hal Canary6cc65e12019-07-03 15:53:04 -04001106 bool onChar(SkUnichar uni) override {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001107 switch (uni) {
1108 case 'w':
1109 ++wordSpacing;
1110 return true;
1111 case 'q':
1112 if (wordSpacing > 0) --wordSpacing;
1113 return true;
1114 case 'l':
1115 ++letterSpacing;
1116 return true;
1117 case 'k':
1118 if (letterSpacing > 0) --letterSpacing;
1119 return true;
1120 default:
1121 break;
1122 }
Hal Canary6cc65e12019-07-03 15:53:04 -04001123 return false;
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001124 }
1125
1126 void drawText(SkCanvas* canvas, SkColor background, SkScalar w, SkScalar h) {
1127 SkAutoCanvasRestore acr(canvas, true);
1128 canvas->clipRect(SkRect::MakeWH(w, h));
1129 canvas->drawColor(background);
1130
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001131 auto fontCollection = sk_make_sp<FontCollection>();
1132 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1133 fontCollection->enableFontFallback();
1134
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001135 const char* text =
1136 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1137 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1138 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001139 auto multiplier = 5.67;
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001140 ParagraphStyle paragraphStyle;
1141 paragraphStyle.setTextAlign(TextAlign::kLeft);
1142 paragraphStyle.setMaxLines(10);
1143 paragraphStyle.turnHintingOff();
1144 TextStyle textStyle;
1145 textStyle.setFontFamilies({SkString("Roboto")});
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001146 textStyle.setFontSize(5 * multiplier);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001147 textStyle.setHeight(1.3f);
1148 textStyle.setColor(SK_ColorBLACK);
1149 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1150 SkFontStyle::kUpright_Slant));
1151
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001152 ParagraphBuilderImpl builder(paragraphStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001153 builder.pushStyle(textStyle);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -04001154 builder.addText(text, strlen(text));
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001155 builder.pop();
1156
1157 auto paragraph = builder.Build();
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001158 paragraph->layout(200 * multiplier);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001159
1160 std::vector<size_t> sizes = {0, 1, 2, 8, 19, 21, 22, 30, 150};
1161
1162 std::vector<size_t> colors = {SK_ColorBLUE, SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGREEN,
1163 SK_ColorRED, SK_ColorWHITE, SK_ColorYELLOW, SK_ColorMAGENTA};
1164
1165 RectHeightStyle rect_height_style = RectHeightStyle::kTight;
1166 RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1167
1168 for (size_t i = 0; i < sizes.size() - 1; ++i) {
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001169 size_t from = sizes[i];
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001170 size_t to = sizes[i + 1];
1171 auto boxes = paragraph->getRectsForRange(from, to, rect_height_style, rect_width_style);
1172 if (boxes.empty()) {
1173 continue;
1174 }
1175 for (auto& box : boxes) {
1176 SkPaint paint;
1177 paint.setColor(colors[i % colors.size()]);
1178 paint.setShader(setgrad(box.rect, colors[i % colors.size()], SK_ColorWHITE));
1179 canvas->drawRect(box.rect, paint);
1180 }
1181 }
1182
1183 paragraph->paint(canvas, 0, 0);
1184 }
1185
1186 void onDrawContent(SkCanvas* canvas) override {
1187 canvas->drawColor(SK_ColorWHITE);
1188
1189 auto h = this->height();
1190 auto w = this->width();
1191
1192 drawText(canvas, SK_ColorGRAY, w, h);
1193 }
1194
1195private:
1196 typedef Sample INHERITED;
1197 SkScalar letterSpacing;
1198 SkScalar wordSpacing;
1199};
1200
Mike Reed21a940d2019-07-23 10:11:03 -04001201class ParagraphView10 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001202protected:
Hal Canary8a027312019-07-03 10:55:44 -04001203 SkString name() override { return SkString("Paragraph10"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001204
1205 void onDrawContent(SkCanvas* canvas) override {
1206 canvas->drawColor(SK_ColorWHITE);
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001207 auto multiplier = 5.67;
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001208 const char* text = "English English 字典 字典 😀😃😄 😀😃😄";
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001209
1210 auto fontCollection = sk_make_sp<FontCollection>();
1211 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1212 fontCollection->enableFontFallback();
1213
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001214 ParagraphStyle paragraph_style;
1215 paragraph_style.turnHintingOff();
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001216 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001217
1218 TextStyle text_style;
Julia Lavrova5207f352019-06-21 12:22:32 -04001219 text_style.setFontFamilies({SkString("Roboto"),
1220 SkString("Noto Color Emoji"),
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001221 SkString("Noto Serif CJK JP")});
1222 text_style.setFontSize(10 * multiplier);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001223 text_style.setLetterSpacing(0);
1224 text_style.setWordSpacing(0);
1225 text_style.setColor(SK_ColorBLACK);
1226 text_style.setHeight(1);
1227 builder.pushStyle(text_style);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -04001228 builder.addText(text, strlen(text));
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001229 builder.pop();
1230
1231 auto paragraph = builder.Build();
1232 paragraph->layout(width());
1233
1234 paragraph->paint(canvas, 0, 0);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001235 }
1236
1237private:
1238 typedef Sample INHERITED;
1239};
1240
Mike Reed21a940d2019-07-23 10:11:03 -04001241class ParagraphView11 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001242protected:
Hal Canary8a027312019-07-03 10:55:44 -04001243 SkString name() override { return SkString("Paragraph11"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001244
1245 void onDrawContent(SkCanvas* canvas) override {
1246 canvas->drawColor(SK_ColorWHITE);
Julia Lavrova5207f352019-06-21 12:22:32 -04001247
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001248 auto text = "\U0001f469\U0000200D\U0001f469\U0000200D\U0001f466\U0001f469\U0000200D\U0001f469\U0000200D\U0001f467\U0000200D\U0001f467\U0001f1fa\U0001f1f8";
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001249
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001250 TextStyle text_style;
1251 text_style.setFontFamilies({SkString("Ahem")});
1252 text_style.setColor(SK_ColorBLACK);
1253 text_style.setFontSize(60);
1254 text_style.setLetterSpacing(0);
1255 text_style.setWordSpacing(0);
1256 ParagraphStyle paragraph_style;
1257 paragraph_style.setTextStyle(text_style);
1258
1259 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), true, true);
1260 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1261 builder.addText(text, strlen(text));
1262 auto paragraph = builder.Build();
1263 paragraph->layout(1000);
1264 paragraph->paint(canvas, 0, 0);
1265
1266 struct pair {
1267 unsigned fX;
1268 unsigned fY;
1269 };
1270
1271 pair hit1[] =
1272 {{ 0, 8},{1, 33}, {2, 34}, { 3, 19}, {4, 20},
1273 { 5, 21}, { 6, 22 }, { 7, 23 }, {8, 24 }, { 9, 25},
1274 { 10, 26}, { 11, 27}, {12, 28}, { 13, 21}, {14, 22 },
1275 { 15, 23}, {16, 24}, {17, 21}, { 18, 22}, {19, 21},
1276 { 20, 24}, { 21, 23}, };
1277
1278 pair miss[] =
1279 {{ 0, 4},{1, 17}, {2, 18}, { 3, 11}, {4, 12},
1280 { 5, 13}, { 6, 14 }, { 7, 15 }, {8, 16 }, { 9, 17},
1281 { 10, 18}, { 11, 19}, {12, 20}, { 13, 17}, {14, 18 },
1282 { 15, 19}, {16, 20}, {17, 19}, { 18, 20},
1283 { 20, 22}, };
1284
1285 auto rects = paragraph->getRectsForRange(7, 9, RectHeightStyle::kTight, RectWidthStyle::kTight);
1286 SkPaint paint;
1287 paint.setColor(SK_ColorRED);
1288 paint.setStyle(SkPaint::kStroke_Style);
1289 paint.setAntiAlias(true);
1290 paint.setStrokeWidth(1);
1291 if (!rects.empty()) {
1292 canvas->drawRect(rects[0].rect, paint);
1293 }
1294
1295 for (auto& query : hit1) {
1296 auto rects = paragraph->getRectsForRange(query.fX, query.fY, RectHeightStyle::kTight, RectWidthStyle::kTight);
1297 if (rects.size() >= 1 && rects[0].rect.width() > 0) {
1298 } else {
1299 SkDebugf("+[%d:%d): Bad\n", query.fX, query.fY);
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001300 }
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001301 }
1302
1303 for (auto& query : miss) {
1304 auto miss = paragraph->getRectsForRange(query.fX, query.fY, RectHeightStyle::kTight, RectWidthStyle::kTight);
1305 if (miss.empty()) {
1306 } else {
1307 SkDebugf("-[%d:%d): Bad\n", query.fX, query.fY);
1308 }
1309 }
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001310 }
1311
1312private:
1313 typedef Sample INHERITED;
1314};
1315
1316class ParagraphView12 : public ParagraphView_Base {
1317protected:
1318 SkString name() override { return SkString("Paragraph12"); }
1319
1320 void onDrawContent(SkCanvas* canvas) override {
1321 canvas->drawColor(SK_ColorWHITE);
1322
1323 const char* text = "Atwater Peel Sherbrooke Bonaventure Angrignon Peel Côte-des-Neiges";
1324 TextStyle text_style;
1325 text_style.setFontFamilies({SkString("Ahem")});
1326 text_style.setColor(SK_ColorBLACK);
1327 text_style.setFontSize(16);
1328 //text_style.setLetterSpacing(-0.41);
1329 StrutStyle strut_style;
1330 strut_style.setStrutEnabled(false);
1331 ParagraphStyle paragraph_style;
1332 paragraph_style.setStrutStyle(strut_style);
1333 paragraph_style.setTextStyle(text_style);
1334 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1335 builder.addText(text);
1336 auto paragraph = builder.Build();
1337 paragraph->layout(1095.000000);
1338 auto result = paragraph->getRectsForRange(65, 66, RectHeightStyle::kTight, RectWidthStyle::kTight);
1339 paragraph->paint(canvas, 0, 0);
1340
1341 SkPaint paint;
1342 paint.setColor(SK_ColorRED);
1343 paint.setStyle(SkPaint::kStroke_Style);
1344 paint.setAntiAlias(true);
1345 paint.setStrokeWidth(1);
1346 canvas->drawRect(result.front().rect, paint);
1347 }
1348
1349private:
1350 typedef Sample INHERITED;
1351};
1352
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001353class ParagraphView14 : public ParagraphView_Base {
1354protected:
1355 SkString name() override { return SkString("Paragraph14"); }
1356
1357 void onDrawContent(SkCanvas* canvas) override {
1358 canvas->drawColor(SK_ColorWHITE);
1359 TextStyle text_style;
1360 text_style.setFontFamilies({SkString("Ahem")});
1361 text_style.setColor(SK_ColorBLACK);
1362 text_style.setFontSize(25);
1363 text_style.setDecoration((TextDecoration)(TextDecoration::kUnderline | TextDecoration::kOverline | TextDecoration::kLineThrough));
1364 text_style.setDecorationColor(SK_ColorBLUE);
1365 text_style.setDecorationStyle(TextDecorationStyle::kWavy);
1366 text_style.setDecorationThicknessMultiplier(4.0f);
1367 ParagraphStyle paragraph_style;
1368 paragraph_style.setTextStyle(text_style);
1369 paragraph_style.setTextDirection(TextDirection::kRtl);
1370 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
1371 builder.pushStyle(text_style);
1372 builder.addText("Hello, wor!\nabcd.");
1373 auto paragraph = builder.Build();
1374 paragraph->layout(300);
1375 paragraph->paint(canvas, 0, 0);
1376 SkPaint paint;
1377 paint.setColor(SK_ColorRED);
1378 paint.setStyle(SkPaint::kStroke_Style);
1379 paint.setAntiAlias(true);
1380 paint.setStrokeWidth(1);
1381 canvas->drawRect(SkRect::MakeXYWH(0, 0, 300, 100), paint);
1382 }
1383
1384private:
1385 typedef Sample INHERITED;
1386};
1387
1388class ParagraphView15 : public ParagraphView_Base {
1389protected:
1390 SkString name() override { return SkString("Paragraph15"); }
1391
1392 void onDrawContent(SkCanvas* canvas) override {
1393 canvas->drawColor(SK_ColorWHITE);
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001394
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001395 TextStyle text_style;
1396 text_style.setFontFamilies({SkString("abc.ttf")});
1397 text_style.setFontSize(50);
1398
1399 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false);
1400
1401 fontCollection->addFontFromFile("abc/abc.ttf", "abc");
1402 fontCollection->addFontFromFile("abc/abc+grave.ttf", "abc+grave");
1403 fontCollection->addFontFromFile("abc/abc+agrave.ttf", "abc+agrave");
1404
1405 ParagraphStyle paragraph_style;
1406 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1407
1408 text_style.setFontFamilies({SkString("abc"), SkString("abc+grave")});
1409 text_style.setColor(SK_ColorBLUE);
1410 builder.pushStyle(text_style);
1411 builder.addText(u"a\u0300");
1412 text_style.setColor(SK_ColorMAGENTA);
1413 builder.pushStyle(text_style);
1414 builder.addText(u"à");
1415
1416 text_style.setFontFamilies({SkString("abc"), SkString("abc+agrave")});
1417
1418 text_style.setColor(SK_ColorRED);
1419 builder.pushStyle(text_style);
1420 builder.addText(u"a\u0300");
1421 text_style.setColor(SK_ColorGREEN);
1422 builder.pushStyle(text_style);
1423 builder.addText(u"à");
1424
1425 auto paragraph = builder.Build();
1426 paragraph->layout(800);
1427 paragraph->paint(canvas, 50, 50);
1428
Julia Lavrova5207f352019-06-21 12:22:32 -04001429 }
1430
1431private:
1432 typedef Sample INHERITED;
1433};
1434
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001435class ParagraphView16 : public ParagraphView_Base {
1436protected:
1437 SkString name() override { return SkString("Paragraph16"); }
1438
1439 void onDrawContent(SkCanvas* canvas) override {
1440 canvas->drawColor(SK_ColorWHITE);
1441
1442 const char* text = "content";
1443
1444 ParagraphStyle paragraph_style;
1445 paragraph_style.setMaxLines(1);
1446 paragraph_style.setEllipsis(u"\u2026");
1447 //auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
1448 auto fontCollection = sk_make_sp<FontCollection>();
1449 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1450 fontCollection->enableFontFallback();
1451 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1452
1453 TextStyle text_style;
1454 text_style.setFontFamilies({SkString(".SF Pro Text")});
1455 text_style.setColor(SK_ColorBLACK);
1456 text_style.setFontSize(17.0f * 99.0f);
1457 text_style.setLetterSpacing(0.41f);
1458 builder.pushStyle(text_style);
1459 builder.addText(text);
1460
1461 auto paragraph = builder.Build();
1462 paragraph->layout(800);
1463 paragraph->paint(canvas, 0, 0);
1464 }
1465
1466private:
1467 typedef Sample INHERITED;
1468};
1469
1470class ParagraphView17 : public ParagraphView_Base {
1471protected:
1472 SkString name() override { return SkString("Paragraph17"); }
1473
1474 void onDrawContent(SkCanvas* canvas) override {
1475 canvas->drawColor(SK_ColorWHITE);
1476
1477 auto fontCollection = sk_make_sp<FontCollection>();
1478 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1479 fontCollection->enableFontFallback();
1480 auto navy = SkColorSetRGB(0, 0, 139);
1481 auto ltgray = SkColorSetRGB(211, 211, 211);
1482 auto multiplier = 5.67;
1483
1484 const char* text = ">Sͬ͑̀͐̈͒̈́̋̎ͮͩ̽̓ͬ̂̆̔͗́̓ͣͧ͊ͫ͛̉͌̐̑ͪ͗̚͝҉̴͉͢k̡̊̓ͫͭͩ͂͊ͨͪͬ̑ͫ̍̌̄͛̌̂̑̂̋̊̔ͫ͛̽̑ͨ̍ͭ̓̀ͪͪ̉͐͗̌̓̃̚͟͝҉̢͏̫̞̙͇͖̮͕̗̟͕͇͚̻͈̣̻̪͉̰̲̣̫ͅͅP̴̅̍͒̿͗͗̇ͩ̃͆͌̀̽͏̧̡͕͖̝̖̼̺̰̣̬͔͖͔̼͙̞̦̫͓̘͜a̸̴̸̴̢̢̨̨̫͍͓̥̼̭̼̻̤̯̙̤̻̠͚̍̌͋̂ͦͨ̽̇͌͌͆̀̽̎͒̄ͪ̐ͦ̈ͫ͐͗̓̚̚͜ͅr͐͐ͤͫ̐ͥ͂̈́̿́ͮ̃͗̓̏ͫ̀̿͏̸̵̧́͘̕͟͝͠͞͠҉̷̧͚͢͟a̓̽̎̄͗̔͛̄̐͊͛ͫ͂͌̂̂̈̈̓̔̅̅̄͊̉́ͪ̑̄͆ͬ̍͆ͭ͋̐ͬ͏̷̵̨̢̩̹̖͓̥̳̰͔̱̬͖̙͓̙͇̀̀̕͜͟͟͢͟͜͠͡g̨̅̇ͦ͋̂ͦͨͭ̓͐͆̏̂͛̉ͧ̑ͫ̐̒͛ͫ̍̒͛́̚҉̷̨̛̛̀͜͢͞҉̩̘̲͍͎̯̹̝̭̗̱͇͉̲̱͔̯̠̹̥̻͉̲̜̤̰̪̗̺̖̺r̷͌̓̇̅ͭ̀̐̃̃ͭ͑͗̉̈̇̈́ͥ̓ͣ́ͤ͂ͤ͂̏͌̆̚҉̴̸̧̢̢̛̫͉̦̥̤̙͈͉͈͉͓̙̗̟̳̜͈̗̺̟̠̠͖͓̖̪͕̠̕̕͝ͅả̸̴̡̡̧͠͞͡͞҉̛̕͟͏̷̘̪̱͈̲͉̞̠̞̪̫͎̲̬̖̀̀͟͝͞͞͠p̛͂̈͐̚͠҉̵̸̡̢̢̩̹͙̯͖̙̙̮̥̙͚̠͔̥̭̮̞̣̪̬̥̠̖̝̥̪͎́̀̕͜͡͡ͅͅh̵̷̵̡̛ͤ̂͌̐̓̐̋̋͊̒̆̽́̀̀̀͢͠͞͞҉̷̸̢̕҉͚̯͖̫̜̞̟̠̱͉̝̲̹̼͉̟͉̩̮͔̤͖̞̭̙̹̬ͅ<";
1485
1486 ParagraphStyle paragraph_style;
1487 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1488 SkPaint paint;
1489 paint.setColor(ltgray);
1490 TextStyle text_style;
1491 text_style.setBackgroundColor(paint);
1492 text_style.setColor(navy);
1493 text_style.setFontFamilies({SkString("Roboto")});
1494 text_style.setFontSize(20 * multiplier);
1495 builder.pushStyle(text_style);
1496 builder.addText(text);
1497 auto paragraph = builder.Build();
1498 paragraph->layout(10000);
1499 paragraph->paint(canvas, 0, 0);
1500 }
1501
1502private:
1503 typedef Sample INHERITED;
1504};
1505
1506class Zalgo {
1507 private:
1508 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";
1509 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";
1510 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";
1511
1512 std::u16string randomMarks(std::u16string& combiningMarks) {
1513 std::u16string result;
1514 auto num = std::rand() % (combiningMarks.size() / 1);
1515 for (size_t i = 0; i < num; ++i) {
1516 auto index = std::rand() % combiningMarks.size();
1517 result += combiningMarks[index];
1518 }
1519 return result;
1520 }
1521
1522public:
1523 std::u16string zalgo(std::string victim) {
1524 std::u16string result;
1525 for (auto& c : victim) {
1526 result += c;
1527 result += randomMarks(COMBINING_UP);
1528 result += randomMarks(COMBINING_MIDDLE);
1529 result += randomMarks(COMBINING_DOWN);
1530 }
1531 return result;
1532 }
1533};
1534
1535class ParagraphView18 : public ParagraphView_Base {
1536protected:
1537 SkString name() override { return SkString("Paragraph18"); }
1538
1539 bool onChar(SkUnichar uni) override {
1540 switch (uni) {
1541 case ' ':
1542 fLimit = 400;
1543 return true;
1544 case 's':
1545 fLimit += 10;
1546 return true;
1547 case 'f':
1548 if (fLimit > 10) {
1549 fLimit -= 10;
1550 }
1551 return true;
1552 default:
1553 break;
1554 }
1555 return false;
1556 }
1557
1558 bool onAnimate(double nanos) override {
1559 if (++fIndex > fLimit) {
1560 fRedraw = true;
1561 fIndex = 0;
1562 } else {
1563 fRepeat = true;
1564 }
1565 return true;
1566 }
1567
1568 void onDrawContent(SkCanvas* canvas) override {
1569 canvas->drawColor(SK_ColorWHITE);
1570
1571 auto navy = SkColorSetRGB(0, 0, 139);
1572 auto ltgray = SkColorSetRGB(211, 211, 211);
1573
1574 auto multiplier = 5.67;
1575 auto fontCollection = sk_make_sp<FontCollection>();
1576 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
1577 fontCollection->enableFontFallback();
1578
1579 ParagraphStyle paragraph_style;
1580 TextStyle text_style;
1581 text_style.setFontFamilies({SkString("Roboto")});
1582 text_style.setFontSize(20 * multiplier);
1583 text_style.setColor(navy);
1584 SkPaint paint;
1585 paint.setColor(ltgray);
1586 text_style.setBackgroundColor(paint);
1587
1588 Zalgo zalgo;
1589
1590 if (fRedraw || fRepeat) {
1591
1592 if (fRedraw || fParagraph.get() == nullptr) {
1593 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1594 builder.pushStyle(text_style);
1595 auto utf16text = zalgo.zalgo("SkParagraph");
1596 icu::UnicodeString unicode((UChar*)utf16text.data(), SkToS32(utf16text.size()));
1597 std::string str;
1598 unicode.toUTF8String(str);
1599 SkDebugf("Text:>%s<\n", str.data());
1600 builder.addText(utf16text);
1601 fParagraph = builder.Build();
1602 }
1603
1604 auto impl = static_cast<ParagraphImpl*>(fParagraph.get());
1605 impl->setState(InternalState::kUnknown);
1606 fParagraph->layout(1000);
1607 fParagraph->paint(canvas, 300, 200);
1608
1609 for (auto& run : impl->runs()) {
1610 SkString fontFamily("unresolved");
1611 if (run.font().getTypeface() != nullptr) {
1612 run.font().getTypeface()->getFamilyName(&fontFamily);
1613 }
1614 if (run.font().getTypeface() != nullptr) {
1615 for (size_t i = 0; i < run.size(); ++i) {
1616 auto glyph = run.glyphs().begin() + i;
1617 if (*glyph == 0) {
1618 SkDebugf("Run[%d] @pos=%d\n", run.index(), i);
1619 SkASSERT(false);
1620 }
1621 }
1622 } else {
1623 SkDebugf("Run[%d]: %s\n", run.index(), fontFamily.c_str());
1624 SkASSERT(false);
1625 }
1626 }
1627 fRedraw = false;
1628 fRepeat = false;
1629 }
1630 }
1631
1632private:
1633 bool fRedraw = true;
1634 bool fRepeat = false;
1635 size_t fIndex = 0;
1636 size_t fLimit = 20;
1637 std::unique_ptr<Paragraph> fParagraph;
1638 typedef Sample INHERITED;
1639};
1640
1641class ParagraphView19 : public ParagraphView_Base {
1642protected:
1643 SkString name() override { return SkString("Paragraph19"); }
1644
1645 void onDrawContent(SkCanvas* canvas) override {
1646 canvas->drawColor(SK_ColorWHITE);
1647
1648 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
1649
Julia Lavrovac028b422019-11-25 10:00:43 -05001650 const char* text = "World domination is such an ugly phrase - I prefer to call it world optimisation";
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001651 ParagraphStyle paragraph_style;
Julia Lavrovac028b422019-11-25 10:00:43 -05001652 paragraph_style.setMaxLines(7);
1653 paragraph_style.setEllipsis(u"\u2026");
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001654 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001655 TextStyle text_style;
Julia Lavrovac028b422019-11-25 10:00:43 -05001656 text_style.setColor(SK_ColorBLACK);
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001657 text_style.setFontFamilies({SkString("Roboto")});
Julia Lavrovac028b422019-11-25 10:00:43 -05001658 text_style.setFontSize(40);
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001659 builder.pushStyle(text_style);
1660 builder.addText(text);
1661 auto paragraph = builder.Build();
Julia Lavrovac028b422019-11-25 10:00:43 -05001662 paragraph->layout(this->width());
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001663
Julia Lavrovac028b422019-11-25 10:00:43 -05001664 paragraph->paint(canvas, 0, 0);
1665 }
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001666
Julia Lavrovac028b422019-11-25 10:00:43 -05001667private:
1668 typedef Sample INHERITED;
1669};
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001670
Julia Lavrovac028b422019-11-25 10:00:43 -05001671class ParagraphView20 : public ParagraphView_Base {
1672protected:
1673 SkString name() override { return SkString("Paragraph20"); }
1674
1675 void onDrawContent(SkCanvas* canvas) override {
1676 canvas->drawColor(SK_ColorWHITE);
1677
1678 auto fontCollection = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str(), false, true);
1679
1680 const char* text = "";
1681 ParagraphStyle paragraph_style;
1682 paragraph_style.setMaxLines(std::numeric_limits<size_t>::max());
1683 //paragraph_style.setEllipsis(u"\u2026");
1684 ParagraphBuilderImpl builder(paragraph_style, fontCollection);
1685 TextStyle text_style;
1686 text_style.setColor(SK_ColorBLACK);
1687 text_style.setFontFamilies({SkString("Roboto")});
1688 text_style.setFontSize(40);
1689 builder.pushStyle(text_style);
1690 builder.addText(text);
1691 auto paragraph = builder.Build();
1692 paragraph->layout(this->width());
1693
1694 paragraph->paint(canvas, 0, 0);
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001695 }
1696
1697private:
1698 typedef Sample INHERITED;
1699};
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001700//////////////////////////////////////////////////////////////////////////////
1701
1702DEF_SAMPLE(return new ParagraphView1();)
1703DEF_SAMPLE(return new ParagraphView2();)
1704DEF_SAMPLE(return new ParagraphView3();)
1705DEF_SAMPLE(return new ParagraphView4();)
1706DEF_SAMPLE(return new ParagraphView5();)
1707DEF_SAMPLE(return new ParagraphView6();)
1708DEF_SAMPLE(return new ParagraphView7();)
1709DEF_SAMPLE(return new ParagraphView8();)
1710DEF_SAMPLE(return new ParagraphView9();)
1711DEF_SAMPLE(return new ParagraphView10();)
1712DEF_SAMPLE(return new ParagraphView11();)
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001713DEF_SAMPLE(return new ParagraphView12();)
Julia Lavrovaf3ed2732019-09-05 14:35:17 -04001714DEF_SAMPLE(return new ParagraphView14();)
1715DEF_SAMPLE(return new ParagraphView15();)
Julia Lavrova2e30fde2019-10-09 09:43:02 -04001716DEF_SAMPLE(return new ParagraphView16();)
1717DEF_SAMPLE(return new ParagraphView17();)
1718DEF_SAMPLE(return new ParagraphView18();)
1719DEF_SAMPLE(return new ParagraphView19();)
Julia Lavrovac028b422019-11-25 10:00:43 -05001720DEF_SAMPLE(return new ParagraphView20();)