Flutter Engine
The Flutter Engine
ChineseFlingSlide.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
13#include "src/base/SkRandom.h"
14#include "tools/Resources.h"
15#include "tools/ToolUtils.h"
17#include "tools/viewer/Slide.h"
18
19#if defined(SK_GANESH)
22
24#endif
25
27#ifdef SK_BUILD_FOR_ANDROID
28 return ToolUtils::CreateTypefaceFromResource("fonts/NotoSansCJK-Regular.ttc");
29#elif defined(SK_BUILD_FOR_WIN)
31#elif defined(SK_BUILD_FOR_MAC)
32 return ToolUtils::CreateTestTypeface("Hiragino Sans GB W3", SkFontStyle());
33#elif defined(SK_BUILD_FOR_IOS)
34 return ToolUtils::CreateTestTypeface("Hiragino Sans GB W3", SkFontStyle());
35#elif defined(SK_BUILD_FOR_UNIX)
36 return ToolUtils::CreateTestTypeface("Noto Sans CJK SC", SkFontStyle());
37#else
38 return nullptr;
39#endif
40}
41
42class ChineseFlingSlide : public Slide {
43 inline static constexpr int kNumBlobs = 200;
44 inline static constexpr int kWordLength = 16;
45
46 sk_sp<SkTypeface> fTypeface;
47 SkFontMetrics fMetrics;
48 sk_sp<SkTextBlob> fBlobs[kNumBlobs];
49 SkRandom fRand;
50 int fIndex = 0;
51
52public:
53 ChineseFlingSlide() { fName = "chinese-fling"; }
54
55 void draw(SkCanvas* canvas) override {
56 canvas->clear(0xFFDDDDDD);
57
59 paint.setColor(0xDE000000);
60
61 // draw a consistent run of the 'words' - one word per line
62 int index = fIndex;
63 for (SkScalar y = 0.0f; y < 1024.0f; ) {
64
65 y += -fMetrics.fAscent;
66 canvas->drawTextBlob(fBlobs[index], 0, y, paint);
67
68 y += fMetrics.fDescent + fMetrics.fLeading;
69 ++index;
70 index %= kNumBlobs;
71 }
72 // now "fling" a random amount
73 fIndex += fRand.nextRangeU(5, 20);
74 fIndex %= kNumBlobs;
75 }
76
77 void load(SkScalar w, SkScalar h) override {
78 fTypeface = chinese_typeface();
79
80 SkFont font(fTypeface, 56);
81 font.getMetrics(&fMetrics);
82
83 SkUnichar glyphs[kWordLength];
84 for (int32_t i = 0; i < kNumBlobs; ++i) {
85 this->createRandomWord(glyphs);
86
89 (const char*)glyphs,
90 kWordLength * 4,
92 font,
93 0,
94 0);
95
96 fBlobs[i] = builder.make();
97 }
98 }
99
100 // Construct a random kWordLength character 'word' drawing from the full Chinese set
101 void createRandomWord(SkUnichar glyphs[kWordLength]) {
102 for (int i = 0; i < kWordLength; ++i) {
103 glyphs[i] = fRand.nextRangeU(0x4F00, 0x9FA0);
104 }
105 }
106};
107
108class ChineseZoomSlide : public Slide {
109 inline static constexpr int kNumBlobs = 8;
110 inline static constexpr int kParagraphLength = 175;
111
112 bool fAfterFirstFrame = false;
113 sk_sp<SkTypeface> fTypeface;
114 SkFontMetrics fMetrics;
115 sk_sp<SkTextBlob> fBlobs[kNumBlobs];
116 SkRandom fRand;
117 SkScalar fScale = 15;
118 SkScalar fTranslate = 0;
119
120public:
121 ChineseZoomSlide() { fName = "chinese-zoom"; }
122
123 bool onChar(SkUnichar uni) override {
124 if ('>' == uni) {
125 fScale += 0.125f;
126 return true;
127 }
128 if ('<' == uni) {
129 fScale -= 0.125f;
130 return true;
131 }
132 return false;
133 }
134
135 void draw(SkCanvas* canvas) override {
136 canvas->clear(0xFFDDDDDD);
137
139 paint.setAntiAlias(true);
140 paint.setColor(0xDE000000);
141
142 if (fAfterFirstFrame) {
143#if defined(SK_GANESH)
144 auto direct = GrAsDirectContext(canvas->recordingContext());
145 if (direct) {
146 sk_sp<SkImage> image = direct->priv().testingOnly_getFontAtlasImage(MaskFormat::kA8,
147 0);
148 canvas->drawImageRect(image,
149 SkRect::MakeXYWH(10.0f, 10.0f, 512.0f, 512.0),
151 image = direct->priv().testingOnly_getFontAtlasImage(MaskFormat::kA8, 1);
152 canvas->drawImageRect(image,
153 SkRect::MakeXYWH(522.0f, 10.0f, 512.f, 512.0f),
155 image = direct->priv().testingOnly_getFontAtlasImage(MaskFormat::kA8, 2);
156 canvas->drawImageRect(image,
157 SkRect::MakeXYWH(10.0f, 522.0f, 512.0f, 512.0f),
159 image = direct->priv().testingOnly_getFontAtlasImage(MaskFormat::kA8, 3);
160 canvas->drawImageRect(image,
161 SkRect::MakeXYWH(522.0f, 522.0f, 512.0f, 512.0f),
163 }
164#endif
165 }
166
167 canvas->scale(fScale, fScale);
168 canvas->translate(0, fTranslate);
169 fTranslate -= 0.5f;
170
171 // draw a consistent run of the 'words' - one word per line
172 SkScalar y = 0;
173 for (int index = 0; index < kNumBlobs; ++index) {
174 y += -fMetrics.fAscent;
175 canvas->drawTextBlob(fBlobs[index], 0, y, paint);
176
177 y += 3*(fMetrics.fDescent - fMetrics.fAscent + fMetrics.fLeading);
178 }
179 if (!fAfterFirstFrame) {
180 fAfterFirstFrame = true;
181 }
182 }
183
184 void load(SkScalar w, SkScalar h) override {
185 fTypeface = chinese_typeface();
186
187 SkFont font(fTypeface, 11);
188 font.getMetrics(&fMetrics);
189
191 paint.setColor(0xDE000000);
192
193 SkUnichar glyphs[45];
194 for (int32_t i = 0; i < kNumBlobs; ++i) {
196 auto paragraphLength = kParagraphLength;
197 SkScalar y = 0;
198 while (paragraphLength - 45 > 0) {
199 auto currentLineLength = std::min(45, paragraphLength - 45);
200 this->createRandomLine(glyphs, currentLineLength);
201
203 (const char*)glyphs,
204 currentLineLength * 4,
206 font,
207 0,
208 y);
209 y += fMetrics.fDescent - fMetrics.fAscent + fMetrics.fLeading;
210 paragraphLength -= 45;
211 }
212 fBlobs[i] = builder.make();
213 }
214 }
215
216 // Construct a random kWordLength character 'word' drawing from the full Chinese set
217 void createRandomLine(SkUnichar glyphs[45], int lineLength) {
218 for (auto i = 0; i < lineLength; ++i) {
219 glyphs[i] = fRand.nextRangeU(0x4F00, 0x9FA0);
220 }
221 }
222};
223
224//////////////////////////////////////////////////////////////////////////////
225
226DEF_SLIDE( return new ChineseFlingSlide(); )
227DEF_SLIDE( return new ChineseZoomSlide(); )
static sk_sp< SkTypeface > chinese_typeface()
uint16_t glyphs[5]
Definition: FontMgrTest.cpp:46
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
@ kUTF32
uses four byte words to represent all of Unicode
int32_t SkUnichar
Definition: SkTypes.h:175
#define DEF_SLIDE(code)
Definition: Slide.h:25
void createRandomWord(SkUnichar glyphs[kWordLength])
void load(SkScalar w, SkScalar h) override
void draw(SkCanvas *canvas) override
void load(SkScalar w, SkScalar h) override
void createRandomLine(SkUnichar glyphs[45], int lineLength)
bool onChar(SkUnichar uni) override
void draw(SkCanvas *canvas) override
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
virtual GrRecordingContext * recordingContext() const
Definition: SkCanvas.cpp:1637
void clear(SkColor color)
Definition: SkCanvas.h:1199
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
Definition: SkCanvas.cpp:2333
void scale(SkScalar sx, SkScalar sy)
Definition: SkCanvas.cpp:1289
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
Definition: SkCanvas.cpp:2484
Definition: SkFont.h:35
uint32_t nextRangeU(uint32_t min, uint32_t max)
Definition: SkRandom.h:80
Definition: Slide.h:29
SkString fName
Definition: Slide.h:54
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
static float min(float r, float g, float b)
Definition: hsl.cpp:48
double y
sk_sp< const SkImage > image
Definition: SkRecords.h:269
void add_to_text_blob_w_len(SkTextBlobBuilder *builder, const char *text, size_t len, SkTextEncoding encoding, const SkFont &font, SkScalar x, SkScalar y)
Definition: ToolUtils.cpp:213
sk_sp< SkTypeface > CreateTypefaceFromResource(const char *resource, int ttcIndex)
sk_sp< SkTypeface > CreateTestTypeface(const char *name, SkFontStyle style)
font
Font Metadata and Metrics.
MaskFormat
Definition: AtlasTypes.h:98
SkSamplingOptions(SkFilterMode::kLinear))
SkScalar w
SkScalar h
SkScalar fLeading
distance to add between lines, typically positive or zero
Definition: SkFontMetrics.h:57
SkScalar fAscent
distance to reserve above baseline, typically negative
Definition: SkFontMetrics.h:54
SkScalar fDescent
distance to reserve below baseline, typically positive
Definition: SkFontMetrics.h:55
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659