Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
87 SkTextBlobBuilder builder;
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) {
195 SkTextBlobBuilder builder;
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]
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)
virtual GrRecordingContext * recordingContext() const
void clear(SkColor color)
Definition SkCanvas.h:1199
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
void scale(SkScalar sx, SkScalar sy)
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
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
sk_sp< SkImage > image
Definition examples.cpp:29
float SkScalar
Definition extension.cpp:12
double y
void add_to_text_blob_w_len(SkTextBlobBuilder *builder, const char *text, size_t len, SkTextEncoding encoding, const SkFont &font, SkScalar x, SkScalar y)
sk_sp< SkTypeface > CreateTypefaceFromResource(const char *resource, int ttcIndex)
sk_sp< SkTypeface > CreateTestTypeface(const char *name, SkFontStyle style)
SkScalar w
SkScalar h
SkScalar fLeading
distance to add between lines, typically positive or zero
SkScalar fAscent
distance to reserve above baseline, typically negative
SkScalar fDescent
distance to reserve below baseline, typically positive
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659