blob: 6657d5e71dfab41693e7037131be758c14f0f3cb [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001#include "SampleCode.h"
2#include "SkView.h"
3#include "SkCanvas.h"
4#include "SkGradientShader.h"
5#include "SkGraphics.h"
6#include "SkImageDecoder.h"
7#include "SkPackBits.h"
8#include "SkPath.h"
9#include "SkPathMeasure.h"
10#include "SkRandom.h"
11#include "SkRegion.h"
12#include "SkShader.h"
13#include "SkUtils.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000014#include "SkColorPriv.h"
15#include "SkColorFilter.h"
16#include "SkTypeface.h"
17#include "SkAvoidXfermode.h"
18
reed@android.comf2b98d62010-12-20 18:26:13 +000019#define REPEAT_COUNT 0
reed@android.com8a1c16f2008-12-17 15:59:43 +000020
21static const char gText[] = "Hamburgefons";
22
23static bool gDevKern;
24
25static void rand_text(char text[], SkRandom& rand, size_t count) {
26 for (size_t i = 0; i < count; i++) {
27 text[i] = rand.nextU() & 0x7F;
28 }
29}
30
31static SkScalar sum_widths(const SkScalar widths[], int count) {
32 SkScalar w = 0;
33 for (int i = 0; i < count; i++) {
34 w += widths[i];
35 }
36 return w;
37}
38
39static void test_measure(const SkPaint& paint) {
40 char text[256];
41 SkScalar widths[256];
42 SkRect rects[256];
43 SkRect bounds;
44 int count = 256;
45
46 SkRandom rand;
47
48 for (int i = 0; i < 100; i++) {
49 rand_text(text, rand, 256);
50 paint.getTextWidths(text, count, widths, NULL);
reed@android.comf2b98d62010-12-20 18:26:13 +000051 SkDEBUGCODE(SkScalar tw0 = sum_widths(widths, count);)
reed@android.com8a1c16f2008-12-17 15:59:43 +000052 paint.getTextWidths(text, count, widths, rects);
reed@android.comf2b98d62010-12-20 18:26:13 +000053 SkDEBUGCODE(SkScalar tw1 = sum_widths(widths, count);)
reed@android.com8a1c16f2008-12-17 15:59:43 +000054 SkASSERT(tw0 == tw1);
55
reed@android.comf2b98d62010-12-20 18:26:13 +000056 SkDEBUGCODE(SkScalar w0 = paint.measureText(text, count, NULL);)
57 SkDEBUGCODE(SkScalar w1 = paint.measureText(text, count, &bounds);)
reed@android.com8a1c16f2008-12-17 15:59:43 +000058 SkASSERT(w0 == w1);
59 SkASSERT(w0 == tw0);
60
61 SkRect r = rects[0];
62 SkScalar x = 0;
63 for (int j = 1; j < count; j++) {
64 x += widths[j-1];
65 rects[j].offset(x, 0);
66 r.join(rects[j]);
67 }
68 SkASSERT(r == bounds);
69
70 if (r != bounds) {
71 printf("flags=%x i=%d [%g %g %g %g] [%g %g %g %g]\n",
72 paint.getFlags(), i,
73 SkScalarToFloat(r.fLeft),
74 SkScalarToFloat(r.fTop),
75 SkScalarToFloat(r.fRight),
76 SkScalarToFloat(r.fBottom),
77 SkScalarToFloat(bounds.fLeft),
78 SkScalarToFloat(bounds.fTop),
79 SkScalarToFloat(bounds.fRight),
80 SkScalarToFloat(bounds.fBottom));
81 }
82 }
83}
84
85static void test_measure() {
86 SkPaint paint;
87
88 for (int i = 0; i <= SkPaint::kAllFlags; i++) {
89 paint.setFlags(i);
90 test_measure(paint);
91 }
92}
93
94//////////////////////////////////////////////////////////////////////////////
95
96static void test_textBounds(SkCanvas* canvas) {
97// canvas->scale(SK_Scalar1/2, SK_Scalar1/2);
98
99// canvas->rotate(SkIntToScalar(30));
100
101 gDevKern = !gDevKern;
102
103 SkScalar x = SkIntToScalar(50);
104 SkScalar y = SkIntToScalar(150);
105 SkScalar w[100];
106 SkRect r[100], bounds;
107
108 SkPaint paint;
109 paint.setTextSize(SkIntToScalar(64));
110 paint.setAntiAlias(true);
111 paint.setDevKernText(gDevKern);
112
113 (void)paint.measureText(gText, strlen(gText), &bounds, NULL);
114 paint.setColor(SK_ColorGREEN);
115 bounds.offset(x, y);
116 canvas->drawRect(bounds, paint);
117
118 int count = paint.getTextWidths(gText, strlen(gText), w, r);
119
120 paint.setColor(SK_ColorRED);
121 for (int i = 0; i < count; i++) {
122 r[i].offset(x, y);
123 canvas->drawRect(r[i], paint);
124 x += w[i];
125 }
126 x = SkIntToScalar(50);
127 paint.setColor(gDevKern ? SK_ColorDKGRAY : SK_ColorBLACK);
128 canvas->drawText(gText, strlen(gText), x, y, paint);
129}
130
131static void create_src(SkBitmap* bitmap, SkBitmap::Config config) {
132 bitmap->setConfig(config, 100, 100);
133 bitmap->allocPixels();
134 bitmap->eraseColor(0);
135
136 SkCanvas canvas(*bitmap);
137 SkPaint paint;
138
139 paint.setAntiAlias(true);
140 canvas.drawCircle(SkIntToScalar(50), SkIntToScalar(50),
141 SkIntToScalar(50), paint);
142}
143
144static void blur(SkBitmap* dst, const SkBitmap& src, SkScalar radius) {
145 *dst = src;
146}
147
148static void test_bitmap_blur(SkCanvas* canvas) {
149 SkBitmap src, dst;
150
151 create_src(&src, SkBitmap::kARGB_8888_Config);
152 blur(&dst, src, SkIntToScalar(4));
153
154 SkPaint paint;
155
156 paint.setColor(SK_ColorRED);
157
158 canvas->drawBitmap(dst, SkIntToScalar(30), SkIntToScalar(60), &paint);
159}
160
161static SkScalar getpathlen(const SkPath& path) {
162 SkPathMeasure meas(path, false);
163 return meas.getLength();
164}
165
166static void test_textpathmatrix(SkCanvas* canvas) {
167 SkPaint paint;
168 SkPath path;
169 SkMatrix matrix;
170
171 path.moveTo(SkIntToScalar(200), SkIntToScalar(300));
172 path.quadTo(SkIntToScalar(400), SkIntToScalar(100),
173 SkIntToScalar(600), SkIntToScalar(300));
174
175 paint.setAntiAlias(true);
176
177 paint.setStyle(SkPaint::kStroke_Style);
reed@android.comf2b98d62010-12-20 18:26:13 +0000178 // canvas->drawPath(path, paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000179 paint.setStyle(SkPaint::kFill_Style);
180 paint.setTextSize(SkIntToScalar(48));
181 paint.setTextAlign(SkPaint::kRight_Align);
182
reed@android.comf2b98d62010-12-20 18:26:13 +0000183 const char* text = "Reflection";
reed@android.com8a1c16f2008-12-17 15:59:43 +0000184 size_t len = strlen(text);
185 SkScalar pathLen = getpathlen(path);
186
187 canvas->drawTextOnPath(text, len, path, NULL, paint);
188
189 paint.setColor(SK_ColorRED);
190 matrix.setScale(-SK_Scalar1, SK_Scalar1);
191 matrix.postTranslate(pathLen, 0);
192 canvas->drawTextOnPath(text, len, path, &matrix, paint);
193
194 paint.setColor(SK_ColorBLUE);
195 matrix.setScale(SK_Scalar1, -SK_Scalar1);
196 canvas->drawTextOnPath(text, len, path, &matrix, paint);
197
198 paint.setColor(SK_ColorGREEN);
199 matrix.setScale(-SK_Scalar1, -SK_Scalar1);
200 matrix.postTranslate(pathLen, 0);
201 canvas->drawTextOnPath(text, len, path, &matrix, paint);
202}
203
204class TextOnPathView : public SkView {
205public:
206 SkPath fPath;
207 SkScalar fHOffset;
208
209 TextOnPathView() {
210 SkRect r;
211 r.set(SkIntToScalar(100), SkIntToScalar(100),
212 SkIntToScalar(300), SkIntToScalar(300));
213 fPath.addOval(r);
reed@android.comf2b98d62010-12-20 18:26:13 +0000214 fPath.offset(SkIntToScalar(200), 0);
215
reed@android.com8a1c16f2008-12-17 15:59:43 +0000216 fHOffset = SkIntToScalar(50);
217 }
218
219protected:
220 // overrides from SkEventSink
221 virtual bool onQuery(SkEvent* evt) {
222 if (SampleCode::TitleQ(*evt)) {
223 SampleCode::TitleR(evt, "Text On Path");
224 return true;
225 }
226 return this->INHERITED::onQuery(evt);
227 }
228
229 void drawBG(SkCanvas* canvas) {
230 canvas->drawColor(SK_ColorWHITE);
231#if 0
232 SkRect r;
233 SkPaint p;
234 SkRandom rand;
235 p.setAntiAlias(true);
236
237 for (int i = 0; i < 100; i++) {
238 SkScalar x = rand.nextUScalar1() * 300 + SkIntToScalar(50);
239 SkScalar y = rand.nextUScalar1() * 200 + SkIntToScalar(50);
240 SkScalar w = rand.nextUScalar1() * 10;
241 SkScalar h = rand.nextUScalar1() * 10;
242 r.set(x, y, x + w, y + h);
243 canvas->drawRect(r, p);
244 }
245
246 test_textBounds(canvas);
247// return;
248
249 SkBitmap bm;
250 if (SkImageDecoder::DecodeFile("/loading_tile.png",
251 &bm, SkBitmap::kRGB_565_Config, true))
252 canvas->drawBitmap(bm, 0, 0);
253#endif
254 }
255
256 virtual void onDraw(SkCanvas* canvas) {
257 this->drawBG(canvas);
258
259 SkPaint paint;
260
261 paint.setAntiAlias(true);
262 paint.setTextSize(SkIntToScalar(50));
263
264 for (int j = 0; j < REPEAT_COUNT; j++) {
265 SkScalar x = fHOffset;
266
267 paint.setColor(SK_ColorBLACK);
268 canvas->drawTextOnPathHV(gText, sizeof(gText)-1, fPath,
269 x, paint.getTextSize()/2, paint);
270
271 paint.setColor(SK_ColorRED);
272 canvas->drawTextOnPathHV(gText, sizeof(gText)-1, fPath,
273 x + SkIntToScalar(50), 0, paint);
274
275 paint.setColor(SK_ColorBLUE);
276 canvas->drawTextOnPathHV(gText, sizeof(gText)-1, fPath,
277 x + SkIntToScalar(100), -paint.getTextSize()/2, paint);
278 }
279
280 paint.setColor(SK_ColorGREEN);
281 paint.setStyle(SkPaint::kStroke_Style);
reed@android.comf2b98d62010-12-20 18:26:13 +0000282// canvas->drawPath(fPath, paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000283
reed@android.comf2b98d62010-12-20 18:26:13 +0000284 canvas->translate(0, SkIntToScalar(100));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000285 test_textpathmatrix(canvas);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000286
287 if (REPEAT_COUNT > 1)
288 this->inval(NULL);
289 }
290
291 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
292 fHints += 1;
293 this->inval(NULL);
294 return this->INHERITED::onFindClickHandler(x, y);
295 }
296
297 virtual bool onClick(Click* click) {
298 return this->INHERITED::onClick(click);
299 }
300
301private:
302 int fHints;
303 typedef SkView INHERITED;
304};
305
reed@android.com8a1c16f2008-12-17 15:59:43 +0000306//////////////////////////////////////////////////////////////////////////////
307
308static SkView* MyFactory() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000309 return new TextOnPathView;
310}
311
312static SkViewRegister reg(MyFactory);
313