blob: 60e015aa5f20d6673fa8c742a06685138595eadc [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 "Sk64.h"
5#include "SkGradientShader.h"
6#include "SkGraphics.h"
7#include "SkImageDecoder.h"
8#include "SkKernel33MaskFilter.h"
9#include "SkPath.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 "SkTime.h"
17#include "SkTypeface.h"
18#include "SkXfermode.h"
19
20#include "SkStream.h"
21#include "SkXMLParser.h"
22
23static const int gKernel[3][3] = {
24// { -1, -2, -1 }, { -2, 12, -2 }, { -1, -2, -1 }
25 { 1, 2, 1 }, { 2, 64-12, 2 }, { 1, 2, 1 }
26};
27static const int gShift = 6;
28
29class ReduceNoise : public SkKernel33ProcMaskFilter {
30public:
31 ReduceNoise(int percent256) : SkKernel33ProcMaskFilter(percent256) {}
32 virtual uint8_t computeValue(uint8_t* const* srcRows)
33 {
34 int c = srcRows[1][1];
35 int min = 255, max = 0;
36 for (int i = 0; i < 3; i++)
37 for (int j = 0; j < 3; j++)
38 if (i != 1 || j != 1)
39 {
40 int v = srcRows[i][j];
41 if (max < v)
42 max = v;
43 if (min > v)
44 min = v;
45 }
46 if (c > max) c = max;
47 // if (c < min) c = min;
48 return c;
49 }
50 virtual Factory getFactory() { return Create; }
51private:
52 ReduceNoise(SkFlattenableReadBuffer& rb) : SkKernel33ProcMaskFilter(rb) {}
53 static SkFlattenable* Create(SkFlattenableReadBuffer& rb)
54 {
55 return new ReduceNoise(rb);
56 }
57};
58
59class Darken : public SkKernel33ProcMaskFilter {
60public:
61 Darken(int percent256) : SkKernel33ProcMaskFilter(percent256) {}
62 virtual uint8_t computeValue(uint8_t* const* srcRows)
63 {
64 int c = srcRows[1][1];
65 float f = c / 255.f;
66
67 if (c >= 0)
68 {
69 f = sqrtf(f);
70 }
71 else
72 {
73 f *= f;
74 }
75 SkASSERT(f >= 0 && f <= 1);
76 return (int)(f * 255);
77 }
78 virtual Factory getFactory() { return Create; }
79private:
80 Darken(SkFlattenableReadBuffer& rb) : SkKernel33ProcMaskFilter(rb) {}
81 static SkFlattenable* Create(SkFlattenableReadBuffer& rb)
82 {
83 return new Darken(rb);
84 }
85};
86
87static SkMaskFilter* makemf() { return new Darken(0x30); }
88
89//#ifdef TEST_CLICKX
90
91static void test_typefaceCache()
92{
93 SkTypeface* t0 = SkTypeface::Create("sans-serif", SkTypeface::kNormal);
94 SkTypeface* t1 = SkTypeface::Create(NULL, SkTypeface::kNormal);
95 SkTypeface* t2 = SkTypeface::Create("arial", SkTypeface::kNormal);
96 SkTypeface* t3 = SkTypeface::Create("helvetica", SkTypeface::kItalic);
97
reed@android.comda342a82008-12-23 18:37:08 +000098#ifndef SK_BUILD_FOR_MAC
reed@android.com8a1c16f2008-12-17 15:59:43 +000099 SkASSERT(t0 == t1);
100 SkASSERT(t0 == t2);
101 SkASSERT(t0 == t3);
reed@android.comda342a82008-12-23 18:37:08 +0000102#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000103}
104
105static void test_breakText()
106{
107 SkPaint paint;
108 const char* text = "sdfkljAKLDFJKEWkldfjlk#$%&sdfs.dsj";
109 size_t length = strlen(text);
110 SkScalar width = paint.measureText(text, length);
111
112 SkScalar mm = 0;
113 SkScalar nn = 0;
114 for (SkScalar w = 0; w <= width; w += SK_Scalar1)
115 {
116 SkScalar m;
117 size_t n = paint.breakText(text, length, w, &m,
118 SkPaint::kBackward_TextBufferDirection);
119
120 SkASSERT(n <= length);
121 SkASSERT(m <= width);
122
123 if (n == 0)
124 SkASSERT(m == 0);
125 else
126 {
127 // now assert that we're monotonic
128 if (n == nn)
129 SkASSERT(m == mm);
130 else
131 {
132 SkASSERT(n > nn);
133 SkASSERT(m > mm);
134 }
135 }
136 nn = n;
137 mm = m;
138 }
139
140 nn = paint.breakText(text, length, width, &mm);
141 SkASSERT(nn == length);
142 SkASSERT(mm == width);
143}
144
145static SkRandom gRand;
146
147class SkPowerMode : public SkXfermode {
148public:
149 SkPowerMode(SkScalar exponent) { this->init(exponent); }
150
151 virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count, const SkAlpha aa[]);
152
153 typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
154
155 // overrides for SkFlattenable
156 virtual Factory getFactory() { return Create; }
157 virtual void flatten(SkFlattenableWriteBuffer& b)
158 {
159 // this->INHERITED::flatten(b); How can we know if this is legal????
160 b.write32(SkScalarToFixed(fExp));
161 }
162
163private:
164 SkScalar fExp; // user's value
165 uint8_t fTable[256]; // cache
166
167 void init(SkScalar exponent);
168 SkPowerMode(SkFlattenableReadBuffer& b) : SkXfermode(b)
169 {
170 // read the exponent
171 this->init(SkFixedToScalar(b.readS32()));
172 }
173 static SkFlattenable* Create(SkFlattenableReadBuffer& b)
174 {
175 return SkNEW_ARGS(SkPowerMode, (b));
176 }
177
178 typedef SkXfermode INHERITED;
179};
180
181void SkPowerMode::init(SkScalar e)
182{
183 fExp = e;
184 float ee = SkScalarToFloat(e);
185
186 printf("------ %g\n", ee);
187 for (int i = 0; i < 256; i++)
188 {
189 float x = i / 255.f;
190 // printf(" %d %g", i, x);
191 x = powf(x, ee);
192 // printf(" %g", x);
193 int xx = SkScalarRound(SkFloatToScalar(x * 255));
194 // printf(" %d\n", xx);
195 fTable[i] = SkToU8(xx);
196 }
197}
198
199void SkPowerMode::xfer16(uint16_t dst[], const SkPMColor src[], int count, const SkAlpha aa[])
200{
201 for (int i = 0; i < count; i++)
202 {
203 SkPMColor c = src[i];
204 int r = SkGetPackedR32(c);
205 int g = SkGetPackedG32(c);
206 int b = SkGetPackedB32(c);
207 r = fTable[r];
208 g = fTable[g];
209 b = fTable[b];
210 dst[i] = SkPack888ToRGB16(r, g, b);
211 }
212}
213
214static const struct {
215 const char* fName;
216 uint32_t fFlags;
217 bool fFlushCache;
218} gHints[] = {
219 { "Linear", SkPaint::kLinearText_Flag, false },
220 { "Normal", 0, true },
221 { "Subpixel", SkPaint::kSubpixelText_Flag, true }
222};
223
224#ifdef SK_DEBUG
225 #define REPEAT_COUNT 1
226#else
227 #define REPEAT_COUNT 5000
228#endif
229
230static int count_char_points(const SkPaint& paint, char c)
231{
232 SkPath path;
233
234 paint.getTextPath(&c, 1, 0, 0, &path);
235 return path.getPoints(NULL, 0);
236}
237
238static int gOld, gNew, gCount;
239
240static void dump(int c, int oldc, int newc)
241{
242 if (oldc != newc)
243 {
244 gOld += oldc;
245 gNew += newc;
246 gCount += 1;
247 printf("char %c: old = %3d, new = %3d, reduction %g%%\n", c, oldc, newc, 100. * (oldc - newc) / oldc);
248 }
249}
250
251static void tab(int n)
252{
253// printf("[%d] ", n); return;
254 SkASSERT(n >= 0);
255 for (int i = 0; i < n; i++)
256 printf(" ");
257}
258
259#if 0
260#include "badrects.cpp"
261
262static void make_badrgn(SkRegion* rgn, int insetAmount)
263{
264 SkRect16 r, bounds;
265 int i;
266
267 rgn->setEmpty();
268 bounds.setEmpty();
269
270 for (i = 0; i < SK_ARRAY_COUNT(badrects); i++)
271 {
272 SkASSERT(badrects[i].width > 0 && badrects[i].height > 0);
273
274 r.set(badrects[i].x, badrects[i].y, badrects[i].x + badrects[i].width, badrects[i].y + badrects[i].height);
275 r.inset(insetAmount, insetAmount);
276 rgn->op(r, SkRegion::kUnion_Op);
277 bounds.join(r);
278 }
279 SkASSERT(bounds == rgn->getBounds());
280
281 for (i = 0; i < SK_ARRAY_COUNT(badrects); i++)
282 {
283 r.set(badrects[i].x, badrects[i].y, badrects[i].x + badrects[i].width, badrects[i].y + badrects[i].height);
284 SkASSERT(rgn->contains(r));
285 }
286}
287#endif
288
289static void draw_rgn(const SkRegion& rgn, SkCanvas* canvas, const SkPaint& paint)
290{
291 SkRect r;
292 SkRegion::Iterator iter(rgn);
293
294 for (; !iter.done(); iter.next())
295 {
296 r.set(iter.rect());
297 canvas->drawRect(r, paint);
298 }
299}
300
301static void test_break(SkCanvas* canvas, const char text[], size_t length,
302 SkScalar x, SkScalar y, const SkPaint& paint,
303 SkScalar clickX)
304{
305 SkPaint linePaint;
306
307 linePaint.setAntiAlias(true);
308
309 SkScalar measured;
310
311 if (paint.breakText(text, length, clickX - x, &measured, SkPaint::kForward_TextBufferDirection))
312 {
313 linePaint.setColor(SK_ColorRED);
314 canvas->drawLine(x, y, x + measured, y, linePaint);
315 }
316
317 x += paint.measureText(text, length);
318 if (paint.breakText(text, length, x - clickX, &measured, SkPaint::kBackward_TextBufferDirection))
319 {
320 linePaint.setColor(SK_ColorBLUE);
321 canvas->drawLine(x - measured, y, x, y, linePaint);
322 }
323}
324
325static void test_poly()
326{
327 static const SkPoint dst[] = {
328 SkIntToScalar(2), SkIntToScalar(1),
329 SkIntToScalar(5), SkIntToScalar(1),
330 SkIntToScalar(5), SkIntToScalar(3),
331 SkIntToScalar(2), SkIntToScalar(3)
332 };
333
334 static const SkPoint src[] = {
335 SkIntToScalar(0), SkIntToScalar(0),
336 SkIntToScalar(1), SkIntToScalar(0),
337 SkIntToScalar(1), SkIntToScalar(1),
338 SkIntToScalar(0), SkIntToScalar(1)
339 };
340
341 SkMatrix matrix;
342
343 if (matrix.setPolyToPoly(src, dst, 4))
344 {
345 SkPoint pt = { SK_Scalar1/2, SK_Scalar1/2 };
346 matrix.mapPoints(&pt, 1);
347 printf("---- x = %g y = %g\n", SkScalarToFloat(pt.fX), SkScalarToFloat(pt.fY));
348 }
349 else
350 printf("---- setPolyToPoly failed\n");
351}
352
353#include "SkColorShader.h"
354
355static void DrawTheText(SkCanvas* canvas, const char text[], size_t length,
356 SkScalar x, SkScalar y, const SkPaint& paint,
357 SkScalar clickX, SkMaskFilter* mf)
358{
359 SkPaint p(paint);
360
361#if 0
362 canvas->drawText(text, length, x, y, paint);
363#else
364 {
365 SkPoint pts[1000];
366 SkScalar xpos = x;
367 SkASSERT(length <= SK_ARRAY_COUNT(pts));
368 for (size_t i = 0; i < length; i++)
369 pts[i].set(xpos, y), xpos += paint.getTextSize();
370 canvas->drawPosText(text, length, pts, paint);
371 }
372#endif
373
374 p.setSubpixelText(true);
375 x += SkIntToScalar(180);
376 canvas->drawText(text, length, x, y, p);
377
378#ifdef TEST_CLICKX
379 test_break(canvas, text, length, x, y, p, clickX);
380#endif
381
382#ifdef SK_DEBUG
383 if (false)
384 {
385 SkColorShader shader;
386 p.setShader(&shader);
387 x += SkIntToScalar(180);
388 canvas->drawText(text, length, x, y, p);
389 p.setShader(NULL);
390 }
391
392 if (true)
393 {
394 // p.setMaskFilter(mf);
395 p.setSubpixelText(false);
396 p.setLinearText(true);
397 x += SkIntToScalar(180);
398 canvas->drawText(text, length, x, y, p);
399 }
400#endif
401}
402
403class TextSpeedView : public SkView {
404public:
405 TextSpeedView()
406 {
407 fMF = makemf();
408
409 fHints = 0;
410
411 if (false)
412 {
413 static const char extra[] = { '.', ',', ':', ';', '!' };
414 SkPaint paint, paint2;
415
416 paint2.setTypeface(SkTypeface::Create(NULL, SkTypeface::kItalic))->unref();
417
418 for (int i = 0; i < 26; i++)
419 ::dump('a' + i, count_char_points(paint, 'a' + i), count_char_points(paint2, 'a' + i));
420 for (int j = 0; j < SK_ARRAY_COUNT(extra); j++)
421 ::dump(extra[j], count_char_points(paint, extra[j]), count_char_points(paint2, extra[j]));
422
423 printf("--- ave reduction = %g%%\n", 100. * (gOld - gNew) / gOld);
424 }
425
426 if (true)
427 {
428 SkPoint pts[] = { SkIntToScalar(20), 0, SkIntToScalar(256+20), 0 };
429 SkColor colors[] = { SkColorSetARGB(0, 255, 255, 255), SkColorSetARGB(255, 255, 255, 255) };
430 fGradient = SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode);
431 }
432
433 fClickX = 0;
434
435 test_breakText();
436 test_typefaceCache();
437 test_poly();
438 }
439
440 virtual ~TextSpeedView()
441 {
442 fGradient->unref();
443 fMF->safeUnref();
444 }
445
446protected:
447 // overrides from SkEventSink
448 virtual bool onQuery(SkEvent* evt)
449 {
450 if (SampleCode::TitleQ(*evt))
451 {
452 SampleCode::TitleR(evt, "Text");
453 return true;
454 }
455 return this->INHERITED::onQuery(evt);
456 }
457
458 void drawBG(SkCanvas* canvas)
459 {
460// canvas->drawColor(0xFFDDDDDD);
461 canvas->drawColor(SK_ColorWHITE);
462 // canvas->drawColor(SK_ColorBLACK);
463 }
464
465 static void make_textstrip(SkBitmap* bm)
466 {
467 bm->setConfig(SkBitmap::kRGB_565_Config, 200, 18);
468 bm->allocPixels();
469 bm->eraseColor(SK_ColorWHITE);
470
471 SkCanvas canvas(*bm);
472 SkPaint paint;
473 const char* s = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit";
474
475 paint.setFlags(paint.getFlags() | SkPaint::kAntiAlias_Flag
476 | SkPaint::kDevKernText_Flag);
477 paint.setTextSize(SkIntToScalar(14));
478 canvas.drawText(s, strlen(s), SkIntToScalar(8), SkIntToScalar(14), paint);
479 }
480
481 static void fill_pts(SkPoint pts[], size_t n, SkRandom* rand)
482 {
483 for (size_t i = 0; i < n; i++)
484 pts[i].set(rand->nextUScalar1() * 640, rand->nextUScalar1() * 480);
485 }
486
487 virtual void onDraw(SkCanvas* canvas)
488 {
489 if (false)
490 {
491 canvas->translate(SkIntToScalar(480), 0);
492 canvas->rotate(SkIntToScalar(90));
493 }
494
495 this->drawBG(canvas);
496
497 if (false)
498 {
499 SkPaint p;
500
501 p.setAntiAlias(true);
502 p.setSubpixelText(true);
503 // p.setLinearText(true);
504
505 SkScalar size = SkIntToScalar(6);
506 SkMSec dur = 0;
507 const int LOOP = 16;
508 const int TIMES = 10;
509
510 for (int times = 0; times < TIMES; times++)
511 {
512 SkMSec now = SkTime::GetMSecs();
513 for (int loop = 0; loop < LOOP; loop++)
514 {
515 p.setTextSize(size);
516 size += SK_Scalar1/5;
517 canvas->drawText("Hamburgefons", 12, SkIntToScalar(10), SkIntToScalar(50), p);
518 }
519 dur += SkTime::GetMSecs() - now;
520 SkGraphics::SetFontCacheUsed(0);
521 }
522
523 printf("----- duration = %g\n", dur * 1.0 / TIMES);
524 this->inval(NULL);
525 return;
526 }
527
528 if (false)
529 {
530 SkPaint p;
531 p.setAntiAlias(true);
532 for (int i = 6; i <= 36; i++)
533 {
534 SkRect r;
535 SkPaint::FontMetrics m;
536 p.setTextSize(SkIntToScalar(i));
537 p.getFontMetrics(&m);
538 int ascent = SkScalarRound(m.fAscent);
539 int descent = SkScalarRound(m.fDescent);
540 for (uint8_t c = ' '; c <= 127; c++)
541 {
542 p.getTextWidths(&c, 1, NULL, &r);
543 if (SkScalarRound(r.fTop) < ascent)
544 printf("PS %d --- %c [%d] top=%g, ascent=%g ymax=%g\n", i, c, c,
545 SkScalarToFloat(r.fTop), SkScalarToFloat(m.fAscent), SkScalarToFloat(m.fTop));
546 if (SkScalarRound(r.fBottom) > descent)
547 printf("PS %d --- %c [%d] bottom=%g, descent=%g ymin=%g\n", i, c, c,
548 SkScalarToFloat(r.fBottom), SkScalarToFloat(m.fDescent), SkScalarToFloat(m.fBottom));
549 }
550 }
551 }
552
553 if (false)
554 {
555 SkPaint p;
556 p.setShader(fGradient);
557
558#ifdef SK_RELEASE
559 SkMSec now = SkTime::GetMSecs();
560 for (int i = 0; i < 100; i++)
561#endif
562 canvas->drawPaint(p);
563#ifdef SK_RELEASE
564 printf("----- %d ms\n", SkTime::GetMSecs() - now);
565 this->inval(NULL);
566#endif
567 return;
568 }
569
570 if (false)
571 {
572 SkBitmap bm;
573
574 make_textstrip(&bm);
575 canvas->translate(0, SkIntToScalar(50));
576 for (int i = 0; i < 10; i++)
577 {
578 float gamma = 1 + i * 0.2f;
579 SkPowerMode mode(SkFloatToScalar(1 / gamma));
580 SkPaint p;
581 p.setXfermode(&mode);
582
583 canvas->drawBitmap(bm, 0, SkIntToScalar(i) * bm.height(), &p);
584 }
585 return;
586 }
587
588 if (false)
589 {
590 SkPaint paint;
591
592 paint.setAntiAlias(true);
593 paint.setDevKernText(true);
594 SkMSec now = SkTime::GetMSecs();
595 for (int i = 0; i < 1000000; i++)
596 {
597 paint.measureText("Hamburgefons", 15, NULL, NULL);
598 }
599 printf("--------- measure %d\n", SkTime::GetMSecs() - now);
600 this->inval(NULL);
601 return;
602 }
603
604 if (false)
605 {
606 SkRegion rgn;
607 SkPath path;
608 SkPaint paint;
609
610 // make_badrgn(&rgn, -2);
611
612 if (false)
613 {
614 paint.setColor(SK_ColorBLUE);
615 canvas->drawIRect(rgn.getBounds(), paint);
616 }
617 paint.setColor(SK_ColorRED);
618 draw_rgn(rgn, canvas, paint);
619
620 rgn.getBoundaryPath(&path);
621 paint.setARGB(0x80, 0, 0, 0xFF);
622 canvas->drawPath(path, paint);
623 return;
624 }
625
626 if (false)
627 {
628 SkRect r = { SkIntToScalar(50), SkIntToScalar(50), SkIntToScalar(300), SkIntToScalar(300) };
629 SkPaint p;
630
631 p.setStyle(SkPaint::kStroke_Style);
632 p.setAlpha(0x80);
633 p.setStrokeWidth(SkIntToScalar(20));
634 canvas->drawRect(r, p);
635 }
636
637 if (false)
638 {
639 SkPaint p;
640 SkRect r = { SkIntToScalar(100), SkIntToScalar(100), SkIntToScalar(104), SkIntToScalar(104) };
641 // r.offset(SK_ScalarHalf, SK_ScalarHalf);
642 p.setStyle(SkPaint::kStroke_Style);
643 p.setStrokeWidth(SK_Scalar1*2);
644 // p.setAntiAliasOn(true);
645 canvas->drawRect(r, p);
646 return;
647 }
648
649 if (false)
650 {
651 Sk64 aa, bb;
652 int64_t a = (int64_t)6062080 * -30596;
653 int64_t b = (int64_t)4816896 * 57957;
654 aa.setMul(6062080, -30596);
655 bb.setMul(4816896, 57957);
656
657 a += b;
658 b = a >> 16;
659
660// SkFixed c = aa.addGetFixed(bb);
661
662 printf("%d %d\n", (int)a, a >> 32);
663
664 SkBitmap bm;
665 SkPaint paint;
666 SkScalar scale = SkFloatToScalar(0.5625f);
667 SkScalar x = SkIntToScalar(100);
668 SkScalar y = SkIntToScalar(100);
669
670 //paint.setFilterType(SkPaint::kBilinear_FilterType);
671
672 SkImageDecoder::DecodeFile("/app_web_browser.png", &bm);
673
674 // canvas->drawBitmap(bm, x, y, paint);
675 x += SkIntToScalar(100);
676 canvas->save();
677 canvas->translate(x, y);
678 canvas->scale(SkIntToScalar(2)/1, SkIntToScalar(2)/1);
679 canvas->translate(-x, -y);
680 canvas->drawBitmap(bm, x, y, &paint);
681 canvas->restore();
682 x += SkIntToScalar(100);
683 canvas->save();
684 canvas->translate(x, y);
685 canvas->scale(scale, scale);
686 canvas->translate(-x, -y);
687 // canvas->drawBitmap(bm, x, y, paint);
688 canvas->restore();
689 return;
690 }
691
692 SkAutoCanvasRestore restore(canvas, false);
693 {
694 SkRect r;
695 r.set(0, 0, SkIntToScalar(1000), SkIntToScalar(20));
696 // canvas->saveLayer(&r, NULL, SkCanvas::kHasAlphaLayer_SaveFlag);
697 }
698
699 SkPaint paint;
700// const uint16_t glyphs[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 };
701 int index = fHints % SK_ARRAY_COUNT(gHints);
702 index = 1;
703// const char* style = gHints[index].fName;
704
705// canvas->translate(0, SkIntToScalar(50));
706
707 // canvas->drawText(style, strlen(style), SkIntToScalar(20), SkIntToScalar(20), paint);
708
709// paint.setTypeface(SkTypeface::Create(NULL, SkTypeface::kItalic))->unref();
710 paint.setAntiAlias(true);
711 paint.setFlags(paint.getFlags() | gHints[index].fFlags);
712
713 SkMSec now = 0;
714 if (REPEAT_COUNT > 1)
715 now = SkTime::GetMSecs();
716
717 SkRect clip;
718 clip.set(SkIntToScalar(25), SkIntToScalar(34), SkIntToScalar(88), SkIntToScalar(155));
719
720 if (0) {
721 canvas->clipRect(clip);
722 }
723
724 if (0) {
725 SkPath clipPath;
726 clipPath.addOval(clip);
727 canvas->clipPath(clipPath);
728 }
729
730 const char* text = "Hamburgefons";
731 size_t length = strlen(text);
732
733#ifdef TEST_CLICKX
734 {
735 SkPaint p;
736
737 p.setColor(SK_ColorGREEN);
738 p.setAntiAlias(true);
739 canvas->drawLine(fClickX, 0, fClickX, SkIntToScalar(1000), p);
740 }
741#endif
742
743 for (int j = 0; j < REPEAT_COUNT; j++)
744 {
745 SkScalar y = SkIntToScalar(0);
746 for (int i = 9; i <= 24; i++) {
747 paint.setTextSize(SkIntToScalar(i) /*+ (gRand.nextU() & 0xFFFF)*/);
748 for (SkScalar dx = 0; dx <= SkIntToScalar(3)/4; dx += SkIntToScalar(1) /* /4 */)
749 {
750 y += paint.getFontSpacing();
751 DrawTheText(canvas, text, length, SkIntToScalar(20) + dx, y, paint, fClickX, fMF);
752 }
753 }
754 if (gHints[index].fFlushCache) {
755 SkGraphics::SetFontCacheUsed(0);
756 }
757 }
758
759 if (REPEAT_COUNT > 1)
760 {
761 printf("--------- FPS = %g\n", REPEAT_COUNT * 1000. / (SkTime::GetMSecs() - now));
762 this->inval(NULL);
763 }
764 }
765
766 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y)
767 {
768 fClickX = x;
769 this->inval(NULL);
770 return this->INHERITED::onFindClickHandler(x, y);
771 }
772
773 virtual bool onClick(Click* click)
774 {
775 return this->INHERITED::onClick(click);
776 }
777
778private:
779 int fHints;
780 SkScalar fClickX;
781 SkMaskFilter* fMF;
782 SkShader* fGradient;
783
784 typedef SkView INHERITED;
785};
786
787//////////////////////////////////////////////////////////////////////////////
788
789static SkView* MyFactory() { return new TextSpeedView; }
790static SkViewRegister reg(MyFactory);
791