blob: ef86747dafefe2c539c3818c551252ae560e00c3 [file] [log] [blame]
Robert Phillips4c72b262017-08-15 13:28:42 -04001/*
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
8#include "Resources.h"
9#include "SampleCode.h"
10#include "sk_tool_utils.h"
11
12#include "SkCanvas.h"
13#include "SkFontMgr.h"
14#include "SkRandom.h"
15#include "SkTypeface.h"
16#include "SkTextBlob.h"
17
Jim Van Verth87d18ce2018-01-22 12:45:47 -050018#if SK_SUPPORT_GPU
19#include "GrContext.h"
20#endif
21
Robert Phillips4c72b262017-08-15 13:28:42 -040022static void make_paint(SkPaint* paint, sk_sp<SkTypeface> typeface) {
23 static const int kTextSize = 56;
24
25 paint->setAntiAlias(true);
26 paint->setColor(0xDE000000);
27 paint->setTypeface(typeface);
28 paint->setTextSize(kTextSize);
29 paint->setTextEncoding(SkPaint::kUTF32_TextEncoding);
30}
31
Robert Phillips4c72b262017-08-15 13:28:42 -040032static sk_sp<SkTypeface> chinese_typeface() {
33#ifdef SK_BUILD_FOR_ANDROID
Hal Canary53e5e7d2017-12-08 14:25:14 -050034 return MakeResourceAsTypeface("fonts/NotoSansCJK-Regular.ttc");
Mike Klein8f11d4d2018-01-24 12:42:55 -050035#elif defined(SK_BUILD_FOR_WIN)
Robert Phillips4c72b262017-08-15 13:28:42 -040036 return SkTypeface::MakeFromName("SimSun", SkFontStyle());
37#elif defined(SK_BUILD_FOR_MAC)
38 return SkTypeface::MakeFromName("Hiragino Sans GB W3", SkFontStyle());
39#elif defined(SK_BUILD_FOR_IOS)
40 return SkTypeface::MakeFromName("Hiragino Sans GB W3", SkFontStyle());
41#elif defined(SK_BUILD_FOR_UNIX)
42 return SkTypeface::MakeFromName("Noto Sans CJK SC", SkFontStyle());
43#else
44 return nullptr;
45#endif
46}
47
48class ChineseFlingView : public SampleView {
49public:
Jim Van Verthc3269ae2017-09-28 15:04:00 -040050 ChineseFlingView() : fBlobs(kNumBlobs) {}
Robert Phillips4c72b262017-08-15 13:28:42 -040051
52protected:
53 bool onQuery(SkEvent* evt) override {
54 if (SampleCode::TitleQ(*evt)) {
55 SampleCode::TitleR(evt, "chinese-fling");
56 return true;
57 }
58 return this->INHERITED::onQuery(evt);
59 }
60
61 void onDrawContent(SkCanvas* canvas) override {
62 if (!fInitialized) {
63 this->init();
64 fInitialized = true;
65 }
66
67 canvas->clear(0xFFDDDDDD);
68
69 SkPaint paint;
70 make_paint(&paint, fTypeface);
71
Jim Van Verthc3269ae2017-09-28 15:04:00 -040072 // draw a consistent run of the 'words' - one word per line
73 int index = fIndex;
Robert Phillips4c72b262017-08-15 13:28:42 -040074 for (SkScalar y = 0.0f; y < 1024.0f; ) {
Robert Phillips4c72b262017-08-15 13:28:42 -040075
76 y += -fMetrics.fAscent;
77 canvas->drawTextBlob(fBlobs[index], 0, y, paint);
78
79 y += fMetrics.fDescent + fMetrics.fLeading;
Jim Van Verthc3269ae2017-09-28 15:04:00 -040080 ++index;
81 index %= fBlobs.count();
Robert Phillips4c72b262017-08-15 13:28:42 -040082 }
Jim Van Verthc3269ae2017-09-28 15:04:00 -040083 // now "fling" a random amount
84 fIndex += fRand.nextRangeU(5, 20);
85 fIndex %= fBlobs.count();
Robert Phillips4c72b262017-08-15 13:28:42 -040086 }
87
88private:
Jim Van Verthc3269ae2017-09-28 15:04:00 -040089 static constexpr auto kNumBlobs = 200;
90 static constexpr auto kWordLength = 16;
91
Robert Phillips4c72b262017-08-15 13:28:42 -040092 void init() {
93 fTypeface = chinese_typeface();
94
95 SkPaint paint;
96 make_paint(&paint, fTypeface);
97
98 paint.getFontMetrics(&fMetrics);
99
Jim Van Verthc3269ae2017-09-28 15:04:00 -0400100 SkUnichar glyphs[kWordLength];
101 for (int32_t i = 0; i < kNumBlobs; ++i) {
102 this->createRandomWord(glyphs);
Robert Phillips4c72b262017-08-15 13:28:42 -0400103
104 SkTextBlobBuilder builder;
Jim Van Verthc3269ae2017-09-28 15:04:00 -0400105 sk_tool_utils::add_to_text_blob_w_len(&builder, (const char*) glyphs, kWordLength*4,
106 paint, 0, 0);
Robert Phillips4c72b262017-08-15 13:28:42 -0400107
108 fBlobs.emplace_back(builder.make());
109 }
Jim Van Verthc3269ae2017-09-28 15:04:00 -0400110
111 fIndex = 0;
112 }
113
114 // Construct a random kWordLength character 'word' drawing from the full Chinese set
115 void createRandomWord(SkUnichar glyphs[kWordLength]) {
116 for (int i = 0; i < kWordLength; ++i) {
117 glyphs[i] = fRand.nextRangeU(0x4F00, 0x9FA0);
118 }
Robert Phillips4c72b262017-08-15 13:28:42 -0400119 }
120
121 bool fInitialized = false;
122 sk_sp<SkTypeface> fTypeface;
123 SkPaint::FontMetrics fMetrics;
124 SkTArray<sk_sp<SkTextBlob>> fBlobs;
125 SkRandom fRand;
Jim Van Verthc3269ae2017-09-28 15:04:00 -0400126 int fIndex;
Robert Phillips4c72b262017-08-15 13:28:42 -0400127
128 typedef SkView INHERITED;
129};
130
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500131class ChineseZoomView : public SampleView {
132public:
133 ChineseZoomView() : fBlobs(kNumBlobs), fScale(1.0f) {}
134
135protected:
136 bool onQuery(SkEvent* evt) override {
137 if (SampleCode::TitleQ(*evt)) {
138 SampleCode::TitleR(evt, "chinese-zoom");
139 return true;
140 }
141 SkUnichar uni;
142 if (SampleCode::CharQ(*evt, &uni)) {
143 if ('>' == uni) {
144 fScale += 0.125f;
145 return true;
146 }
147 if ('<' == uni) {
148 fScale -= 0.125f;
149 return true;
150 }
151 }
152 return this->INHERITED::onQuery(evt);
153 }
154
155 void onDrawContent(SkCanvas* canvas) override {
156 if (!fInitialized) {
157 this->init();
158 fInitialized = true;
159 }
160
161 canvas->clear(0xFFDDDDDD);
162
163 SkPaint paint;
164 paint.setAntiAlias(true);
165 paint.setColor(0xDE000000);
166 paint.setTypeface(fTypeface);
167 paint.setTextSize(11);
168 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
169
170#if SK_SUPPORT_GPU
171 GrContext* grContext = canvas->getGrContext();
172 if (grContext) {
173 sk_sp<SkImage> image =
174 grContext->getFontAtlasImage_ForTesting(GrMaskFormat::kA8_GrMaskFormat, 0);
175 canvas->drawImageRect(image,
176 SkRect::MakeXYWH(512.0f, 10.0f, 512.0f, 512.0), &paint);
177 image = grContext->getFontAtlasImage_ForTesting(GrMaskFormat::kA8_GrMaskFormat, 1);
178 canvas->drawImageRect(image,
179 SkRect::MakeXYWH(1024.0f, 10.0f, 512.f, 512.0f), &paint);
180 image = grContext->getFontAtlasImage_ForTesting(GrMaskFormat::kA8_GrMaskFormat, 2);
181 canvas->drawImageRect(image,
182 SkRect::MakeXYWH(512.0f, 522.0f, 512.0f, 512.0f), &paint);
183 image = grContext->getFontAtlasImage_ForTesting(GrMaskFormat::kA8_GrMaskFormat, 3);
184 canvas->drawImageRect(image,
185 SkRect::MakeXYWH(1024.0f, 522.0f, 512.0f, 512.0f), &paint);
186 }
187#endif
188
189 canvas->scale(fScale, fScale);
190
191 // draw a consistent run of the 'words' - one word per line
192 SkScalar y = 0;
193 for (int index = 0; index < kNumBlobs; ++index) {
194 y += -fMetrics.fAscent;
195 canvas->drawTextBlob(fBlobs[index], 0, y, paint);
196
197 y += 3*(fMetrics.fDescent - fMetrics.fAscent + fMetrics.fLeading);
198 }
199 }
200
201private:
202 static constexpr auto kNumBlobs = 8;
203 static constexpr auto kParagraphLength = 175;
204
205 void init() {
206 fTypeface = chinese_typeface();
207
208 SkPaint paint;
209 paint.setAntiAlias(true);
210 paint.setColor(0xDE000000);
211 paint.setTypeface(fTypeface);
212 paint.setTextSize(11);
213 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
214
215 paint.getFontMetrics(&fMetrics);
216
217 SkUnichar glyphs[45];
218 for (int32_t i = 0; i < kNumBlobs; ++i) {
219 SkTextBlobBuilder builder;
220 auto paragraphLength = kParagraphLength;
221 SkScalar y = 0;
222 while (paragraphLength - 45 > 0) {
223 auto currentLineLength = SkTMin(45, paragraphLength - 45);
224 this->createRandomLine(glyphs, currentLineLength);
225
226 sk_tool_utils::add_to_text_blob_w_len(&builder, (const char*) glyphs,
227 currentLineLength*4, paint, 0, y);
228 y += fMetrics.fDescent - fMetrics.fAscent + fMetrics.fLeading;
229 paragraphLength -= 45;
230 }
231 fBlobs.emplace_back(builder.make());
232 }
233
234 fIndex = 0;
235 }
236
237 // Construct a random kWordLength character 'word' drawing from the full Chinese set
238 void createRandomLine(SkUnichar glyphs[45], int lineLength) {
239 for (auto i = 0; i < lineLength; ++i) {
240 glyphs[i] = fRand.nextRangeU(0x4F00, 0x9FA0);
241 }
242 }
243
244 bool fInitialized = false;
245 sk_sp<SkTypeface> fTypeface;
246 SkPaint::FontMetrics fMetrics;
247 SkTArray<sk_sp<SkTextBlob>> fBlobs;
248 SkRandom fRand;
249 SkScalar fScale;
250 int fIndex;
251
252 typedef SkView INHERITED;
253};
254
Robert Phillips4c72b262017-08-15 13:28:42 -0400255//////////////////////////////////////////////////////////////////////////////
256
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500257static SkView* FlingFactory() { return new ChineseFlingView; }
258static SkViewRegister regFling(FlingFactory);
259
260static SkView* ZoomFactory() { return new ChineseZoomView; }
261static SkViewRegister regZoom(ZoomFactory);