C++11 override should now be supported by all of {bots,Chrome,Android,Mozilla}
[platform/upstream/libSkiaSharp.git] / 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 #define __STDC_LIMIT_MACROS
8
9 #include "SkDraw.h"
10 #include "SkBlitter.h"
11 #include "SkCanvas.h"
12 #include "SkColorPriv.h"
13 #include "SkDevice.h"
14 #include "SkDeviceLooper.h"
15 #include "SkFixed.h"
16 #include "SkMaskFilter.h"
17 #include "SkPaint.h"
18 #include "SkPathEffect.h"
19 #include "SkRasterClip.h"
20 #include "SkRasterizer.h"
21 #include "SkRRect.h"
22 #include "SkScan.h"
23 #include "SkShader.h"
24 #include "SkSmallAllocator.h"
25 #include "SkString.h"
26 #include "SkStroke.h"
27 #include "SkTextMapStateProc.h"
28 #include "SkTLazy.h"
29 #include "SkUtils.h"
30 #include "SkVertState.h"
31
32 #include "SkAutoKern.h"
33 #include "SkBitmapProcShader.h"
34 #include "SkDrawProcs.h"
35 #include "SkMatrixUtils.h"
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(SkCreateBitmapShader(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 inline SkPoint compute_stroke_size(const SkPaint& paint, const SkMatrix& matrix) {
739     SkASSERT(matrix.rectStaysRect());
740     SkASSERT(SkPaint::kFill_Style != paint.getStyle());
741
742     SkVector size;
743     SkPoint pt = { paint.getStrokeWidth(), paint.getStrokeWidth() };
744     matrix.mapVectors(&size, &pt, 1);
745     return SkPoint::Make(SkScalarAbs(size.fX), SkScalarAbs(size.fY));
746 }
747
748 static bool easy_rect_join(const SkPaint& paint, const SkMatrix& matrix,
749                            SkPoint* strokeSize) {
750     if (SkPaint::kMiter_Join != paint.getStrokeJoin() ||
751         paint.getStrokeMiter() < SK_ScalarSqrt2) {
752         return false;
753     }
754
755     *strokeSize = compute_stroke_size(paint, matrix);
756     return true;
757 }
758
759 SkDraw::RectType SkDraw::ComputeRectType(const SkPaint& paint,
760                                          const SkMatrix& matrix,
761                                          SkPoint* strokeSize) {
762     RectType rtype;
763     const SkScalar width = paint.getStrokeWidth();
764     const bool zeroWidth = (0 == width);
765     SkPaint::Style style = paint.getStyle();
766
767     if ((SkPaint::kStrokeAndFill_Style == style) && zeroWidth) {
768         style = SkPaint::kFill_Style;
769     }
770
771     if (paint.getPathEffect() || paint.getMaskFilter() ||
772         paint.getRasterizer() || !matrix.rectStaysRect() ||
773         SkPaint::kStrokeAndFill_Style == style) {
774         rtype = kPath_RectType;
775     } else if (SkPaint::kFill_Style == style) {
776         rtype = kFill_RectType;
777     } else if (zeroWidth) {
778         rtype = kHair_RectType;
779     } else if (easy_rect_join(paint, matrix, strokeSize)) {
780         rtype = kStroke_RectType;
781     } else {
782         rtype = kPath_RectType;
783     }
784     return rtype;
785 }
786
787 static const SkPoint* rect_points(const SkRect& r) {
788     return SkTCast<const SkPoint*>(&r);
789 }
790
791 static SkPoint* rect_points(SkRect& r) {
792     return SkTCast<SkPoint*>(&r);
793 }
794
795 void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint,
796                       const SkMatrix* paintMatrix, const SkRect* postPaintRect) const {
797     SkDEBUGCODE(this->validate();)
798
799     // nothing to draw
800     if (fRC->isEmpty()) {
801         return;
802     }
803
804     const SkMatrix* matrix;
805     SkMatrix combinedMatrixStorage;
806     if (paintMatrix) {
807         SkASSERT(postPaintRect);
808         combinedMatrixStorage.setConcat(*fMatrix, *paintMatrix);
809         matrix = &combinedMatrixStorage;
810     } else {
811         SkASSERT(!postPaintRect);
812         matrix = fMatrix;
813     }
814
815     SkPoint strokeSize;
816     RectType rtype = ComputeRectType(paint, *fMatrix, &strokeSize);
817
818     if (kPath_RectType == rtype) {
819         SkDraw draw(*this);
820         if (paintMatrix) {
821             draw.fMatrix = matrix;
822         }
823         SkPath  tmp;
824         tmp.addRect(prePaintRect);
825         tmp.setFillType(SkPath::kWinding_FillType);
826         draw.drawPath(tmp, paint, NULL, true);
827         return;
828     }
829
830     SkRect devRect;
831     const SkRect& paintRect = paintMatrix ? *postPaintRect : prePaintRect;
832     // skip the paintMatrix when transforming the rect by the CTM
833     fMatrix->mapPoints(rect_points(devRect), rect_points(paintRect), 2);
834     devRect.sort();
835
836     // look for the quick exit, before we build a blitter
837     SkRect bbox = devRect;
838     if (paint.getStyle() != SkPaint::kFill_Style) {
839         // extra space for hairlines
840         if (paint.getStrokeWidth() == 0) {
841             bbox.outset(1, 1);
842         } else {
843             // For kStroke_RectType, strokeSize is already computed.
844             const SkPoint& ssize = (kStroke_RectType == rtype)
845                 ? strokeSize
846                 : compute_stroke_size(paint, *fMatrix);
847             bbox.outset(SkScalarHalf(ssize.x()), SkScalarHalf(ssize.y()));
848         }
849     }
850
851     SkIRect ir = bbox.roundOut();
852     if (fRC->quickReject(ir)) {
853         return;
854     }
855
856     SkDeviceLooper looper(*fBitmap, *fRC, ir, paint.isAntiAlias());
857     while (looper.next()) {
858         SkRect localDevRect;
859         looper.mapRect(&localDevRect, devRect);
860         SkMatrix localMatrix;
861         looper.mapMatrix(&localMatrix, *matrix);
862
863         SkAutoBlitterChoose blitterStorage(looper.getBitmap(), localMatrix, paint);
864         const SkRasterClip& clip = looper.getRC();
865         SkBlitter*          blitter = blitterStorage.get();
866
867         // we want to "fill" if we are kFill or kStrokeAndFill, since in the latter
868         // case we are also hairline (if we've gotten to here), which devolves to
869         // effectively just kFill
870         switch (rtype) {
871             case kFill_RectType:
872                 if (paint.isAntiAlias()) {
873                     SkScan::AntiFillRect(localDevRect, clip, blitter);
874                 } else {
875                     SkScan::FillRect(localDevRect, clip, blitter);
876                 }
877                 break;
878             case kStroke_RectType:
879                 if (paint.isAntiAlias()) {
880                     SkScan::AntiFrameRect(localDevRect, strokeSize, clip, blitter);
881                 } else {
882                     SkScan::FrameRect(localDevRect, strokeSize, clip, blitter);
883                 }
884                 break;
885             case kHair_RectType:
886                 if (paint.isAntiAlias()) {
887                     SkScan::AntiHairRect(localDevRect, clip, blitter);
888                 } else {
889                     SkScan::HairRect(localDevRect, clip, blitter);
890                 }
891                 break;
892             default:
893                 SkDEBUGFAIL("bad rtype");
894         }
895     }
896 }
897
898 void SkDraw::drawDevMask(const SkMask& srcM, const SkPaint& paint) const {
899     if (srcM.fBounds.isEmpty()) {
900         return;
901     }
902
903     const SkMask* mask = &srcM;
904
905     SkMask dstM;
906     if (paint.getMaskFilter() &&
907             paint.getMaskFilter()->filterMask(&dstM, srcM, *fMatrix, NULL)) {
908         mask = &dstM;
909     } else {
910         dstM.fImage = NULL;
911     }
912     SkAutoMaskFreeImage ami(dstM.fImage);
913
914     SkAutoBlitterChoose blitterChooser(*fBitmap, *fMatrix, paint);
915     SkBlitter* blitter = blitterChooser.get();
916
917     SkAAClipBlitterWrapper wrapper;
918     const SkRegion* clipRgn;
919
920     if (fRC->isBW()) {
921         clipRgn = &fRC->bwRgn();
922     } else {
923         wrapper.init(*fRC, blitter);
924         clipRgn = &wrapper.getRgn();
925         blitter = wrapper.getBlitter();
926     }
927     blitter->blitMaskRegion(*mask, *clipRgn);
928 }
929
930 static SkScalar fast_len(const SkVector& vec) {
931     SkScalar x = SkScalarAbs(vec.fX);
932     SkScalar y = SkScalarAbs(vec.fY);
933     if (x < y) {
934         SkTSwap(x, y);
935     }
936     return x + SkScalarHalf(y);
937 }
938
939 bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix& matrix,
940                                    SkScalar* coverage) {
941     SkASSERT(strokeWidth > 0);
942     // We need to try to fake a thick-stroke with a modulated hairline.
943
944     if (matrix.hasPerspective()) {
945         return false;
946     }
947
948     SkVector src[2], dst[2];
949     src[0].set(strokeWidth, 0);
950     src[1].set(0, strokeWidth);
951     matrix.mapVectors(dst, src, 2);
952     SkScalar len0 = fast_len(dst[0]);
953     SkScalar len1 = fast_len(dst[1]);
954     if (len0 <= SK_Scalar1 && len1 <= SK_Scalar1) {
955         if (coverage) {
956             *coverage = SkScalarAve(len0, len1);
957         }
958         return true;
959     }
960     return false;
961 }
962
963 void SkDraw::drawRRect(const SkRRect& rrect, const SkPaint& paint) const {
964     SkDEBUGCODE(this->validate());
965
966     if (fRC->isEmpty()) {
967         return;
968     }
969
970     {
971         // TODO: Investigate optimizing these options. They are in the same
972         // order as SkDraw::drawPath, which handles each case. It may be
973         // that there is no way to optimize for these using the SkRRect path.
974         SkScalar coverage;
975         if (SkDrawTreatAsHairline(paint, *fMatrix, &coverage)) {
976             goto DRAW_PATH;
977         }
978
979         if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
980             goto DRAW_PATH;
981         }
982
983         if (paint.getRasterizer()) {
984             goto DRAW_PATH;
985         }
986     }
987
988     if (paint.getMaskFilter()) {
989         // Transform the rrect into device space.
990         SkRRect devRRect;
991         if (rrect.transform(*fMatrix, &devRRect)) {
992             SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, paint);
993             if (paint.getMaskFilter()->filterRRect(devRRect, *fMatrix, *fRC, blitter.get(),
994                                                    SkPaint::kFill_Style)) {
995                 return; // filterRRect() called the blitter, so we're done
996             }
997         }
998     }
999
1000 DRAW_PATH:
1001     // Now fall back to the default case of using a path.
1002     SkPath path;
1003     path.addRRect(rrect);
1004     this->drawPath(path, paint, NULL, true);
1005 }
1006
1007 static SkScalar compute_res_scale_for_stroking(const SkMatrix& matrix) {
1008     if (!matrix.hasPerspective()) {
1009         SkScalar sx = SkPoint::Length(matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY]);
1010         SkScalar sy = SkPoint::Length(matrix[SkMatrix::kMSkewX],  matrix[SkMatrix::kMScaleY]);
1011         if (SkScalarsAreFinite(sx, sy)) {
1012             return SkTMax(sx, sy);
1013         }
1014     }
1015     return 1;
1016 }
1017
1018 void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
1019                       const SkMatrix* prePathMatrix, bool pathIsMutable,
1020                       bool drawCoverage, SkBlitter* customBlitter) const {
1021     SkDEBUGCODE(this->validate();)
1022
1023     // nothing to draw
1024     if (fRC->isEmpty()) {
1025         return;
1026     }
1027
1028     SkPath*         pathPtr = (SkPath*)&origSrcPath;
1029     bool            doFill = true;
1030     SkPath          tmpPath;
1031     SkMatrix        tmpMatrix;
1032     const SkMatrix* matrix = fMatrix;
1033     tmpPath.setIsVolatile(true);
1034
1035     if (prePathMatrix) {
1036         if (origPaint.getPathEffect() || origPaint.getStyle() != SkPaint::kFill_Style ||
1037                 origPaint.getRasterizer()) {
1038             SkPath* result = pathPtr;
1039
1040             if (!pathIsMutable) {
1041                 result = &tmpPath;
1042                 pathIsMutable = true;
1043             }
1044             pathPtr->transform(*prePathMatrix, result);
1045             pathPtr = result;
1046         } else {
1047             tmpMatrix.setConcat(*matrix, *prePathMatrix);
1048             matrix = &tmpMatrix;
1049         }
1050     }
1051     // at this point we're done with prePathMatrix
1052     SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
1053
1054     SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
1055
1056     {
1057         SkScalar coverage;
1058         if (SkDrawTreatAsHairline(origPaint, *matrix, &coverage)) {
1059             if (SK_Scalar1 == coverage) {
1060                 paint.writable()->setStrokeWidth(0);
1061             } else if (SkXfermode::SupportsCoverageAsAlpha(origPaint.getXfermode())) {
1062                 U8CPU newAlpha;
1063 #if 0
1064                 newAlpha = SkToU8(SkScalarRoundToInt(coverage *
1065                                                      origPaint.getAlpha()));
1066 #else
1067                 // this is the old technique, which we preserve for now so
1068                 // we don't change previous results (testing)
1069                 // the new way seems fine, its just (a tiny bit) different
1070                 int scale = (int)SkScalarMul(coverage, 256);
1071                 newAlpha = origPaint.getAlpha() * scale >> 8;
1072 #endif
1073                 SkPaint* writablePaint = paint.writable();
1074                 writablePaint->setStrokeWidth(0);
1075                 writablePaint->setAlpha(newAlpha);
1076             }
1077         }
1078     }
1079
1080     if (paint->getPathEffect() || paint->getStyle() != SkPaint::kFill_Style) {
1081         SkRect cullRect;
1082         const SkRect* cullRectPtr = NULL;
1083         if (this->computeConservativeLocalClipBounds(&cullRect)) {
1084             cullRectPtr = &cullRect;
1085         }
1086         doFill = paint->getFillPath(*pathPtr, &tmpPath, cullRectPtr,
1087                                     compute_res_scale_for_stroking(*fMatrix));
1088         pathPtr = &tmpPath;
1089     }
1090
1091     if (paint->getRasterizer()) {
1092         SkMask  mask;
1093         if (paint->getRasterizer()->rasterize(*pathPtr, *matrix,
1094                             &fRC->getBounds(), paint->getMaskFilter(), &mask,
1095                             SkMask::kComputeBoundsAndRenderImage_CreateMode)) {
1096             this->drawDevMask(mask, *paint);
1097             SkMask::FreeImage(mask.fImage);
1098         }
1099         return;
1100     }
1101
1102     // avoid possibly allocating a new path in transform if we can
1103     SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath;
1104
1105     // transform the path into device space
1106     pathPtr->transform(*matrix, devPathPtr);
1107
1108     SkBlitter* blitter = NULL;
1109     SkAutoBlitterChoose blitterStorage;
1110     if (NULL == customBlitter) {
1111         blitterStorage.choose(*fBitmap, *fMatrix, *paint, drawCoverage);
1112         blitter = blitterStorage.get();
1113     } else {
1114         blitter = customBlitter;
1115     }
1116
1117     if (paint->getMaskFilter()) {
1118         SkPaint::Style style = doFill ? SkPaint::kFill_Style :
1119             SkPaint::kStroke_Style;
1120         if (paint->getMaskFilter()->filterPath(*devPathPtr, *fMatrix, *fRC, blitter, style)) {
1121             return; // filterPath() called the blitter, so we're done
1122         }
1123     }
1124
1125     void (*proc)(const SkPath&, const SkRasterClip&, SkBlitter*);
1126     if (doFill) {
1127         if (paint->isAntiAlias()) {
1128             proc = SkScan::AntiFillPath;
1129         } else {
1130             proc = SkScan::FillPath;
1131         }
1132     } else {    // hairline
1133         if (paint->isAntiAlias()) {
1134             proc = SkScan::AntiHairPath;
1135         } else {
1136             proc = SkScan::HairPath;
1137         }
1138     }
1139     proc(*devPathPtr, *fRC, blitter);
1140 }
1141
1142 /** For the purposes of drawing bitmaps, if a matrix is "almost" translate
1143     go ahead and treat it as if it were, so that subsequent code can go fast.
1144  */
1145 static bool just_translate(const SkMatrix& matrix, const SkBitmap& bitmap) {
1146     unsigned bits = 0;  // TODO: find a way to allow the caller to tell us to
1147                         // respect filtering.
1148     return SkTreatAsSprite(matrix, bitmap.width(), bitmap.height(), bits);
1149 }
1150
1151 void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap,
1152                               const SkPaint& paint) const {
1153     SkASSERT(bitmap.colorType() == kAlpha_8_SkColorType);
1154
1155     if (just_translate(*fMatrix, bitmap)) {
1156         int ix = SkScalarRoundToInt(fMatrix->getTranslateX());
1157         int iy = SkScalarRoundToInt(fMatrix->getTranslateY());
1158
1159         SkAutoLockPixels alp(bitmap);
1160         if (!bitmap.readyToDraw()) {
1161             return;
1162         }
1163
1164         SkMask  mask;
1165         mask.fBounds.set(ix, iy, ix + bitmap.width(), iy + bitmap.height());
1166         mask.fFormat = SkMask::kA8_Format;
1167         mask.fRowBytes = SkToU32(bitmap.rowBytes());
1168         mask.fImage = bitmap.getAddr8(0, 0);
1169
1170         this->drawDevMask(mask, paint);
1171     } else {    // need to xform the bitmap first
1172         SkRect  r;
1173         SkMask  mask;
1174
1175         r.set(0, 0,
1176               SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
1177         fMatrix->mapRect(&r);
1178         r.round(&mask.fBounds);
1179
1180         // set the mask's bounds to the transformed bitmap-bounds,
1181         // clipped to the actual device
1182         {
1183             SkIRect    devBounds;
1184             devBounds.set(0, 0, fBitmap->width(), fBitmap->height());
1185             // need intersect(l, t, r, b) on irect
1186             if (!mask.fBounds.intersect(devBounds)) {
1187                 return;
1188             }
1189         }
1190
1191         mask.fFormat = SkMask::kA8_Format;
1192         mask.fRowBytes = SkAlign4(mask.fBounds.width());
1193         size_t size = mask.computeImageSize();
1194         if (0 == size) {
1195             // the mask is too big to allocated, draw nothing
1196             return;
1197         }
1198
1199         // allocate (and clear) our temp buffer to hold the transformed bitmap
1200         SkAutoMalloc    storage(size);
1201         mask.fImage = (uint8_t*)storage.get();
1202         memset(mask.fImage, 0, size);
1203
1204         // now draw our bitmap(src) into mask(dst), transformed by the matrix
1205         {
1206             SkBitmap    device;
1207             device.installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), mask.fBounds.height()),
1208                                  mask.fImage, mask.fRowBytes);
1209
1210             SkCanvas c(device);
1211             // need the unclipped top/left for the translate
1212             c.translate(-SkIntToScalar(mask.fBounds.fLeft),
1213                         -SkIntToScalar(mask.fBounds.fTop));
1214             c.concat(*fMatrix);
1215
1216             // We can't call drawBitmap, or we'll infinitely recurse. Instead
1217             // we manually build a shader and draw that into our new mask
1218             SkPaint tmpPaint;
1219             tmpPaint.setFlags(paint.getFlags());
1220             SkAutoBitmapShaderInstall install(bitmap, tmpPaint);
1221             SkRect rr;
1222             rr.set(0, 0, SkIntToScalar(bitmap.width()),
1223                    SkIntToScalar(bitmap.height()));
1224             c.drawRect(rr, install.paintWithShader());
1225         }
1226         this->drawDevMask(mask, paint);
1227     }
1228 }
1229
1230 static bool clipped_out(const SkMatrix& m, const SkRasterClip& c,
1231                         const SkRect& srcR) {
1232     SkRect  dstR;
1233     m.mapRect(&dstR, srcR);
1234     return c.quickReject(dstR.roundOut());
1235 }
1236
1237 static bool clipped_out(const SkMatrix& matrix, const SkRasterClip& clip,
1238                         int width, int height) {
1239     SkRect  r;
1240     r.set(0, 0, SkIntToScalar(width), SkIntToScalar(height));
1241     return clipped_out(matrix, clip, r);
1242 }
1243
1244 static bool clipHandlesSprite(const SkRasterClip& clip, int x, int y,
1245                               const SkBitmap& bitmap) {
1246     return clip.isBW() ||
1247            clip.quickContains(x, y, x + bitmap.width(), y + bitmap.height());
1248 }
1249
1250 void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
1251                         const SkRect* dstBounds, const SkPaint& origPaint) const {
1252     SkDEBUGCODE(this->validate();)
1253
1254     // nothing to draw
1255     if (fRC->isEmpty() ||
1256             bitmap.width() == 0 || bitmap.height() == 0 ||
1257             bitmap.colorType() == kUnknown_SkColorType) {
1258         return;
1259     }
1260
1261     SkPaint paint(origPaint);
1262     paint.setStyle(SkPaint::kFill_Style);
1263
1264     SkMatrix matrix;
1265     matrix.setConcat(*fMatrix, prematrix);
1266
1267     if (clipped_out(matrix, *fRC, bitmap.width(), bitmap.height())) {
1268         return;
1269     }
1270
1271     if (bitmap.colorType() != kAlpha_8_SkColorType && just_translate(matrix, bitmap)) {
1272         //
1273         // It is safe to call lock pixels now, since we know the matrix is
1274         // (more or less) identity.
1275         //
1276         SkAutoLockPixels alp(bitmap);
1277         if (!bitmap.readyToDraw()) {
1278             return;
1279         }
1280         int ix = SkScalarRoundToInt(matrix.getTranslateX());
1281         int iy = SkScalarRoundToInt(matrix.getTranslateY());
1282         if (clipHandlesSprite(*fRC, ix, iy, bitmap)) {
1283             SkTBlitterAllocator allocator;
1284             // blitter will be owned by the allocator.
1285             SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap,
1286                                                          ix, iy, &allocator);
1287             if (blitter) {
1288                 SkIRect    ir;
1289                 ir.set(ix, iy, ix + bitmap.width(), iy + bitmap.height());
1290
1291                 SkScan::FillIRect(ir, *fRC, blitter);
1292                 return;
1293             }
1294         }
1295     }
1296
1297     // now make a temp draw on the stack, and use it
1298     //
1299     SkDraw draw(*this);
1300     draw.fMatrix = &matrix;
1301
1302     if (bitmap.colorType() == kAlpha_8_SkColorType) {
1303         draw.drawBitmapAsMask(bitmap, paint);
1304     } else {
1305         SkAutoBitmapShaderInstall install(bitmap, paint);
1306         const SkPaint& paintWithShader = install.paintWithShader();
1307         const SkRect srcBounds = SkRect::MakeIWH(bitmap.width(), bitmap.height());
1308         if (dstBounds) {
1309             this->drawRect(srcBounds, paintWithShader, &prematrix, dstBounds);
1310         } else {
1311             draw.drawRect(srcBounds, paintWithShader);
1312         }
1313     }
1314 }
1315
1316 void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y,
1317                         const SkPaint& origPaint) const {
1318     SkDEBUGCODE(this->validate();)
1319
1320     // nothing to draw
1321     if (fRC->isEmpty() ||
1322             bitmap.width() == 0 || bitmap.height() == 0 ||
1323             bitmap.colorType() == kUnknown_SkColorType) {
1324         return;
1325     }
1326
1327     SkIRect    bounds;
1328     bounds.set(x, y, x + bitmap.width(), y + bitmap.height());
1329
1330     if (fRC->quickReject(bounds)) {
1331         return; // nothing to draw
1332     }
1333
1334     SkPaint paint(origPaint);
1335     paint.setStyle(SkPaint::kFill_Style);
1336
1337     if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, bitmap)) {
1338         SkTBlitterAllocator allocator;
1339         // blitter will be owned by the allocator.
1340         SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap,
1341                                                      x, y, &allocator);
1342
1343         if (blitter) {
1344             SkScan::FillIRect(bounds, *fRC, blitter);
1345             return;
1346         }
1347     }
1348
1349     SkMatrix        matrix;
1350     SkRect          r;
1351
1352     // get a scalar version of our rect
1353     r.set(bounds);
1354
1355     // create shader with offset
1356     matrix.setTranslate(r.fLeft, r.fTop);
1357     SkAutoBitmapShaderInstall install(bitmap, paint, &matrix);
1358     const SkPaint& shaderPaint = install.paintWithShader();
1359
1360     SkDraw draw(*this);
1361     matrix.reset();
1362     draw.fMatrix = &matrix;
1363     // call ourself with a rect
1364     // is this OK if paint has a rasterizer?
1365     draw.drawRect(r, shaderPaint);
1366 }
1367
1368 ///////////////////////////////////////////////////////////////////////////////
1369
1370 #include "SkScalerContext.h"
1371 #include "SkGlyphCache.h"
1372 #include "SkTextToPathIter.h"
1373 #include "SkUtils.h"
1374
1375 static void measure_text(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
1376                 const char text[], size_t byteLength, SkVector* stopVector) {
1377     SkFixed     x = 0, y = 0;
1378     const char* stop = text + byteLength;
1379
1380     SkAutoKern  autokern;
1381
1382     while (text < stop) {
1383         // don't need x, y here, since all subpixel variants will have the
1384         // same advance
1385         const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1386
1387         x += autokern.adjust(glyph) + glyph.fAdvanceX;
1388         y += glyph.fAdvanceY;
1389     }
1390     stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y));
1391
1392     SkASSERT(text == stop);
1393 }
1394
1395 bool SkDraw::ShouldDrawTextAsPaths(const SkPaint& paint, const SkMatrix& ctm) {
1396     // hairline glyphs are fast enough so we don't need to cache them
1397     if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) {
1398         return true;
1399     }
1400
1401     // we don't cache perspective
1402     if (ctm.hasPerspective()) {
1403         return true;
1404     }
1405
1406     SkMatrix textM;
1407     return SkPaint::TooBigToUseCache(ctm, *paint.setTextMatrix(&textM));
1408 }
1409
1410 void SkDraw::drawText_asPaths(const char text[], size_t byteLength,
1411                               SkScalar x, SkScalar y,
1412                               const SkPaint& paint) const {
1413     SkDEBUGCODE(this->validate();)
1414
1415     SkTextToPathIter iter(text, byteLength, paint, true);
1416
1417     SkMatrix    matrix;
1418     matrix.setScale(iter.getPathScale(), iter.getPathScale());
1419     matrix.postTranslate(x, y);
1420
1421     const SkPath* iterPath;
1422     SkScalar xpos, prevXPos = 0;
1423
1424     while (iter.next(&iterPath, &xpos)) {
1425         matrix.postTranslate(xpos - prevXPos, 0);
1426         if (iterPath) {
1427             const SkPaint& pnt = iter.getPaint();
1428             if (fDevice) {
1429                 fDevice->drawPath(*this, *iterPath, pnt, &matrix, false);
1430             } else {
1431                 this->drawPath(*iterPath, pnt, &matrix, false);
1432             }
1433         }
1434         prevXPos = xpos;
1435     }
1436 }
1437
1438 // disable warning : local variable used without having been initialized
1439 #if defined _WIN32 && _MSC_VER >= 1300
1440 #pragma warning ( push )
1441 #pragma warning ( disable : 4701 )
1442 #endif
1443
1444 //////////////////////////////////////////////////////////////////////////////
1445
1446 static void D1G_RectClip(const SkDraw1Glyph& state, Sk48Dot16 fx, Sk48Dot16 fy, const SkGlyph& glyph) {
1447     // Prevent glyphs from being drawn outside of or straddling the edge of device space.
1448     if ((fx >> 16) > INT_MAX - (INT16_MAX + UINT16_MAX) ||
1449         (fx >> 16) < INT_MIN - (INT16_MIN + 0 /*UINT16_MIN*/) ||
1450         (fy >> 16) > INT_MAX - (INT16_MAX + UINT16_MAX) ||
1451         (fy >> 16) < INT_MIN - (INT16_MIN + 0 /*UINT16_MIN*/))
1452     {
1453         return;
1454     }
1455
1456     int left = Sk48Dot16FloorToInt(fx);
1457     int top = Sk48Dot16FloorToInt(fy);
1458     SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);
1459     SkASSERT((NULL == state.fClip && state.fAAClip) ||
1460              (state.fClip && NULL == state.fAAClip && state.fClip->isRect()));
1461
1462     left += glyph.fLeft;
1463     top  += glyph.fTop;
1464
1465     int right   = left + glyph.fWidth;
1466     int bottom  = top + glyph.fHeight;
1467
1468     SkMask        mask;
1469     SkIRect        storage;
1470     SkIRect*    bounds = &mask.fBounds;
1471
1472     mask.fBounds.set(left, top, right, bottom);
1473
1474     // this extra test is worth it, assuming that most of the time it succeeds
1475     // since we can avoid writing to storage
1476     if (!state.fClipBounds.containsNoEmptyCheck(left, top, right, bottom)) {
1477         if (!storage.intersectNoEmptyCheck(mask.fBounds, state.fClipBounds))
1478             return;
1479         bounds = &storage;
1480     }
1481
1482     uint8_t* aa = (uint8_t*)glyph.fImage;
1483     if (NULL == aa) {
1484         aa = (uint8_t*)state.fCache->findImage(glyph);
1485         if (NULL == aa) {
1486             return; // can't rasterize glyph
1487         }
1488     }
1489
1490     mask.fRowBytes = glyph.rowBytes();
1491     mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
1492     mask.fImage = aa;
1493     state.blitMask(mask, *bounds);
1494 }
1495
1496 static void D1G_RgnClip(const SkDraw1Glyph& state, Sk48Dot16 fx, Sk48Dot16 fy, const SkGlyph& glyph) {
1497     int left = Sk48Dot16FloorToInt(fx);
1498     int top = Sk48Dot16FloorToInt(fy);
1499     SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);
1500     SkASSERT(!state.fClip->isRect());
1501
1502     SkMask  mask;
1503
1504     left += glyph.fLeft;
1505     top  += glyph.fTop;
1506
1507     mask.fBounds.set(left, top, left + glyph.fWidth, top + glyph.fHeight);
1508     SkRegion::Cliperator clipper(*state.fClip, mask.fBounds);
1509
1510     if (!clipper.done()) {
1511         const SkIRect&  cr = clipper.rect();
1512         const uint8_t*  aa = (const uint8_t*)glyph.fImage;
1513         if (NULL == aa) {
1514             aa = (uint8_t*)state.fCache->findImage(glyph);
1515             if (NULL == aa) {
1516                 return;
1517             }
1518         }
1519
1520         mask.fRowBytes = glyph.rowBytes();
1521         mask.fFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
1522         mask.fImage = (uint8_t*)aa;
1523         do {
1524             state.blitMask(mask, cr);
1525             clipper.next();
1526         } while (!clipper.done());
1527     }
1528 }
1529
1530 static bool hasCustomD1GProc(const SkDraw& draw) {
1531     return draw.fProcs && draw.fProcs->fD1GProc;
1532 }
1533
1534 static bool needsRasterTextBlit(const SkDraw& draw) {
1535     return !hasCustomD1GProc(draw);
1536 }
1537
1538 SkDraw1Glyph::Proc SkDraw1Glyph::init(const SkDraw* draw, SkBlitter* blitter, SkGlyphCache* cache,
1539                                       const SkPaint& pnt) {
1540     fDraw = draw;
1541     fBlitter = blitter;
1542     fCache = cache;
1543     fPaint = &pnt;
1544
1545     if (cache->isSubpixel()) {
1546         fHalfSampleX = fHalfSampleY = SkFixedToScalar(SkGlyph::kSubpixelRound);
1547     } else {
1548         fHalfSampleX = fHalfSampleY = SK_ScalarHalf;
1549     }
1550
1551     if (hasCustomD1GProc(*draw)) {
1552         // todo: fix this assumption about clips w/ custom
1553         fClip = draw->fClip;
1554         fClipBounds = fClip->getBounds();
1555         return draw->fProcs->fD1GProc;
1556     }
1557
1558     if (draw->fRC->isBW()) {
1559         fAAClip = NULL;
1560         fClip = &draw->fRC->bwRgn();
1561         fClipBounds = fClip->getBounds();
1562         if (fClip->isRect()) {
1563             return D1G_RectClip;
1564         } else {
1565             return D1G_RgnClip;
1566         }
1567     } else {    // aaclip
1568         fAAClip = &draw->fRC->aaRgn();
1569         fClip = NULL;
1570         fClipBounds = fAAClip->getBounds();
1571         return D1G_RectClip;
1572     }
1573 }
1574
1575 void SkDraw1Glyph::blitMaskAsSprite(const SkMask& mask) const {
1576     SkASSERT(SkMask::kARGB32_Format == mask.fFormat);
1577
1578     SkBitmap bm;
1579     bm.installPixels(SkImageInfo::MakeN32Premul(mask.fBounds.width(), mask.fBounds.height()),
1580                      (SkPMColor*)mask.fImage, mask.fRowBytes);
1581
1582     fDraw->drawSprite(bm, mask.fBounds.x(), mask.fBounds.y(), *fPaint);
1583 }
1584
1585 ///////////////////////////////////////////////////////////////////////////////
1586
1587 void SkDraw::drawText(const char text[], size_t byteLength,
1588                       SkScalar x, SkScalar y, const SkPaint& paint) const {
1589     SkASSERT(byteLength == 0 || text != NULL);
1590
1591     SkDEBUGCODE(this->validate();)
1592
1593     // nothing to draw
1594     if (text == NULL || byteLength == 0 || fRC->isEmpty()) {
1595         return;
1596     }
1597
1598     // SkScalarRec doesn't currently have a way of representing hairline stroke and
1599     // will fill if its frame-width is 0.
1600     if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
1601         this->drawText_asPaths(text, byteLength, x, y, paint);
1602         return;
1603     }
1604
1605     SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
1606
1607     SkAutoGlyphCache    autoCache(paint, &fDevice->getLeakyProperties(), fMatrix);
1608     SkGlyphCache*       cache = autoCache.getCache();
1609
1610     // transform our starting point
1611     {
1612         SkPoint loc;
1613         fMatrix->mapXY(x, y, &loc);
1614         x = loc.fX;
1615         y = loc.fY;
1616     }
1617
1618     // need to measure first
1619     if (paint.getTextAlign() != SkPaint::kLeft_Align) {
1620         SkVector    stop;
1621
1622         measure_text(cache, glyphCacheProc, text, byteLength, &stop);
1623
1624         SkScalar    stopX = stop.fX;
1625         SkScalar    stopY = stop.fY;
1626
1627         if (paint.getTextAlign() == SkPaint::kCenter_Align) {
1628             stopX = SkScalarHalf(stopX);
1629             stopY = SkScalarHalf(stopY);
1630         }
1631         x -= stopX;
1632         y -= stopY;
1633     }
1634
1635     const char* stop = text + byteLength;
1636
1637     SkAAClipBlitter     aaBlitter;
1638     SkAutoBlitterChoose blitterChooser;
1639     SkBlitter*          blitter = NULL;
1640     if (needsRasterTextBlit(*this)) {
1641         blitterChooser.choose(*fBitmap, *fMatrix, paint);
1642         blitter = blitterChooser.get();
1643         if (fRC->isAA()) {
1644             aaBlitter.init(blitter, &fRC->aaRgn());
1645             blitter = &aaBlitter;
1646         }
1647     }
1648
1649     SkAutoKern          autokern;
1650     SkDraw1Glyph        d1g;
1651     SkDraw1Glyph::Proc  proc = d1g.init(this, blitter, cache, paint);
1652
1653     SkFixed fxMask = ~0;
1654     SkFixed fyMask = ~0;
1655     if (cache->isSubpixel()) {
1656         SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix);
1657         if (kX_SkAxisAlignment == baseline) {
1658             fyMask = 0;
1659             d1g.fHalfSampleY = SK_ScalarHalf;
1660         } else if (kY_SkAxisAlignment == baseline) {
1661             fxMask = 0;
1662             d1g.fHalfSampleX = SK_ScalarHalf;
1663         }
1664     }
1665
1666     Sk48Dot16 fx = SkScalarTo48Dot16(x + d1g.fHalfSampleX);
1667     Sk48Dot16 fy = SkScalarTo48Dot16(y + d1g.fHalfSampleY);
1668
1669     while (text < stop) {
1670         const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask);
1671
1672         fx += autokern.adjust(glyph);
1673
1674         if (glyph.fWidth) {
1675             proc(d1g, fx, fy, glyph);
1676         }
1677
1678         fx += glyph.fAdvanceX;
1679         fy += glyph.fAdvanceY;
1680     }
1681 }
1682
1683 //////////////////////////////////////////////////////////////////////////////
1684
1685 void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength,
1686                                  const SkScalar pos[], int scalarsPerPosition,
1687                                  const SkPoint& offset, const SkPaint& origPaint) const {
1688     // setup our std paint, in hopes of getting hits in the cache
1689     SkPaint paint(origPaint);
1690     SkScalar matrixScale = paint.setupForAsPaths();
1691
1692     SkMatrix matrix;
1693     matrix.setScale(matrixScale, matrixScale);
1694
1695     // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache.
1696     paint.setStyle(SkPaint::kFill_Style);
1697     paint.setPathEffect(NULL);
1698
1699     SkDrawCacheProc     glyphCacheProc = paint.getDrawCacheProc();
1700     SkAutoGlyphCache    autoCache(paint, NULL, NULL);
1701     SkGlyphCache*       cache = autoCache.getCache();
1702
1703     const char*        stop = text + byteLength;
1704     SkTextAlignProc    alignProc(paint.getTextAlign());
1705     SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
1706
1707     // Now restore the original settings, so we "draw" with whatever style/stroking.
1708     paint.setStyle(origPaint.getStyle());
1709     paint.setPathEffect(origPaint.getPathEffect());
1710
1711     while (text < stop) {
1712         const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1713         if (glyph.fWidth) {
1714             const SkPath* path = cache->findPath(glyph);
1715             if (path) {
1716                 SkPoint tmsLoc;
1717                 tmsProc(pos, &tmsLoc);
1718                 SkPoint loc;
1719                 alignProc(tmsLoc, glyph, &loc);
1720
1721                 matrix[SkMatrix::kMTransX] = loc.fX;
1722                 matrix[SkMatrix::kMTransY] = loc.fY;
1723                 if (fDevice) {
1724                     fDevice->drawPath(*this, *path, paint, &matrix, false);
1725                 } else {
1726                     this->drawPath(*path, paint, &matrix, false);
1727                 }
1728             }
1729         }
1730         pos += scalarsPerPosition;
1731     }
1732 }
1733
1734 void SkDraw::drawPosText(const char text[], size_t byteLength,
1735                          const SkScalar pos[], int scalarsPerPosition,
1736                          const SkPoint& offset, const SkPaint& paint) const {
1737     SkASSERT(byteLength == 0 || text != NULL);
1738     SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
1739
1740     SkDEBUGCODE(this->validate();)
1741
1742     // nothing to draw
1743     if (text == NULL || byteLength == 0 || fRC->isEmpty()) {
1744         return;
1745     }
1746
1747     if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
1748         this->drawPosText_asPaths(text, byteLength, pos, scalarsPerPosition, offset, paint);
1749         return;
1750     }
1751
1752     SkDrawCacheProc     glyphCacheProc = paint.getDrawCacheProc();
1753     SkAutoGlyphCache    autoCache(paint, &fDevice->getLeakyProperties(), fMatrix);
1754     SkGlyphCache*       cache = autoCache.getCache();
1755
1756     SkAAClipBlitterWrapper wrapper;
1757     SkAutoBlitterChoose blitterChooser;
1758     SkBlitter* blitter = NULL;
1759     if (needsRasterTextBlit(*this)) {
1760         blitterChooser.choose(*fBitmap, *fMatrix, paint);
1761         blitter = blitterChooser.get();
1762         if (fRC->isAA()) {
1763             wrapper.init(*fRC, blitter);
1764             blitter = wrapper.getBlitter();
1765         }
1766     }
1767
1768     const char*        stop = text + byteLength;
1769     SkTextAlignProc    alignProc(paint.getTextAlign());
1770     SkDraw1Glyph       d1g;
1771     SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint);
1772     SkTextMapStateProc tmsProc(*fMatrix, offset, scalarsPerPosition);
1773
1774     if (cache->isSubpixel()) {
1775         // maybe we should skip the rounding if linearText is set
1776         SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*fMatrix);
1777
1778         SkFixed fxMask = ~0;
1779         SkFixed fyMask = ~0;
1780         if (kX_SkAxisAlignment == baseline) {
1781             fyMask = 0;
1782             d1g.fHalfSampleY = SK_ScalarHalf;
1783         } else if (kY_SkAxisAlignment == baseline) {
1784             fxMask = 0;
1785             d1g.fHalfSampleX = SK_ScalarHalf;
1786         }
1787
1788         if (SkPaint::kLeft_Align == paint.getTextAlign()) {
1789             while (text < stop) {
1790                 SkPoint tmsLoc;
1791                 tmsProc(pos, &tmsLoc);
1792
1793                 Sk48Dot16 fx = SkScalarTo48Dot16(tmsLoc.fX + d1g.fHalfSampleX);
1794                 Sk48Dot16 fy = SkScalarTo48Dot16(tmsLoc.fY + d1g.fHalfSampleY);
1795
1796                 const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask);
1797
1798                 if (glyph.fWidth) {
1799                     proc(d1g, fx, fy, glyph);
1800                 }
1801                 pos += scalarsPerPosition;
1802             }
1803         } else {
1804             while (text < stop) {
1805                 const char* currentText = text;
1806                 const SkGlyph& metricGlyph = glyphCacheProc(cache, &text, 0, 0);
1807
1808                 if (metricGlyph.fWidth) {
1809                     SkDEBUGCODE(SkFixed prevAdvX = metricGlyph.fAdvanceX;)
1810                     SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;)
1811                     SkPoint tmsLoc;
1812                     tmsProc(pos, &tmsLoc);
1813
1814                     SkPoint alignLoc;
1815                     alignProc(tmsLoc, metricGlyph, &alignLoc);
1816
1817                     Sk48Dot16 fx = SkScalarTo48Dot16(alignLoc.fX + d1g.fHalfSampleX);
1818                     Sk48Dot16 fy = SkScalarTo48Dot16(alignLoc.fY + d1g.fHalfSampleY);
1819
1820                     // have to call again, now that we've been "aligned"
1821                     const SkGlyph& glyph = glyphCacheProc(cache, &currentText,
1822                                                           fx & fxMask, fy & fyMask);
1823                     // the assumption is that the metrics haven't changed
1824                     SkASSERT(prevAdvX == glyph.fAdvanceX);
1825                     SkASSERT(prevAdvY == glyph.fAdvanceY);
1826                     SkASSERT(glyph.fWidth);
1827
1828                     proc(d1g, fx, fy, glyph);
1829                 }
1830                 pos += scalarsPerPosition;
1831             }
1832         }
1833     } else {    // not subpixel
1834         if (SkPaint::kLeft_Align == paint.getTextAlign()) {
1835             while (text < stop) {
1836                 // the last 2 parameters are ignored
1837                 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1838
1839                 if (glyph.fWidth) {
1840                     SkPoint tmsLoc;
1841                     tmsProc(pos, &tmsLoc);
1842
1843                     proc(d1g,
1844                          SkScalarTo48Dot16(tmsLoc.fX + SK_ScalarHalf), //d1g.fHalfSampleX,
1845                          SkScalarTo48Dot16(tmsLoc.fY + SK_ScalarHalf), //d1g.fHalfSampleY,
1846                          glyph);
1847                 }
1848                 pos += scalarsPerPosition;
1849             }
1850         } else {
1851             while (text < stop) {
1852                 // the last 2 parameters are ignored
1853                 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
1854
1855                 if (glyph.fWidth) {
1856                     SkPoint tmsLoc;
1857                     tmsProc(pos, &tmsLoc);
1858
1859                     SkPoint alignLoc;
1860                     alignProc(tmsLoc, glyph, &alignLoc);
1861
1862                     proc(d1g,
1863                          SkScalarTo48Dot16(alignLoc.fX + SK_ScalarHalf), //d1g.fHalfSampleX,
1864                          SkScalarTo48Dot16(alignLoc.fY + SK_ScalarHalf), //d1g.fHalfSampleY,
1865                          glyph);
1866                 }
1867                 pos += scalarsPerPosition;
1868             }
1869         }
1870     }
1871 }
1872
1873 #if defined _WIN32 && _MSC_VER >= 1300
1874 #pragma warning ( pop )
1875 #endif
1876
1877 ///////////////////////////////////////////////////////////////////////////////
1878
1879 typedef void (*HairProc)(const SkPoint&, const SkPoint&, const SkRasterClip&,
1880                          SkBlitter*);
1881
1882 static HairProc ChooseHairProc(bool doAntiAlias) {
1883     return doAntiAlias ? SkScan::AntiHairLine : SkScan::HairLine;
1884 }
1885
1886 static bool texture_to_matrix(const VertState& state, const SkPoint verts[],
1887                               const SkPoint texs[], SkMatrix* matrix) {
1888     SkPoint src[3], dst[3];
1889
1890     src[0] = texs[state.f0];
1891     src[1] = texs[state.f1];
1892     src[2] = texs[state.f2];
1893     dst[0] = verts[state.f0];
1894     dst[1] = verts[state.f1];
1895     dst[2] = verts[state.f2];
1896     return matrix->setPolyToPoly(src, dst, 3);
1897 }
1898
1899 class SkTriColorShader : public SkShader {
1900 public:
1901     SkTriColorShader() {}
1902
1903     size_t contextSize() const override;
1904
1905     class TriColorShaderContext : public SkShader::Context {
1906     public:
1907         TriColorShaderContext(const SkTriColorShader& shader, const ContextRec&);
1908         virtual ~TriColorShaderContext();
1909
1910         bool setup(const SkPoint pts[], const SkColor colors[], int, int, int);
1911
1912         void shadeSpan(int x, int y, SkPMColor dstC[], int count) override;
1913
1914     private:
1915         SkMatrix    fDstToUnit;
1916         SkPMColor   fColors[3];
1917
1918         typedef SkShader::Context INHERITED;
1919     };
1920
1921     SK_TO_STRING_OVERRIDE()
1922
1923     // For serialization.  This will never be called.
1924     Factory getFactory() const override { sk_throw(); return NULL; }
1925
1926 protected:
1927     Context* onCreateContext(const ContextRec& rec, void* storage) const override {
1928         return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, rec));
1929     }
1930
1931 private:
1932     typedef SkShader INHERITED;
1933 };
1934
1935 bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const SkColor colors[],
1936                                                     int index0, int index1, int index2) {
1937
1938     fColors[0] = SkPreMultiplyColor(colors[index0]);
1939     fColors[1] = SkPreMultiplyColor(colors[index1]);
1940     fColors[2] = SkPreMultiplyColor(colors[index2]);
1941
1942     SkMatrix m, im;
1943     m.reset();
1944     m.set(0, pts[index1].fX - pts[index0].fX);
1945     m.set(1, pts[index2].fX - pts[index0].fX);
1946     m.set(2, pts[index0].fX);
1947     m.set(3, pts[index1].fY - pts[index0].fY);
1948     m.set(4, pts[index2].fY - pts[index0].fY);
1949     m.set(5, pts[index0].fY);
1950     if (!m.invert(&im)) {
1951         return false;
1952     }
1953     // We can't call getTotalInverse(), because we explicitly don't want to look at the localmatrix
1954     // as our interators are intrinsically tied to the vertices, and nothing else.
1955     SkMatrix ctmInv;
1956     if (!this->getCTM().invert(&ctmInv)) {
1957         return false;
1958     }
1959     fDstToUnit.setConcat(im, ctmInv);
1960     return true;
1961 }
1962
1963 #include "SkColorPriv.h"
1964 #include "SkComposeShader.h"
1965
1966 static int ScalarTo256(SkScalar v) {
1967     int scale = SkScalarToFixed(v) >> 8;
1968     if (scale < 0) {
1969         scale = 0;
1970     }
1971     if (scale > 255) {
1972         scale = 255;
1973     }
1974     return SkAlpha255To256(scale);
1975 }
1976
1977
1978 SkTriColorShader::TriColorShaderContext::TriColorShaderContext(const SkTriColorShader& shader,
1979                                                                const ContextRec& rec)
1980     : INHERITED(shader, rec) {}
1981
1982 SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {}
1983
1984 size_t SkTriColorShader::contextSize() const {
1985     return sizeof(TriColorShaderContext);
1986 }
1987 void SkTriColorShader::TriColorShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
1988     const int alphaScale = Sk255To256(this->getPaintAlpha());
1989
1990     SkPoint src;
1991
1992     for (int i = 0; i < count; i++) {
1993         fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src);
1994         x += 1;
1995
1996         int scale1 = ScalarTo256(src.fX);
1997         int scale2 = ScalarTo256(src.fY);
1998         int scale0 = 256 - scale1 - scale2;
1999         if (scale0 < 0) {
2000             if (scale1 > scale2) {
2001                 scale2 = 256 - scale1;
2002             } else {
2003                 scale1 = 256 - scale2;
2004             }
2005             scale0 = 0;
2006         }
2007
2008         if (256 != alphaScale) {
2009             scale0 = SkAlphaMul(scale0, alphaScale);
2010             scale1 = SkAlphaMul(scale1, alphaScale);
2011             scale2 = SkAlphaMul(scale2, alphaScale);
2012         }
2013
2014         dstC[i] = SkAlphaMulQ(fColors[0], scale0) +
2015                   SkAlphaMulQ(fColors[1], scale1) +
2016                   SkAlphaMulQ(fColors[2], scale2);
2017     }
2018 }
2019
2020 #ifndef SK_IGNORE_TO_STRING
2021 void SkTriColorShader::toString(SkString* str) const {
2022     str->append("SkTriColorShader: (");
2023
2024     this->INHERITED::toString(str);
2025
2026     str->append(")");
2027 }
2028 #endif
2029
2030 void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
2031                           const SkPoint vertices[], const SkPoint textures[],
2032                           const SkColor colors[], SkXfermode* xmode,
2033                           const uint16_t indices[], int indexCount,
2034                           const SkPaint& paint) const {
2035     SkASSERT(0 == count || vertices);
2036
2037     // abort early if there is nothing to draw
2038     if (count < 3 || (indices && indexCount < 3) || fRC->isEmpty()) {
2039         return;
2040     }
2041
2042     // transform out vertices into device coordinates
2043     SkAutoSTMalloc<16, SkPoint> storage(count);
2044     SkPoint* devVerts = storage.get();
2045     fMatrix->mapPoints(devVerts, vertices, count);
2046
2047     /*
2048         We can draw the vertices in 1 of 4 ways:
2049
2050         - solid color (no shader/texture[], no colors[])
2051         - just colors (no shader/texture[], has colors[])
2052         - just texture (has shader/texture[], no colors[])
2053         - colors * texture (has shader/texture[], has colors[])
2054
2055         Thus for texture drawing, we need both texture[] and a shader.
2056     */
2057
2058     SkTriColorShader triShader; // must be above declaration of p
2059     SkPaint p(paint);
2060
2061     SkShader* shader = p.getShader();
2062     if (NULL == shader) {
2063         // if we have no shader, we ignore the texture coordinates
2064         textures = NULL;
2065     } else if (NULL == textures) {
2066         // if we don't have texture coordinates, ignore the shader
2067         p.setShader(NULL);
2068         shader = NULL;
2069     }
2070
2071     // setup the custom shader (if needed)
2072     SkAutoTUnref<SkComposeShader> composeShader;
2073     if (colors) {
2074         if (NULL == textures) {
2075             // just colors (no texture)
2076             shader = p.setShader(&triShader);
2077         } else {
2078             // colors * texture
2079             SkASSERT(shader);
2080             bool releaseMode = false;
2081             if (NULL == xmode) {
2082                 xmode = SkXfermode::Create(SkXfermode::kModulate_Mode);
2083                 releaseMode = true;
2084             }
2085             composeShader.reset(SkNEW_ARGS(SkComposeShader, (&triShader, shader, xmode)));
2086             p.setShader(composeShader);
2087             if (releaseMode) {
2088                 xmode->unref();
2089             }
2090         }
2091     }
2092
2093     SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p);
2094     // Abort early if we failed to create a shader context.
2095     if (blitter->isNullBlitter()) {
2096         return;
2097     }
2098
2099     // setup our state and function pointer for iterating triangles
2100     VertState       state(count, indices, indexCount);
2101     VertState::Proc vertProc = state.chooseProc(vmode);
2102
2103     if (textures || colors) {
2104         while (vertProc(&state)) {
2105             if (textures) {
2106                 SkMatrix tempM;
2107                 if (texture_to_matrix(state, vertices, textures, &tempM)) {
2108                     SkShader::ContextRec rec(*fBitmap, p, *fMatrix);
2109                     rec.fLocalMatrix = &tempM;
2110                     if (!blitter->resetShaderContext(rec)) {
2111                         continue;
2112                     }
2113                 }
2114             }
2115             if (colors) {
2116                 // Find the context for triShader.
2117                 SkTriColorShader::TriColorShaderContext* triColorShaderContext;
2118
2119                 SkShader::Context* shaderContext = blitter->getShaderContext();
2120                 SkASSERT(shaderContext);
2121                 if (p.getShader() == &triShader) {
2122                     triColorShaderContext =
2123                             static_cast<SkTriColorShader::TriColorShaderContext*>(shaderContext);
2124                 } else {
2125                     // The shader is a compose shader and triShader is its first shader.
2126                     SkASSERT(p.getShader() == composeShader);
2127                     SkASSERT(composeShader->getShaderA() == &triShader);
2128                     SkComposeShader::ComposeShaderContext* composeShaderContext =
2129                             static_cast<SkComposeShader::ComposeShaderContext*>(shaderContext);
2130                     SkShader::Context* shaderContextA = composeShaderContext->getShaderContextA();
2131                     triColorShaderContext =
2132                             static_cast<SkTriColorShader::TriColorShaderContext*>(shaderContextA);
2133                 }
2134
2135                 if (!triColorShaderContext->setup(vertices, colors,
2136                                                   state.f0, state.f1, state.f2)) {
2137                     continue;
2138                 }
2139             }
2140
2141             SkPoint tmp[] = {
2142                 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2]
2143             };
2144             SkScan::FillTriangle(tmp, *fRC, blitter.get());
2145         }
2146     } else {
2147         // no colors[] and no texture, stroke hairlines with paint's color.
2148         HairProc hairProc = ChooseHairProc(paint.isAntiAlias());
2149         const SkRasterClip& clip = *fRC;
2150         while (vertProc(&state)) {
2151             hairProc(devVerts[state.f0], devVerts[state.f1], clip, blitter.get());
2152             hairProc(devVerts[state.f1], devVerts[state.f2], clip, blitter.get());
2153             hairProc(devVerts[state.f2], devVerts[state.f0], clip, blitter.get());
2154         }
2155     }
2156 }
2157
2158 ///////////////////////////////////////////////////////////////////////////////
2159 ///////////////////////////////////////////////////////////////////////////////
2160
2161 #ifdef SK_DEBUG
2162
2163 void SkDraw::validate() const {
2164     SkASSERT(fBitmap != NULL);
2165     SkASSERT(fMatrix != NULL);
2166     SkASSERT(fClip != NULL);
2167     SkASSERT(fRC != NULL);
2168
2169     const SkIRect&  cr = fRC->getBounds();
2170     SkIRect         br;
2171
2172     br.set(0, 0, fBitmap->width(), fBitmap->height());
2173     SkASSERT(cr.isEmpty() || br.contains(cr));
2174 }
2175
2176 #endif
2177
2178 ////////////////////////////////////////////////////////////////////////////////////////////////
2179
2180 #include "SkPath.h"
2181 #include "SkDraw.h"
2182 #include "SkRegion.h"
2183 #include "SkBlitter.h"
2184
2185 static bool compute_bounds(const SkPath& devPath, const SkIRect* clipBounds,
2186                            const SkMaskFilter* filter, const SkMatrix* filterMatrix,
2187                            SkIRect* bounds) {
2188     if (devPath.isEmpty()) {
2189         return false;
2190     }
2191
2192     //  init our bounds from the path
2193     *bounds = devPath.getBounds().makeOutset(SK_ScalarHalf, SK_ScalarHalf).roundOut();
2194
2195     SkIPoint margin = SkIPoint::Make(0, 0);
2196     if (filter) {
2197         SkASSERT(filterMatrix);
2198
2199         SkMask srcM, dstM;
2200
2201         srcM.fBounds = *bounds;
2202         srcM.fFormat = SkMask::kA8_Format;
2203         srcM.fImage = NULL;
2204         if (!filter->filterMask(&dstM, srcM, *filterMatrix, &margin)) {
2205             return false;
2206         }
2207     }
2208
2209     // (possibly) trim the bounds to reflect the clip
2210     // (plus whatever slop the filter needs)
2211     if (clipBounds) {
2212         // Ugh. Guard against gigantic margins from wacky filters. Without this
2213         // check we can request arbitrary amounts of slop beyond our visible
2214         // clip, and bring down the renderer (at least on finite RAM machines
2215         // like handsets, etc.). Need to balance this invented value between
2216         // quality of large filters like blurs, and the corresponding memory
2217         // requests.
2218         static const int MAX_MARGIN = 128;
2219         if (!bounds->intersect(clipBounds->makeOutset(SkMin32(margin.fX, MAX_MARGIN),
2220                                                       SkMin32(margin.fY, MAX_MARGIN)))) {
2221             return false;
2222         }
2223     }
2224
2225     return true;
2226 }
2227
2228 static void draw_into_mask(const SkMask& mask, const SkPath& devPath,
2229                            SkPaint::Style style) {
2230     SkBitmap        bm;
2231     SkDraw          draw;
2232     SkRasterClip    clip;
2233     SkMatrix        matrix;
2234     SkPaint         paint;
2235
2236     bm.installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), mask.fBounds.height()),
2237                      mask.fImage, mask.fRowBytes);
2238
2239     clip.setRect(SkIRect::MakeWH(mask.fBounds.width(), mask.fBounds.height()));
2240     matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
2241                         -SkIntToScalar(mask.fBounds.fTop));
2242
2243     draw.fBitmap    = &bm;
2244     draw.fRC        = &clip;
2245     draw.fClip      = &clip.bwRgn();
2246     draw.fMatrix    = &matrix;
2247     paint.setAntiAlias(true);
2248     paint.setStyle(style);
2249     draw.drawPath(devPath, paint);
2250 }
2251
2252 bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
2253                         const SkMaskFilter* filter, const SkMatrix* filterMatrix,
2254                         SkMask* mask, SkMask::CreateMode mode,
2255                         SkPaint::Style style) {
2256     if (SkMask::kJustRenderImage_CreateMode != mode) {
2257         if (!compute_bounds(devPath, clipBounds, filter, filterMatrix, &mask->fBounds))
2258             return false;
2259     }
2260
2261     if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) {
2262         mask->fFormat = SkMask::kA8_Format;
2263         mask->fRowBytes = mask->fBounds.width();
2264         size_t size = mask->computeImageSize();
2265         if (0 == size) {
2266             // we're too big to allocate the mask, abort
2267             return false;
2268         }
2269         mask->fImage = SkMask::AllocImage(size);
2270         memset(mask->fImage, 0, mask->computeImageSize());
2271     }
2272
2273     if (SkMask::kJustComputeBounds_CreateMode != mode) {
2274         draw_into_mask(*mask, devPath, style);
2275     }
2276
2277     return true;
2278 }