blob: 726414630d33296f5eeaffd7f7f46635dd35a14a [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"
24#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) {
36 fFC = sk_make_sp<TestFontCollection>(GetResourcePath("fonts").c_str());
37 }
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 Lavrova5207f352019-06-21 12:22:32 -040047
Julia Lavrovaa3552c52019-05-30 16:12:56 -040048} // namespace
49
Mike Reed21a940d2019-07-23 10:11:03 -040050class ParagraphView1 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -040051protected:
Hal Canary8a027312019-07-03 10:55:44 -040052 SkString name() override { return SkString("Paragraph1"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -040053
54 void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) {
55 const std::vector<
56 std::tuple<std::string, bool, bool, int, SkColor, SkColor, bool, TextDecorationStyle>>
57 gParagraph = {{"monospace", true, false, 14, SK_ColorWHITE, SK_ColorRED, true,
58 TextDecorationStyle::kDashed},
59 {"Assyrian", false, false, 20, SK_ColorWHITE, SK_ColorBLUE, false,
60 TextDecorationStyle::kDotted},
61 {"serif", true, true, 10, SK_ColorWHITE, SK_ColorRED, true,
62 TextDecorationStyle::kDouble},
63 {"Arial", false, true, 16, SK_ColorGRAY, SK_ColorGREEN, true,
64 TextDecorationStyle::kSolid},
65 {"sans-serif", false, false, 8, SK_ColorWHITE, SK_ColorRED, false,
66 TextDecorationStyle::kWavy}};
67 SkAutoCanvasRestore acr(canvas, true);
68
69 canvas->clipRect(SkRect::MakeWH(w, h));
70 canvas->drawColor(SK_ColorWHITE);
71
72 SkScalar margin = 20;
73
74 SkPaint paint;
75 paint.setAntiAlias(true);
76 paint.setColor(fg);
77
78 SkPaint blue;
79 blue.setColor(SK_ColorBLUE);
80
81 TextStyle defaultStyle;
82 defaultStyle.setBackgroundColor(blue);
83 defaultStyle.setForegroundColor(paint);
84 ParagraphStyle paraStyle;
85
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -040086 auto fontCollection = sk_make_sp<FontCollection>();
87 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
Julia Lavrovaa3552c52019-05-30 16:12:56 -040088 for (auto i = 1; i < 5; ++i) {
89 defaultStyle.setFontSize(24 * i);
90 paraStyle.setTextStyle(defaultStyle);
Julia Lavrova5207f352019-06-21 12:22:32 -040091 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -040092 std::string name = "Paragraph: " + std::to_string(24 * i);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -040093 builder.addText(name.c_str(), name.length());
Julia Lavrovaa3552c52019-05-30 16:12:56 -040094 for (auto para : gParagraph) {
95 TextStyle style;
96 style.setFontFamilies({SkString(std::get<0>(para).c_str())});
97 SkFontStyle fontStyle(std::get<1>(para) ? SkFontStyle::Weight::kBold_Weight
98 : SkFontStyle::Weight::kNormal_Weight,
99 SkFontStyle::Width::kNormal_Width,
100 std::get<2>(para) ? SkFontStyle::Slant::kItalic_Slant
101 : SkFontStyle::Slant::kUpright_Slant);
102 style.setFontStyle(fontStyle);
103 style.setFontSize(std::get<3>(para) * i);
104 SkPaint background;
105 background.setColor(std::get<4>(para));
106 style.setBackgroundColor(background);
107 SkPaint foreground;
108 foreground.setColor(std::get<5>(para));
109 foreground.setAntiAlias(true);
110 style.setForegroundColor(foreground);
111 if (std::get<6>(para)) {
112 style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(5, 5), 2));
113 }
114
115 auto decoration = (i % 4);
116 if (decoration == 3) {
117 decoration = 4;
118 }
119
120 bool test = (TextDecoration)decoration != TextDecoration::kNoDecoration;
121 std::string deco = std::to_string((int)decoration);
122 if (test) {
123 style.setDecoration((TextDecoration)decoration);
124 style.setDecorationStyle(std::get<7>(para));
125 style.setDecorationColor(std::get<5>(para));
126 }
127 builder.pushStyle(style);
128 std::string name = " " + std::get<0>(para) + " " +
129 (std::get<1>(para) ? ", bold" : "") +
130 (std::get<2>(para) ? ", italic" : "") + " " +
131 std::to_string(std::get<3>(para) * i) +
132 (std::get<4>(para) != bg ? ", background" : "") +
133 (std::get<5>(para) != fg ? ", foreground" : "") +
134 (std::get<6>(para) ? ", shadow" : "") +
135 (test ? ", decorations " + deco : "") + ";";
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400136 builder.addText(name.c_str(), name.length());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400137 builder.pop();
138 }
139
140 auto paragraph = builder.Build();
141 paragraph->layout(w - margin * 2);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400142 paragraph->paint(canvas, margin, margin);
143
144 canvas->translate(0, paragraph->getHeight());
145 }
146 }
147
148 void onDrawContent(SkCanvas* canvas) override {
149 drawTest(canvas, this->width(), this->height(), SK_ColorRED, SK_ColorWHITE);
150 }
151
152private:
153
154 typedef Sample INHERITED;
155};
156
Mike Reed21a940d2019-07-23 10:11:03 -0400157class ParagraphView2 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400158protected:
Hal Canary8a027312019-07-03 10:55:44 -0400159 SkString name() override { return SkString("Paragraph2"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400160
161 void drawCode(SkCanvas* canvas, SkScalar w, SkScalar h) {
162 SkPaint comment;
163 comment.setColor(SK_ColorGRAY);
164 SkPaint constant;
165 constant.setColor(SK_ColorMAGENTA);
166 SkPaint null;
167 null.setColor(SK_ColorMAGENTA);
168 SkPaint literal;
169 literal.setColor(SK_ColorGREEN);
170 SkPaint code;
171 code.setColor(SK_ColorDKGRAY);
172 SkPaint number;
173 number.setColor(SK_ColorBLUE);
174 SkPaint name;
175 name.setColor(SK_ColorRED);
176
177 SkPaint white;
178 white.setColor(SK_ColorWHITE);
179
180 TextStyle defaultStyle;
181 defaultStyle.setBackgroundColor(white);
182 defaultStyle.setForegroundColor(code);
183 defaultStyle.setFontFamilies({SkString("monospace")});
184 defaultStyle.setFontSize(30);
185 ParagraphStyle paraStyle;
186 paraStyle.setTextStyle(defaultStyle);
187
Julia Lavrova5207f352019-06-21 12:22:32 -0400188 auto fontCollection = sk_make_sp<FontCollection>();
189 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
190 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400191
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400192 const char* text1 = "RaisedButton";
193 const char* text2 = "(\n";
194 const char* text3 = " child: ";
195 const char* text4 = "const";
196 const char* text5 = "Text";
197 const char* text6 = "'BUTTON TITLE'";
198 const char* text7 = "),\n";
199
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400200 builder.pushStyle(style(name));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400201 builder.addText(text1, strlen(text1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400202 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400203 builder.addText(text2, strlen(text2));
204 builder.addText(text3, strlen(text3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400205 builder.pushStyle(style(constant));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400206 builder.addText(text4, strlen(text4));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400207 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400208 builder.addText(" ", 1);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400209 builder.pushStyle(style(name));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400210 builder.addText(text5, strlen(text5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400211 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400212 builder.addText("(", 1);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400213 builder.pushStyle(style(literal));
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400214 builder.addText(text6, strlen(text6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400215 builder.pop();
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400216 builder.addText(text7, strlen(text7));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400217
218 auto paragraph = builder.Build();
219 paragraph->layout(w - 20);
220
221 paragraph->paint(canvas, 20, 20);
222 }
223
224 TextStyle style(SkPaint paint) {
225 TextStyle style;
226 paint.setAntiAlias(true);
227 style.setForegroundColor(paint);
228 style.setFontFamilies({SkString("monospace")});
229 style.setFontSize(30);
230
231 return style;
232 }
233
Julia Lavrova5207f352019-06-21 12:22:32 -0400234 void drawText(SkCanvas* canvas, SkScalar w, SkScalar h, std::vector<const char*>& text,
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400235 SkColor fg = SK_ColorDKGRAY, SkColor bg = SK_ColorWHITE,
236 const char* ff = "sans-serif", SkScalar fs = 24,
237 size_t lineLimit = 30,
238 const std::u16string& ellipsis = u"\u2026") {
239 SkAutoCanvasRestore acr(canvas, true);
240
241 canvas->clipRect(SkRect::MakeWH(w, h));
242 canvas->drawColor(bg);
243
244 SkScalar margin = 20;
245
246 SkPaint paint;
247 paint.setAntiAlias(true);
248 paint.setColor(fg);
249
250 SkPaint blue;
251 blue.setColor(SK_ColorBLUE);
252
253 SkPaint background;
254 background.setColor(bg);
255
256 TextStyle style;
257 style.setBackgroundColor(blue);
258 style.setForegroundColor(paint);
259 style.setFontFamilies({SkString(ff)});
260 style.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight,
261 SkFontStyle::kNormal_Width,
262 SkFontStyle::kUpright_Slant));
263 style.setFontSize(fs);
264 ParagraphStyle paraStyle;
265 paraStyle.setTextStyle(style);
266 paraStyle.setMaxLines(lineLimit);
267
268 paraStyle.setEllipsis(ellipsis);
269 TextStyle defaultStyle;
270 defaultStyle.setFontSize(20);
271 paraStyle.setTextStyle(defaultStyle);
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400272 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400273
274 SkPaint foreground;
275 foreground.setColor(fg);
276 style.setForegroundColor(foreground);
277 style.setBackgroundColor(background);
278
279 for (auto& part : text) {
280 builder.pushStyle(style);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400281 builder.addText(part, strlen(part));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400282 builder.pop();
283 }
284
285 auto paragraph = builder.Build();
286 paragraph->layout(w - margin * 2);
287 paragraph->paint(canvas, margin, margin);
288
289 canvas->translate(0, paragraph->getHeight() + margin);
290 }
291
292 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
293 TextAlign align) {
294 SkAutoCanvasRestore acr(canvas, true);
295
296 canvas->clipRect(SkRect::MakeWH(w, h));
297 canvas->drawColor(SK_ColorWHITE);
298
299 SkScalar margin = 20;
300
301 SkPaint paint;
302 paint.setAntiAlias(true);
303 paint.setColor(SK_ColorBLUE);
304
305 SkPaint gray;
306 gray.setColor(SK_ColorLTGRAY);
307
308 TextStyle style;
309 style.setBackgroundColor(gray);
310 style.setForegroundColor(paint);
311 style.setFontFamilies({SkString("Arial")});
312 style.setFontSize(30);
313 ParagraphStyle paraStyle;
314 paraStyle.setTextStyle(style);
315 paraStyle.setTextAlign(align);
316
Julia Lavrova5207f352019-06-21 12:22:32 -0400317 auto fontCollection = sk_make_sp<FontCollection>();
318 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
319 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400320 builder.addText(text.c_str(), text.length());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400321
322 auto paragraph = builder.Build();
323 paragraph->layout(w - margin * 2);
324 paragraph->layout(w - margin);
325 paragraph->paint(canvas, margin, margin);
326
327 canvas->translate(0, paragraph->getHeight() + margin);
328 }
329
330 void onDrawContent(SkCanvas* canvas) override {
Julia Lavrova5207f352019-06-21 12:22:32 -0400331 std::vector<const char*> cupertino = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400332 "google_logogoogle_gsuper_g_logo 1 "
333 "google_logogoogle_gsuper_g_logo 12 "
334 "google_logogoogle_gsuper_g_logo 123 "
335 "google_logogoogle_gsuper_g_logo 1234 "
336 "google_logogoogle_gsuper_g_logo 12345 "
337 "google_logogoogle_gsuper_g_logo 123456 "
338 "google_logogoogle_gsuper_g_logo 1234567 "
339 "google_logogoogle_gsuper_g_logo 12345678 "
340 "google_logogoogle_gsuper_g_logo 123456789 "
341 "google_logogoogle_gsuper_g_logo 1234567890 "
342 "google_logogoogle_gsuper_g_logo 123456789 "
343 "google_logogoogle_gsuper_g_logo 12345678 "
344 "google_logogoogle_gsuper_g_logo 1234567 "
345 "google_logogoogle_gsuper_g_logo 123456 "
346 "google_logogoogle_gsuper_g_logo 12345 "
347 "google_logogoogle_gsuper_g_logo 1234 "
348 "google_logogoogle_gsuper_g_logo 123 "
349 "google_logogoogle_gsuper_g_logo 12 "
350 "google_logogoogle_gsuper_g_logo 1 "
351 "google_logogoogle_gsuper_g_logo "
352 "google_logogoogle_gsuper_g_logo "
353 "google_logogoogle_gsuper_g_logo "
354 "google_logogoogle_gsuper_g_logo "
355 "google_logogoogle_gsuper_g_logo "
356 "google_logogoogle_gsuper_g_logo"};
Julia Lavrova5207f352019-06-21 12:22:32 -0400357 std::vector<const char*> text = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400358 "My neighbor came over to say,\n"
359 "Although not in a neighborly way,\n\n"
360 "That he'd knock me around,\n\n\n"
361 "If I didn't stop the sound,\n\n\n\n"
362 "Of the classical music I play."};
363
Julia Lavrova5207f352019-06-21 12:22:32 -0400364 std::vector<const char*> long_word = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400365 "A_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
366 "very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
367 "very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_"
368 "very_very_very_very_very_very_very_long_text"};
369
Julia Lavrova5207f352019-06-21 12:22:32 -0400370 std::vector<const char*> very_long = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400371 "A very very very very very very very very very very very very very very very very "
372 "very very very very very very very very very very very very very very very very "
373 "very very very very very very very very very very very very very very very very "
374 "very very very very very very very long text"};
375
Julia Lavrova5207f352019-06-21 12:22:32 -0400376 std::vector<const char*> very_word = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400377 "A very_very_very_very_very_very_very_very_very_very "
378 "very_very_very_very_very_very_very_very_very_very very very very very very very "
379 "very very very very very very very very very very very very very very very very "
380 "very very very very very very very very very very very very very long text"};
381
382 SkScalar width = this->width() / 5;
383 SkScalar height = this->height();
384 drawText(canvas, width, height, long_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
385 canvas->translate(width, 0);
386 drawText(canvas, width, height, very_long, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
387 canvas->translate(width, 0);
388 drawText(canvas, width, height, very_word, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
389 canvas->translate(width, 0);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400390 drawText(canvas, width, height / 2, text, SK_ColorBLACK, SK_ColorWHITE, "Roboto", 20, 100,
391 u"\u2026");
392 canvas->translate(0, height / 2);
393 drawCode(canvas, width, height / 2);
394 canvas->translate(width, -height / 2);
395
396 drawText(canvas, width, height, cupertino, SK_ColorBLACK, SK_ColorWHITE, "Google Sans", 30);
397 }
398
399private:
400 typedef Sample INHERITED;
401};
402
Mike Reed21a940d2019-07-23 10:11:03 -0400403class ParagraphView3 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400404protected:
Hal Canary8a027312019-07-03 10:55:44 -0400405 SkString name() override { return SkString("Paragraph3"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400406
407 void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h, const std::string& text,
408 TextAlign align, size_t lineLimit = std::numeric_limits<size_t>::max(),
409 bool RTL = false, SkColor background = SK_ColorGRAY,
410 const std::u16string& ellipsis = u"\u2026") {
411 SkAutoCanvasRestore acr(canvas, true);
412
413 canvas->clipRect(SkRect::MakeWH(w, h));
414 canvas->drawColor(SK_ColorWHITE);
415
416 SkScalar margin = 20;
417
418 SkPaint paint;
419 paint.setAntiAlias(true);
420 paint.setColor(SK_ColorBLACK);
421
422 SkPaint gray;
423 gray.setColor(background);
424
425 SkPaint yellow;
426 yellow.setColor(SK_ColorYELLOW);
427
428 TextStyle style;
429 style.setBackgroundColor(gray);
430 style.setForegroundColor(paint);
431 style.setFontFamilies({SkString("sans-serif")});
432 style.setFontSize(30);
433 ParagraphStyle paraStyle;
434 paraStyle.setTextStyle(style);
435 paraStyle.setTextAlign(align);
436 paraStyle.setMaxLines(lineLimit);
437 paraStyle.setEllipsis(ellipsis);
438 // paraStyle.setTextDirection(RTL ? SkTextDirection::rtl : SkTextDirection::ltr);
439
Julia Lavrova5207f352019-06-21 12:22:32 -0400440 auto fontCollection = sk_make_sp<FontCollection>();
441 fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
442 ParagraphBuilderImpl builder(paraStyle, fontCollection);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400443 if (RTL) {
444 builder.addText(mirror(text));
445 } else {
446 builder.addText(normal(text));
447 }
448
449 canvas->drawRect(SkRect::MakeXYWH(margin, margin, w - margin * 2, h - margin * 2), yellow);
450 auto paragraph = builder.Build();
451 paragraph->layout(w - margin * 2);
452 paragraph->paint(canvas, margin, margin);
453 }
454
455 std::u16string mirror(const std::string& text) {
456 std::u16string result;
457 result += u"\u202E";
458 // for (auto i = text.size(); i > 0; --i) {
459 // result += text[i - 1];
460 //}
461
462 for (auto i = text.size(); i > 0; --i) {
463 auto ch = text[i - 1];
464 if (ch == ',') {
465 result += u"!";
466 } else if (ch == '.') {
467 result += u"!";
468 } else {
469 result += ch;
470 }
471 }
472
473 result += u"\u202C";
474 return result;
475 }
476
477 std::u16string normal(const std::string& text) {
478 std::u16string result;
479 result += u"\u202D";
480 for (auto ch : text) {
481 result += ch;
482 }
483 result += u"\u202C";
484 return result;
485 }
486
487 void onDrawContent(SkCanvas* canvas) override {
488 const std::string options = // { "open-source open-source open-source open-source" };
489 {"Flutter is an open-source project to help developers "
490 "build high-performance, high-fidelity, mobile apps for "
491 "iOS and Android "
492 "from a single codebase. This design lab is a playground "
493 "and showcase of Flutter's many widgets, behaviors, "
494 "animations, layouts, and more."};
495
496 canvas->drawColor(SK_ColorDKGRAY);
497 SkScalar width = this->width() / 4;
498 SkScalar height = this->height() / 2;
499
500 const std::string line =
501 "World domination is such an ugly phrase - I prefer to call it world optimisation";
502
503 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, false, SK_ColorLTGRAY);
504 canvas->translate(width, 0);
505 drawLine(canvas, width, height, line, TextAlign::kRight, 2, false, SK_ColorLTGRAY);
506 canvas->translate(width, 0);
507 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, false, SK_ColorLTGRAY);
508 canvas->translate(width, 0);
509 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, false, SK_ColorLTGRAY);
510 canvas->translate(-width * 3, height);
511
512 drawLine(canvas, width, height, line, TextAlign::kLeft, 1, true, SK_ColorLTGRAY);
513 canvas->translate(width, 0);
514 drawLine(canvas, width, height, line, TextAlign::kRight, 2, true, SK_ColorLTGRAY);
515 canvas->translate(width, 0);
516 drawLine(canvas, width, height, line, TextAlign::kCenter, 3, true, SK_ColorLTGRAY);
517 canvas->translate(width, 0);
518 drawLine(canvas, width, height, line, TextAlign::kJustify, 4, true, SK_ColorLTGRAY);
519 canvas->translate(width, 0);
520 }
521
522private:
523 typedef Sample INHERITED;
524};
525
Mike Reed21a940d2019-07-23 10:11:03 -0400526class ParagraphView4 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400527protected:
Hal Canary8a027312019-07-03 10:55:44 -0400528 SkString name() override { return SkString("Paragraph4"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400529
530 void drawFlutter(SkCanvas* canvas, SkScalar w, SkScalar h,
531 const char* ff = "Google Sans", SkScalar fs = 30,
532 size_t lineLimit = std::numeric_limits<size_t>::max(),
533 const std::u16string& ellipsis = u"\u2026") {
534 SkAutoCanvasRestore acr(canvas, true);
535
536 canvas->clipRect(SkRect::MakeWH(w, h));
537
538 SkScalar margin = 20;
539
540 SkPaint black;
541 black.setAntiAlias(true);
542 black.setColor(SK_ColorBLACK);
543
544 SkPaint blue;
545 blue.setAntiAlias(true);
546 blue.setColor(SK_ColorBLUE);
547
548 SkPaint red;
549 red.setAntiAlias(true);
550 red.setColor(SK_ColorRED);
551
552 SkPaint green;
553 green.setAntiAlias(true);
554 green.setColor(SK_ColorGREEN);
555
556 SkPaint gray;
557 gray.setColor(SK_ColorLTGRAY);
558
559 SkPaint yellow;
560 yellow.setColor(SK_ColorYELLOW);
561
562 SkPaint magenta;
563 magenta.setAntiAlias(true);
564 magenta.setColor(SK_ColorMAGENTA);
565
566 TextStyle style;
567 style.setFontFamilies({SkString(ff)});
568 style.setFontSize(fs);
569
570 TextStyle style0;
571 style0.setForegroundColor(black);
572 style0.setBackgroundColor(gray);
573 style0.setFontFamilies({SkString(ff)});
574 style0.setFontSize(fs);
575 style0.setDecoration(TextDecoration::kUnderline);
576 style0.setDecorationStyle(TextDecorationStyle::kDouble);
577 style0.setDecorationColor(SK_ColorBLACK);
578
579 TextStyle style1;
580 style1.setForegroundColor(blue);
581 style1.setBackgroundColor(yellow);
582 style1.setFontFamilies({SkString(ff)});
583 style1.setFontSize(fs);
584 style1.setDecoration(TextDecoration::kOverline);
585 style1.setDecorationStyle(TextDecorationStyle::kWavy);
586 style1.setDecorationColor(SK_ColorBLACK);
587
588 TextStyle style2;
589 style2.setForegroundColor(red);
590 style2.setFontFamilies({SkString(ff)});
591 style2.setFontSize(fs);
592
593 TextStyle style3;
594 style3.setForegroundColor(green);
595 style3.setFontFamilies({SkString(ff)});
596 style3.setFontSize(fs);
597
598 TextStyle style4;
599 style4.setForegroundColor(magenta);
600 style4.setFontFamilies({SkString(ff)});
601 style4.setFontSize(fs);
602
603 ParagraphStyle paraStyle;
604 paraStyle.setTextStyle(style);
605 paraStyle.setMaxLines(lineLimit);
606
607 paraStyle.setEllipsis(ellipsis);
608
609 const char* logo1 = "google_";
610 const char* logo2 = "logo";
611 const char* logo3 = "go";
612 const char* logo4 = "ogle_logo";
613 const char* logo5 = "google_lo";
614 const char* logo6 = "go";
615 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400616 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400617
618 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400619 builder.addText(logo1, strlen(logo1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400620 builder.pop();
621 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400622 builder.addText(logo2, strlen(logo2));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400623 builder.pop();
624
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400625 builder.addText(" ", 1);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400626
627 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400628 builder.addText(logo3, strlen(logo3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400629 builder.pop();
630 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400631 builder.addText(logo4, strlen(logo4));
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(logo5, strlen(logo5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400638 builder.pop();
639 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400640 builder.addText(logo6, strlen(logo6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400641 builder.pop();
642
643 auto paragraph = builder.Build();
644 paragraph->layout(w - margin * 2);
645 paragraph->paint(canvas, margin, margin);
646 canvas->translate(0, h + margin);
647 }
648 }
649
650 void onDrawContent(SkCanvas* canvas) override {
651 canvas->drawColor(SK_ColorWHITE);
652 SkScalar width = this->width();
653 SkScalar height = this->height();
654
655 drawFlutter(canvas, width, height / 2);
656 }
657
658private:
659 typedef Sample INHERITED;
660};
661
Mike Reed21a940d2019-07-23 10:11:03 -0400662class ParagraphView5 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400663protected:
Julia Lavrova5207f352019-06-21 12:22:32 -0400664 SkString name() override { return SkString("Paragraph5"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400665
666 void bidi(SkCanvas* canvas, SkScalar w, SkScalar h, const std::u16string& text,
667 const std::u16string& expected, size_t lineLimit = std::numeric_limits<size_t>::max(),
668 const char* ff = "Roboto", SkScalar fs = 30,
669 const std::u16string& ellipsis = u"\u2026") {
670 SkAutoCanvasRestore acr(canvas, true);
671
672 canvas->clipRect(SkRect::MakeWH(w, h));
673
674 SkScalar margin = 20;
675
676 SkPaint black;
677 black.setColor(SK_ColorBLACK);
678 SkPaint gray;
679 gray.setColor(SK_ColorLTGRAY);
680
681 TextStyle style;
682 style.setForegroundColor(black);
683 style.setFontFamilies({SkString(ff)});
684 style.setFontSize(fs);
685
686 TextStyle style0;
687 style0.setForegroundColor(black);
688 style0.setFontFamilies({SkString(ff)});
689 style0.setFontSize(fs);
690 style0.setFontStyle(SkFontStyle(SkFontStyle::kNormal_Weight, SkFontStyle::kNormal_Width,
691 SkFontStyle::kItalic_Slant));
692
693 TextStyle style1;
694 style1.setForegroundColor(gray);
695 style1.setFontFamilies({SkString(ff)});
696 style1.setFontSize(fs);
697 style1.setFontStyle(SkFontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
698 SkFontStyle::kUpright_Slant));
699
700 ParagraphStyle paraStyle;
701 paraStyle.setTextStyle(style);
702 paraStyle.setMaxLines(lineLimit);
703
704 paraStyle.setEllipsis(ellipsis);
705
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400706 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400707
708 if (text.empty()) {
709 const std::u16string text0 = u"\u202Dabc";
710 const std::u16string text1 = u"\u202EFED";
711 const std::u16string text2 = u"\u202Dghi";
712 const std::u16string text3 = u"\u202ELKJ";
713 const std::u16string text4 = u"\u202Dmno";
714 builder.pushStyle(style0);
715 builder.addText(text0);
716 builder.pop();
717 builder.pushStyle(style1);
718 builder.addText(text1);
719 builder.pop();
720 builder.pushStyle(style0);
721 builder.addText(text2);
722 builder.pop();
723 builder.pushStyle(style1);
724 builder.addText(text3);
725 builder.pop();
726 builder.pushStyle(style0);
727 builder.addText(text4);
728 builder.pop();
729 } else {
730 // icu::UnicodeString unicode((UChar*) text.data(), SkToS32(text.size()));
731 // std::string str;
732 // unicode.toUTF8String(str);
733 // SkDebugf("Text: %s\n", str.c_str());
734 builder.addText(text + expected);
735 }
736
737 auto paragraph = builder.Build();
738 paragraph->layout(w - margin * 2);
739 paragraph->paint(canvas, margin, margin);
740 }
741
742 void onDrawContent(SkCanvas* canvas) override {
743 canvas->drawColor(SK_ColorWHITE);
744 SkScalar width = this->width();
745 SkScalar height = this->height() / 8;
746
747 const std::u16string text1 =
748 u"A \u202ENAC\u202Cner, exceedingly \u202ENAC\u202Cny,\n"
749 "One morning remarked to his granny:\n"
750 "A \u202ENAC\u202Cner \u202ENAC\u202C \u202ENAC\u202C,\n"
751 "Anything that he \u202ENAC\u202C,\n"
752 "But a \u202ENAC\u202Cner \u202ENAC\u202C't \u202ENAC\u202C a \u202ENAC\u202C, "
753 "\u202ENAC\u202C he?";
754 bidi(canvas, width, height * 3, text1, u"", 5);
755 canvas->translate(0, height * 3);
756
757 bidi(canvas, width, height, u"\u2067DETALOSI\u2069", u"");
758 canvas->translate(0, height);
759
760 bidi(canvas, width, height, u"\u202BDEDDEBME\u202C", u"");
761 canvas->translate(0, height);
762
763 bidi(canvas, width, height, u"\u202EEDIRREVO\u202C", u"");
764 canvas->translate(0, height);
765
766 bidi(canvas, width, height, u"\u200FTICILPMI\u200E", u"");
767 canvas->translate(0, height);
768
769 bidi(canvas, width, height, u"123 456 7890 \u202EZYXWV UTS RQP ONM LKJ IHG FED CBA\u202C.",
770 u"", 2);
771 canvas->translate(0, height);
772
773 // bidi(canvas, width, height, u"", u"");
774 // canvas->translate(0, height);
775 }
776
777private:
778 typedef Sample INHERITED;
779};
780
Mike Reed21a940d2019-07-23 10:11:03 -0400781class ParagraphView6 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400782protected:
Julia Lavrova5207f352019-06-21 12:22:32 -0400783 SkString name() override { return SkString("Paragraph6"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400784
785 void hangingS(SkCanvas* canvas, SkScalar w, SkScalar h, SkScalar fs = 60.0) {
786 auto ff = "HangingS";
787
788 canvas->drawColor(SK_ColorLTGRAY);
789
790 SkPaint black;
791 black.setAntiAlias(true);
792 black.setColor(SK_ColorBLACK);
793
794 SkPaint blue;
795 blue.setAntiAlias(true);
796 blue.setColor(SK_ColorBLUE);
797
798 SkPaint red;
799 red.setAntiAlias(true);
800 red.setColor(SK_ColorRED);
801
802 SkPaint green;
803 green.setAntiAlias(true);
804 green.setColor(SK_ColorGREEN);
805
806 SkPaint gray;
807 gray.setColor(SK_ColorCYAN);
808
809 SkPaint yellow;
810 yellow.setColor(SK_ColorYELLOW);
811
812 SkPaint magenta;
813 magenta.setAntiAlias(true);
814 magenta.setColor(SK_ColorMAGENTA);
815
816 SkFontStyle fontStyle(SkFontStyle::kBold_Weight, SkFontStyle::kNormal_Width,
817 SkFontStyle::kItalic_Slant);
818
819 TextStyle style;
820 style.setFontFamilies({SkString(ff)});
821 style.setFontSize(fs);
822 style.setFontStyle(fontStyle);
823
824 TextStyle style0;
825 style0.setForegroundColor(black);
826 style0.setBackgroundColor(gray);
827 style0.setFontFamilies({SkString(ff)});
828 style0.setFontSize(fs);
829 style0.setFontStyle(fontStyle);
830
831 TextStyle style1;
832 style1.setForegroundColor(blue);
833 style1.setBackgroundColor(yellow);
834 style1.setFontFamilies({SkString(ff)});
835 style1.setFontSize(fs);
836 style1.setFontStyle(fontStyle);
837
838 TextStyle style2;
839 style2.setForegroundColor(red);
840 style2.setFontFamilies({SkString(ff)});
841 style2.setFontSize(fs);
842 style2.setFontStyle(fontStyle);
843
844 TextStyle style3;
845 style3.setForegroundColor(green);
846 style3.setFontFamilies({SkString(ff)});
847 style3.setFontSize(fs);
848 style3.setFontStyle(fontStyle);
849
850 TextStyle style4;
851 style4.setForegroundColor(magenta);
852 style4.setFontFamilies({SkString(ff)});
853 style4.setFontSize(fs);
854 style4.setFontStyle(fontStyle);
855
856 ParagraphStyle paraStyle;
857 paraStyle.setTextStyle(style);
858
859 const char* logo1 = "S";
860 const char* logo2 = "kia";
861 const char* logo3 = "Sk";
862 const char* logo4 = "ia";
863 const char* logo5 = "Ski";
864 const char* logo6 = "a";
865 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400866 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400867
868 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400869 builder.addText(logo1, strlen(logo1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400870 builder.pop();
871 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400872 builder.addText(logo2, strlen(logo2));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400873 builder.pop();
874
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400875 builder.addText(" ", 3);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400876
877 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400878 builder.addText(logo3, strlen(logo3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400879 builder.pop();
880 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400881 builder.addText(logo4, strlen(logo4));
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(logo5, strlen(logo5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400888 builder.pop();
889 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400890 builder.addText(logo6, strlen(logo6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400891 builder.pop();
892
893 auto paragraph = builder.Build();
894 paragraph->layout(w);
895 paragraph->paint(canvas, 40, 40);
896 canvas->translate(0, h);
897 }
898
899 const char* logo11 = "S";
900 const char* logo12 = "S";
901 const char* logo13 = "S";
902 const char* logo14 = "S";
903 const char* logo15 = "S";
904 const char* logo16 = "S";
905 {
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400906 ParagraphBuilderImpl builder(paraStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400907
908 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400909 builder.addText(logo11, strlen(logo1));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400910 builder.pop();
911 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400912 builder.addText(logo12, strlen(logo2));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400913 builder.pop();
914
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400915 builder.addText(" ", 3);
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400916
917 builder.pushStyle(style0);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400918 builder.addText(logo13, strlen(logo3));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400919 builder.pop();
920 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400921 builder.addText(logo14, strlen(logo4));
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(logo15, strlen(logo5));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400928 builder.pop();
929 builder.pushStyle(style1);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400930 builder.addText(logo16, strlen(logo6));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400931 builder.pop();
932
933 auto paragraph = builder.Build();
934 paragraph->layout(w);
935 paragraph->paint(canvas, 40, h);
936 canvas->translate(0, h);
937 }
938 }
939
940 void onDrawContent(SkCanvas* canvas) override {
941 canvas->drawColor(SK_ColorWHITE);
942 SkScalar width = this->width();
943 SkScalar height = this->height() / 4;
944
945 hangingS(canvas, width, height);
946 }
947
948private:
949 typedef Sample INHERITED;
950};
951
Mike Reed21a940d2019-07-23 10:11:03 -0400952class ParagraphView7 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400953protected:
Hal Canary8a027312019-07-03 10:55:44 -0400954 SkString name() override { return SkString("Paragraph7"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400955
956 void drawText(SkCanvas* canvas, SkColor background, SkScalar letterSpace, SkScalar w,
957 SkScalar h) {
958 SkAutoCanvasRestore acr(canvas, true);
959 canvas->clipRect(SkRect::MakeWH(w, h));
960 canvas->drawColor(background);
961
962 const char* line =
Julia Lavrovadb9f6692019-08-01 16:02:17 -0400963 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400964
965 ParagraphStyle paragraphStyle;
966 paragraphStyle.setTextAlign(TextAlign::kLeft);
967 paragraphStyle.setMaxLines(10);
968 paragraphStyle.turnHintingOff();
969 TextStyle textStyle;
970 textStyle.setFontFamilies({SkString("Roboto")});
971 textStyle.setFontSize(30);
972 textStyle.setLetterSpacing(letterSpace);
973 textStyle.setColor(SK_ColorBLACK);
974 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
975 SkFontStyle::kUpright_Slant));
976
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -0400977 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400978 builder.pushStyle(textStyle);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -0400979 builder.addText(line, strlen(line));
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400980 builder.pop();
981
982 auto paragraph = builder.Build();
983 paragraph->layout(w - 20);
984 paragraph->paint(canvas, 10, 10);
985 }
986
987 void onDrawContent(SkCanvas* canvas) override {
988 canvas->drawColor(SK_ColorWHITE);
989
990 auto h = this->height() / 4;
991 auto w = this->width() / 2;
992
993 drawText(canvas, SK_ColorGRAY, 1, w, h);
994 canvas->translate(0, h);
995
996 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
997 canvas->translate(0, h);
998
999 drawText(canvas, SK_ColorCYAN, 3, w, h);
1000 canvas->translate(0, h);
1001
1002 drawText(canvas, SK_ColorGRAY, 4, w, h);
1003 canvas->translate(w, -3 * h);
1004
1005 drawText(canvas, SK_ColorYELLOW, 5, w, h);
1006 canvas->translate(0, h);
1007
1008 drawText(canvas, SK_ColorGREEN, 10, w, h);
1009 canvas->translate(0, h);
1010
1011 drawText(canvas, SK_ColorRED, 15, w, h);
1012 canvas->translate(0, h);
1013
1014 drawText(canvas, SK_ColorBLUE, 20, w, h);
1015 canvas->translate(0, h);
1016 }
1017
1018private:
1019 typedef Sample INHERITED;
1020};
1021
Mike Reed21a940d2019-07-23 10:11:03 -04001022class ParagraphView8 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001023protected:
Julia Lavrovadb9f6692019-08-01 16:02:17 -04001024 SkString name() override { return SkString("Paragraph8"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001025
1026 void drawText(SkCanvas* canvas, SkColor background, SkScalar wordSpace, SkScalar w,
1027 SkScalar h) {
1028 SkAutoCanvasRestore acr(canvas, true);
1029 canvas->clipRect(SkRect::MakeWH(w, h));
1030 canvas->drawColor(background);
1031
1032 const char* line =
Julia Lavrovadb9f6692019-08-01 16:02:17 -04001033 "World domination is such an ugly phrase - I prefer to call it world optimisation.";
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001034
1035 ParagraphStyle paragraphStyle;
1036 paragraphStyle.setTextAlign(TextAlign::kLeft);
1037 paragraphStyle.setMaxLines(10);
1038 paragraphStyle.turnHintingOff();
1039 TextStyle textStyle;
1040 textStyle.setFontFamilies({SkString("Roboto")});
1041 textStyle.setFontSize(30);
1042 textStyle.setWordSpacing(wordSpace);
1043 textStyle.setColor(SK_ColorBLACK);
1044 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1045 SkFontStyle::kUpright_Slant));
1046
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001047 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001048 builder.pushStyle(textStyle);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -04001049 builder.addText(line, strlen(line));
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001050 builder.pop();
1051
1052 auto paragraph = builder.Build();
1053 paragraph->layout(w - 20);
1054 paragraph->paint(canvas, 10, 10);
1055 }
1056
1057 void onDrawContent(SkCanvas* canvas) override {
1058 canvas->drawColor(SK_ColorWHITE);
1059
1060 auto h = this->height() / 4;
1061 auto w = this->width() / 2;
1062
1063 drawText(canvas, SK_ColorGRAY, 1, w, h);
1064 canvas->translate(0, h);
1065
1066 drawText(canvas, SK_ColorLTGRAY, 2, w, h);
1067 canvas->translate(0, h);
1068
1069 drawText(canvas, SK_ColorCYAN, 3, w, h);
1070 canvas->translate(0, h);
1071
1072 drawText(canvas, SK_ColorGRAY, 4, w, h);
1073 canvas->translate(w, -3 * h);
1074
1075 drawText(canvas, SK_ColorYELLOW, 5, w, h);
1076 canvas->translate(0, h);
1077
1078 drawText(canvas, SK_ColorGREEN, 10, w, h);
1079 canvas->translate(0, h);
1080
1081 drawText(canvas, SK_ColorRED, 15, w, h);
1082 canvas->translate(0, h);
1083
1084 drawText(canvas, SK_ColorBLUE, 20, w, h);
1085 canvas->translate(0, h);
1086 }
1087
1088private:
1089 typedef Sample INHERITED;
1090};
1091
Mike Reed21a940d2019-07-23 10:11:03 -04001092class ParagraphView9 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001093protected:
Hal Canary8a027312019-07-03 10:55:44 -04001094 SkString name() override { return SkString("Paragraph9"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001095
Hal Canary6cc65e12019-07-03 15:53:04 -04001096 bool onChar(SkUnichar uni) override {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001097 switch (uni) {
1098 case 'w':
1099 ++wordSpacing;
1100 return true;
1101 case 'q':
1102 if (wordSpacing > 0) --wordSpacing;
1103 return true;
1104 case 'l':
1105 ++letterSpacing;
1106 return true;
1107 case 'k':
1108 if (letterSpacing > 0) --letterSpacing;
1109 return true;
1110 default:
1111 break;
1112 }
Hal Canary6cc65e12019-07-03 15:53:04 -04001113 return false;
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001114 }
1115
1116 void drawText(SkCanvas* canvas, SkColor background, SkScalar w, SkScalar h) {
1117 SkAutoCanvasRestore acr(canvas, true);
1118 canvas->clipRect(SkRect::MakeWH(w, h));
1119 canvas->drawColor(background);
1120
1121 const char* text =
1122 "( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1123 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)("
1124 " ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)( ´・‿・`)";
1125
1126 ParagraphStyle paragraphStyle;
1127 paragraphStyle.setTextAlign(TextAlign::kLeft);
1128 paragraphStyle.setMaxLines(10);
1129 paragraphStyle.turnHintingOff();
1130 TextStyle textStyle;
1131 textStyle.setFontFamilies({SkString("Roboto")});
1132 textStyle.setFontSize(50);
1133 textStyle.setHeight(1.3f);
1134 textStyle.setColor(SK_ColorBLACK);
1135 textStyle.setFontStyle(SkFontStyle(SkFontStyle::kMedium_Weight, SkFontStyle::kNormal_Width,
1136 SkFontStyle::kUpright_Slant));
1137
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001138 ParagraphBuilderImpl builder(paragraphStyle, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001139 builder.pushStyle(textStyle);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -04001140 builder.addText(text, strlen(text));
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001141 builder.pop();
1142
1143 auto paragraph = builder.Build();
1144 paragraph->layout(550);
1145
1146 std::vector<size_t> sizes = {0, 1, 2, 8, 19, 21, 22, 30, 150};
1147
1148 std::vector<size_t> colors = {SK_ColorBLUE, SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorGREEN,
1149 SK_ColorRED, SK_ColorWHITE, SK_ColorYELLOW, SK_ColorMAGENTA};
1150
1151 RectHeightStyle rect_height_style = RectHeightStyle::kTight;
1152 RectWidthStyle rect_width_style = RectWidthStyle::kTight;
1153
1154 for (size_t i = 0; i < sizes.size() - 1; ++i) {
1155 size_t from = (i == 0 ? 0 : 1) + sizes[i];
1156 size_t to = sizes[i + 1];
1157 auto boxes = paragraph->getRectsForRange(from, to, rect_height_style, rect_width_style);
1158 if (boxes.empty()) {
1159 continue;
1160 }
1161 for (auto& box : boxes) {
1162 SkPaint paint;
1163 paint.setColor(colors[i % colors.size()]);
1164 paint.setShader(setgrad(box.rect, colors[i % colors.size()], SK_ColorWHITE));
1165 canvas->drawRect(box.rect, paint);
1166 }
1167 }
1168
1169 paragraph->paint(canvas, 0, 0);
1170 }
1171
1172 void onDrawContent(SkCanvas* canvas) override {
1173 canvas->drawColor(SK_ColorWHITE);
1174
1175 auto h = this->height();
1176 auto w = this->width();
1177
1178 drawText(canvas, SK_ColorGRAY, w, h);
1179 }
1180
1181private:
1182 typedef Sample INHERITED;
1183 SkScalar letterSpacing;
1184 SkScalar wordSpacing;
1185};
1186
Mike Reed21a940d2019-07-23 10:11:03 -04001187class ParagraphView10 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001188protected:
Hal Canary8a027312019-07-03 10:55:44 -04001189 SkString name() override { return SkString("Paragraph10"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001190
1191 void onDrawContent(SkCanvas* canvas) override {
1192 canvas->drawColor(SK_ColorWHITE);
1193
1194 const char* text = "English English 字典 字典 😀😃😄 😀😃😄";
1195 ParagraphStyle paragraph_style;
1196 paragraph_style.turnHintingOff();
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001197 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001198
1199 TextStyle text_style;
Julia Lavrova5207f352019-06-21 12:22:32 -04001200 text_style.setFontFamilies({SkString("Roboto"),
1201 SkString("Noto Color Emoji"),
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001202 SkString("Source Han Serif CN")});
1203 text_style.setColor(SK_ColorRED);
1204 text_style.setFontSize(60);
1205 text_style.setLetterSpacing(0);
1206 text_style.setWordSpacing(0);
1207 text_style.setColor(SK_ColorBLACK);
1208 text_style.setHeight(1);
1209 builder.pushStyle(text_style);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -04001210 builder.addText(text, strlen(text));
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001211 builder.pop();
1212
1213 auto paragraph = builder.Build();
1214 paragraph->layout(width());
1215
1216 paragraph->paint(canvas, 0, 0);
1217 SkDEBUGCODE(auto impl = reinterpret_cast<ParagraphImpl*>(paragraph.get()));
1218 SkASSERT(impl->runs().size() == 3);
Julia Lavrova5207f352019-06-21 12:22:32 -04001219 SkASSERT(impl->runs()[0].textRange().end == impl->runs()[1].textRange().start);
1220 SkASSERT(impl->runs()[1].textRange().end == impl->runs()[2].textRange().start);
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001221 }
1222
1223private:
1224 typedef Sample INHERITED;
1225};
1226
Mike Reed21a940d2019-07-23 10:11:03 -04001227class ParagraphView11 : public ParagraphView_Base {
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001228protected:
Hal Canary8a027312019-07-03 10:55:44 -04001229 SkString name() override { return SkString("Paragraph11"); }
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001230
1231 void onDrawContent(SkCanvas* canvas) override {
1232 canvas->drawColor(SK_ColorWHITE);
Julia Lavrova5207f352019-06-21 12:22:32 -04001233 const char* text = "The same text many times";
1234
1235 for (size_t i = 0; i < 10; i++) {
1236 ParagraphStyle paragraph_style;
Julia Lavrovab7b0b3a2019-07-30 13:32:08 -04001237 ParagraphBuilderImpl builder(paragraph_style, getFontCollection());
Julia Lavrova5207f352019-06-21 12:22:32 -04001238 TextStyle text_style;
1239 text_style.setFontFamilies({SkString("Roboto")});
1240 text_style.setColor(SK_ColorBLACK);
1241 text_style.setFontSize(10 + 2 * (i % 10));
1242 builder.pushStyle(text_style);
Kevin Lubick7aeabcf2019-09-27 15:16:13 -04001243 builder.addText(text, strlen(text));
Julia Lavrova5207f352019-06-21 12:22:32 -04001244 builder.pop();
1245 auto paragraph = builder.Build();
1246 paragraph->layout(500);
Mike Reed21a940d2019-07-23 10:11:03 -04001247 paragraph->paint(canvas, 0, 40 * (i % 10));
Julia Lavrova5207f352019-06-21 12:22:32 -04001248 }
1249 }
1250
1251private:
1252 typedef Sample INHERITED;
1253};
1254
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001255//////////////////////////////////////////////////////////////////////////////
1256
1257DEF_SAMPLE(return new ParagraphView1();)
1258DEF_SAMPLE(return new ParagraphView2();)
1259DEF_SAMPLE(return new ParagraphView3();)
1260DEF_SAMPLE(return new ParagraphView4();)
1261DEF_SAMPLE(return new ParagraphView5();)
1262DEF_SAMPLE(return new ParagraphView6();)
1263DEF_SAMPLE(return new ParagraphView7();)
1264DEF_SAMPLE(return new ParagraphView8();)
1265DEF_SAMPLE(return new ParagraphView9();)
1266DEF_SAMPLE(return new ParagraphView10();)
1267DEF_SAMPLE(return new ParagraphView11();)
Julia Lavrova526df262019-08-21 17:49:44 -04001268