blob: 2a259984722fca042936cd175510bdf16f385202 [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"
Ben Wagnerb2c4ea62018-08-08 11:36:17 -04009#include "Sample.h"
Robert Phillips4c72b262017-08-15 13:28:42 -040010#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"
Robert Phillips0c4b7b12018-03-06 08:20:37 -050020#include "GrContextPriv.h"
Jim Van Verth87d18ce2018-01-22 12:45:47 -050021#endif
22
Robert Phillips4c72b262017-08-15 13:28:42 -040023static void make_paint(SkPaint* paint, sk_sp<SkTypeface> typeface) {
24 static const int kTextSize = 56;
25
26 paint->setAntiAlias(true);
27 paint->setColor(0xDE000000);
28 paint->setTypeface(typeface);
29 paint->setTextSize(kTextSize);
30 paint->setTextEncoding(SkPaint::kUTF32_TextEncoding);
31}
32
Robert Phillips4c72b262017-08-15 13:28:42 -040033static sk_sp<SkTypeface> chinese_typeface() {
34#ifdef SK_BUILD_FOR_ANDROID
Hal Canary53e5e7d2017-12-08 14:25:14 -050035 return MakeResourceAsTypeface("fonts/NotoSansCJK-Regular.ttc");
Mike Klein8f11d4d2018-01-24 12:42:55 -050036#elif defined(SK_BUILD_FOR_WIN)
Robert Phillips4c72b262017-08-15 13:28:42 -040037 return SkTypeface::MakeFromName("SimSun", SkFontStyle());
38#elif defined(SK_BUILD_FOR_MAC)
39 return SkTypeface::MakeFromName("Hiragino Sans GB W3", SkFontStyle());
40#elif defined(SK_BUILD_FOR_IOS)
41 return SkTypeface::MakeFromName("Hiragino Sans GB W3", SkFontStyle());
42#elif defined(SK_BUILD_FOR_UNIX)
43 return SkTypeface::MakeFromName("Noto Sans CJK SC", SkFontStyle());
44#else
45 return nullptr;
46#endif
47}
48
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040049class ChineseFlingView : public Sample {
Robert Phillips4c72b262017-08-15 13:28:42 -040050public:
Jim Van Verthc3269ae2017-09-28 15:04:00 -040051 ChineseFlingView() : fBlobs(kNumBlobs) {}
Robert Phillips4c72b262017-08-15 13:28:42 -040052
53protected:
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040054 bool onQuery(Sample::Event* evt) override {
55 if (Sample::TitleQ(*evt)) {
56 Sample::TitleR(evt, "chinese-fling");
Robert Phillips4c72b262017-08-15 13:28:42 -040057 return true;
58 }
59 return this->INHERITED::onQuery(evt);
60 }
61
62 void onDrawContent(SkCanvas* canvas) override {
63 if (!fInitialized) {
64 this->init();
65 fInitialized = true;
66 }
67
68 canvas->clear(0xFFDDDDDD);
69
70 SkPaint paint;
71 make_paint(&paint, fTypeface);
72
Jim Van Verthc3269ae2017-09-28 15:04:00 -040073 // draw a consistent run of the 'words' - one word per line
74 int index = fIndex;
Robert Phillips4c72b262017-08-15 13:28:42 -040075 for (SkScalar y = 0.0f; y < 1024.0f; ) {
Robert Phillips4c72b262017-08-15 13:28:42 -040076
77 y += -fMetrics.fAscent;
78 canvas->drawTextBlob(fBlobs[index], 0, y, paint);
79
80 y += fMetrics.fDescent + fMetrics.fLeading;
Jim Van Verthc3269ae2017-09-28 15:04:00 -040081 ++index;
82 index %= fBlobs.count();
Robert Phillips4c72b262017-08-15 13:28:42 -040083 }
Jim Van Verthc3269ae2017-09-28 15:04:00 -040084 // now "fling" a random amount
85 fIndex += fRand.nextRangeU(5, 20);
86 fIndex %= fBlobs.count();
Robert Phillips4c72b262017-08-15 13:28:42 -040087 }
88
89private:
Jim Van Verthc3269ae2017-09-28 15:04:00 -040090 static constexpr auto kNumBlobs = 200;
91 static constexpr auto kWordLength = 16;
92
Robert Phillips4c72b262017-08-15 13:28:42 -040093 void init() {
94 fTypeface = chinese_typeface();
95
96 SkPaint paint;
97 make_paint(&paint, fTypeface);
98
99 paint.getFontMetrics(&fMetrics);
100
Jim Van Verthc3269ae2017-09-28 15:04:00 -0400101 SkUnichar glyphs[kWordLength];
102 for (int32_t i = 0; i < kNumBlobs; ++i) {
103 this->createRandomWord(glyphs);
Robert Phillips4c72b262017-08-15 13:28:42 -0400104
105 SkTextBlobBuilder builder;
Jim Van Verthc3269ae2017-09-28 15:04:00 -0400106 sk_tool_utils::add_to_text_blob_w_len(&builder, (const char*) glyphs, kWordLength*4,
107 paint, 0, 0);
Robert Phillips4c72b262017-08-15 13:28:42 -0400108
109 fBlobs.emplace_back(builder.make());
110 }
Jim Van Verthc3269ae2017-09-28 15:04:00 -0400111
112 fIndex = 0;
113 }
114
115 // Construct a random kWordLength character 'word' drawing from the full Chinese set
116 void createRandomWord(SkUnichar glyphs[kWordLength]) {
117 for (int i = 0; i < kWordLength; ++i) {
118 glyphs[i] = fRand.nextRangeU(0x4F00, 0x9FA0);
119 }
Robert Phillips4c72b262017-08-15 13:28:42 -0400120 }
121
122 bool fInitialized = false;
123 sk_sp<SkTypeface> fTypeface;
124 SkPaint::FontMetrics fMetrics;
125 SkTArray<sk_sp<SkTextBlob>> fBlobs;
126 SkRandom fRand;
Jim Van Verthc3269ae2017-09-28 15:04:00 -0400127 int fIndex;
Robert Phillips4c72b262017-08-15 13:28:42 -0400128
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400129 typedef Sample INHERITED;
Robert Phillips4c72b262017-08-15 13:28:42 -0400130};
131
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400132class ChineseZoomView : public Sample {
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500133public:
Jim Van Verthcad0acf2018-02-16 18:41:41 -0500134 ChineseZoomView() : fBlobs(kNumBlobs), fScale(15.0f), fTranslate(0.0f) {}
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500135
136protected:
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400137 bool onQuery(Sample::Event* evt) override {
138 if (Sample::TitleQ(*evt)) {
139 Sample::TitleR(evt, "chinese-zoom");
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500140 return true;
141 }
142 SkUnichar uni;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400143 if (Sample::CharQ(*evt, &uni)) {
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500144 if ('>' == uni) {
145 fScale += 0.125f;
146 return true;
147 }
148 if ('<' == uni) {
149 fScale -= 0.125f;
150 return true;
151 }
152 }
153 return this->INHERITED::onQuery(evt);
154 }
155
156 void onDrawContent(SkCanvas* canvas) override {
Jim Van Verthcad0acf2018-02-16 18:41:41 -0500157 bool afterFirstFrame = fInitialized;
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500158 if (!fInitialized) {
159 this->init();
160 fInitialized = true;
161 }
162
163 canvas->clear(0xFFDDDDDD);
164
165 SkPaint paint;
166 paint.setAntiAlias(true);
167 paint.setColor(0xDE000000);
168 paint.setTypeface(fTypeface);
169 paint.setTextSize(11);
170 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
171
Jim Van Verthcad0acf2018-02-16 18:41:41 -0500172 if (afterFirstFrame) {
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500173#if SK_SUPPORT_GPU
Jim Van Verthcad0acf2018-02-16 18:41:41 -0500174 GrContext* grContext = canvas->getGrContext();
175 if (grContext) {
176 sk_sp<SkImage> image =
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500177 grContext->contextPriv().getFontAtlasImage_ForTesting(
178 GrMaskFormat::kA8_GrMaskFormat, 0);
Jim Van Verthcad0acf2018-02-16 18:41:41 -0500179 canvas->drawImageRect(image,
180 SkRect::MakeXYWH(10.0f, 10.0f, 512.0f, 512.0), &paint);
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500181 image = grContext->contextPriv().getFontAtlasImage_ForTesting(
182 GrMaskFormat::kA8_GrMaskFormat, 1);
Jim Van Verthcad0acf2018-02-16 18:41:41 -0500183 canvas->drawImageRect(image,
184 SkRect::MakeXYWH(522.0f, 10.0f, 512.f, 512.0f), &paint);
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500185 image = grContext->contextPriv().getFontAtlasImage_ForTesting(
186 GrMaskFormat::kA8_GrMaskFormat, 2);
Jim Van Verthcad0acf2018-02-16 18:41:41 -0500187 canvas->drawImageRect(image,
188 SkRect::MakeXYWH(10.0f, 522.0f, 512.0f, 512.0f), &paint);
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500189 image = grContext->contextPriv().getFontAtlasImage_ForTesting(
190 GrMaskFormat::kA8_GrMaskFormat, 3);
Jim Van Verthcad0acf2018-02-16 18:41:41 -0500191 canvas->drawImageRect(image,
192 SkRect::MakeXYWH(522.0f, 522.0f, 512.0f, 512.0f), &paint);
193 }
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500194#endif
Jim Van Verthcad0acf2018-02-16 18:41:41 -0500195 }
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500196
197 canvas->scale(fScale, fScale);
Jim Van Verthcad0acf2018-02-16 18:41:41 -0500198 canvas->translate(0, fTranslate);
199 fTranslate -= 0.5f;
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500200
201 // draw a consistent run of the 'words' - one word per line
202 SkScalar y = 0;
203 for (int index = 0; index < kNumBlobs; ++index) {
204 y += -fMetrics.fAscent;
205 canvas->drawTextBlob(fBlobs[index], 0, y, paint);
206
207 y += 3*(fMetrics.fDescent - fMetrics.fAscent + fMetrics.fLeading);
208 }
209 }
210
211private:
212 static constexpr auto kNumBlobs = 8;
213 static constexpr auto kParagraphLength = 175;
214
215 void init() {
216 fTypeface = chinese_typeface();
217
218 SkPaint paint;
219 paint.setAntiAlias(true);
220 paint.setColor(0xDE000000);
221 paint.setTypeface(fTypeface);
222 paint.setTextSize(11);
223 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
224
225 paint.getFontMetrics(&fMetrics);
226
227 SkUnichar glyphs[45];
228 for (int32_t i = 0; i < kNumBlobs; ++i) {
229 SkTextBlobBuilder builder;
230 auto paragraphLength = kParagraphLength;
231 SkScalar y = 0;
232 while (paragraphLength - 45 > 0) {
233 auto currentLineLength = SkTMin(45, paragraphLength - 45);
234 this->createRandomLine(glyphs, currentLineLength);
235
236 sk_tool_utils::add_to_text_blob_w_len(&builder, (const char*) glyphs,
237 currentLineLength*4, paint, 0, y);
238 y += fMetrics.fDescent - fMetrics.fAscent + fMetrics.fLeading;
239 paragraphLength -= 45;
240 }
241 fBlobs.emplace_back(builder.make());
242 }
243
244 fIndex = 0;
245 }
246
247 // Construct a random kWordLength character 'word' drawing from the full Chinese set
248 void createRandomLine(SkUnichar glyphs[45], int lineLength) {
249 for (auto i = 0; i < lineLength; ++i) {
250 glyphs[i] = fRand.nextRangeU(0x4F00, 0x9FA0);
251 }
252 }
253
254 bool fInitialized = false;
255 sk_sp<SkTypeface> fTypeface;
256 SkPaint::FontMetrics fMetrics;
257 SkTArray<sk_sp<SkTextBlob>> fBlobs;
258 SkRandom fRand;
259 SkScalar fScale;
Jim Van Verthcad0acf2018-02-16 18:41:41 -0500260 SkScalar fTranslate;
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500261 int fIndex;
262
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400263 typedef Sample INHERITED;
Jim Van Verth87d18ce2018-01-22 12:45:47 -0500264};
265
Robert Phillips4c72b262017-08-15 13:28:42 -0400266//////////////////////////////////////////////////////////////////////////////
267
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400268DEF_SAMPLE( return new ChineseFlingView(); )
269DEF_SAMPLE( return new ChineseZoomView(); )