Upstream version 11.40.277.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->isScaleTranslate() && 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                         path.setIsVolatile((count-1) == i);
605                         if (fDevice) {
606                             fDevice->drawPath(*this, path, newPaint, &preMatrix,
607                                               (count-1) == i);
608                         } else {
609                             this->drawPath(path, newPaint, &preMatrix,
610                                            (count-1) == i);
611                         }
612                     }
613                 } else {
614                     SkRect  r;
615
616                     for (size_t i = 0; i < count; i++) {
617                         r.fLeft = pts[i].fX - radius;
618                         r.fTop = pts[i].fY - radius;
619                         r.fRight = r.fLeft + width;
620                         r.fBottom = r.fTop + width;
621                         if (fDevice) {
622                             fDevice->drawRect(*this, r, newPaint);
623                         } else {
624                             this->drawRect(r, newPaint);
625                         }
626                     }
627                 }
628                 break;
629             }
630             case SkCanvas::kLines_PointMode:
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                 // couldn't take fast path so fall through!
715             case SkCanvas::kPolygon_PointMode: {
716                 count -= 1;
717                 SkPath path;
718                 SkPaint p(paint);
719                 p.setStyle(SkPaint::kStroke_Style);
720                 size_t inc = (SkCanvas::kLines_PointMode == mode) ? 2 : 1;
721                 path.setIsVolatile(true);
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     tmpPath.setIsVolatile(true);
1015
1016     if (prePathMatrix) {
1017         if (origPaint.getPathEffect() || origPaint.getStyle() != SkPaint::kFill_Style ||
1018                 origPaint.getRasterizer()) {
1019             SkPath* result = pathPtr;
1020
1021             if (!pathIsMutable) {
1022                 result = &tmpPath;
1023                 pathIsMutable = true;
1024             }
1025             pathPtr->transform(*prePathMatrix, result);
1026             pathPtr = result;
1027         } else {
1028             tmpMatrix.setConcat(*matrix, *prePathMatrix);
1029             matrix = &tmpMatrix;
1030         }
1031     }
1032     // at this point we're done with prePathMatrix
1033     SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
1034
1035     SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
1036
1037     {
1038         SkScalar coverage;
1039         if (SkDrawTreatAsHairline(origPaint, *matrix, &coverage)) {
1040             if (SK_Scalar1 == coverage) {
1041                 paint.writable()->setStrokeWidth(0);
1042             } else if (xfermodeSupportsCoverageAsAlpha(origPaint.getXfermode())) {
1043                 U8CPU newAlpha;
1044 #if 0
1045                 newAlpha = SkToU8(SkScalarRoundToInt(coverage *
1046                                                      origPaint.getAlpha()));
1047 #else
1048                 // this is the old technique, which we preserve for now so
1049                 // we don't change previous results (testing)
1050                 // the new way seems fine, its just (a tiny bit) different
1051                 int scale = (int)SkScalarMul(coverage, 256);
1052                 newAlpha = origPaint.getAlpha() * scale >> 8;
1053 #endif
1054                 SkPaint* writablePaint = paint.writable();
1055                 writablePaint->setStrokeWidth(0);
1056                 writablePaint->setAlpha(newAlpha);
1057             }
1058         }
1059     }
1060
1061     if (paint->getPathEffect() || paint->getStyle() != SkPaint::kFill_Style) {
1062         SkRect cullRect;
1063         const SkRect* cullRectPtr = NULL;
1064         if (this->computeConservativeLocalClipBounds(&cullRect)) {
1065             cullRectPtr = &cullRect;
1066         }
1067         doFill = paint->getFillPath(*pathPtr, &tmpPath, cullRectPtr);
1068         pathPtr = &tmpPath;
1069     }
1070
1071     if (paint->getRasterizer()) {
1072         SkMask  mask;
1073         if (paint->getRasterizer()->rasterize(*pathPtr, *matrix,
1074                             &fRC->getBounds(), paint->getMaskFilter(), &mask,
1075                             SkMask::kComputeBoundsAndRenderImage_CreateMode)) {
1076             this->drawDevMask(mask, *paint);
1077             SkMask::FreeImage(mask.fImage);
1078         }
1079         return;
1080     }
1081
1082     // avoid possibly allocating a new path in transform if we can
1083     SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath;
1084
1085     // transform the path into device space
1086     pathPtr->transform(*matrix, devPathPtr);
1087
1088     SkBlitter* blitter = NULL;
1089     SkAutoBlitterChoose blitterStorage;
1090     if (NULL == customBlitter) {
1091         blitterStorage.choose(*fBitmap, *fMatrix, *paint, drawCoverage);
1092         blitter = blitterStorage.get();
1093     } else {
1094         blitter = customBlitter;
1095     }
1096
1097     if (paint->getMaskFilter()) {
1098         SkPaint::Style style = doFill ? SkPaint::kFill_Style :
1099             SkPaint::kStroke_Style;
1100         if (paint->getMaskFilter()->filterPath(*devPathPtr, *fMatrix, *fRC, blitter, style)) {
1101             return; // filterPath() called the blitter, so we're done
1102         }
1103     }
1104
1105     void (*proc)(const SkPath&, const SkRasterClip&, SkBlitter*);
1106     if (doFill) {
1107         if (paint->isAntiAlias()) {
1108             proc = SkScan::AntiFillPath;
1109         } else {
1110             proc = SkScan::FillPath;
1111         }
1112     } else {    // hairline
1113         if (paint->isAntiAlias()) {
1114             proc = SkScan::AntiHairPath;
1115         } else {
1116             proc = SkScan::HairPath;
1117         }
1118     }
1119     proc(*devPathPtr, *fRC, blitter);
1120 }
1121
1122 /** For the purposes of drawing bitmaps, if a matrix is "almost" translate
1123     go ahead and treat it as if it were, so that subsequent code can go fast.
1124  */
1125 static bool just_translate(const SkMatrix& matrix, const SkBitmap& bitmap) {
1126     unsigned bits = 0;  // TODO: find a way to allow the caller to tell us to
1127                         // respect filtering.
1128     return SkTreatAsSprite(matrix, bitmap.width(), bitmap.height(), bits);
1129 }
1130
1131 void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap,
1132                               const SkPaint& paint) const {
1133     SkASSERT(bitmap.colorType() == kAlpha_8_SkColorType);
1134
1135     if (just_translate(*fMatrix, bitmap)) {
1136         int ix = SkScalarRoundToInt(fMatrix->getTranslateX());
1137         int iy = SkScalarRoundToInt(fMatrix->getTranslateY());
1138
1139         SkAutoLockPixels alp(bitmap);
1140         if (!bitmap.readyToDraw()) {
1141             return;
1142         }
1143
1144         SkMask  mask;
1145         mask.fBounds.set(ix, iy, ix + bitmap.width(), iy + bitmap.height());
1146         mask.fFormat = SkMask::kA8_Format;
1147         mask.fRowBytes = SkToU32(bitmap.rowBytes());
1148         mask.fImage = bitmap.getAddr8(0, 0);
1149
1150         this->drawDevMask(mask, paint);
1151     } else {    // need to xform the bitmap first
1152         SkRect  r;
1153         SkMask  mask;
1154
1155         r.set(0, 0,
1156               SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
1157         fMatrix->mapRect(&r);
1158         r.round(&mask.fBounds);
1159
1160         // set the mask's bounds to the transformed bitmap-bounds,
1161         // clipped to the actual device
1162         {
1163             SkIRect    devBounds;
1164             devBounds.set(0, 0, fBitmap->width(), fBitmap->height());
1165             // need intersect(l, t, r, b) on irect
1166             if (!mask.fBounds.intersect(devBounds)) {
1167                 return;
1168             }
1169         }
1170
1171         mask.fFormat = SkMask::kA8_Format;
1172         mask.fRowBytes = SkAlign4(mask.fBounds.width());
1173         size_t size = mask.computeImageSize();
1174         if (0 == size) {
1175             // the mask is too big to allocated, draw nothing
1176             return;
1177         }
1178
1179         // allocate (and clear) our temp buffer to hold the transformed bitmap
1180         SkAutoMalloc    storage(size);
1181         mask.fImage = (uint8_t*)storage.get();
1182         memset(mask.fImage, 0, size);
1183
1184         // now draw our bitmap(src) into mask(dst), transformed by the matrix
1185         {
1186             SkBitmap    device;
1187             device.installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), mask.fBounds.height()),
1188                                  mask.fImage, mask.fRowBytes);
1189
1190             SkCanvas c(device);
1191             // need the unclipped top/left for the translate
1192             c.translate(-SkIntToScalar(mask.fBounds.fLeft),
1193                         -SkIntToScalar(mask.fBounds.fTop));
1194             c.concat(*fMatrix);
1195
1196             // We can't call drawBitmap, or we'll infinitely recurse. Instead
1197             // we manually build a shader and draw that into our new mask
1198             SkPaint tmpPaint;
1199             tmpPaint.setFlags(paint.getFlags());
1200             SkAutoBitmapShaderInstall install(bitmap, tmpPaint);
1201             SkRect rr;
1202             rr.set(0, 0, SkIntToScalar(bitmap.width()),
1203                    SkIntToScalar(bitmap.height()));
1204             c.drawRect(rr, install.paintWithShader());
1205         }
1206         this->drawDevMask(mask, paint);
1207     }
1208 }
1209
1210 static bool clipped_out(const SkMatrix& m, const SkRasterClip& c,
1211                         const SkRect& srcR) {
1212     SkRect  dstR;
1213     SkIRect devIR;
1214
1215     m.mapRect(&dstR, srcR);
1216     dstR.roundOut(&devIR);
1217     return c.quickReject(devIR);
1218 }
1219
1220 static bool clipped_out(const SkMatrix& matrix, const SkRasterClip& clip,
1221                         int width, int height) {
1222     SkRect  r;
1223     r.set(0, 0, SkIntToScalar(width), SkIntToScalar(height));
1224     return clipped_out(matrix, clip, r);
1225 }
1226
1227 static bool clipHandlesSprite(const SkRasterClip& clip, int x, int y,
1228                               const SkBitmap& bitmap) {
1229     return clip.isBW() ||
1230            clip.quickContains(x, y, x + bitmap.width(), y + bitmap.height());
1231 }
1232
1233 void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
1234                         const SkPaint& origPaint) const {
1235     SkDEBUGCODE(this->validate();)
1236
1237     // nothing to draw
1238     if (fRC->isEmpty() ||
1239             bitmap.width() == 0 || bitmap.height() == 0 ||
1240             bitmap.colorType() == kUnknown_SkColorType) {
1241         return;
1242     }
1243
1244     SkPaint paint(origPaint);
1245     paint.setStyle(SkPaint::kFill_Style);
1246
1247     SkMatrix matrix;
1248     matrix.setConcat(*fMatrix, prematrix);
1249
1250     if (clipped_out(matrix, *fRC, bitmap.width(), bitmap.height())) {
1251         return;
1252     }
1253
1254     if (bitmap.colorType() != kAlpha_8_SkColorType && just_translate(matrix, bitmap)) {
1255         //
1256         // It is safe to call lock pixels now, since we know the matrix is
1257         // (more or less) identity.
1258         //
1259         SkAutoLockPixels alp(bitmap);
1260         if (!bitmap.readyToDraw()) {
1261             return;
1262         }
1263         int ix = SkScalarRoundToInt(matrix.getTranslateX());
1264         int iy = SkScalarRoundToInt(matrix.getTranslateY());
1265         if (clipHandlesSprite(*fRC, ix, iy, bitmap)) {
1266             SkTBlitterAllocator allocator;
1267             // blitter will be owned by the allocator.
1268             SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap,
1269                                                          ix, iy, &allocator);
1270             if (blitter) {
1271                 SkIRect    ir;
1272                 ir.set(ix, iy, ix + bitmap.width(), iy + bitmap.height());
1273
1274                 SkScan::FillIRect(ir, *fRC, blitter);
1275                 return;
1276             }
1277         }
1278     }
1279
1280     // now make a temp draw on the stack, and use it
1281     //
1282     SkDraw draw(*this);
1283     draw.fMatrix = &matrix;
1284
1285     if (bitmap.colorType() == kAlpha_8_SkColorType) {
1286         draw.drawBitmapAsMask(bitmap, paint);
1287     } else {
1288         SkAutoBitmapShaderInstall install(bitmap, paint);
1289
1290         SkRect  r;
1291         r.set(0, 0, SkIntToScalar(bitmap.width()),
1292               SkIntToScalar(bitmap.height()));
1293         // is this ok if paint has a rasterizer?
1294         draw.drawRect(r, install.paintWithShader());
1295     }
1296 }
1297
1298 void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y,
1299                         const SkPaint& origPaint) const {
1300     SkDEBUGCODE(this->validate();)
1301
1302     // nothing to draw
1303     if (fRC->isEmpty() ||
1304             bitmap.width() == 0 || bitmap.height() == 0 ||
1305             bitmap.colorType() == kUnknown_SkColorType) {
1306         return;
1307     }
1308
1309     SkIRect    bounds;
1310     bounds.set(x, y, x + bitmap.width(), y + bitmap.height());
1311
1312     if (fRC->quickReject(bounds)) {
1313         return; // nothing to draw
1314     }
1315
1316     SkPaint paint(origPaint);
1317     paint.setStyle(SkPaint::kFill_Style);
1318
1319     if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, bitmap)) {
1320         SkTBlitterAllocator allocator;
1321         // blitter will be owned by the allocator.
1322         SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap,
1323                                                      x, y, &allocator);
1324
1325         if (blitter) {
1326             SkScan::FillIRect(bounds, *fRC, blitter);
1327             return;
1328         }
1329     }
1330
1331     SkMatrix        matrix;
1332     SkRect          r;
1333
1334     // get a scalar version of our rect
1335     r.set(bounds);
1336
1337     // create shader with offset
1338     matrix.setTranslate(r.fLeft, r.fTop);
1339     SkAutoBitmapShaderInstall install(bitmap, paint, &matrix);
1340     const SkPaint& shaderPaint = install.paintWithShader();
1341
1342     SkDraw draw(*this);
1343     matrix.reset();
1344     draw.fMatrix = &matrix;
1345     // call ourself with a rect
1346     // is this OK if paint has a rasterizer?
1347     draw.drawRect(r, shaderPaint);
1348 }
1349
1350 ///////////////////////////////////////////////////////////////////////////////
1351
1352 #include "SkScalerContext.h"
1353 #include "SkGlyphCache.h"
1354 #include "SkTextToPathIter.h"
1355 #include "SkUtils.h"
1356
1357 static void measure_text(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
1358                 const char text[], size_t byteLength, SkVector* stopVector) {
1359     SkFixed     x = 0, y = 0;
1360     const char* stop = text + byteLength;
1361
1362     SkAutoKern  autokern;
1363
1364     while (text < stop) {
1365         // don't need x, y here, since all subpixel variants will have the
1366         // same advance
1367         const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1368
1369         x += autokern.adjust(glyph) + glyph.fAdvanceX;
1370         y += glyph.fAdvanceY;
1371     }
1372     stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y));
1373
1374     SkASSERT(text == stop);
1375 }
1376
1377 bool SkDraw::ShouldDrawTextAsPaths(const SkPaint& paint, const SkMatrix& ctm) {
1378     // hairline glyphs are fast enough so we don't need to cache them
1379     if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) {
1380         return true;
1381     }
1382
1383     // we don't cache perspective
1384     if (ctm.hasPerspective()) {
1385         return true;
1386     }
1387
1388     SkMatrix textM;
1389     return SkPaint::TooBigToUseCache(ctm, *paint.setTextMatrix(&textM));
1390 }
1391
1392 void SkDraw::drawText_asPaths(const char text[], size_t byteLength,
1393                               SkScalar x, SkScalar y,
1394                               const SkPaint& paint) const {
1395     SkDEBUGCODE(this->validate();)
1396
1397     SkTextToPathIter iter(text, byteLength, paint, true);
1398
1399     SkMatrix    matrix;
1400     matrix.setScale(iter.getPathScale(), iter.getPathScale());
1401     matrix.postTranslate(x, y);
1402
1403     const SkPath* iterPath;
1404     SkScalar xpos, prevXPos = 0;
1405
1406     while (iter.next(&iterPath, &xpos)) {
1407         matrix.postTranslate(xpos - prevXPos, 0);
1408         if (iterPath) {
1409             const SkPaint& pnt = iter.getPaint();
1410             if (fDevice) {
1411                 fDevice->drawPath(*this, *iterPath, pnt, &matrix, false);
1412             } else {
1413                 this->drawPath(*iterPath, pnt, &matrix, false);
1414             }
1415         }
1416         prevXPos = xpos;
1417     }
1418 }
1419
1420 // disable warning : local variable used without having been initialized
1421 #if defined _WIN32 && _MSC_VER >= 1300
1422 #pragma warning ( push )
1423 #pragma warning ( disable : 4701 )
1424 #endif
1425
1426 //////////////////////////////////////////////////////////////////////////////
1427
1428 static void D1G_RectClip(const SkDraw1Glyph& state, SkFixed fx, SkFixed fy, const SkGlyph& glyph) {
1429     int left = SkFixedFloorToInt(fx);
1430     int top = SkFixedFloorToInt(fy);
1431     SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);
1432     SkASSERT((NULL == state.fClip && state.fAAClip) ||
1433              (state.fClip && NULL == state.fAAClip && state.fClip->isRect()));
1434
1435     left += glyph.fLeft;
1436     top  += glyph.fTop;
1437
1438     int right   = left + glyph.fWidth;
1439     int bottom  = top + glyph.fHeight;
1440
1441     SkMask        mask;
1442     SkIRect        storage;
1443     SkIRect*    bounds = &mask.fBounds;
1444
1445     mask.fBounds.set(left, top, right, bottom);
1446
1447     // this extra test is worth it, assuming that most of the time it succeeds
1448     // since we can avoid writing to storage
1449     if (!state.fClipBounds.containsNoEmptyCheck(left, top, right, bottom)) {
1450         if (!storage.intersectNoEmptyCheck(mask.fBounds, state.fClipBounds))
1451             return;
1452         bounds = &storage;
1453     }
1454
1455     uint8_t* aa = (uint8_t*)glyph.fImage;
1456     if (NULL == aa) {
1457         aa = (uint8_t*)state.fCache->findImage(glyph);
1458         if (NULL == aa) {
1459             return; // can't rasterize glyph
1460         }
1461     }
1462
1463     mask.fRowBytes = glyph.rowBytes();
1464     mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
1465     mask.fImage = aa;
1466     state.blitMask(mask, *bounds);
1467 }
1468
1469 static void D1G_RgnClip(const SkDraw1Glyph& state, SkFixed fx, SkFixed fy, const SkGlyph& glyph) {
1470     int left = SkFixedFloorToInt(fx);
1471     int top = SkFixedFloorToInt(fy);
1472     SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);
1473     SkASSERT(!state.fClip->isRect());
1474
1475     SkMask  mask;
1476
1477     left += glyph.fLeft;
1478     top  += glyph.fTop;
1479
1480     mask.fBounds.set(left, top, left + glyph.fWidth, top + glyph.fHeight);
1481     SkRegion::Cliperator clipper(*state.fClip, mask.fBounds);
1482
1483     if (!clipper.done()) {
1484         const SkIRect&  cr = clipper.rect();
1485         const uint8_t*  aa = (const uint8_t*)glyph.fImage;
1486         if (NULL == aa) {
1487             aa = (uint8_t*)state.fCache->findImage(glyph);
1488             if (NULL == aa) {
1489                 return;
1490             }
1491         }
1492
1493         mask.fRowBytes = glyph.rowBytes();
1494         mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
1495         mask.fImage = (uint8_t*)aa;
1496         do {
1497             state.blitMask(mask, cr);
1498             clipper.next();
1499         } while (!clipper.done());
1500     }
1501 }
1502
1503 static bool hasCustomD1GProc(const SkDraw& draw) {
1504     return draw.fProcs && draw.fProcs->fD1GProc;
1505 }
1506
1507 static bool needsRasterTextBlit(const SkDraw& draw) {
1508     return !hasCustomD1GProc(draw);
1509 }
1510
1511 SkDraw1Glyph::Proc SkDraw1Glyph::init(const SkDraw* draw, SkBlitter* blitter, SkGlyphCache* cache,
1512                                       const SkPaint& pnt) {
1513     fDraw = draw;
1514     fBlitter = blitter;
1515     fCache = cache;
1516     fPaint = &pnt;
1517
1518     if (cache->isSubpixel()) {
1519         fHalfSampleX = fHalfSampleY = (SK_FixedHalf >> SkGlyph::kSubBits);
1520     } else {
1521         fHalfSampleX = fHalfSampleY = SK_FixedHalf;
1522     }
1523
1524     if (hasCustomD1GProc(*draw)) {
1525         // todo: fix this assumption about clips w/ custom
1526         fClip = draw->fClip;
1527         fClipBounds = fClip->getBounds();
1528         return draw->fProcs->fD1GProc;
1529     }
1530
1531     if (draw->fRC->isBW()) {
1532         fAAClip = NULL;
1533         fClip = &draw->fRC->bwRgn();
1534         fClipBounds = fClip->getBounds();
1535         if (fClip->isRect()) {
1536             return D1G_RectClip;
1537         } else {
1538             return D1G_RgnClip;
1539         }
1540     } else {    // aaclip
1541         fAAClip = &draw->fRC->aaRgn();
1542         fClip = NULL;
1543         fClipBounds = fAAClip->getBounds();
1544         return D1G_RectClip;
1545     }
1546 }
1547
1548 void SkDraw1Glyph::blitMaskAsSprite(const SkMask& mask) const {
1549     SkASSERT(SkMask::kARGB32_Format == mask.fFormat);
1550
1551     SkBitmap bm;
1552     bm.installPixels(SkImageInfo::MakeN32Premul(mask.fBounds.width(), mask.fBounds.height()),
1553                      (SkPMColor*)mask.fImage, mask.fRowBytes);
1554
1555     fDraw->drawSprite(bm, mask.fBounds.x(), mask.fBounds.y(), *fPaint);
1556 }
1557
1558 ///////////////////////////////////////////////////////////////////////////////
1559
1560 void SkDraw::drawText(const char text[], size_t byteLength,
1561                       SkScalar x, SkScalar y, const SkPaint& paint) const {
1562     SkASSERT(byteLength == 0 || text != NULL);
1563
1564     SkDEBUGCODE(this->validate();)
1565
1566     // nothing to draw
1567     if (text == NULL || byteLength == 0 || fRC->isEmpty()) {
1568         return;
1569     }
1570
1571     // SkScalarRec doesn't currently have a way of representing hairline stroke and
1572     // will fill if its frame-width is 0.
1573     if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
1574         this->drawText_asPaths(text, byteLength, x, y, paint);
1575         return;
1576     }
1577
1578     SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
1579
1580     SkAutoGlyphCache    autoCache(paint, &fDevice->getLeakyProperties(), fMatrix);
1581     SkGlyphCache*       cache = autoCache.getCache();
1582
1583     // transform our starting point
1584     {
1585         SkPoint loc;
1586         fMatrix->mapXY(x, y, &loc);
1587         x = loc.fX;
1588         y = loc.fY;
1589     }
1590
1591     // need to measure first
1592     if (paint.getTextAlign() != SkPaint::kLeft_Align) {
1593         SkVector    stop;
1594
1595         measure_text(cache, glyphCacheProc, text, byteLength, &stop);
1596
1597         SkScalar    stopX = stop.fX;
1598         SkScalar    stopY = stop.fY;
1599
1600         if (paint.getTextAlign() == SkPaint::kCenter_Align) {
1601             stopX = SkScalarHalf(stopX);
1602             stopY = SkScalarHalf(stopY);
1603         }
1604         x -= stopX;
1605         y -= stopY;
1606     }
1607
1608     const char* stop = text + byteLength;
1609
1610     SkAAClipBlitter     aaBlitter;
1611     SkAutoBlitterChoose blitterChooser;
1612     SkBlitter*          blitter = NULL;
1613     if (needsRasterTextBlit(*this)) {
1614         blitterChooser.choose(*fBitmap, *fMatrix, paint);
1615         blitter = blitterChooser.get();
1616         if (fRC->isAA()) {
1617             aaBlitter.init(blitter, &fRC->aaRgn());
1618             blitter = &aaBlitter;
1619         }
1620     }
1621
1622     SkAutoKern          autokern;
1623     SkDraw1Glyph        d1g;
1624     SkDraw1Glyph::Proc  proc = d1g.init(this, blitter, cache, paint);
1625
1626     SkFixed fxMask = ~0;
1627     SkFixed fyMask = ~0;
1628     if (cache->isSubpixel()) {
1629         SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix);
1630         if (kX_SkAxisAlignment == baseline) {
1631             fyMask = 0;
1632             d1g.fHalfSampleY = SK_FixedHalf;
1633         } else if (kY_SkAxisAlignment == baseline) {
1634             fxMask = 0;
1635             d1g.fHalfSampleX = SK_FixedHalf;
1636         }
1637     }
1638
1639     SkFixed fx = SkScalarToFixed(x) + d1g.fHalfSampleX;
1640     SkFixed fy = SkScalarToFixed(y) + d1g.fHalfSampleY;
1641
1642     while (text < stop) {
1643         const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask);
1644
1645         fx += autokern.adjust(glyph);
1646
1647         if (glyph.fWidth) {
1648             proc(d1g, fx, fy, glyph);
1649         }
1650
1651         fx += glyph.fAdvanceX;
1652         fy += glyph.fAdvanceY;
1653     }
1654 }
1655
1656 //////////////////////////////////////////////////////////////////////////////
1657
1658 void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength,
1659                                  const SkScalar pos[], int scalarsPerPosition,
1660                                  const SkPoint& offset, 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(), offset, 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[], int scalarsPerPosition,
1709                          const SkPoint& offset, 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, scalarsPerPosition, offset, paint);
1722         return;
1723     }
1724
1725     SkDrawCacheProc     glyphCacheProc = paint.getDrawCacheProc();
1726     SkAutoGlyphCache    autoCache(paint, &fDevice->getLeakyProperties(), fMatrix);
1727     SkGlyphCache*       cache = autoCache.getCache();
1728
1729     SkAAClipBlitterWrapper wrapper;
1730     SkAutoBlitterChoose blitterChooser;
1731     SkBlitter* blitter = NULL;
1732     if (needsRasterTextBlit(*this)) {
1733         blitterChooser.choose(*fBitmap, *fMatrix, paint);
1734         blitter = blitterChooser.get();
1735         if (fRC->isAA()) {
1736             wrapper.init(*fRC, blitter);
1737             blitter = wrapper.getBlitter();
1738         }
1739     }
1740
1741     const char*        stop = text + byteLength;
1742     SkTextAlignProc    alignProc(paint.getTextAlign());
1743     SkDraw1Glyph       d1g;
1744     SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint);
1745     SkTextMapStateProc tmsProc(*fMatrix, offset, scalarsPerPosition);
1746
1747     if (cache->isSubpixel()) {
1748         // maybe we should skip the rounding if linearText is set
1749         SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix);
1750
1751         SkFixed fxMask = ~0;
1752         SkFixed fyMask = ~0;
1753         if (kX_SkAxisAlignment == baseline) {
1754             fyMask = 0;
1755 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
1756             d1g.fHalfSampleY = SK_FixedHalf;
1757 #endif
1758         } else if (kY_SkAxisAlignment == baseline) {
1759             fxMask = 0;
1760 #ifndef SK_IGNORE_SUBPIXEL_AXIS_ALIGN_FIX
1761             d1g.fHalfSampleX = SK_FixedHalf;
1762 #endif
1763         }
1764
1765         if (SkPaint::kLeft_Align == paint.getTextAlign()) {
1766             while (text < stop) {
1767                 SkPoint tmsLoc;
1768                 tmsProc(pos, &tmsLoc);
1769                 SkFixed fx = SkScalarToFixed(tmsLoc.fX) + d1g.fHalfSampleX;
1770                 SkFixed fy = SkScalarToFixed(tmsLoc.fY) + d1g.fHalfSampleY;
1771
1772                 const SkGlyph& glyph = glyphCacheProc(cache, &text,
1773                                                       fx & fxMask, fy & fyMask);
1774
1775                 if (glyph.fWidth) {
1776                     proc(d1g, fx, fy, glyph);
1777                 }
1778                 pos += scalarsPerPosition;
1779             }
1780         } else {
1781             while (text < stop) {
1782                 const char* currentText = text;
1783                 const SkGlyph& metricGlyph = glyphCacheProc(cache, &text, 0, 0);
1784
1785                 if (metricGlyph.fWidth) {
1786                     SkDEBUGCODE(SkFixed prevAdvX = metricGlyph.fAdvanceX;)
1787                     SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;)
1788                     SkPoint tmsLoc;
1789                     tmsProc(pos, &tmsLoc);
1790                     SkIPoint fixedLoc;
1791                     alignProc(tmsLoc, metricGlyph, &fixedLoc);
1792
1793                     SkFixed fx = fixedLoc.fX + d1g.fHalfSampleX;
1794                     SkFixed fy = fixedLoc.fY + d1g.fHalfSampleY;
1795
1796                     // have to call again, now that we've been "aligned"
1797                     const SkGlyph& glyph = glyphCacheProc(cache, &currentText,
1798                                                           fx & fxMask, fy & fyMask);
1799                     // the assumption is that the metrics haven't changed
1800                     SkASSERT(prevAdvX == glyph.fAdvanceX);
1801                     SkASSERT(prevAdvY == glyph.fAdvanceY);
1802                     SkASSERT(glyph.fWidth);
1803
1804                     proc(d1g, fx, fy, glyph);
1805                 }
1806                 pos += scalarsPerPosition;
1807             }
1808         }
1809     } else {    // not subpixel
1810         if (SkPaint::kLeft_Align == paint.getTextAlign()) {
1811             while (text < stop) {
1812                 // the last 2 parameters are ignored
1813                 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1814
1815                 if (glyph.fWidth) {
1816                     SkPoint tmsLoc;
1817                     tmsProc(pos, &tmsLoc);
1818
1819                     proc(d1g,
1820                          SkScalarToFixed(tmsLoc.fX) + SK_FixedHalf, //d1g.fHalfSampleX,
1821                          SkScalarToFixed(tmsLoc.fY) + SK_FixedHalf, //d1g.fHalfSampleY,
1822                          glyph);
1823                 }
1824                 pos += scalarsPerPosition;
1825             }
1826         } else {
1827             while (text < stop) {
1828                 // the last 2 parameters are ignored
1829                 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1830
1831                 if (glyph.fWidth) {
1832                     SkPoint tmsLoc;
1833                     tmsProc(pos, &tmsLoc);
1834
1835                     SkIPoint fixedLoc;
1836                     alignProc(tmsLoc, glyph, &fixedLoc);
1837
1838                     proc(d1g,
1839                          fixedLoc.fX + SK_FixedHalf, //d1g.fHalfSampleX,
1840                          fixedLoc.fY + SK_FixedHalf, //d1g.fHalfSampleY,
1841                          glyph);
1842                 }
1843                 pos += scalarsPerPosition;
1844             }
1845         }
1846     }
1847 }
1848
1849 #if defined _WIN32 && _MSC_VER >= 1300
1850 #pragma warning ( pop )
1851 #endif
1852
1853 ///////////////////////////////////////////////////////////////////////////////
1854
1855 #include "SkPathMeasure.h"
1856
1857 static void morphpoints(SkPoint dst[], const SkPoint src[], int count,
1858                         SkPathMeasure& meas, const SkMatrix& matrix) {
1859     SkMatrix::MapXYProc proc = matrix.getMapXYProc();
1860
1861     for (int i = 0; i < count; i++) {
1862         SkPoint pos;
1863         SkVector tangent;
1864
1865         proc(matrix, src[i].fX, src[i].fY, &pos);
1866         SkScalar sx = pos.fX;
1867         SkScalar sy = pos.fY;
1868
1869         if (!meas.getPosTan(sx, &pos, &tangent)) {
1870             // set to 0 if the measure failed, so that we just set dst == pos
1871             tangent.set(0, 0);
1872         }
1873
1874         /*  This is the old way (that explains our approach but is way too slow
1875             SkMatrix    matrix;
1876             SkPoint     pt;
1877
1878             pt.set(sx, sy);
1879             matrix.setSinCos(tangent.fY, tangent.fX);
1880             matrix.preTranslate(-sx, 0);
1881             matrix.postTranslate(pos.fX, pos.fY);
1882             matrix.mapPoints(&dst[i], &pt, 1);
1883         */
1884         dst[i].set(pos.fX - SkScalarMul(tangent.fY, sy),
1885                    pos.fY + SkScalarMul(tangent.fX, sy));
1886     }
1887 }
1888
1889 /*  TODO
1890
1891     Need differentially more subdivisions when the follow-path is curvy. Not sure how to
1892     determine that, but we need it. I guess a cheap answer is let the caller tell us,
1893     but that seems like a cop-out. Another answer is to get Rob Johnson to figure it out.
1894 */
1895 static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas,
1896                       const SkMatrix& matrix) {
1897     SkPath::Iter    iter(src, false);
1898     SkPoint         srcP[4], dstP[3];
1899     SkPath::Verb    verb;
1900
1901     while ((verb = iter.next(srcP)) != SkPath::kDone_Verb) {
1902         switch (verb) {
1903             case SkPath::kMove_Verb:
1904                 morphpoints(dstP, srcP, 1, meas, matrix);
1905                 dst->moveTo(dstP[0]);
1906                 break;
1907             case SkPath::kLine_Verb:
1908                 // turn lines into quads to look bendy
1909                 srcP[0].fX = SkScalarAve(srcP[0].fX, srcP[1].fX);
1910                 srcP[0].fY = SkScalarAve(srcP[0].fY, srcP[1].fY);
1911                 morphpoints(dstP, srcP, 2, meas, matrix);
1912                 dst->quadTo(dstP[0], dstP[1]);
1913                 break;
1914             case SkPath::kQuad_Verb:
1915                 morphpoints(dstP, &srcP[1], 2, meas, matrix);
1916                 dst->quadTo(dstP[0], dstP[1]);
1917                 break;
1918             case SkPath::kCubic_Verb:
1919                 morphpoints(dstP, &srcP[1], 3, meas, matrix);
1920                 dst->cubicTo(dstP[0], dstP[1], dstP[2]);
1921                 break;
1922             case SkPath::kClose_Verb:
1923                 dst->close();
1924                 break;
1925             default:
1926                 SkDEBUGFAIL("unknown verb");
1927                 break;
1928         }
1929     }
1930 }
1931
1932 void SkDraw::drawTextOnPath(const char text[], size_t byteLength,
1933                             const SkPath& follow, const SkMatrix* matrix,
1934                             const SkPaint& paint) const {
1935     SkASSERT(byteLength == 0 || text != NULL);
1936
1937     // nothing to draw
1938     if (text == NULL || byteLength == 0 || fRC->isEmpty()) {
1939         return;
1940     }
1941
1942     SkTextToPathIter    iter(text, byteLength, paint, true);
1943     SkPathMeasure       meas(follow, false);
1944     SkScalar            hOffset = 0;
1945
1946     // need to measure first
1947     if (paint.getTextAlign() != SkPaint::kLeft_Align) {
1948         SkScalar pathLen = meas.getLength();
1949         if (paint.getTextAlign() == SkPaint::kCenter_Align) {
1950             pathLen = SkScalarHalf(pathLen);
1951         }
1952         hOffset += pathLen;
1953     }
1954
1955     const SkPath*   iterPath;
1956     SkScalar        xpos;
1957     SkMatrix        scaledMatrix;
1958     SkScalar        scale = iter.getPathScale();
1959
1960     scaledMatrix.setScale(scale, scale);
1961
1962     while (iter.next(&iterPath, &xpos)) {
1963         if (iterPath) {
1964             SkPath      tmp;
1965             SkMatrix    m(scaledMatrix);
1966             
1967             tmp.setIsVolatile(true);
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 }