Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkDraw.cpp
1 /*
2  * Copyright 2006 The Android Open Source Project
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 "SkDraw.h"
9 #include "SkBlitter.h"
10 #include "SkCanvas.h"
11 #include "SkColorPriv.h"
12 #include "SkDevice.h"
13 #include "SkDeviceLooper.h"
14 #include "SkFixed.h"
15 #include "SkMaskFilter.h"
16 #include "SkPaint.h"
17 #include "SkPathEffect.h"
18 #include "SkRasterClip.h"
19 #include "SkRasterizer.h"
20 #include "SkRRect.h"
21 #include "SkScan.h"
22 #include "SkShader.h"
23 #include "SkSmallAllocator.h"
24 #include "SkString.h"
25 #include "SkStroke.h"
26 #include "SkTextMapStateProc.h"
27 #include "SkTLazy.h"
28 #include "SkUtils.h"
29 #include "SkVertState.h"
30
31 #include "SkAutoKern.h"
32 #include "SkBitmapProcShader.h"
33 #include "SkDrawProcs.h"
34 #include "SkMatrixUtils.h"
35
36
37 //#define TRACE_BITMAP_DRAWS
38
39
40 /** Helper for allocating small blitters on the stack.
41  */
42 class SkAutoBlitterChoose : SkNoncopyable {
43 public:
44     SkAutoBlitterChoose() {
45         fBlitter = NULL;
46     }
47     SkAutoBlitterChoose(const SkBitmap& device, const SkMatrix& matrix,
48                         const SkPaint& paint, bool drawCoverage = false) {
49         fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator,
50                                      drawCoverage);
51     }
52
53     SkBlitter*  operator->() { return fBlitter; }
54     SkBlitter*  get() const { return fBlitter; }
55
56     void choose(const SkBitmap& device, const SkMatrix& matrix,
57                 const SkPaint& paint, bool drawCoverage = false) {
58         SkASSERT(!fBlitter);
59         fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator,
60                                      drawCoverage);
61     }
62
63 private:
64     // Owned by fAllocator, which will handle the delete.
65     SkBlitter*          fBlitter;
66     SkTBlitterAllocator fAllocator;
67 };
68 #define SkAutoBlitterChoose(...) SK_REQUIRE_LOCAL_VAR(SkAutoBlitterChoose)
69
70 /**
71  *  Since we are providing the storage for the shader (to avoid the perf cost
72  *  of calling new) we insist that in our destructor we can account for all
73  *  owners of the shader.
74  */
75 class SkAutoBitmapShaderInstall : SkNoncopyable {
76 public:
77     SkAutoBitmapShaderInstall(const SkBitmap& src, const SkPaint& paint,
78                               const SkMatrix* localMatrix = NULL)
79             : fPaint(paint) /* makes a copy of the paint */ {
80         fPaint.setShader(CreateBitmapShader(src, SkShader::kClamp_TileMode,
81                                             SkShader::kClamp_TileMode,
82                                             localMatrix, &fAllocator));
83         // we deliberately left the shader with an owner-count of 2
84         SkASSERT(2 == fPaint.getShader()->getRefCnt());
85     }
86
87     ~SkAutoBitmapShaderInstall() {
88         // since fAllocator will destroy shader, we insist that owners == 2
89         SkASSERT(2 == fPaint.getShader()->getRefCnt());
90
91         fPaint.setShader(NULL); // unref the shader by 1
92
93     }
94
95     // return the new paint that has the shader applied
96     const SkPaint& paintWithShader() const { return fPaint; }
97
98 private:
99     // copy of caller's paint (which we then modify)
100     SkPaint             fPaint;
101     // Stores the shader.
102     SkTBlitterAllocator fAllocator;
103 };
104 #define SkAutoBitmapShaderInstall(...) SK_REQUIRE_LOCAL_VAR(SkAutoBitmapShaderInstall)
105
106 ///////////////////////////////////////////////////////////////////////////////
107
108 SkDraw::SkDraw() {
109     sk_bzero(this, sizeof(*this));
110 }
111
112 SkDraw::SkDraw(const SkDraw& src) {
113     memcpy(this, &src, sizeof(*this));
114 }
115
116 bool SkDraw::computeConservativeLocalClipBounds(SkRect* localBounds) const {
117     if (fRC->isEmpty()) {
118         return false;
119     }
120
121     SkMatrix inverse;
122     if (!fMatrix->invert(&inverse)) {
123         return false;
124     }
125
126     SkIRect devBounds = fRC->getBounds();
127     // outset to have slop for antialasing and hairlines
128     devBounds.outset(1, 1);
129     inverse.mapRect(localBounds, SkRect::Make(devBounds));
130     return true;
131 }
132
133 ///////////////////////////////////////////////////////////////////////////////
134
135 typedef void (*BitmapXferProc)(void* pixels, size_t bytes, uint32_t data);
136
137 static void D_Clear_BitmapXferProc(void* pixels, size_t bytes, uint32_t) {
138     sk_bzero(pixels, bytes);
139 }
140
141 static void D_Dst_BitmapXferProc(void*, size_t, uint32_t data) {}
142
143 static void D32_Src_BitmapXferProc(void* pixels, size_t bytes, uint32_t data) {
144     sk_memset32((uint32_t*)pixels, data, SkToInt(bytes >> 2));
145 }
146
147 static void D16_Src_BitmapXferProc(void* pixels, size_t bytes, uint32_t data) {
148     sk_memset16((uint16_t*)pixels, data, SkToInt(bytes >> 1));
149 }
150
151 static void DA8_Src_BitmapXferProc(void* pixels, size_t bytes, uint32_t data) {
152     memset(pixels, data, bytes);
153 }
154
155 static BitmapXferProc ChooseBitmapXferProc(const SkBitmap& bitmap,
156                                            const SkPaint& paint,
157                                            uint32_t* data) {
158     // todo: we can apply colorfilter up front if no shader, so we wouldn't
159     // need to abort this fastpath
160     if (paint.getShader() || paint.getColorFilter()) {
161         return NULL;
162     }
163
164     SkXfermode::Mode mode;
165     if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) {
166         return NULL;
167     }
168
169     SkColor color = paint.getColor();
170
171     // collaps modes based on color...
172     if (SkXfermode::kSrcOver_Mode == mode) {
173         unsigned alpha = SkColorGetA(color);
174         if (0 == alpha) {
175             mode = SkXfermode::kDst_Mode;
176         } else if (0xFF == alpha) {
177             mode = SkXfermode::kSrc_Mode;
178         }
179     }
180
181     switch (mode) {
182         case SkXfermode::kClear_Mode:
183 //            SkDebugf("--- D_Clear_BitmapXferProc\n");
184             return D_Clear_BitmapXferProc;  // ignore data
185         case SkXfermode::kDst_Mode:
186 //            SkDebugf("--- D_Dst_BitmapXferProc\n");
187             return D_Dst_BitmapXferProc;    // ignore data
188         case SkXfermode::kSrc_Mode: {
189             /*
190                 should I worry about dithering for the lower depths?
191             */
192             SkPMColor pmc = SkPreMultiplyColor(color);
193             switch (bitmap.colorType()) {
194                 case kN32_SkColorType:
195                     if (data) {
196                         *data = pmc;
197                     }
198 //                    SkDebugf("--- D32_Src_BitmapXferProc\n");
199                     return D32_Src_BitmapXferProc;
200                 case kRGB_565_SkColorType:
201                     if (data) {
202                         *data = SkPixel32ToPixel16(pmc);
203                     }
204 //                    SkDebugf("--- D16_Src_BitmapXferProc\n");
205                     return D16_Src_BitmapXferProc;
206                 case kAlpha_8_SkColorType:
207                     if (data) {
208                         *data = SkGetPackedA32(pmc);
209                     }
210 //                    SkDebugf("--- DA8_Src_BitmapXferProc\n");
211                     return DA8_Src_BitmapXferProc;
212                 default:
213                     break;
214             }
215             break;
216         }
217         default:
218             break;
219     }
220     return NULL;
221 }
222
223 static void CallBitmapXferProc(const SkBitmap& bitmap, const SkIRect& rect,
224                                BitmapXferProc proc, uint32_t procData) {
225     int shiftPerPixel;
226     switch (bitmap.colorType()) {
227         case kN32_SkColorType:
228             shiftPerPixel = 2;
229             break;
230         case kRGB_565_SkColorType:
231             shiftPerPixel = 1;
232             break;
233         case kAlpha_8_SkColorType:
234             shiftPerPixel = 0;
235             break;
236         default:
237             SkDEBUGFAIL("Can't use xferproc on this config");
238             return;
239     }
240
241     uint8_t* pixels = (uint8_t*)bitmap.getPixels();
242     SkASSERT(pixels);
243     const size_t rowBytes = bitmap.rowBytes();
244     const int widthBytes = rect.width() << shiftPerPixel;
245
246     // skip down to the first scanline and X position
247     pixels += rect.fTop * rowBytes + (rect.fLeft << shiftPerPixel);
248     for (int scans = rect.height() - 1; scans >= 0; --scans) {
249         proc(pixels, widthBytes, procData);
250         pixels += rowBytes;
251     }
252 }
253
254 void SkDraw::drawPaint(const SkPaint& paint) const {
255     SkDEBUGCODE(this->validate();)
256
257     if (fRC->isEmpty()) {
258         return;
259     }
260
261     SkIRect    devRect;
262     devRect.set(0, 0, fBitmap->width(), fBitmap->height());
263
264     if (fRC->isBW()) {
265         /*  If we don't have a shader (i.e. we're just a solid color) we may
266             be faster to operate directly on the device bitmap, rather than invoking
267             a blitter. Esp. true for xfermodes, which require a colorshader to be
268             present, which is just redundant work. Since we're drawing everywhere
269             in the clip, we don't have to worry about antialiasing.
270         */
271         uint32_t procData = 0;  // to avoid the warning
272         BitmapXferProc proc = ChooseBitmapXferProc(*fBitmap, paint, &procData);
273         if (proc) {
274             if (D_Dst_BitmapXferProc == proc) { // nothing to do
275                 return;
276             }
277
278             SkRegion::Iterator iter(fRC->bwRgn());
279             while (!iter.done()) {
280                 CallBitmapXferProc(*fBitmap, iter.rect(), proc, procData);
281                 iter.next();
282             }
283             return;
284         }
285     }
286
287     // normal case: use a blitter
288     SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint);
289     SkScan::FillIRect(devRect, *fRC, blitter.get());
290 }
291
292 ///////////////////////////////////////////////////////////////////////////////
293
294 struct PtProcRec {
295     SkCanvas::PointMode fMode;
296     const SkPaint*  fPaint;
297     const SkRegion* fClip;
298     const SkRasterClip* fRC;
299
300     // computed values
301     SkFixed fRadius;
302
303     typedef void (*Proc)(const PtProcRec&, const SkPoint devPts[], int count,
304                          SkBlitter*);
305
306     bool init(SkCanvas::PointMode, const SkPaint&, const SkMatrix* matrix,
307               const SkRasterClip*);
308     Proc chooseProc(SkBlitter** blitter);
309
310 private:
311     SkAAClipBlitterWrapper fWrapper;
312 };
313
314 static void bw_pt_rect_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
315                                  int count, SkBlitter* blitter) {
316     SkASSERT(rec.fClip->isRect());
317     const SkIRect& r = rec.fClip->getBounds();
318
319     for (int i = 0; i < count; i++) {
320         int x = SkScalarFloorToInt(devPts[i].fX);
321         int y = SkScalarFloorToInt(devPts[i].fY);
322         if (r.contains(x, y)) {
323             blitter->blitH(x, y, 1);
324         }
325     }
326 }
327
328 static void bw_pt_rect_16_hair_proc(const PtProcRec& rec,
329                                     const SkPoint devPts[], int count,
330                                     SkBlitter* blitter) {
331     SkASSERT(rec.fRC->isRect());
332     const SkIRect& r = rec.fRC->getBounds();
333     uint32_t value;
334     const SkBitmap* bitmap = blitter->justAnOpaqueColor(&value);
335     SkASSERT(bitmap);
336
337     uint16_t* addr = bitmap->getAddr16(0, 0);
338     size_t    rb = bitmap->rowBytes();
339
340     for (int i = 0; i < count; i++) {
341         int x = SkScalarFloorToInt(devPts[i].fX);
342         int y = SkScalarFloorToInt(devPts[i].fY);
343         if (r.contains(x, y)) {
344             ((uint16_t*)((char*)addr + y * rb))[x] = SkToU16(value);
345         }
346     }
347 }
348
349 static void bw_pt_rect_32_hair_proc(const PtProcRec& rec,
350                                     const SkPoint devPts[], int count,
351                                     SkBlitter* blitter) {
352     SkASSERT(rec.fRC->isRect());
353     const SkIRect& r = rec.fRC->getBounds();
354     uint32_t value;
355     const SkBitmap* bitmap = blitter->justAnOpaqueColor(&value);
356     SkASSERT(bitmap);
357
358     SkPMColor* addr = bitmap->getAddr32(0, 0);
359     size_t     rb = bitmap->rowBytes();
360
361     for (int i = 0; i < count; i++) {
362         int x = SkScalarFloorToInt(devPts[i].fX);
363         int y = SkScalarFloorToInt(devPts[i].fY);
364         if (r.contains(x, y)) {
365             ((SkPMColor*)((char*)addr + y * rb))[x] = value;
366         }
367     }
368 }
369
370 static void bw_pt_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
371                             int count, SkBlitter* blitter) {
372     for (int i = 0; i < count; i++) {
373         int x = SkScalarFloorToInt(devPts[i].fX);
374         int y = SkScalarFloorToInt(devPts[i].fY);
375         if (rec.fClip->contains(x, y)) {
376             blitter->blitH(x, y, 1);
377         }
378     }
379 }
380
381 static void bw_line_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
382                               int count, SkBlitter* blitter) {
383     for (int i = 0; i < count; i += 2) {
384         SkScan::HairLine(devPts[i], devPts[i+1], *rec.fRC, blitter);
385     }
386 }
387
388 static void bw_poly_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
389                               int count, SkBlitter* blitter) {
390     for (int i = 0; i < count - 1; i++) {
391         SkScan::HairLine(devPts[i], devPts[i+1], *rec.fRC, blitter);
392     }
393 }
394
395 // aa versions
396
397 static void aa_line_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
398                               int count, SkBlitter* blitter) {
399     for (int i = 0; i < count; i += 2) {
400         SkScan::AntiHairLine(devPts[i], devPts[i+1], *rec.fRC, blitter);
401     }
402 }
403
404 static void aa_poly_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
405                               int count, SkBlitter* blitter) {
406     for (int i = 0; i < count - 1; i++) {
407         SkScan::AntiHairLine(devPts[i], devPts[i+1], *rec.fRC, blitter);
408     }
409 }
410
411 // square procs (strokeWidth > 0 but matrix is square-scale (sx == sy)
412
413 static void bw_square_proc(const PtProcRec& rec, const SkPoint devPts[],
414                            int count, SkBlitter* blitter) {
415     const SkFixed radius = rec.fRadius;
416     for (int i = 0; i < count; i++) {
417         SkFixed x = SkScalarToFixed(devPts[i].fX);
418         SkFixed y = SkScalarToFixed(devPts[i].fY);
419
420         SkXRect r;
421         r.fLeft = x - radius;
422         r.fTop = y - radius;
423         r.fRight = x + radius;
424         r.fBottom = y + radius;
425
426         SkScan::FillXRect(r, *rec.fRC, blitter);
427     }
428 }
429
430 static void aa_square_proc(const PtProcRec& rec, const SkPoint devPts[],
431                            int count, SkBlitter* blitter) {
432     const SkFixed radius = rec.fRadius;
433     for (int i = 0; i < count; i++) {
434         SkFixed x = SkScalarToFixed(devPts[i].fX);
435         SkFixed y = SkScalarToFixed(devPts[i].fY);
436
437         SkXRect r;
438         r.fLeft = x - radius;
439         r.fTop = y - radius;
440         r.fRight = x + radius;
441         r.fBottom = y + radius;
442
443         SkScan::AntiFillXRect(r, *rec.fRC, blitter);
444     }
445 }
446
447 // If this guy returns true, then chooseProc() must return a valid proc
448 bool PtProcRec::init(SkCanvas::PointMode mode, const SkPaint& paint,
449                      const SkMatrix* matrix, const SkRasterClip* rc) {
450     if (paint.getPathEffect()) {
451         return false;
452     }
453     SkScalar width = paint.getStrokeWidth();
454     if (0 == width) {
455         fMode = mode;
456         fPaint = &paint;
457         fClip = NULL;
458         fRC = rc;
459         fRadius = SK_FixedHalf;
460         return true;
461     }
462     if (paint.getStrokeCap() != SkPaint::kRound_Cap &&
463             matrix->rectStaysRect() && SkCanvas::kPoints_PointMode == mode) {
464         SkScalar sx = matrix->get(SkMatrix::kMScaleX);
465         SkScalar sy = matrix->get(SkMatrix::kMScaleY);
466         if (SkScalarNearlyZero(sx - sy)) {
467             if (sx < 0) {
468                 sx = -sx;
469             }
470
471             fMode = mode;
472             fPaint = &paint;
473             fClip = NULL;
474             fRC = rc;
475             fRadius = SkScalarToFixed(SkScalarMul(width, sx)) >> 1;
476             return true;
477         }
478     }
479     return false;
480 }
481
482 PtProcRec::Proc PtProcRec::chooseProc(SkBlitter** blitterPtr) {
483     Proc proc = NULL;
484
485     SkBlitter* blitter = *blitterPtr;
486     if (fRC->isBW()) {
487         fClip = &fRC->bwRgn();
488     } else {
489         fWrapper.init(*fRC, blitter);
490         fClip = &fWrapper.getRgn();
491         blitter = fWrapper.getBlitter();
492         *blitterPtr = blitter;
493     }
494
495     // for our arrays
496     SkASSERT(0 == SkCanvas::kPoints_PointMode);
497     SkASSERT(1 == SkCanvas::kLines_PointMode);
498     SkASSERT(2 == SkCanvas::kPolygon_PointMode);
499     SkASSERT((unsigned)fMode <= (unsigned)SkCanvas::kPolygon_PointMode);
500
501     if (fPaint->isAntiAlias()) {
502         if (0 == fPaint->getStrokeWidth()) {
503             static const Proc gAAProcs[] = {
504                 aa_square_proc, aa_line_hair_proc, aa_poly_hair_proc
505             };
506             proc = gAAProcs[fMode];
507         } else if (fPaint->getStrokeCap() != SkPaint::kRound_Cap) {
508             SkASSERT(SkCanvas::kPoints_PointMode == fMode);
509             proc = aa_square_proc;
510         }
511     } else {    // BW
512         if (fRadius <= SK_FixedHalf) {    // small radii and hairline
513             if (SkCanvas::kPoints_PointMode == fMode && fClip->isRect()) {
514                 uint32_t value;
515                 const SkBitmap* bm = blitter->justAnOpaqueColor(&value);
516                 if (bm && kRGB_565_SkColorType == bm->colorType()) {
517                     proc = bw_pt_rect_16_hair_proc;
518                 } else if (bm && kN32_SkColorType == bm->colorType()) {
519                     proc = bw_pt_rect_32_hair_proc;
520                 } else {
521                     proc = bw_pt_rect_hair_proc;
522                 }
523             } else {
524                 static Proc gBWProcs[] = {
525                     bw_pt_hair_proc, bw_line_hair_proc, bw_poly_hair_proc
526                 };
527                 proc = gBWProcs[fMode];
528             }
529         } else {
530             proc = bw_square_proc;
531         }
532     }
533     return proc;
534 }
535
536 // each of these costs 8-bytes of stack space, so don't make it too large
537 // must be even for lines/polygon to work
538 #define MAX_DEV_PTS     32
539
540 void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
541                         const SkPoint pts[], const SkPaint& paint,
542                         bool forceUseDevice) const {
543     // if we're in lines mode, force count to be even
544     if (SkCanvas::kLines_PointMode == mode) {
545         count &= ~(size_t)1;
546     }
547
548     if ((long)count <= 0) {
549         return;
550     }
551
552     SkASSERT(pts != NULL);
553     SkDEBUGCODE(this->validate();)
554
555      // nothing to draw
556     if (fRC->isEmpty()) {
557         return;
558     }
559
560     PtProcRec rec;
561     if (!forceUseDevice && rec.init(mode, paint, fMatrix, fRC)) {
562         SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint);
563
564         SkPoint             devPts[MAX_DEV_PTS];
565         const SkMatrix*     matrix = fMatrix;
566         SkBlitter*          bltr = blitter.get();
567         PtProcRec::Proc     proc = rec.chooseProc(&bltr);
568         // we have to back up subsequent passes if we're in polygon mode
569         const size_t backup = (SkCanvas::kPolygon_PointMode == mode);
570
571         do {
572             int n = SkToInt(count);
573             if (n > MAX_DEV_PTS) {
574                 n = MAX_DEV_PTS;
575             }
576             matrix->mapPoints(devPts, pts, n);
577             proc(rec, devPts, n, bltr);
578             pts += n - backup;
579             SkASSERT(SkToInt(count) >= n);
580             count -= n;
581             if (count > 0) {
582                 count += backup;
583             }
584         } while (count != 0);
585     } else {
586         switch (mode) {
587             case SkCanvas::kPoints_PointMode: {
588                 // temporarily mark the paint as filling.
589                 SkPaint newPaint(paint);
590                 newPaint.setStyle(SkPaint::kFill_Style);
591
592                 SkScalar width = newPaint.getStrokeWidth();
593                 SkScalar radius = SkScalarHalf(width);
594
595                 if (newPaint.getStrokeCap() == SkPaint::kRound_Cap) {
596                     SkPath      path;
597                     SkMatrix    preMatrix;
598
599                     path.addCircle(0, 0, radius);
600                     for (size_t i = 0; i < count; i++) {
601                         preMatrix.setTranslate(pts[i].fX, pts[i].fY);
602                         // pass true for the last point, since we can modify
603                         // then path then
604                         if (fDevice) {
605                             fDevice->drawPath(*this, path, newPaint, &preMatrix,
606                                               (count-1) == i);
607                         } else {
608                             this->drawPath(path, newPaint, &preMatrix,
609                                            (count-1) == i);
610                         }
611                     }
612                 } else {
613                     SkRect  r;
614
615                     for (size_t i = 0; i < count; i++) {
616                         r.fLeft = pts[i].fX - radius;
617                         r.fTop = pts[i].fY - radius;
618                         r.fRight = r.fLeft + width;
619                         r.fBottom = r.fTop + width;
620                         if (fDevice) {
621                             fDevice->drawRect(*this, r, newPaint);
622                         } else {
623                             this->drawRect(r, newPaint);
624                         }
625                     }
626                 }
627                 break;
628             }
629             case SkCanvas::kLines_PointMode:
630 #ifndef SK_DISABLE_DASHING_OPTIMIZATION
631                 if (2 == count && paint.getPathEffect()) {
632                     // most likely a dashed line - see if it is one of the ones
633                     // we can accelerate
634                     SkStrokeRec rec(paint);
635                     SkPathEffect::PointData pointData;
636
637                     SkPath path;
638                     path.moveTo(pts[0]);
639                     path.lineTo(pts[1]);
640
641                     SkRect cullRect = SkRect::Make(fRC->getBounds());
642
643                     if (paint.getPathEffect()->asPoints(&pointData, path, rec,
644                                                         *fMatrix, &cullRect)) {
645                         // 'asPoints' managed to find some fast path
646
647                         SkPaint newP(paint);
648                         newP.setPathEffect(NULL);
649                         newP.setStyle(SkPaint::kFill_Style);
650
651                         if (!pointData.fFirst.isEmpty()) {
652                             if (fDevice) {
653                                 fDevice->drawPath(*this, pointData.fFirst, newP);
654                             } else {
655                                 this->drawPath(pointData.fFirst, newP);
656                             }
657                         }
658
659                         if (!pointData.fLast.isEmpty()) {
660                             if (fDevice) {
661                                 fDevice->drawPath(*this, pointData.fLast, newP);
662                             } else {
663                                 this->drawPath(pointData.fLast, newP);
664                             }
665                         }
666
667                         if (pointData.fSize.fX == pointData.fSize.fY) {
668                             // The rest of the dashed line can just be drawn as points
669                             SkASSERT(pointData.fSize.fX == SkScalarHalf(newP.getStrokeWidth()));
670
671                             if (SkPathEffect::PointData::kCircles_PointFlag & pointData.fFlags) {
672                                 newP.setStrokeCap(SkPaint::kRound_Cap);
673                             } else {
674                                 newP.setStrokeCap(SkPaint::kButt_Cap);
675                             }
676
677                             if (fDevice) {
678                                 fDevice->drawPoints(*this,
679                                                     SkCanvas::kPoints_PointMode,
680                                                     pointData.fNumPoints,
681                                                     pointData.fPoints,
682                                                     newP);
683                             } else {
684                                 this->drawPoints(SkCanvas::kPoints_PointMode,
685                                                  pointData.fNumPoints,
686                                                  pointData.fPoints,
687                                                  newP,
688                                                  forceUseDevice);
689                             }
690                             break;
691                         } else {
692                             // The rest of the dashed line must be drawn as rects
693                             SkASSERT(!(SkPathEffect::PointData::kCircles_PointFlag &
694                                       pointData.fFlags));
695
696                             SkRect r;
697
698                             for (int i = 0; i < pointData.fNumPoints; ++i) {
699                                 r.set(pointData.fPoints[i].fX - pointData.fSize.fX,
700                                       pointData.fPoints[i].fY - pointData.fSize.fY,
701                                       pointData.fPoints[i].fX + pointData.fSize.fX,
702                                       pointData.fPoints[i].fY + pointData.fSize.fY);
703                                 if (fDevice) {
704                                     fDevice->drawRect(*this, r, newP);
705                                 } else {
706                                     this->drawRect(r, newP);
707                                 }
708                             }
709                         }
710
711                         break;
712                     }
713                 }
714 #endif // DISABLE_DASHING_OPTIMIZATION
715                 // couldn't take fast path so fall through!
716             case SkCanvas::kPolygon_PointMode: {
717                 count -= 1;
718                 SkPath path;
719                 SkPaint p(paint);
720                 p.setStyle(SkPaint::kStroke_Style);
721                 size_t inc = (SkCanvas::kLines_PointMode == mode) ? 2 : 1;
722                 for (size_t i = 0; i < count; i += inc) {
723                     path.moveTo(pts[i]);
724                     path.lineTo(pts[i+1]);
725                     if (fDevice) {
726                         fDevice->drawPath(*this, path, p, NULL, true);
727                     } else {
728                         this->drawPath(path, p, NULL, true);
729                     }
730                     path.rewind();
731                 }
732                 break;
733             }
734         }
735     }
736 }
737
738 static bool easy_rect_join(const SkPaint& paint, const SkMatrix& matrix,
739                            SkPoint* strokeSize) {
740     if (SkPaint::kMiter_Join != paint.getStrokeJoin() ||
741         paint.getStrokeMiter() < SK_ScalarSqrt2) {
742         return false;
743     }
744
745     SkASSERT(matrix.rectStaysRect());
746     SkPoint pt = { paint.getStrokeWidth(), paint.getStrokeWidth() };
747     matrix.mapVectors(strokeSize, &pt, 1);
748     strokeSize->fX = SkScalarAbs(strokeSize->fX);
749     strokeSize->fY = SkScalarAbs(strokeSize->fY);
750     return true;
751 }
752
753 SkDraw::RectType SkDraw::ComputeRectType(const SkPaint& paint,
754                                          const SkMatrix& matrix,
755                                          SkPoint* strokeSize) {
756     RectType rtype;
757     const SkScalar width = paint.getStrokeWidth();
758     const bool zeroWidth = (0 == width);
759     SkPaint::Style style = paint.getStyle();
760
761     if ((SkPaint::kStrokeAndFill_Style == style) && zeroWidth) {
762         style = SkPaint::kFill_Style;
763     }
764
765     if (paint.getPathEffect() || paint.getMaskFilter() ||
766         paint.getRasterizer() || !matrix.rectStaysRect() ||
767         SkPaint::kStrokeAndFill_Style == style) {
768         rtype = kPath_RectType;
769     } else if (SkPaint::kFill_Style == style) {
770         rtype = kFill_RectType;
771     } else if (zeroWidth) {
772         rtype = kHair_RectType;
773     } else if (easy_rect_join(paint, matrix, strokeSize)) {
774         rtype = kStroke_RectType;
775     } else {
776         rtype = kPath_RectType;
777     }
778     return rtype;
779 }
780
781 static const SkPoint* rect_points(const SkRect& r) {
782     return SkTCast<const SkPoint*>(&r);
783 }
784
785 static SkPoint* rect_points(SkRect& r) {
786     return SkTCast<SkPoint*>(&r);
787 }
788
789 void SkDraw::drawRect(const SkRect& rect, const SkPaint& paint) const {
790     SkDEBUGCODE(this->validate();)
791
792     // nothing to draw
793     if (fRC->isEmpty()) {
794         return;
795     }
796
797     SkPoint strokeSize;
798     RectType rtype = ComputeRectType(paint, *fMatrix, &strokeSize);
799
800     if (kPath_RectType == rtype) {
801         SkPath  tmp;
802         tmp.addRect(rect);
803         tmp.setFillType(SkPath::kWinding_FillType);
804         this->drawPath(tmp, paint, NULL, true);
805         return;
806     }
807
808     const SkMatrix& matrix = *fMatrix;
809     SkRect          devRect;
810
811     // transform rect into devRect
812     matrix.mapPoints(rect_points(devRect), rect_points(rect), 2);
813     devRect.sort();
814
815     // look for the quick exit, before we build a blitter
816     SkIRect ir;
817     devRect.roundOut(&ir);
818     if (paint.getStyle() != SkPaint::kFill_Style) {
819         // extra space for hairlines
820         if (paint.getStrokeWidth() == 0) {
821             ir.outset(1, 1);
822         } else {
823             SkScalar radius = SkScalarHalf(paint.getStrokeWidth());
824             ir.outset(radius, radius);
825         }
826     }
827     if (fRC->quickReject(ir)) {
828         return;
829     }
830
831     SkDeviceLooper looper(*fBitmap, *fRC, ir, paint.isAntiAlias());
832     while (looper.next()) {
833         SkRect localDevRect;
834         looper.mapRect(&localDevRect, devRect);
835         SkMatrix localMatrix;
836         looper.mapMatrix(&localMatrix, matrix);
837
838         SkAutoBlitterChoose blitterStorage(looper.getBitmap(), localMatrix,
839                                            paint);
840         const SkRasterClip& clip = looper.getRC();
841         SkBlitter*          blitter = blitterStorage.get();
842
843         // we want to "fill" if we are kFill or kStrokeAndFill, since in the latter
844         // case we are also hairline (if we've gotten to here), which devolves to
845         // effectively just kFill
846         switch (rtype) {
847             case kFill_RectType:
848                 if (paint.isAntiAlias()) {
849                     SkScan::AntiFillRect(localDevRect, clip, blitter);
850                 } else {
851                     SkScan::FillRect(localDevRect, clip, blitter);
852                 }
853                 break;
854             case kStroke_RectType:
855                 if (paint.isAntiAlias()) {
856                     SkScan::AntiFrameRect(localDevRect, strokeSize, clip, blitter);
857                 } else {
858                     SkScan::FrameRect(localDevRect, strokeSize, clip, blitter);
859                 }
860                 break;
861             case kHair_RectType:
862                 if (paint.isAntiAlias()) {
863                     SkScan::AntiHairRect(localDevRect, clip, blitter);
864                 } else {
865                     SkScan::HairRect(localDevRect, clip, blitter);
866                 }
867                 break;
868             default:
869                 SkDEBUGFAIL("bad rtype");
870         }
871     }
872 }
873
874 void SkDraw::drawDevMask(const SkMask& srcM, const SkPaint& paint) const {
875     if (srcM.fBounds.isEmpty()) {
876         return;
877     }
878
879     const SkMask* mask = &srcM;
880
881     SkMask dstM;
882     if (paint.getMaskFilter() &&
883             paint.getMaskFilter()->filterMask(&dstM, srcM, *fMatrix, NULL)) {
884         mask = &dstM;
885     } else {
886         dstM.fImage = NULL;
887     }
888     SkAutoMaskFreeImage ami(dstM.fImage);
889
890     SkAutoBlitterChoose blitterChooser(*fBitmap, *fMatrix, paint);
891     SkBlitter* blitter = blitterChooser.get();
892
893     SkAAClipBlitterWrapper wrapper;
894     const SkRegion* clipRgn;
895
896     if (fRC->isBW()) {
897         clipRgn = &fRC->bwRgn();
898     } else {
899         wrapper.init(*fRC, blitter);
900         clipRgn = &wrapper.getRgn();
901         blitter = wrapper.getBlitter();
902     }
903     blitter->blitMaskRegion(*mask, *clipRgn);
904 }
905
906 static SkScalar fast_len(const SkVector& vec) {
907     SkScalar x = SkScalarAbs(vec.fX);
908     SkScalar y = SkScalarAbs(vec.fY);
909     if (x < y) {
910         SkTSwap(x, y);
911     }
912     return x + SkScalarHalf(y);
913 }
914
915 static bool xfermodeSupportsCoverageAsAlpha(SkXfermode* xfer) {
916     SkXfermode::Coeff dc;
917     if (!SkXfermode::AsCoeff(xfer, NULL, &dc)) {
918         return false;
919     }
920
921     switch (dc) {
922         case SkXfermode::kOne_Coeff:
923         case SkXfermode::kISA_Coeff:
924         case SkXfermode::kISC_Coeff:
925             return true;
926         default:
927             return false;
928     }
929 }
930
931 bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix& matrix,
932                                    SkScalar* coverage) {
933     SkASSERT(strokeWidth > 0);
934     // We need to try to fake a thick-stroke with a modulated hairline.
935
936     if (matrix.hasPerspective()) {
937         return false;
938     }
939
940     SkVector src[2], dst[2];
941     src[0].set(strokeWidth, 0);
942     src[1].set(0, strokeWidth);
943     matrix.mapVectors(dst, src, 2);
944     SkScalar len0 = fast_len(dst[0]);
945     SkScalar len1 = fast_len(dst[1]);
946     if (len0 <= SK_Scalar1 && len1 <= SK_Scalar1) {
947         if (coverage) {
948             *coverage = SkScalarAve(len0, len1);
949         }
950         return true;
951     }
952     return false;
953 }
954
955 void SkDraw::drawRRect(const SkRRect& rrect, const SkPaint& paint) const {
956     SkDEBUGCODE(this->validate());
957
958     if (fRC->isEmpty()) {
959         return;
960     }
961
962     {
963         // TODO: Investigate optimizing these options. They are in the same
964         // order as SkDraw::drawPath, which handles each case. It may be
965         // that there is no way to optimize for these using the SkRRect path.
966         SkScalar coverage;
967         if (SkDrawTreatAsHairline(paint, *fMatrix, &coverage)) {
968             goto DRAW_PATH;
969         }
970
971         if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
972             goto DRAW_PATH;
973         }
974
975         if (paint.getRasterizer()) {
976             goto DRAW_PATH;
977         }
978     }
979
980     if (paint.getMaskFilter()) {
981         // Transform the rrect into device space.
982         SkRRect devRRect;
983         if (rrect.transform(*fMatrix, &devRRect)) {
984             SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint);
985             if (paint.getMaskFilter()->filterRRect(devRRect, *fMatrix, *fRC, blitter.get(),
986                                                    SkPaint::kFill_Style)) {
987                 return; // filterRRect() called the blitter, so we're done
988             }
989         }
990     }
991
992 DRAW_PATH:
993     // Now fall back to the default case of using a path.
994     SkPath path;
995     path.addRRect(rrect);
996     this->drawPath(path, paint, NULL, true);
997 }
998
999 void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
1000                       const SkMatrix* prePathMatrix, bool pathIsMutable,
1001                       bool drawCoverage, SkBlitter* customBlitter) const {
1002     SkDEBUGCODE(this->validate();)
1003
1004     // nothing to draw
1005     if (fRC->isEmpty()) {
1006         return;
1007     }
1008
1009     SkPath*         pathPtr = (SkPath*)&origSrcPath;
1010     bool            doFill = true;
1011     SkPath          tmpPath;
1012     SkMatrix        tmpMatrix;
1013     const SkMatrix* matrix = fMatrix;
1014
1015     if (prePathMatrix) {
1016         if (origPaint.getPathEffect() || origPaint.getStyle() != SkPaint::kFill_Style ||
1017                 origPaint.getRasterizer()) {
1018             SkPath* result = pathPtr;
1019
1020             if (!pathIsMutable) {
1021                 result = &tmpPath;
1022                 pathIsMutable = true;
1023             }
1024             pathPtr->transform(*prePathMatrix, result);
1025             pathPtr = result;
1026         } else {
1027             tmpMatrix.setConcat(*matrix, *prePathMatrix);
1028             matrix = &tmpMatrix;
1029         }
1030     }
1031     // at this point we're done with prePathMatrix
1032     SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
1033
1034     SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
1035
1036     {
1037         SkScalar coverage;
1038         if (SkDrawTreatAsHairline(origPaint, *matrix, &coverage)) {
1039             if (SK_Scalar1 == coverage) {
1040                 paint.writable()->setStrokeWidth(0);
1041             } else if (xfermodeSupportsCoverageAsAlpha(origPaint.getXfermode())) {
1042                 U8CPU newAlpha;
1043 #if 0
1044                 newAlpha = SkToU8(SkScalarRoundToInt(coverage *
1045                                                      origPaint.getAlpha()));
1046 #else
1047                 // this is the old technique, which we preserve for now so
1048                 // we don't change previous results (testing)
1049                 // the new way seems fine, its just (a tiny bit) different
1050                 int scale = (int)SkScalarMul(coverage, 256);
1051                 newAlpha = origPaint.getAlpha() * scale >> 8;
1052 #endif
1053                 SkPaint* writablePaint = paint.writable();
1054                 writablePaint->setStrokeWidth(0);
1055                 writablePaint->setAlpha(newAlpha);
1056             }
1057         }
1058     }
1059
1060     if (paint->getPathEffect() || paint->getStyle() != SkPaint::kFill_Style) {
1061         SkRect cullRect;
1062         const SkRect* cullRectPtr = NULL;
1063         if (this->computeConservativeLocalClipBounds(&cullRect)) {
1064             cullRectPtr = &cullRect;
1065         }
1066         doFill = paint->getFillPath(*pathPtr, &tmpPath, cullRectPtr);
1067         pathPtr = &tmpPath;
1068     }
1069
1070     if (paint->getRasterizer()) {
1071         SkMask  mask;
1072         if (paint->getRasterizer()->rasterize(*pathPtr, *matrix,
1073                             &fRC->getBounds(), paint->getMaskFilter(), &mask,
1074                             SkMask::kComputeBoundsAndRenderImage_CreateMode)) {
1075             this->drawDevMask(mask, *paint);
1076             SkMask::FreeImage(mask.fImage);
1077         }
1078         return;
1079     }
1080
1081     // avoid possibly allocating a new path in transform if we can
1082     SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath;
1083
1084     // transform the path into device space
1085     pathPtr->transform(*matrix, devPathPtr);
1086
1087     SkBlitter* blitter = NULL;
1088     SkAutoBlitterChoose blitterStorage;
1089     if (NULL == customBlitter) {
1090         blitterStorage.choose(*fBitmap, *fMatrix, *paint, drawCoverage);
1091         blitter = blitterStorage.get();
1092     } else {
1093         blitter = customBlitter;
1094     }
1095
1096     if (paint->getMaskFilter()) {
1097         SkPaint::Style style = doFill ? SkPaint::kFill_Style :
1098             SkPaint::kStroke_Style;
1099         if (paint->getMaskFilter()->filterPath(*devPathPtr, *fMatrix, *fRC, blitter, style)) {
1100             return; // filterPath() called the blitter, so we're done
1101         }
1102     }
1103
1104     void (*proc)(const SkPath&, const SkRasterClip&, SkBlitter*);
1105     if (doFill) {
1106         if (paint->isAntiAlias()) {
1107             proc = SkScan::AntiFillPath;
1108         } else {
1109             proc = SkScan::FillPath;
1110         }
1111     } else {    // hairline
1112         if (paint->isAntiAlias()) {
1113             proc = SkScan::AntiHairPath;
1114         } else {
1115             proc = SkScan::HairPath;
1116         }
1117     }
1118     proc(*devPathPtr, *fRC, blitter);
1119 }
1120
1121 /** For the purposes of drawing bitmaps, if a matrix is "almost" translate
1122     go ahead and treat it as if it were, so that subsequent code can go fast.
1123  */
1124 static bool just_translate(const SkMatrix& matrix, const SkBitmap& bitmap) {
1125     unsigned bits = 0;  // TODO: find a way to allow the caller to tell us to
1126                         // respect filtering.
1127     return SkTreatAsSprite(matrix, bitmap.width(), bitmap.height(), bits);
1128 }
1129
1130 void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap,
1131                               const SkPaint& paint) const {
1132     SkASSERT(bitmap.colorType() == kAlpha_8_SkColorType);
1133
1134     if (just_translate(*fMatrix, bitmap)) {
1135         int ix = SkScalarRoundToInt(fMatrix->getTranslateX());
1136         int iy = SkScalarRoundToInt(fMatrix->getTranslateY());
1137
1138         SkAutoLockPixels alp(bitmap);
1139         if (!bitmap.readyToDraw()) {
1140             return;
1141         }
1142
1143         SkMask  mask;
1144         mask.fBounds.set(ix, iy, ix + bitmap.width(), iy + bitmap.height());
1145         mask.fFormat = SkMask::kA8_Format;
1146         mask.fRowBytes = SkToU32(bitmap.rowBytes());
1147         mask.fImage = bitmap.getAddr8(0, 0);
1148
1149         this->drawDevMask(mask, paint);
1150     } else {    // need to xform the bitmap first
1151         SkRect  r;
1152         SkMask  mask;
1153
1154         r.set(0, 0,
1155               SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
1156         fMatrix->mapRect(&r);
1157         r.round(&mask.fBounds);
1158
1159         // set the mask's bounds to the transformed bitmap-bounds,
1160         // clipped to the actual device
1161         {
1162             SkIRect    devBounds;
1163             devBounds.set(0, 0, fBitmap->width(), fBitmap->height());
1164             // need intersect(l, t, r, b) on irect
1165             if (!mask.fBounds.intersect(devBounds)) {
1166                 return;
1167             }
1168         }
1169
1170         mask.fFormat = SkMask::kA8_Format;
1171         mask.fRowBytes = SkAlign4(mask.fBounds.width());
1172         size_t size = mask.computeImageSize();
1173         if (0 == size) {
1174             // the mask is too big to allocated, draw nothing
1175             return;
1176         }
1177
1178         // allocate (and clear) our temp buffer to hold the transformed bitmap
1179         SkAutoMalloc    storage(size);
1180         mask.fImage = (uint8_t*)storage.get();
1181         memset(mask.fImage, 0, size);
1182
1183         // now draw our bitmap(src) into mask(dst), transformed by the matrix
1184         {
1185             SkBitmap    device;
1186             device.installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), mask.fBounds.height()),
1187                                  mask.fImage, mask.fRowBytes);
1188
1189             SkCanvas c(device);
1190             // need the unclipped top/left for the translate
1191             c.translate(-SkIntToScalar(mask.fBounds.fLeft),
1192                         -SkIntToScalar(mask.fBounds.fTop));
1193             c.concat(*fMatrix);
1194
1195             // We can't call drawBitmap, or we'll infinitely recurse. Instead
1196             // we manually build a shader and draw that into our new mask
1197             SkPaint tmpPaint;
1198             tmpPaint.setFlags(paint.getFlags());
1199             SkAutoBitmapShaderInstall install(bitmap, tmpPaint);
1200             SkRect rr;
1201             rr.set(0, 0, SkIntToScalar(bitmap.width()),
1202                    SkIntToScalar(bitmap.height()));
1203             c.drawRect(rr, install.paintWithShader());
1204         }
1205         this->drawDevMask(mask, paint);
1206     }
1207 }
1208
1209 static bool clipped_out(const SkMatrix& m, const SkRasterClip& c,
1210                         const SkRect& srcR) {
1211     SkRect  dstR;
1212     SkIRect devIR;
1213
1214     m.mapRect(&dstR, srcR);
1215     dstR.roundOut(&devIR);
1216     return c.quickReject(devIR);
1217 }
1218
1219 static bool clipped_out(const SkMatrix& matrix, const SkRasterClip& clip,
1220                         int width, int height) {
1221     SkRect  r;
1222     r.set(0, 0, SkIntToScalar(width), SkIntToScalar(height));
1223     return clipped_out(matrix, clip, r);
1224 }
1225
1226 static bool clipHandlesSprite(const SkRasterClip& clip, int x, int y,
1227                               const SkBitmap& bitmap) {
1228     return clip.isBW() ||
1229            clip.quickContains(x, y, x + bitmap.width(), y + bitmap.height());
1230 }
1231
1232 void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
1233                         const SkPaint& origPaint) const {
1234     SkDEBUGCODE(this->validate();)
1235
1236     // nothing to draw
1237     if (fRC->isEmpty() ||
1238             bitmap.width() == 0 || bitmap.height() == 0 ||
1239             bitmap.colorType() == kUnknown_SkColorType) {
1240         return;
1241     }
1242
1243     SkPaint paint(origPaint);
1244     paint.setStyle(SkPaint::kFill_Style);
1245
1246     SkMatrix matrix;
1247     matrix.setConcat(*fMatrix, prematrix);
1248
1249     if (clipped_out(matrix, *fRC, bitmap.width(), bitmap.height())) {
1250         return;
1251     }
1252
1253     if (bitmap.colorType() != kAlpha_8_SkColorType && just_translate(matrix, bitmap)) {
1254         //
1255         // It is safe to call lock pixels now, since we know the matrix is
1256         // (more or less) identity.
1257         //
1258         SkAutoLockPixels alp(bitmap);
1259         if (!bitmap.readyToDraw()) {
1260             return;
1261         }
1262         int ix = SkScalarRoundToInt(matrix.getTranslateX());
1263         int iy = SkScalarRoundToInt(matrix.getTranslateY());
1264         if (clipHandlesSprite(*fRC, ix, iy, bitmap)) {
1265             SkTBlitterAllocator allocator;
1266             // blitter will be owned by the allocator.
1267             SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap,
1268                                                          ix, iy, &allocator);
1269             if (blitter) {
1270                 SkIRect    ir;
1271                 ir.set(ix, iy, ix + bitmap.width(), iy + bitmap.height());
1272
1273                 SkScan::FillIRect(ir, *fRC, blitter);
1274                 return;
1275             }
1276         }
1277     }
1278
1279     // now make a temp draw on the stack, and use it
1280     //
1281     SkDraw draw(*this);
1282     draw.fMatrix = &matrix;
1283
1284     if (bitmap.colorType() == kAlpha_8_SkColorType) {
1285         draw.drawBitmapAsMask(bitmap, paint);
1286     } else {
1287         SkAutoBitmapShaderInstall install(bitmap, paint);
1288
1289         SkRect  r;
1290         r.set(0, 0, SkIntToScalar(bitmap.width()),
1291               SkIntToScalar(bitmap.height()));
1292         // is this ok if paint has a rasterizer?
1293         draw.drawRect(r, install.paintWithShader());
1294     }
1295 }
1296
1297 void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y,
1298                         const SkPaint& origPaint) const {
1299     SkDEBUGCODE(this->validate();)
1300
1301     // nothing to draw
1302     if (fRC->isEmpty() ||
1303             bitmap.width() == 0 || bitmap.height() == 0 ||
1304             bitmap.colorType() == kUnknown_SkColorType) {
1305         return;
1306     }
1307
1308     SkIRect    bounds;
1309     bounds.set(x, y, x + bitmap.width(), y + bitmap.height());
1310
1311     if (fRC->quickReject(bounds)) {
1312         return; // nothing to draw
1313     }
1314
1315     SkPaint paint(origPaint);
1316     paint.setStyle(SkPaint::kFill_Style);
1317
1318     if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, bitmap)) {
1319         SkTBlitterAllocator allocator;
1320         // blitter will be owned by the allocator.
1321         SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap,
1322                                                      x, y, &allocator);
1323
1324         if (blitter) {
1325             SkScan::FillIRect(bounds, *fRC, blitter);
1326             return;
1327         }
1328     }
1329
1330     SkMatrix        matrix;
1331     SkRect          r;
1332
1333     // get a scalar version of our rect
1334     r.set(bounds);
1335
1336     // create shader with offset
1337     matrix.setTranslate(r.fLeft, r.fTop);
1338     SkAutoBitmapShaderInstall install(bitmap, paint, &matrix);
1339     const SkPaint& shaderPaint = install.paintWithShader();
1340
1341     SkDraw draw(*this);
1342     matrix.reset();
1343     draw.fMatrix = &matrix;
1344     // call ourself with a rect
1345     // is this OK if paint has a rasterizer?
1346     draw.drawRect(r, shaderPaint);
1347 }
1348
1349 ///////////////////////////////////////////////////////////////////////////////
1350
1351 #include "SkScalerContext.h"
1352 #include "SkGlyphCache.h"
1353 #include "SkTextToPathIter.h"
1354 #include "SkUtils.h"
1355
1356 static void measure_text(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
1357                 const char text[], size_t byteLength, SkVector* stopVector) {
1358     SkFixed     x = 0, y = 0;
1359     const char* stop = text + byteLength;
1360
1361     SkAutoKern  autokern;
1362
1363     while (text < stop) {
1364         // don't need x, y here, since all subpixel variants will have the
1365         // same advance
1366         const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1367
1368         x += autokern.adjust(glyph) + glyph.fAdvanceX;
1369         y += glyph.fAdvanceY;
1370     }
1371     stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y));
1372
1373     SkASSERT(text == stop);
1374 }
1375
1376 bool SkDraw::ShouldDrawTextAsPaths(const SkPaint& paint, const SkMatrix& ctm) {
1377     // hairline glyphs are fast enough so we don't need to cache them
1378     if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) {
1379         return true;
1380     }
1381
1382     // we don't cache perspective
1383     if (ctm.hasPerspective()) {
1384         return true;
1385     }
1386
1387     SkMatrix textM;
1388     return SkPaint::TooBigToUseCache(ctm, *paint.setTextMatrix(&textM));
1389 }
1390
1391 void SkDraw::drawText_asPaths(const char text[], size_t byteLength,
1392                               SkScalar x, SkScalar y,
1393                               const SkPaint& paint) const {
1394     SkDEBUGCODE(this->validate();)
1395
1396     SkTextToPathIter iter(text, byteLength, paint, true);
1397
1398     SkMatrix    matrix;
1399     matrix.setScale(iter.getPathScale(), iter.getPathScale());
1400     matrix.postTranslate(x, y);
1401
1402     const SkPath* iterPath;
1403     SkScalar xpos, prevXPos = 0;
1404
1405     while (iter.next(&iterPath, &xpos)) {
1406         matrix.postTranslate(xpos - prevXPos, 0);
1407         if (iterPath) {
1408             const SkPaint& pnt = iter.getPaint();
1409             if (fDevice) {
1410                 fDevice->drawPath(*this, *iterPath, pnt, &matrix, false);
1411             } else {
1412                 this->drawPath(*iterPath, pnt, &matrix, false);
1413             }
1414         }
1415         prevXPos = xpos;
1416     }
1417 }
1418
1419 // disable warning : local variable used without having been initialized
1420 #if defined _WIN32 && _MSC_VER >= 1300
1421 #pragma warning ( push )
1422 #pragma warning ( disable : 4701 )
1423 #endif
1424
1425 //////////////////////////////////////////////////////////////////////////////
1426
1427 static void D1G_RectClip(const SkDraw1Glyph& state, SkFixed fx, SkFixed fy, const SkGlyph& glyph) {
1428     int left = SkFixedFloorToInt(fx);
1429     int top = SkFixedFloorToInt(fy);
1430     SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);
1431     SkASSERT((NULL == state.fClip && state.fAAClip) ||
1432              (state.fClip && NULL == state.fAAClip && state.fClip->isRect()));
1433
1434     left += glyph.fLeft;
1435     top  += glyph.fTop;
1436
1437     int right   = left + glyph.fWidth;
1438     int bottom  = top + glyph.fHeight;
1439
1440     SkMask        mask;
1441     SkIRect        storage;
1442     SkIRect*    bounds = &mask.fBounds;
1443
1444     mask.fBounds.set(left, top, right, bottom);
1445
1446     // this extra test is worth it, assuming that most of the time it succeeds
1447     // since we can avoid writing to storage
1448     if (!state.fClipBounds.containsNoEmptyCheck(left, top, right, bottom)) {
1449         if (!storage.intersectNoEmptyCheck(mask.fBounds, state.fClipBounds))
1450             return;
1451         bounds = &storage;
1452     }
1453
1454     uint8_t* aa = (uint8_t*)glyph.fImage;
1455     if (NULL == aa) {
1456         aa = (uint8_t*)state.fCache->findImage(glyph);
1457         if (NULL == aa) {
1458             return; // can't rasterize glyph
1459         }
1460     }
1461
1462     mask.fRowBytes = glyph.rowBytes();
1463     mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
1464     mask.fImage = aa;
1465     state.blitMask(mask, *bounds);
1466 }
1467
1468 static void D1G_RgnClip(const SkDraw1Glyph& state, SkFixed fx, SkFixed fy, const SkGlyph& glyph) {
1469     int left = SkFixedFloorToInt(fx);
1470     int top = SkFixedFloorToInt(fy);
1471     SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);
1472     SkASSERT(!state.fClip->isRect());
1473
1474     SkMask  mask;
1475
1476     left += glyph.fLeft;
1477     top  += glyph.fTop;
1478
1479     mask.fBounds.set(left, top, left + glyph.fWidth, top + glyph.fHeight);
1480     SkRegion::Cliperator clipper(*state.fClip, mask.fBounds);
1481
1482     if (!clipper.done()) {
1483         const SkIRect&  cr = clipper.rect();
1484         const uint8_t*  aa = (const uint8_t*)glyph.fImage;
1485         if (NULL == aa) {
1486             aa = (uint8_t*)state.fCache->findImage(glyph);
1487             if (NULL == aa) {
1488                 return;
1489             }
1490         }
1491
1492         mask.fRowBytes = glyph.rowBytes();
1493         mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
1494         mask.fImage = (uint8_t*)aa;
1495         do {
1496             state.blitMask(mask, cr);
1497             clipper.next();
1498         } while (!clipper.done());
1499     }
1500 }
1501
1502 static bool hasCustomD1GProc(const SkDraw& draw) {
1503     return draw.fProcs && draw.fProcs->fD1GProc;
1504 }
1505
1506 static bool needsRasterTextBlit(const SkDraw& draw) {
1507     return !hasCustomD1GProc(draw);
1508 }
1509
1510 SkDraw1Glyph::Proc SkDraw1Glyph::init(const SkDraw* draw, SkBlitter* blitter, SkGlyphCache* cache,
1511                                       const SkPaint& pnt) {
1512     fDraw = draw;
1513     fBlitter = blitter;
1514     fCache = cache;
1515     fPaint = &pnt;
1516
1517     if (cache->isSubpixel()) {
1518         fHalfSampleX = fHalfSampleY = (SK_FixedHalf >> SkGlyph::kSubBits);
1519     } else {
1520         fHalfSampleX = fHalfSampleY = SK_FixedHalf;
1521     }
1522
1523     if (hasCustomD1GProc(*draw)) {
1524         // todo: fix this assumption about clips w/ custom
1525         fClip = draw->fClip;
1526         fClipBounds = fClip->getBounds();
1527         return draw->fProcs->fD1GProc;
1528     }
1529
1530     if (draw->fRC->isBW()) {
1531         fAAClip = NULL;
1532         fClip = &draw->fRC->bwRgn();
1533         fClipBounds = fClip->getBounds();
1534         if (fClip->isRect()) {
1535             return D1G_RectClip;
1536         } else {
1537             return D1G_RgnClip;
1538         }
1539     } else {    // aaclip
1540         fAAClip = &draw->fRC->aaRgn();
1541         fClip = NULL;
1542         fClipBounds = fAAClip->getBounds();
1543         return D1G_RectClip;
1544     }
1545 }
1546
1547 void SkDraw1Glyph::blitMaskAsSprite(const SkMask& mask) const {
1548     SkASSERT(SkMask::kARGB32_Format == mask.fFormat);
1549
1550     SkBitmap bm;
1551     bm.installPixels(SkImageInfo::MakeN32Premul(mask.fBounds.width(), mask.fBounds.height()),
1552                      (SkPMColor*)mask.fImage, mask.fRowBytes);
1553
1554     fDraw->drawSprite(bm, mask.fBounds.x(), mask.fBounds.y(), *fPaint);
1555 }
1556
1557 ///////////////////////////////////////////////////////////////////////////////
1558
1559 void SkDraw::drawText(const char text[], size_t byteLength,
1560                       SkScalar x, SkScalar y, const SkPaint& paint) const {
1561     SkASSERT(byteLength == 0 || text != NULL);
1562
1563     SkDEBUGCODE(this->validate();)
1564
1565     // nothing to draw
1566     if (text == NULL || byteLength == 0 || fRC->isEmpty()) {
1567         return;
1568     }
1569
1570     // SkScalarRec doesn't currently have a way of representing hairline stroke and
1571     // will fill if its frame-width is 0.
1572     if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
1573         this->drawText_asPaths(text, byteLength, x, y, paint);
1574         return;
1575     }
1576
1577     SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
1578
1579     SkAutoGlyphCache    autoCache(paint, &fDevice->getLeakyProperties(), fMatrix);
1580     SkGlyphCache*       cache = autoCache.getCache();
1581
1582     // transform our starting point
1583     {
1584         SkPoint loc;
1585         fMatrix->mapXY(x, y, &loc);
1586         x = loc.fX;
1587         y = loc.fY;
1588     }
1589
1590     // need to measure first
1591     if (paint.getTextAlign() != SkPaint::kLeft_Align) {
1592         SkVector    stop;
1593
1594         measure_text(cache, glyphCacheProc, text, byteLength, &stop);
1595
1596         SkScalar    stopX = stop.fX;
1597         SkScalar    stopY = stop.fY;
1598
1599         if (paint.getTextAlign() == SkPaint::kCenter_Align) {
1600             stopX = SkScalarHalf(stopX);
1601             stopY = SkScalarHalf(stopY);
1602         }
1603         x -= stopX;
1604         y -= stopY;
1605     }
1606
1607     const char* stop = text + byteLength;
1608
1609     SkAAClipBlitter     aaBlitter;
1610     SkAutoBlitterChoose blitterChooser;
1611     SkBlitter*          blitter = NULL;
1612     if (needsRasterTextBlit(*this)) {
1613         blitterChooser.choose(*fBitmap, *fMatrix, paint);
1614         blitter = blitterChooser.get();
1615         if (fRC->isAA()) {
1616             aaBlitter.init(blitter, &fRC->aaRgn());
1617             blitter = &aaBlitter;
1618         }
1619     }
1620
1621     SkAutoKern          autokern;
1622     SkDraw1Glyph        d1g;
1623     SkDraw1Glyph::Proc  proc = d1g.init(this, blitter, cache, paint);
1624
1625     SkFixed fxMask = ~0;
1626     SkFixed fyMask = ~0;
1627     if (cache->isSubpixel()) {
1628         SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix);
1629         if (kX_SkAxisAlignment == baseline) {
1630             fyMask = 0;
1631             d1g.fHalfSampleY = SK_FixedHalf;
1632         } else if (kY_SkAxisAlignment == baseline) {
1633             fxMask = 0;
1634             d1g.fHalfSampleX = SK_FixedHalf;
1635         }
1636     }
1637
1638     SkFixed fx = SkScalarToFixed(x) + d1g.fHalfSampleX;
1639     SkFixed fy = SkScalarToFixed(y) + d1g.fHalfSampleY;
1640
1641     while (text < stop) {
1642         const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask);
1643
1644         fx += autokern.adjust(glyph);
1645
1646         if (glyph.fWidth) {
1647             proc(d1g, fx, fy, glyph);
1648         }
1649
1650         fx += glyph.fAdvanceX;
1651         fy += glyph.fAdvanceY;
1652     }
1653 }
1654
1655 //////////////////////////////////////////////////////////////////////////////
1656
1657 void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength,
1658                                  const SkScalar pos[], SkScalar constY,
1659                                  int scalarsPerPosition,
1660                                  const SkPaint& origPaint) const {
1661     // setup our std paint, in hopes of getting hits in the cache
1662     SkPaint paint(origPaint);
1663     SkScalar matrixScale = paint.setupForAsPaths();
1664
1665     SkMatrix matrix;
1666     matrix.setScale(matrixScale, matrixScale);
1667
1668     // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache.
1669     paint.setStyle(SkPaint::kFill_Style);
1670     paint.setPathEffect(NULL);
1671
1672     SkDrawCacheProc     glyphCacheProc = paint.getDrawCacheProc();
1673     SkAutoGlyphCache    autoCache(paint, NULL, NULL);
1674     SkGlyphCache*       cache = autoCache.getCache();
1675
1676     const char*        stop = text + byteLength;
1677     SkTextAlignProcScalar alignProc(paint.getTextAlign());
1678     SkTextMapStateProc tmsProc(SkMatrix::I(), constY, scalarsPerPosition);
1679
1680     // Now restore the original settings, so we "draw" with whatever style/stroking.
1681     paint.setStyle(origPaint.getStyle());
1682     paint.setPathEffect(origPaint.getPathEffect());
1683
1684     while (text < stop) {
1685         const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1686         if (glyph.fWidth) {
1687             const SkPath* path = cache->findPath(glyph);
1688             if (path) {
1689                 SkPoint tmsLoc;
1690                 tmsProc(pos, &tmsLoc);
1691                 SkPoint loc;
1692                 alignProc(tmsLoc, glyph, &loc);
1693
1694                 matrix[SkMatrix::kMTransX] = loc.fX;
1695                 matrix[SkMatrix::kMTransY] = loc.fY;
1696                 if (fDevice) {
1697                     fDevice->drawPath(*this, *path, paint, &matrix, false);
1698                 } else {
1699                     this->drawPath(*path, paint, &matrix, false);
1700                 }
1701             }
1702         }
1703         pos += scalarsPerPosition;
1704     }
1705 }
1706
1707 void SkDraw::drawPosText(const char text[], size_t byteLength,
1708                          const SkScalar pos[], SkScalar constY,
1709                          int scalarsPerPosition, const SkPaint& paint) const {
1710     SkASSERT(byteLength == 0 || text != NULL);
1711     SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
1712
1713     SkDEBUGCODE(this->validate();)
1714
1715     // nothing to draw
1716     if (text == NULL || byteLength == 0 || fRC->isEmpty()) {
1717         return;
1718     }
1719
1720     if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
1721         this->drawPosText_asPaths(text, byteLength, pos, constY,
1722                                   scalarsPerPosition, paint);
1723         return;
1724     }
1725
1726     SkDrawCacheProc     glyphCacheProc = paint.getDrawCacheProc();
1727     SkAutoGlyphCache    autoCache(paint, &fDevice->getLeakyProperties(), fMatrix);
1728     SkGlyphCache*       cache = autoCache.getCache();
1729
1730     SkAAClipBlitterWrapper wrapper;
1731     SkAutoBlitterChoose blitterChooser;
1732     SkBlitter* blitter = NULL;
1733     if (needsRasterTextBlit(*this)) {
1734         blitterChooser.choose(*fBitmap, *fMatrix, paint);
1735         blitter = blitterChooser.get();
1736         if (fRC->isAA()) {
1737             wrapper.init(*fRC, blitter);
1738             blitter = wrapper.getBlitter();
1739         }
1740     }
1741
1742     const char*        stop = text + byteLength;
1743     SkTextAlignProc    alignProc(paint.getTextAlign());
1744     SkDraw1Glyph       d1g;
1745     SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint);
1746     SkTextMapStateProc tmsProc(*fMatrix, constY, scalarsPerPosition);
1747
1748     if (cache->isSubpixel()) {
1749         // maybe we should skip the rounding if linearText is set
1750         SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix);
1751
1752         SkFixed fxMask = ~0;
1753         SkFixed fyMask = ~0;
1754         if (kX_SkAxisAlignment == baseline) {
1755             fyMask = 0;
1756 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
1757             d1g.fHalfSampleY = SK_FixedHalf;
1758 #endif
1759         } else if (kY_SkAxisAlignment == baseline) {
1760             fxMask = 0;
1761 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
1762             d1g.fHalfSampleX = SK_FixedHalf;
1763 #endif
1764         }
1765
1766         if (SkPaint::kLeft_Align == paint.getTextAlign()) {
1767             while (text < stop) {
1768                 SkPoint tmsLoc;
1769                 tmsProc(pos, &tmsLoc);
1770                 SkFixed fx = SkScalarToFixed(tmsLoc.fX) + d1g.fHalfSampleX;
1771                 SkFixed fy = SkScalarToFixed(tmsLoc.fY) + d1g.fHalfSampleY;
1772
1773                 const SkGlyph& glyph = glyphCacheProc(cache, &text,
1774                                                       fx & fxMask, fy & fyMask);
1775
1776                 if (glyph.fWidth) {
1777                     proc(d1g, fx, fy, glyph);
1778                 }
1779                 pos += scalarsPerPosition;
1780             }
1781         } else {
1782             while (text < stop) {
1783                 const char* currentText = text;
1784                 const SkGlyph& metricGlyph = glyphCacheProc(cache, &text, 0, 0);
1785
1786                 if (metricGlyph.fWidth) {
1787                     SkDEBUGCODE(SkFixed prevAdvX = metricGlyph.fAdvanceX;)
1788                     SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;)
1789                     SkPoint tmsLoc;
1790                     tmsProc(pos, &tmsLoc);
1791                     SkIPoint fixedLoc;
1792                     alignProc(tmsLoc, metricGlyph, &fixedLoc);
1793
1794                     SkFixed fx = fixedLoc.fX + d1g.fHalfSampleX;
1795                     SkFixed fy = fixedLoc.fY + d1g.fHalfSampleY;
1796
1797                     // have to call again, now that we've been "aligned"
1798                     const SkGlyph& glyph = glyphCacheProc(cache, &currentText,
1799                                                           fx & fxMask, fy & fyMask);
1800                     // the assumption is that the metrics haven't changed
1801                     SkASSERT(prevAdvX == glyph.fAdvanceX);
1802                     SkASSERT(prevAdvY == glyph.fAdvanceY);
1803                     SkASSERT(glyph.fWidth);
1804
1805                     proc(d1g, fx, fy, glyph);
1806                 }
1807                 pos += scalarsPerPosition;
1808             }
1809         }
1810     } else {    // not subpixel
1811         if (SkPaint::kLeft_Align == paint.getTextAlign()) {
1812             while (text < stop) {
1813                 // the last 2 parameters are ignored
1814                 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1815
1816                 if (glyph.fWidth) {
1817                     SkPoint tmsLoc;
1818                     tmsProc(pos, &tmsLoc);
1819
1820                     proc(d1g,
1821                          SkScalarToFixed(tmsLoc.fX) + SK_FixedHalf, //d1g.fHalfSampleX,
1822                          SkScalarToFixed(tmsLoc.fY) + SK_FixedHalf, //d1g.fHalfSampleY,
1823                          glyph);
1824                 }
1825                 pos += scalarsPerPosition;
1826             }
1827         } else {
1828             while (text < stop) {
1829                 // the last 2 parameters are ignored
1830                 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1831
1832                 if (glyph.fWidth) {
1833                     SkPoint tmsLoc;
1834                     tmsProc(pos, &tmsLoc);
1835
1836                     SkIPoint fixedLoc;
1837                     alignProc(tmsLoc, glyph, &fixedLoc);
1838
1839                     proc(d1g,
1840                          fixedLoc.fX + SK_FixedHalf, //d1g.fHalfSampleX,
1841                          fixedLoc.fY + SK_FixedHalf, //d1g.fHalfSampleY,
1842                          glyph);
1843                 }
1844                 pos += scalarsPerPosition;
1845             }
1846         }
1847     }
1848 }
1849
1850 #if defined _WIN32 && _MSC_VER >= 1300
1851 #pragma warning ( pop )
1852 #endif
1853
1854 ///////////////////////////////////////////////////////////////////////////////
1855
1856 #include "SkPathMeasure.h"
1857
1858 static void morphpoints(SkPoint dst[], const SkPoint src[], int count,
1859                         SkPathMeasure& meas, const SkMatrix& matrix) {
1860     SkMatrix::MapXYProc proc = matrix.getMapXYProc();
1861
1862     for (int i = 0; i < count; i++) {
1863         SkPoint pos;
1864         SkVector tangent;
1865
1866         proc(matrix, src[i].fX, src[i].fY, &pos);
1867         SkScalar sx = pos.fX;
1868         SkScalar sy = pos.fY;
1869
1870         if (!meas.getPosTan(sx, &pos, &tangent)) {
1871             // set to 0 if the measure failed, so that we just set dst == pos
1872             tangent.set(0, 0);
1873         }
1874
1875         /*  This is the old way (that explains our approach but is way too slow
1876             SkMatrix    matrix;
1877             SkPoint     pt;
1878
1879             pt.set(sx, sy);
1880             matrix.setSinCos(tangent.fY, tangent.fX);
1881             matrix.preTranslate(-sx, 0);
1882             matrix.postTranslate(pos.fX, pos.fY);
1883             matrix.mapPoints(&dst[i], &pt, 1);
1884         */
1885         dst[i].set(pos.fX - SkScalarMul(tangent.fY, sy),
1886                    pos.fY + SkScalarMul(tangent.fX, sy));
1887     }
1888 }
1889
1890 /*  TODO
1891
1892     Need differentially more subdivisions when the follow-path is curvy. Not sure how to
1893     determine that, but we need it. I guess a cheap answer is let the caller tell us,
1894     but that seems like a cop-out. Another answer is to get Rob Johnson to figure it out.
1895 */
1896 static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas,
1897                       const SkMatrix& matrix) {
1898     SkPath::Iter    iter(src, false);
1899     SkPoint         srcP[4], dstP[3];
1900     SkPath::Verb    verb;
1901
1902     while ((verb = iter.next(srcP)) != SkPath::kDone_Verb) {
1903         switch (verb) {
1904             case SkPath::kMove_Verb:
1905                 morphpoints(dstP, srcP, 1, meas, matrix);
1906                 dst->moveTo(dstP[0]);
1907                 break;
1908             case SkPath::kLine_Verb:
1909                 // turn lines into quads to look bendy
1910                 srcP[0].fX = SkScalarAve(srcP[0].fX, srcP[1].fX);
1911                 srcP[0].fY = SkScalarAve(srcP[0].fY, srcP[1].fY);
1912                 morphpoints(dstP, srcP, 2, meas, matrix);
1913                 dst->quadTo(dstP[0], dstP[1]);
1914                 break;
1915             case SkPath::kQuad_Verb:
1916                 morphpoints(dstP, &srcP[1], 2, meas, matrix);
1917                 dst->quadTo(dstP[0], dstP[1]);
1918                 break;
1919             case SkPath::kCubic_Verb:
1920                 morphpoints(dstP, &srcP[1], 3, meas, matrix);
1921                 dst->cubicTo(dstP[0], dstP[1], dstP[2]);
1922                 break;
1923             case SkPath::kClose_Verb:
1924                 dst->close();
1925                 break;
1926             default:
1927                 SkDEBUGFAIL("unknown verb");
1928                 break;
1929         }
1930     }
1931 }
1932
1933 void SkDraw::drawTextOnPath(const char text[], size_t byteLength,
1934                             const SkPath& follow, const SkMatrix* matrix,
1935                             const SkPaint& paint) const {
1936     SkASSERT(byteLength == 0 || text != NULL);
1937
1938     // nothing to draw
1939     if (text == NULL || byteLength == 0 || fRC->isEmpty()) {
1940         return;
1941     }
1942
1943     SkTextToPathIter    iter(text, byteLength, paint, true);
1944     SkPathMeasure       meas(follow, false);
1945     SkScalar            hOffset = 0;
1946
1947     // need to measure first
1948     if (paint.getTextAlign() != SkPaint::kLeft_Align) {
1949         SkScalar pathLen = meas.getLength();
1950         if (paint.getTextAlign() == SkPaint::kCenter_Align) {
1951             pathLen = SkScalarHalf(pathLen);
1952         }
1953         hOffset += pathLen;
1954     }
1955
1956     const SkPath*   iterPath;
1957     SkScalar        xpos;
1958     SkMatrix        scaledMatrix;
1959     SkScalar        scale = iter.getPathScale();
1960
1961     scaledMatrix.setScale(scale, scale);
1962
1963     while (iter.next(&iterPath, &xpos)) {
1964         if (iterPath) {
1965             SkPath      tmp;
1966             SkMatrix    m(scaledMatrix);
1967
1968             m.postTranslate(xpos + hOffset, 0);
1969             if (matrix) {
1970                 m.postConcat(*matrix);
1971             }
1972             morphpath(&tmp, *iterPath, meas, m);
1973             if (fDevice) {
1974                 fDevice->drawPath(*this, tmp, iter.getPaint(), NULL, true);
1975             } else {
1976                 this->drawPath(tmp, iter.getPaint(), NULL, true);
1977             }
1978         }
1979     }
1980 }
1981
1982 ///////////////////////////////////////////////////////////////////////////////
1983
1984 typedef void (*HairProc)(const SkPoint&, const SkPoint&, const SkRasterClip&,
1985                          SkBlitter*);
1986
1987 static HairProc ChooseHairProc(bool doAntiAlias) {
1988     return doAntiAlias ? SkScan::AntiHairLine : SkScan::HairLine;
1989 }
1990
1991 static bool texture_to_matrix(const VertState& state, const SkPoint verts[],
1992                               const SkPoint texs[], SkMatrix* matrix) {
1993     SkPoint src[3], dst[3];
1994
1995     src[0] = texs[state.f0];
1996     src[1] = texs[state.f1];
1997     src[2] = texs[state.f2];
1998     dst[0] = verts[state.f0];
1999     dst[1] = verts[state.f1];
2000     dst[2] = verts[state.f2];
2001     return matrix->setPolyToPoly(src, dst, 3);
2002 }
2003
2004 class SkTriColorShader : public SkShader {
2005 public:
2006     SkTriColorShader() {}
2007
2008     virtual size_t contextSize() const SK_OVERRIDE;
2009
2010     class TriColorShaderContext : public SkShader::Context {
2011     public:
2012         TriColorShaderContext(const SkTriColorShader& shader, const ContextRec&);
2013         virtual ~TriColorShaderContext();
2014
2015         bool setup(const SkPoint pts[], const SkColor colors[], int, int, int);
2016
2017         virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
2018
2019     private:
2020         SkMatrix    fDstToUnit;
2021         SkPMColor   fColors[3];
2022
2023         typedef SkShader::Context INHERITED;
2024     };
2025
2026     SK_TO_STRING_OVERRIDE()
2027     SK_DECLARE_NOT_FLATTENABLE_PROCS(SkTriColorShader)
2028
2029 protected:
2030     virtual Context* onCreateContext(const ContextRec& rec, void* storage) const SK_OVERRIDE {
2031         return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, rec));
2032     }
2033
2034 private:
2035     typedef SkShader INHERITED;
2036 };
2037
2038 bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const SkColor colors[],
2039                                                     int index0, int index1, int index2) {
2040
2041     fColors[0] = SkPreMultiplyColor(colors[index0]);
2042     fColors[1] = SkPreMultiplyColor(colors[index1]);
2043     fColors[2] = SkPreMultiplyColor(colors[index2]);
2044
2045     SkMatrix m, im;
2046     m.reset();
2047     m.set(0, pts[index1].fX - pts[index0].fX);
2048     m.set(1, pts[index2].fX - pts[index0].fX);
2049     m.set(2, pts[index0].fX);
2050     m.set(3, pts[index1].fY - pts[index0].fY);
2051     m.set(4, pts[index2].fY - pts[index0].fY);
2052     m.set(5, pts[index0].fY);
2053     if (!m.invert(&im)) {
2054         return false;
2055     }
2056     // We can't call getTotalInverse(), because we explicitly don't want to look at the localmatrix
2057     // as our interators are intrinsically tied to the vertices, and nothing else.
2058     SkMatrix ctmInv;
2059     if (!this->getCTM().invert(&ctmInv)) {
2060         return false;
2061     }
2062     fDstToUnit.setConcat(im, ctmInv);
2063     return true;
2064 }
2065
2066 #include "SkColorPriv.h"
2067 #include "SkComposeShader.h"
2068
2069 static int ScalarTo256(SkScalar v) {
2070     int scale = SkScalarToFixed(v) >> 8;
2071     if (scale < 0) {
2072         scale = 0;
2073     }
2074     if (scale > 255) {
2075         scale = 255;
2076     }
2077     return SkAlpha255To256(scale);
2078 }
2079
2080
2081 SkTriColorShader::TriColorShaderContext::TriColorShaderContext(const SkTriColorShader& shader,
2082                                                                const ContextRec& rec)
2083     : INHERITED(shader, rec) {}
2084
2085 SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {}
2086
2087 size_t SkTriColorShader::contextSize() const {
2088     return sizeof(TriColorShaderContext);
2089 }
2090 void SkTriColorShader::TriColorShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
2091     const int alphaScale = Sk255To256(this->getPaintAlpha());
2092
2093     SkPoint src;
2094
2095     for (int i = 0; i < count; i++) {
2096         fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src);
2097         x += 1;
2098
2099         int scale1 = ScalarTo256(src.fX);
2100         int scale2 = ScalarTo256(src.fY);
2101         int scale0 = 256 - scale1 - scale2;
2102         if (scale0 < 0) {
2103             if (scale1 > scale2) {
2104                 scale2 = 256 - scale1;
2105             } else {
2106                 scale1 = 256 - scale2;
2107             }
2108             scale0 = 0;
2109         }
2110
2111         if (256 != alphaScale) {
2112             scale0 = SkAlphaMul(scale0, alphaScale);
2113             scale1 = SkAlphaMul(scale1, alphaScale);
2114             scale2 = SkAlphaMul(scale2, alphaScale);
2115         }
2116
2117         dstC[i] = SkAlphaMulQ(fColors[0], scale0) +
2118                   SkAlphaMulQ(fColors[1], scale1) +
2119                   SkAlphaMulQ(fColors[2], scale2);
2120     }
2121 }
2122
2123 #ifndef SK_IGNORE_TO_STRING
2124 void SkTriColorShader::toString(SkString* str) const {
2125     str->append("SkTriColorShader: (");
2126
2127     this->INHERITED::toString(str);
2128
2129     str->append(")");
2130 }
2131 #endif
2132
2133 void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
2134                           const SkPoint vertices[], const SkPoint textures[],
2135                           const SkColor colors[], SkXfermode* xmode,
2136                           const uint16_t indices[], int indexCount,
2137                           const SkPaint& paint) const {
2138     SkASSERT(0 == count || vertices);
2139
2140     // abort early if there is nothing to draw
2141     if (count < 3 || (indices && indexCount < 3) || fRC->isEmpty()) {
2142         return;
2143     }
2144
2145     // transform out vertices into device coordinates
2146     SkAutoSTMalloc<16, SkPoint> storage(count);
2147     SkPoint* devVerts = storage.get();
2148     fMatrix->mapPoints(devVerts, vertices, count);
2149
2150     /*
2151         We can draw the vertices in 1 of 4 ways:
2152
2153         - solid color (no shader/texture[], no colors[])
2154         - just colors (no shader/texture[], has colors[])
2155         - just texture (has shader/texture[], no colors[])
2156         - colors * texture (has shader/texture[], has colors[])
2157
2158         Thus for texture drawing, we need both texture[] and a shader.
2159     */
2160
2161     SkTriColorShader triShader; // must be above declaration of p
2162     SkPaint p(paint);
2163
2164     SkShader* shader = p.getShader();
2165     if (NULL == shader) {
2166         // if we have no shader, we ignore the texture coordinates
2167         textures = NULL;
2168     } else if (NULL == textures) {
2169         // if we don't have texture coordinates, ignore the shader
2170         p.setShader(NULL);
2171         shader = NULL;
2172     }
2173
2174     // setup the custom shader (if needed)
2175     SkAutoTUnref<SkComposeShader> composeShader;
2176     if (colors) {
2177         if (NULL == textures) {
2178             // just colors (no texture)
2179             shader = p.setShader(&triShader);
2180         } else {
2181             // colors * texture
2182             SkASSERT(shader);
2183             bool releaseMode = false;
2184             if (NULL == xmode) {
2185                 xmode = SkXfermode::Create(SkXfermode::kModulate_Mode);
2186                 releaseMode = true;
2187             }
2188             composeShader.reset(SkNEW_ARGS(SkComposeShader, (&triShader, shader, xmode)));
2189             p.setShader(composeShader);
2190             if (releaseMode) {
2191                 xmode->unref();
2192             }
2193         }
2194     }
2195
2196     SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p);
2197     // Abort early if we failed to create a shader context.
2198     if (blitter->isNullBlitter()) {
2199         return;
2200     }
2201
2202     // setup our state and function pointer for iterating triangles
2203     VertState       state(count, indices, indexCount);
2204     VertState::Proc vertProc = state.chooseProc(vmode);
2205
2206     if (textures || colors) {
2207         while (vertProc(&state)) {
2208             if (textures) {
2209                 SkMatrix tempM;
2210                 if (texture_to_matrix(state, vertices, textures, &tempM)) {
2211                     SkShader::ContextRec rec(*fBitmap, p, *fMatrix);
2212                     rec.fLocalMatrix = &tempM;
2213                     if (!blitter->resetShaderContext(rec)) {
2214                         continue;
2215                     }
2216                 }
2217             }
2218             if (colors) {
2219                 // Find the context for triShader.
2220                 SkTriColorShader::TriColorShaderContext* triColorShaderContext;
2221
2222                 SkShader::Context* shaderContext = blitter->getShaderContext();
2223                 SkASSERT(shaderContext);
2224                 if (p.getShader() == &triShader) {
2225                     triColorShaderContext =
2226                             static_cast<SkTriColorShader::TriColorShaderContext*>(shaderContext);
2227                 } else {
2228                     // The shader is a compose shader and triShader is its first shader.
2229                     SkASSERT(p.getShader() == composeShader);
2230                     SkASSERT(composeShader->getShaderA() == &triShader);
2231                     SkComposeShader::ComposeShaderContext* composeShaderContext =
2232                             static_cast<SkComposeShader::ComposeShaderContext*>(shaderContext);
2233                     SkShader::Context* shaderContextA = composeShaderContext->getShaderContextA();
2234                     triColorShaderContext =
2235                             static_cast<SkTriColorShader::TriColorShaderContext*>(shaderContextA);
2236                 }
2237
2238                 if (!triColorShaderContext->setup(vertices, colors,
2239                                                   state.f0, state.f1, state.f2)) {
2240                     continue;
2241                 }
2242             }
2243
2244             SkPoint tmp[] = {
2245                 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2]
2246             };
2247             SkScan::FillTriangle(tmp, *fRC, blitter.get());
2248         }
2249     } else {
2250         // no colors[] and no texture, stroke hairlines with paint's color.
2251         HairProc hairProc = ChooseHairProc(paint.isAntiAlias());
2252         const SkRasterClip& clip = *fRC;
2253         while (vertProc(&state)) {
2254             hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get());
2255             hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get());
2256             hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get());
2257         }
2258     }
2259 }
2260
2261 ///////////////////////////////////////////////////////////////////////////////
2262 ///////////////////////////////////////////////////////////////////////////////
2263
2264 #ifdef SK_DEBUG
2265
2266 void SkDraw::validate() const {
2267     SkASSERT(fBitmap != NULL);
2268     SkASSERT(fMatrix != NULL);
2269     SkASSERT(fClip != NULL);
2270     SkASSERT(fRC != NULL);
2271
2272     const SkIRect&  cr = fRC->getBounds();
2273     SkIRect         br;
2274
2275     br.set(0, 0, fBitmap->width(), fBitmap->height());
2276     SkASSERT(cr.isEmpty() || br.contains(cr));
2277 }
2278
2279 #endif
2280
2281 ////////////////////////////////////////////////////////////////////////////////////////////////
2282
2283 #include "SkPath.h"
2284 #include "SkDraw.h"
2285 #include "SkRegion.h"
2286 #include "SkBlitter.h"
2287
2288 static bool compute_bounds(const SkPath& devPath, const SkIRect* clipBounds,
2289                        const SkMaskFilter* filter, const SkMatrix* filterMatrix,
2290                            SkIRect* bounds) {
2291     if (devPath.isEmpty()) {
2292         return false;
2293     }
2294
2295     //  init our bounds from the path
2296     {
2297         SkRect pathBounds = devPath.getBounds();
2298         pathBounds.inset(-SK_ScalarHalf, -SK_ScalarHalf);
2299         pathBounds.roundOut(bounds);
2300     }
2301
2302     SkIPoint margin = SkIPoint::Make(0, 0);
2303     if (filter) {
2304         SkASSERT(filterMatrix);
2305
2306         SkMask srcM, dstM;
2307
2308         srcM.fBounds = *bounds;
2309         srcM.fFormat = SkMask::kA8_Format;
2310         srcM.fImage = NULL;
2311         if (!filter->filterMask(&dstM, srcM, *filterMatrix, &margin)) {
2312             return false;
2313         }
2314     }
2315
2316     // (possibly) trim the bounds to reflect the clip
2317     // (plus whatever slop the filter needs)
2318     if (clipBounds) {
2319         SkIRect tmp = *clipBounds;
2320         // Ugh. Guard against gigantic margins from wacky filters. Without this
2321         // check we can request arbitrary amounts of slop beyond our visible
2322         // clip, and bring down the renderer (at least on finite RAM machines
2323         // like handsets, etc.). Need to balance this invented value between
2324         // quality of large filters like blurs, and the corresponding memory
2325         // requests.
2326         static const int MAX_MARGIN = 128;
2327         tmp.inset(-SkMin32(margin.fX, MAX_MARGIN),
2328                   -SkMin32(margin.fY, MAX_MARGIN));
2329         if (!bounds->intersect(tmp)) {
2330             return false;
2331         }
2332     }
2333
2334     return true;
2335 }
2336
2337 static void draw_into_mask(const SkMask& mask, const SkPath& devPath,
2338                            SkPaint::Style style) {
2339     SkBitmap        bm;
2340     SkDraw          draw;
2341     SkRasterClip    clip;
2342     SkMatrix        matrix;
2343     SkPaint         paint;
2344
2345     bm.installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), mask.fBounds.height()),
2346                      mask.fImage, mask.fRowBytes);
2347
2348     clip.setRect(SkIRect::MakeWH(mask.fBounds.width(), mask.fBounds.height()));
2349     matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
2350                         -SkIntToScalar(mask.fBounds.fTop));
2351
2352     draw.fBitmap    = &bm;
2353     draw.fRC        = &clip;
2354     draw.fClip      = &clip.bwRgn();
2355     draw.fMatrix    = &matrix;
2356     paint.setAntiAlias(true);
2357     paint.setStyle(style);
2358     draw.drawPath(devPath, paint);
2359 }
2360
2361 bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
2362                         const SkMaskFilter* filter, const SkMatrix* filterMatrix,
2363                         SkMask* mask, SkMask::CreateMode mode,
2364                         SkPaint::Style style) {
2365     if (SkMask::kJustRenderImage_CreateMode != mode) {
2366         if (!compute_bounds(devPath, clipBounds, filter, filterMatrix, &mask->fBounds))
2367             return false;
2368     }
2369
2370     if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) {
2371         mask->fFormat = SkMask::kA8_Format;
2372         mask->fRowBytes = mask->fBounds.width();
2373         size_t size = mask->computeImageSize();
2374         if (0 == size) {
2375             // we're too big to allocate the mask, abort
2376             return false;
2377         }
2378         mask->fImage = SkMask::AllocImage(size);
2379         memset(mask->fImage, 0, mask->computeImageSize());
2380     }
2381
2382     if (SkMask::kJustComputeBounds_CreateMode != mode) {
2383         draw_into_mask(*mask, devPath, style);
2384     }
2385
2386     return true;
2387 }