afd7fbef88bd82c97f7b9b6ced77e259209417cc
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkCanvas.cpp
1 /*
2  * Copyright 2008 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 "SkCanvas.h"
9 #include "SkCanvasPriv.h"
10 #include "SkBitmapDevice.h"
11 #include "SkDeviceImageFilterProxy.h"
12 #include "SkDraw.h"
13 #include "SkDrawFilter.h"
14 #include "SkDrawLooper.h"
15 #include "SkImage.h"
16 #include "SkMetaData.h"
17 #include "SkPathOps.h"
18 #include "SkPatchUtils.h"
19 #include "SkPicture.h"
20 #include "SkRasterClip.h"
21 #include "SkRRect.h"
22 #include "SkSmallAllocator.h"
23 #include "SkSurface_Base.h"
24 #include "SkTemplates.h"
25 #include "SkTextBlob.h"
26 #include "SkTextFormatParams.h"
27 #include "SkTLazy.h"
28 #include "SkUtils.h"
29
30 #if SK_SUPPORT_GPU
31 #include "GrRenderTarget.h"
32 #endif
33
34 // experimental for faster tiled drawing...
35 //#define SK_ENABLE_CLIP_QUICKREJECT
36
37 //#define SK_TRACE_SAVERESTORE
38
39 #ifdef SK_TRACE_SAVERESTORE
40     static int gLayerCounter;
41     static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); }
42     static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); }
43
44     static int gRecCounter;
45     static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); }
46     static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); }
47
48     static int gCanvasCounter;
49     static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); }
50     static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); }
51 #else
52     #define inc_layer()
53     #define dec_layer()
54     #define inc_rec()
55     #define dec_rec()
56     #define inc_canvas()
57     #define dec_canvas()
58 #endif
59
60 typedef SkTLazy<SkPaint> SkLazyPaint;
61
62 void SkCanvas::predrawNotify() {
63     if (fSurfaceBase) {
64         fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode);
65     }
66 }
67
68 ///////////////////////////////////////////////////////////////////////////////
69
70 static uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) {
71     const uint32_t propFlags = props.flags();
72     if (propFlags & SkSurfaceProps::kDisallowDither_Flag) {
73         flags &= ~SkPaint::kDither_Flag;
74     }
75     if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) {
76         flags &= ~SkPaint::kAntiAlias_Flag;
77     }
78     return flags;
79 }
80
81 ///////////////////////////////////////////////////////////////////////////////
82
83 /*  This is the record we keep for each SkBaseDevice that the user installs.
84     The clip/matrix/proc are fields that reflect the top of the save/restore
85     stack. Whenever the canvas changes, it marks a dirty flag, and then before
86     these are used (assuming we're not on a layer) we rebuild these cache
87     values: they reflect the top of the save stack, but translated and clipped
88     by the device's XY offset and bitmap-bounds.
89 */
90 struct DeviceCM {
91     DeviceCM*           fNext;
92     SkBaseDevice*       fDevice;
93     SkRasterClip        fClip;
94     const SkMatrix*     fMatrix;
95     SkPaint*            fPaint; // may be null (in the future)
96
97     DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas* canvas,
98              bool conservativeRasterClip)
99         : fNext(NULL)
100         , fClip(conservativeRasterClip)
101     {
102         if (NULL != device) {
103             device->ref();
104             device->onAttachToCanvas(canvas);
105         }
106         fDevice = device;
107         fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
108     }
109
110     ~DeviceCM() {
111         if (fDevice) {
112             fDevice->onDetachFromCanvas();
113             fDevice->unref();
114         }
115         SkDELETE(fPaint);
116     }
117
118     void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip,
119                   const SkClipStack& clipStack, SkRasterClip* updateClip) {
120         int x = fDevice->getOrigin().x();
121         int y = fDevice->getOrigin().y();
122         int width = fDevice->width();
123         int height = fDevice->height();
124
125         if ((x | y) == 0) {
126             fMatrix = &totalMatrix;
127             fClip = totalClip;
128         } else {
129             fMatrixStorage = totalMatrix;
130             fMatrixStorage.postTranslate(SkIntToScalar(-x),
131                                          SkIntToScalar(-y));
132             fMatrix = &fMatrixStorage;
133
134             totalClip.translate(-x, -y, &fClip);
135         }
136
137         fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op);
138
139         // intersect clip, but don't translate it (yet)
140
141         if (updateClip) {
142             updateClip->op(SkIRect::MakeXYWH(x, y, width, height),
143                            SkRegion::kDifference_Op);
144         }
145
146         fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack);
147
148 #ifdef SK_DEBUG
149         if (!fClip.isEmpty()) {
150             SkIRect deviceR;
151             deviceR.set(0, 0, width, height);
152             SkASSERT(deviceR.contains(fClip.getBounds()));
153         }
154 #endif
155     }
156
157 private:
158     SkMatrix    fMatrixStorage;
159 };
160
161 /*  This is the record we keep for each save/restore level in the stack.
162     Since a level optionally copies the matrix and/or stack, we have pointers
163     for these fields. If the value is copied for this level, the copy is
164     stored in the ...Storage field, and the pointer points to that. If the
165     value is not copied for this level, we ignore ...Storage, and just point
166     at the corresponding value in the previous level in the stack.
167 */
168 class SkCanvas::MCRec {
169 public:
170     SkRasterClip    fRasterClip;
171     SkMatrix        fMatrix;
172     SkDrawFilter*   fFilter;    // the current filter (or null)
173     DeviceCM*       fLayer;
174     /*  If there are any layers in the stack, this points to the top-most
175         one that is at or below this level in the stack (so we know what
176         bitmap/device to draw into from this level. This value is NOT
177         reference counted, since the real owner is either our fLayer field,
178         or a previous one in a lower level.)
179     */
180     DeviceCM*   fTopLayer;
181
182     MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) {
183         fMatrix.reset();
184         fFilter     = NULL;
185         fLayer      = NULL;
186         fTopLayer   = NULL;
187
188         // don't bother initializing fNext
189         inc_rec();
190     }
191     MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip) {
192         fMatrix = prev.fMatrix;
193         fFilter = SkSafeRef(prev.fFilter);
194         fLayer = NULL;
195         fTopLayer = prev.fTopLayer;
196
197         // don't bother initializing fNext
198         inc_rec();
199     }
200     ~MCRec() {
201         SkSafeUnref(fFilter);
202         SkDELETE(fLayer);
203         dec_rec();
204     }
205 };
206
207 class SkDrawIter : public SkDraw {
208 public:
209     SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) {
210         canvas = canvas->canvasForDrawIter();
211         fCanvas = canvas;
212         canvas->updateDeviceCMCache();
213
214         fClipStack = &canvas->fClipStack;
215         fCurrLayer = canvas->fMCRec->fTopLayer;
216         fSkipEmptyClips = skipEmptyClips;
217     }
218
219     bool next() {
220         // skip over recs with empty clips
221         if (fSkipEmptyClips) {
222             while (fCurrLayer && fCurrLayer->fClip.isEmpty()) {
223                 fCurrLayer = fCurrLayer->fNext;
224             }
225         }
226
227         const DeviceCM* rec = fCurrLayer;
228         if (rec && rec->fDevice) {
229
230             fMatrix = rec->fMatrix;
231             fClip   = &((SkRasterClip*)&rec->fClip)->forceGetBW();
232             fRC     = &rec->fClip;
233             fDevice = rec->fDevice;
234             fBitmap = &fDevice->accessBitmap(true);
235             fPaint  = rec->fPaint;
236             SkDEBUGCODE(this->validate();)
237
238             fCurrLayer = rec->fNext;
239             // fCurrLayer may be NULL now
240
241             return true;
242         }
243         return false;
244     }
245
246     SkBaseDevice* getDevice() const { return fDevice; }
247     int getX() const { return fDevice->getOrigin().x(); }
248     int getY() const { return fDevice->getOrigin().y(); }
249     const SkMatrix& getMatrix() const { return *fMatrix; }
250     const SkRegion& getClip() const { return *fClip; }
251     const SkPaint* getPaint() const { return fPaint; }
252
253 private:
254     SkCanvas*       fCanvas;
255     const DeviceCM* fCurrLayer;
256     const SkPaint*  fPaint;     // May be null.
257     SkBool8         fSkipEmptyClips;
258
259     typedef SkDraw INHERITED;
260 };
261
262 /////////////////////////////////////////////////////////////////////////////
263
264 class AutoDrawLooper {
265 public:
266     AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint,
267                    bool skipLayerForImageFilter = false,
268                    const SkRect* bounds = NULL) : fOrigPaint(paint) {
269         fCanvas = canvas;
270         fFilter = canvas->getDrawFilter();
271         fPaint = &fOrigPaint;
272         fSaveCount = canvas->getSaveCount();
273         fDoClearImageFilter = false;
274         fDone = false;
275
276         if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) {
277             SkPaint tmp;
278             tmp.setImageFilter(fOrigPaint.getImageFilter());
279             (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag,
280                                             true, SkCanvas::kFullLayer_SaveLayerStrategy);
281             // we'll clear the imageFilter for the actual draws in next(), so
282             // it will only be applied during the restore().
283             fDoClearImageFilter = true;
284         }
285
286         if (SkDrawLooper* looper = paint.getLooper()) {
287             void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>(
288                     looper->contextSize());
289             fLooperContext = looper->createContext(canvas, buffer);
290             fIsSimple = false;
291         } else {
292             fLooperContext = NULL;
293             // can we be marked as simple?
294             fIsSimple = !fFilter && !fDoClearImageFilter;
295         }
296
297         uint32_t oldFlags = paint.getFlags();
298         fNewPaintFlags = filter_paint_flags(props, oldFlags);
299         if (fIsSimple && (fNewPaintFlags != oldFlags)) {
300             SkPaint* paint = fLazyPaint.set(fOrigPaint);
301             paint->setFlags(fNewPaintFlags);
302             fPaint = paint;
303             // if we're not simple, doNext() will take care of calling setFlags()
304         }
305     }
306
307     ~AutoDrawLooper() {
308         if (fDoClearImageFilter) {
309             fCanvas->internalRestore();
310         }
311         SkASSERT(fCanvas->getSaveCount() == fSaveCount);
312     }
313
314     const SkPaint& paint() const {
315         SkASSERT(fPaint);
316         return *fPaint;
317     }
318
319     bool next(SkDrawFilter::Type drawType) {
320         if (fDone) {
321             return false;
322         } else if (fIsSimple) {
323             fDone = true;
324             return !fPaint->nothingToDraw();
325         } else {
326             return this->doNext(drawType);
327         }
328     }
329
330 private:
331     SkLazyPaint     fLazyPaint;
332     SkCanvas*       fCanvas;
333     const SkPaint&  fOrigPaint;
334     SkDrawFilter*   fFilter;
335     const SkPaint*  fPaint;
336     int             fSaveCount;
337     uint32_t        fNewPaintFlags;
338     bool            fDoClearImageFilter;
339     bool            fDone;
340     bool            fIsSimple;
341     SkDrawLooper::Context* fLooperContext;
342     SkSmallAllocator<1, 32> fLooperContextAllocator;
343
344     bool doNext(SkDrawFilter::Type drawType);
345 };
346
347 bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) {
348     fPaint = NULL;
349     SkASSERT(!fIsSimple);
350     SkASSERT(fLooperContext || fFilter || fDoClearImageFilter);
351
352     SkPaint* paint = fLazyPaint.set(fOrigPaint);
353     paint->setFlags(fNewPaintFlags);
354
355     if (fDoClearImageFilter) {
356         paint->setImageFilter(NULL);
357     }
358
359     if (fLooperContext && !fLooperContext->next(fCanvas, paint)) {
360         fDone = true;
361         return false;
362     }
363     if (fFilter) {
364         if (!fFilter->filter(paint, drawType)) {
365             fDone = true;
366             return false;
367         }
368         if (NULL == fLooperContext) {
369             // no looper means we only draw once
370             fDone = true;
371         }
372     }
373     fPaint = paint;
374
375     // if we only came in here for the imagefilter, mark us as done
376     if (!fLooperContext && !fFilter) {
377         fDone = true;
378     }
379
380     // call this after any possible paint modifiers
381     if (fPaint->nothingToDraw()) {
382         fPaint = NULL;
383         return false;
384     }
385     return true;
386 }
387
388 ////////// macros to place around the internal draw calls //////////////////
389
390 #define LOOPER_BEGIN_DRAWDEVICE(paint, type)                        \
391     this->predrawNotify();                                          \
392     AutoDrawLooper  looper(this, fProps, paint, true);              \
393     while (looper.next(type)) {                                     \
394         SkDrawIter          iter(this);
395
396 #define LOOPER_BEGIN(paint, type, bounds)                           \
397     this->predrawNotify();                                          \
398     AutoDrawLooper  looper(this, fProps, paint, false, bounds);     \
399     while (looper.next(type)) {                                     \
400         SkDrawIter          iter(this);
401
402 #define LOOPER_END    }
403
404 ////////////////////////////////////////////////////////////////////////////
405
406 void SkCanvas::setupDevice(SkBaseDevice* device) {
407     device->setPixelGeometry(fProps.pixelGeometry());
408 }
409
410 SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
411     fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag);
412     fCachedLocalClipBounds.setEmpty();
413     fCachedLocalClipBoundsDirty = true;
414     fAllowSoftClip = true;
415     fAllowSimplifyClip = false;
416     fDeviceCMDirty = true;
417     fSaveLayerCount = 0;
418     fCullCount = 0;
419     fMetaData = NULL;
420
421     fMCRec = (MCRec*)fMCStack.push_back();
422     new (fMCRec) MCRec(fConservativeRasterClip);
423
424     fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL, fConservativeRasterClip));
425     fMCRec->fTopLayer = fMCRec->fLayer;
426
427     fSurfaceBase = NULL;
428
429     if (device) {
430         this->setupDevice(device);
431         if (device->forceConservativeRasterClip()) {
432             fConservativeRasterClip = true;
433         }
434         device->onAttachToCanvas(this);
435         fMCRec->fLayer->fDevice = SkRef(device);
436         fMCRec->fRasterClip.setRect(SkIRect::MakeWH(device->width(), device->height()));
437     }
438     return device;
439 }
440
441 SkCanvas::SkCanvas()
442     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
443     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
444 {
445     inc_canvas();
446
447     this->init(NULL, kDefault_InitFlags);
448 }
449
450 static SkBitmap make_nopixels(int width, int height) {
451     SkBitmap bitmap;
452     bitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
453     return bitmap;
454 }
455
456 class SkNoPixelsBitmapDevice : public SkBitmapDevice {
457 public:
458     SkNoPixelsBitmapDevice(int width, int height) : INHERITED(make_nopixels(width, height)) {}
459
460 private:
461
462     typedef SkBitmapDevice INHERITED;
463 };
464
465 SkCanvas::SkCanvas(int width, int height)
466     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
467     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
468 {
469     inc_canvas();
470
471     this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), kDefault_InitFlags)->unref();
472 }
473
474 SkCanvas::SkCanvas(int width, int height, InitFlags flags)
475     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
476     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
477 {
478     inc_canvas();
479
480     this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unref();
481 }
482
483 SkCanvas::SkCanvas(SkBaseDevice* device, const SkSurfaceProps* props, InitFlags flags)
484     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
485     , fProps(SkSurfacePropsCopyOrDefault(props))
486 {
487     inc_canvas();
488
489     this->init(device, flags);
490 }
491
492 SkCanvas::SkCanvas(SkBaseDevice* device)
493     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
494     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
495 {
496     inc_canvas();
497
498     this->init(device, kDefault_InitFlags);
499 }
500
501 SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
502     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
503     , fProps(props)
504 {
505     inc_canvas();
506
507     SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
508     this->init(device, kDefault_InitFlags);
509 }
510
511 SkCanvas::SkCanvas(const SkBitmap& bitmap)
512     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
513     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
514 {
515     inc_canvas();
516
517     SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
518     this->init(device, kDefault_InitFlags);
519 }
520
521 SkCanvas::~SkCanvas() {
522     // free up the contents of our deque
523     this->restoreToCount(1);    // restore everything but the last
524     SkASSERT(0 == fSaveLayerCount);
525
526     this->internalRestore();    // restore the last, since we're going away
527
528     SkDELETE(fMetaData);
529
530     dec_canvas();
531 }
532
533 SkDrawFilter* SkCanvas::getDrawFilter() const {
534     return fMCRec->fFilter;
535 }
536
537 SkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) {
538     SkRefCnt_SafeAssign(fMCRec->fFilter, filter);
539     return filter;
540 }
541
542 SkMetaData& SkCanvas::getMetaData() {
543     // metadata users are rare, so we lazily allocate it. If that changes we
544     // can decide to just make it a field in the device (rather than a ptr)
545     if (NULL == fMetaData) {
546         fMetaData = new SkMetaData;
547     }
548     return *fMetaData;
549 }
550
551 ///////////////////////////////////////////////////////////////////////////////
552
553 void SkCanvas::flush() {
554     SkBaseDevice* device = this->getDevice();
555     if (device) {
556         device->flush();
557     }
558 }
559
560 SkISize SkCanvas::getTopLayerSize() const {
561     SkBaseDevice* d = this->getTopDevice();
562     return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0);
563 }
564
565 SkIPoint SkCanvas::getTopLayerOrigin() const {
566     SkBaseDevice* d = this->getTopDevice();
567     return d ? d->getOrigin() : SkIPoint::Make(0, 0);
568 }
569
570 SkISize SkCanvas::getBaseLayerSize() const {
571     SkBaseDevice* d = this->getDevice();
572     return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0);
573 }
574
575 SkBaseDevice* SkCanvas::getDevice() const {
576     // return root device
577     MCRec* rec = (MCRec*) fMCStack.front();
578     SkASSERT(rec && rec->fLayer);
579     return rec->fLayer->fDevice;
580 }
581
582 SkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const {
583     if (updateMatrixClip) {
584         const_cast<SkCanvas*>(this)->updateDeviceCMCache();
585     }
586     return fMCRec->fTopLayer->fDevice;
587 }
588
589 SkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) {
590     // return root device
591     SkDeque::F2BIter iter(fMCStack);
592     MCRec*           rec = (MCRec*)iter.next();
593     SkASSERT(rec && rec->fLayer);
594     SkBaseDevice*    rootDevice = rec->fLayer->fDevice;
595
596     if (rootDevice == device) {
597         return device;
598     }
599
600     if (device) {
601         device->onAttachToCanvas(this);
602     }
603     if (rootDevice) {
604         rootDevice->onDetachFromCanvas();
605     }
606
607     SkRefCnt_SafeAssign(rec->fLayer->fDevice, device);
608     rootDevice = device;
609     this->setupDevice(device);
610
611     fDeviceCMDirty = true;
612
613     /*  Now we update our initial region to have the bounds of the new device,
614         and then intersect all of the clips in our stack with these bounds,
615         to ensure that we can't draw outside of the device's bounds (and trash
616                                                                      memory).
617
618     NOTE: this is only a partial-fix, since if the new device is larger than
619         the previous one, we don't know how to "enlarge" the clips in our stack,
620         so drawing may be artificially restricted. Without keeping a history of
621         all calls to canvas->clipRect() and canvas->clipPath(), we can't exactly
622         reconstruct the correct clips, so this approximation will have to do.
623         The caller really needs to restore() back to the base if they want to
624         accurately take advantage of the new device bounds.
625     */
626
627     SkIRect bounds;
628     if (device) {
629         bounds.set(0, 0, device->width(), device->height());
630     } else {
631         bounds.setEmpty();
632     }
633     // now jam our 1st clip to be bounds, and intersect the rest with that
634     rec->fRasterClip.setRect(bounds);
635     while ((rec = (MCRec*)iter.next()) != NULL) {
636         (void)rec->fRasterClip.op(bounds, SkRegion::kIntersect_Op);
637     }
638
639     return device;
640 }
641
642 bool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) {
643     if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) {
644         return false;
645     }
646
647     bool weAllocated = false;
648     if (NULL == bitmap->pixelRef()) {
649         if (!bitmap->tryAllocPixels()) {
650             return false;
651         }
652         weAllocated = true;
653     }
654
655     SkBitmap bm(*bitmap);
656     bm.lockPixels();
657     if (bm.getPixels() && this->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y)) {
658         return true;
659     }
660
661     if (weAllocated) {
662         bitmap->setPixelRef(NULL);
663     }
664     return false;
665 }
666
667 bool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
668     SkIRect r = srcRect;
669     const SkISize size = this->getBaseLayerSize();
670     if (!r.intersect(0, 0, size.width(), size.height())) {
671         bitmap->reset();
672         return false;
673     }
674
675     if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) {
676         // bitmap will already be reset.
677         return false;
678     }
679     if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) {
680         bitmap->reset();
681         return false;
682     }
683     return true;
684 }
685
686 bool SkCanvas::readPixels(const SkImageInfo& origInfo, void* dstP, size_t rowBytes, int x, int y) {
687     switch (origInfo.colorType()) {
688         case kUnknown_SkColorType:
689         case kIndex_8_SkColorType:
690             return false;
691         default:
692             break;
693     }
694     if (NULL == dstP || rowBytes < origInfo.minRowBytes()) {
695         return false;
696     }
697     if (0 == origInfo.width() || 0 == origInfo.height()) {
698         return false;
699     }
700
701     SkBaseDevice* device = this->getDevice();
702     if (!device) {
703         return false;
704     }
705
706     const SkISize size = this->getBaseLayerSize();
707     SkIRect srcR = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height());
708     if (!srcR.intersect(0, 0, size.width(), size.height())) {
709         return false;
710     }
711
712     // the intersect may have shrunk info's logical size
713     const SkImageInfo info = origInfo.makeWH(srcR.width(), srcR.height());
714
715     // if x or y are negative, then we have to adjust pixels
716     if (x > 0) {
717         x = 0;
718     }
719     if (y > 0) {
720         y = 0;
721     }
722     // here x,y are either 0 or negative
723     dstP = ((char*)dstP - y * rowBytes - x * info.bytesPerPixel());
724
725     // The device can assert that the requested area is always contained in its bounds
726     return device->readPixels(info, dstP, rowBytes, srcR.x(), srcR.y());
727 }
728
729 bool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) {
730     if (bitmap.getTexture()) {
731         return false;
732     }
733     SkBitmap bm(bitmap);
734     bm.lockPixels();
735     if (bm.getPixels()) {
736         return this->writePixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y);
737     }
738     return false;
739 }
740
741 bool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes,
742                            int x, int y) {
743     switch (origInfo.colorType()) {
744         case kUnknown_SkColorType:
745         case kIndex_8_SkColorType:
746             return false;
747         default:
748             break;
749     }
750     if (NULL == pixels || rowBytes < origInfo.minRowBytes()) {
751         return false;
752     }
753
754     const SkISize size = this->getBaseLayerSize();
755     SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height());
756     if (!target.intersect(0, 0, size.width(), size.height())) {
757         return false;
758     }
759
760     SkBaseDevice* device = this->getDevice();
761     if (!device) {
762         return false;
763     }
764
765     // the intersect may have shrunk info's logical size
766     const SkImageInfo info = origInfo.makeWH(target.width(), target.height());
767
768     // if x or y are negative, then we have to adjust pixels
769     if (x > 0) {
770         x = 0;
771     }
772     if (y > 0) {
773         y = 0;
774     }
775     // here x,y are either 0 or negative
776     pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel());
777
778     // Tell our owning surface to bump its generation ID
779     this->predrawNotify();
780
781     // The device can assert that the requested area is always contained in its bounds
782     return device->writePixels(info, pixels, rowBytes, target.x(), target.y());
783 }
784
785 SkCanvas* SkCanvas::canvasForDrawIter() {
786     return this;
787 }
788
789 //////////////////////////////////////////////////////////////////////////////
790
791 void SkCanvas::updateDeviceCMCache() {
792     if (fDeviceCMDirty) {
793         const SkMatrix& totalMatrix = this->getTotalMatrix();
794         const SkRasterClip& totalClip = fMCRec->fRasterClip;
795         DeviceCM*       layer = fMCRec->fTopLayer;
796
797         if (NULL == layer->fNext) {   // only one layer
798             layer->updateMC(totalMatrix, totalClip, fClipStack, NULL);
799         } else {
800             SkRasterClip clip(totalClip);
801             do {
802                 layer->updateMC(totalMatrix, clip, fClipStack, &clip);
803             } while ((layer = layer->fNext) != NULL);
804         }
805         fDeviceCMDirty = false;
806     }
807 }
808
809 ///////////////////////////////////////////////////////////////////////////////
810
811 int SkCanvas::internalSave() {
812     int saveCount = this->getSaveCount(); // record this before the actual save
813
814     MCRec* newTop = (MCRec*)fMCStack.push_back();
815     new (newTop) MCRec(*fMCRec);    // balanced in restore()
816     fMCRec = newTop;
817
818     fClipStack.save();
819
820     return saveCount;
821 }
822
823 int SkCanvas::save() {
824     this->willSave();
825     return this->internalSave();
826 }
827
828 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) {
829 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
830     return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0;
831 #else
832     return true;
833 #endif
834 }
835
836 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags,
837                                SkIRect* intersection, const SkImageFilter* imageFilter) {
838     SkIRect clipBounds;
839     SkRegion::Op op = SkRegion::kIntersect_Op;
840     if (!this->getClipDeviceBounds(&clipBounds)) {
841         return false;
842     }
843
844     if (imageFilter) {
845         imageFilter->filterBounds(clipBounds, fMCRec->fMatrix, &clipBounds);
846         // Filters may grow the bounds beyond the device bounds.
847         op = SkRegion::kReplace_Op;
848     }
849     SkIRect ir;
850     if (bounds) {
851         SkRect r;
852
853         this->getTotalMatrix().mapRect(&r, *bounds);
854         r.roundOut(&ir);
855         // early exit if the layer's bounds are clipped out
856         if (!ir.intersect(clipBounds)) {
857             if (bounds_affects_clip(flags)) {
858                 fMCRec->fRasterClip.setEmpty();
859             }
860             return false;
861         }
862     } else {    // no user bounds, so just use the clip
863         ir = clipBounds;
864     }
865
866     if (bounds_affects_clip(flags)) {
867         fClipStack.clipDevRect(ir, op);
868         // early exit if the clip is now empty
869         if (!fMCRec->fRasterClip.op(ir, op)) {
870             return false;
871         }
872     }
873
874     if (intersection) {
875         *intersection = ir;
876     }
877     return true;
878 }
879
880 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) {
881     SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag);
882     return this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, false, strategy);
883 }
884
885 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
886                         SaveFlags flags) {
887     SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags);
888     return this->internalSaveLayer(bounds, paint, flags, false, strategy);
889 }
890
891 int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags,
892                                 bool justForImageFilter, SaveLayerStrategy strategy) {
893 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
894     flags |= kClipToLayer_SaveFlag;
895 #endif
896
897     // do this before we create the layer. We don't call the public save() since
898     // that would invoke a possibly overridden virtual
899     int count = this->internalSave();
900
901     fDeviceCMDirty = true;
902
903     SkIRect ir;
904     if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter() : NULL)) {
905         return count;
906     }
907
908     // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about
909     // the clipRectBounds() call above?
910     if (kNoLayer_SaveLayerStrategy == strategy) {
911         return count;
912     }
913
914     // Kill the imagefilter if our device doesn't allow it
915     SkLazyPaint lazyP;
916     if (paint && paint->getImageFilter()) {
917         if (!this->getTopDevice()->allowImageFilter(paint->getImageFilter())) {
918             if (justForImageFilter) {
919                 // early exit if the layer was just for the imageFilter
920                 return count;
921             }
922             SkPaint* p = lazyP.set(*paint);
923             p->setImageFilter(NULL);
924             paint = p;
925         }
926     }
927
928     bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag);
929     SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(),
930                         isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
931
932     SkBaseDevice* device;
933     if (paint && paint->getImageFilter()) {
934         device = this->getDevice();
935         if (device) {
936             device = device->createCompatibleDevice(info);
937         }
938     } else {
939         device = this->createLayerDevice(info);
940     }
941     if (NULL == device) {
942         SkDebugf("Unable to create device for layer.");
943         return count;
944     }
945     this->setupDevice(device);
946
947     device->setOrigin(ir.fLeft, ir.fTop);
948     DeviceCM* layer = SkNEW_ARGS(DeviceCM,
949                                  (device, ir.fLeft, ir.fTop, paint, this, fConservativeRasterClip));
950     device->unref();
951
952     layer->fNext = fMCRec->fTopLayer;
953     fMCRec->fLayer = layer;
954     fMCRec->fTopLayer = layer;    // this field is NOT an owner of layer
955
956     fSaveLayerCount += 1;
957     return count;
958 }
959
960 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
961     return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag);
962 }
963
964 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
965                              SaveFlags flags) {
966     if (0xFF == alpha) {
967         return this->saveLayer(bounds, NULL, flags);
968     } else {
969         SkPaint tmpPaint;
970         tmpPaint.setAlpha(alpha);
971         return this->saveLayer(bounds, &tmpPaint, flags);
972     }
973 }
974
975 void SkCanvas::restore() {
976     // check for underflow
977     if (fMCStack.count() > 1) {
978         this->willRestore();
979         this->internalRestore();
980         this->didRestore();
981     }
982 }
983
984 void SkCanvas::internalRestore() {
985     SkASSERT(fMCStack.count() != 0);
986
987     fDeviceCMDirty = true;
988     fCachedLocalClipBoundsDirty = true;
989
990     fClipStack.restore();
991
992     // reserve our layer (if any)
993     DeviceCM* layer = fMCRec->fLayer;   // may be null
994     // now detach it from fMCRec so we can pop(). Gets freed after its drawn
995     fMCRec->fLayer = NULL;
996
997     // now do the normal restore()
998     fMCRec->~MCRec();       // balanced in save()
999     fMCStack.pop_back();
1000     fMCRec = (MCRec*)fMCStack.back();
1001
1002     /*  Time to draw the layer's offscreen. We can't call the public drawSprite,
1003         since if we're being recorded, we don't want to record this (the
1004         recorder will have already recorded the restore).
1005     */
1006     if (layer) {
1007         if (layer->fNext) {
1008             const SkIPoint& origin = layer->fDevice->getOrigin();
1009             this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(),
1010                                      layer->fPaint);
1011             // reset this, since internalDrawDevice will have set it to true
1012             fDeviceCMDirty = true;
1013
1014             SkASSERT(fSaveLayerCount > 0);
1015             fSaveLayerCount -= 1;
1016         }
1017         SkDELETE(layer);
1018     }
1019 }
1020
1021 int SkCanvas::getSaveCount() const {
1022     return fMCStack.count();
1023 }
1024
1025 void SkCanvas::restoreToCount(int count) {
1026     // sanity check
1027     if (count < 1) {
1028         count = 1;
1029     }
1030
1031     int n = this->getSaveCount() - count;
1032     for (int i = 0; i < n; ++i) {
1033         this->restore();
1034     }
1035 }
1036
1037 bool SkCanvas::isDrawingToLayer() const {
1038     return fSaveLayerCount > 0;
1039 }
1040
1041 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) {
1042     if (NULL == props) {
1043         props = &fProps;
1044     }
1045     return this->onNewSurface(info, *props);
1046 }
1047
1048 SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
1049     SkBaseDevice* dev = this->getDevice();
1050     return dev ? dev->newSurface(info, props) : NULL;
1051 }
1052
1053 SkImageInfo SkCanvas::imageInfo() const {
1054     SkBaseDevice* dev = this->getDevice();
1055     if (dev) {
1056         return dev->imageInfo();
1057     } else {
1058         return SkImageInfo::MakeUnknown(0, 0);
1059     }
1060 }
1061
1062 const void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) {
1063     return this->onPeekPixels(info, rowBytes);
1064 }
1065
1066 const void* SkCanvas::onPeekPixels(SkImageInfo* info, size_t* rowBytes) {
1067     SkBaseDevice* dev = this->getDevice();
1068     return dev ? dev->peekPixels(info, rowBytes) : NULL;
1069 }
1070
1071 void* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) {
1072     void* pixels = this->onAccessTopLayerPixels(info, rowBytes);
1073     if (pixels && origin) {
1074         *origin = this->getTopDevice(false)->getOrigin();
1075     }
1076     return pixels;
1077 }
1078
1079 void* SkCanvas::onAccessTopLayerPixels(SkImageInfo* info, size_t* rowBytes) {
1080     SkBaseDevice* dev = this->getTopDevice();
1081     return dev ? dev->accessPixels(info, rowBytes) : NULL;
1082 }
1083
1084 SkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) {
1085     fAddr = canvas->peekPixels(&fInfo, &fRowBytes);
1086     if (NULL == fAddr) {
1087         fInfo = canvas->imageInfo();
1088         if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.tryAllocPixels(fInfo)) {
1089             return; // failure, fAddr is NULL
1090         }
1091         if (!canvas->readPixels(&fBitmap, 0, 0)) {
1092             return; // failure, fAddr is NULL
1093         }
1094         fAddr = fBitmap.getPixels();
1095         fRowBytes = fBitmap.rowBytes();
1096     }
1097     SkASSERT(fAddr);    // success
1098 }
1099
1100 bool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const {
1101     if (fAddr) {
1102         return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes);
1103     } else {
1104         bitmap->reset();
1105         return false;
1106     }
1107 }
1108
1109 void SkCanvas::onPushCull(const SkRect& cullRect) {
1110     // do nothing. Subclasses may do something
1111 }
1112
1113 void SkCanvas::onPopCull() {
1114     // do nothing. Subclasses may do something
1115 }
1116
1117 /////////////////////////////////////////////////////////////////////////////
1118 #ifdef SK_DEBUG
1119 // Ensure that cull rects are monotonically nested in device space.
1120 void SkCanvas::validateCull(const SkIRect& devCull) {
1121     if (fCullStack.isEmpty()
1122         || devCull.isEmpty()
1123         || fCullStack.top().contains(devCull)) {
1124         return;
1125     }
1126
1127     SkDEBUGF(("Invalid cull: [%d %d %d %d] (previous cull: [%d %d %d %d])\n",
1128               devCull.x(), devCull.y(), devCull.right(), devCull.bottom(),
1129               fCullStack.top().x(), fCullStack.top().y(),
1130               fCullStack.top().right(), fCullStack.top().bottom()));
1131
1132 #ifdef ASSERT_NESTED_CULLING
1133     SkDEBUGFAIL("Invalid cull.");
1134 #endif
1135 }
1136 #endif
1137
1138 void SkCanvas::pushCull(const SkRect& cullRect) {
1139     ++fCullCount;
1140     this->onPushCull(cullRect);
1141
1142 #ifdef SK_DEBUG
1143     // Map the cull rect into device space.
1144     SkRect mappedCull;
1145     this->getTotalMatrix().mapRect(&mappedCull, cullRect);
1146
1147     // Take clipping into account.
1148     SkIRect devClip, devCull;
1149     mappedCull.roundOut(&devCull);
1150     this->getClipDeviceBounds(&devClip);
1151     if (!devCull.intersect(devClip)) {
1152         devCull.setEmpty();
1153     }
1154
1155     this->validateCull(devCull);
1156     fCullStack.push(devCull); // balanced in popCull
1157 #endif
1158 }
1159
1160 void SkCanvas::popCull() {
1161     SkASSERT(fCullStack.count() == fCullCount);
1162
1163     if (fCullCount > 0) {
1164         --fCullCount;
1165         this->onPopCull();
1166
1167         SkDEBUGCODE(fCullStack.pop());
1168     }
1169 }
1170
1171 /////////////////////////////////////////////////////////////////////////////
1172
1173 void SkCanvas::internalDrawBitmap(const SkBitmap& bitmap,
1174                                 const SkMatrix& matrix, const SkPaint* paint) {
1175     if (bitmap.drawsNothing()) {
1176         return;
1177     }
1178
1179     SkLazyPaint lazy;
1180     if (NULL == paint) {
1181         paint = lazy.init();
1182     }
1183
1184     SkDEBUGCODE(bitmap.validate();)
1185
1186     SkRect storage;
1187     const SkRect* bounds = NULL;
1188     if (paint && paint->canComputeFastBounds()) {
1189         bitmap.getBounds(&storage);
1190         matrix.mapRect(&storage);
1191         bounds = &paint->computeFastBounds(storage, &storage);
1192     }
1193
1194     LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds)
1195
1196     while (iter.next()) {
1197         iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint());
1198     }
1199
1200     LOOPER_END
1201 }
1202
1203 void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y,
1204                                   const SkPaint* paint) {
1205     SkPaint tmp;
1206     if (NULL == paint) {
1207         tmp.setDither(true);
1208         paint = &tmp;
1209     }
1210
1211     LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type)
1212     while (iter.next()) {
1213         SkBaseDevice* dstDev = iter.fDevice;
1214         paint = &looper.paint();
1215         SkImageFilter* filter = paint->getImageFilter();
1216         SkIPoint pos = { x - iter.getX(), y - iter.getY() };
1217         if (filter && !dstDev->canHandleImageFilter(filter)) {
1218             SkDeviceImageFilterProxy proxy(dstDev);
1219             SkBitmap dst;
1220             SkIPoint offset = SkIPoint::Make(0, 0);
1221             const SkBitmap& src = srcDev->accessBitmap(false);
1222             SkMatrix matrix = *iter.fMatrix;
1223             matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y()));
1224             SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height());
1225             SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache());
1226             SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
1227             if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) {
1228                 SkPaint tmpUnfiltered(*paint);
1229                 tmpUnfiltered.setImageFilter(NULL);
1230                 dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(),
1231                                    tmpUnfiltered);
1232             }
1233         } else {
1234             dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint);
1235         }
1236     }
1237     LOOPER_END
1238 }
1239
1240 void SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y,
1241                           const SkPaint* paint) {
1242     if (bitmap.drawsNothing()) {
1243         return;
1244     }
1245     SkDEBUGCODE(bitmap.validate();)
1246
1247     SkPaint tmp;
1248     if (NULL == paint) {
1249         paint = &tmp;
1250     }
1251
1252     LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type)
1253
1254     while (iter.next()) {
1255         paint = &looper.paint();
1256         SkImageFilter* filter = paint->getImageFilter();
1257         SkIPoint pos = { x - iter.getX(), y - iter.getY() };
1258         if (filter && !iter.fDevice->canHandleImageFilter(filter)) {
1259             SkDeviceImageFilterProxy proxy(iter.fDevice);
1260             SkBitmap dst;
1261             SkIPoint offset = SkIPoint::Make(0, 0);
1262             SkMatrix matrix = *iter.fMatrix;
1263             matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y()));
1264             SkIRect clipBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
1265             SkAutoTUnref<SkImageFilter::Cache> cache(iter.fDevice->getImageFilterCache());
1266             SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
1267             if (filter->filterImage(&proxy, bitmap, ctx, &dst, &offset)) {
1268                 SkPaint tmpUnfiltered(*paint);
1269                 tmpUnfiltered.setImageFilter(NULL);
1270                 iter.fDevice->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(),
1271                                          tmpUnfiltered);
1272             }
1273         } else {
1274             iter.fDevice->drawSprite(iter, bitmap, pos.x(), pos.y(), *paint);
1275         }
1276     }
1277     LOOPER_END
1278 }
1279
1280 /////////////////////////////////////////////////////////////////////////////
1281 void SkCanvas::translate(SkScalar dx, SkScalar dy) {
1282     SkMatrix m;
1283     m.setTranslate(dx, dy);
1284     this->concat(m);
1285 }
1286
1287 void SkCanvas::scale(SkScalar sx, SkScalar sy) {
1288     SkMatrix m;
1289     m.setScale(sx, sy);
1290     this->concat(m);
1291 }
1292
1293 void SkCanvas::rotate(SkScalar degrees) {
1294     SkMatrix m;
1295     m.setRotate(degrees);
1296     this->concat(m);
1297 }
1298
1299 void SkCanvas::skew(SkScalar sx, SkScalar sy) {
1300     SkMatrix m;
1301     m.setSkew(sx, sy);
1302     this->concat(m);
1303 }
1304
1305 void SkCanvas::concat(const SkMatrix& matrix) {
1306     if (matrix.isIdentity()) {
1307         return;
1308     }
1309
1310     fDeviceCMDirty = true;
1311     fCachedLocalClipBoundsDirty = true;
1312     fMCRec->fMatrix.preConcat(matrix);
1313
1314     this->didConcat(matrix);
1315 }
1316
1317 void SkCanvas::setMatrix(const SkMatrix& matrix) {
1318     fDeviceCMDirty = true;
1319     fCachedLocalClipBoundsDirty = true;
1320     fMCRec->fMatrix = matrix;
1321     this->didSetMatrix(matrix);
1322 }
1323
1324 void SkCanvas::resetMatrix() {
1325     SkMatrix matrix;
1326
1327     matrix.reset();
1328     this->setMatrix(matrix);
1329 }
1330
1331 //////////////////////////////////////////////////////////////////////////////
1332
1333 void SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
1334     ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle;
1335     this->onClipRect(rect, op, edgeStyle);
1336 }
1337
1338 void SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
1339 #ifdef SK_ENABLE_CLIP_QUICKREJECT
1340     if (SkRegion::kIntersect_Op == op) {
1341         if (fMCRec->fRasterClip.isEmpty()) {
1342             return false;
1343         }
1344
1345         if (this->quickReject(rect)) {
1346             fDeviceCMDirty = true;
1347             fCachedLocalClipBoundsDirty = true;
1348
1349             fClipStack.clipEmpty();
1350             return fMCRec->fRasterClip.setEmpty();
1351         }
1352     }
1353 #endif
1354
1355     AutoValidateClip avc(this);
1356
1357     fDeviceCMDirty = true;
1358     fCachedLocalClipBoundsDirty = true;
1359     if (!fAllowSoftClip) {
1360         edgeStyle = kHard_ClipEdgeStyle;
1361     }
1362
1363     if (fMCRec->fMatrix.rectStaysRect()) {
1364         // for these simpler matrices, we can stay a rect even after applying
1365         // the matrix. This means we don't have to a) make a path, and b) tell
1366         // the region code to scan-convert the path, only to discover that it
1367         // is really just a rect.
1368         SkRect      r;
1369
1370         fMCRec->fMatrix.mapRect(&r, rect);
1371         fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle);
1372         fMCRec->fRasterClip.op(r, this->getBaseLayerSize(), op, kSoft_ClipEdgeStyle == edgeStyle);
1373     } else {
1374         // since we're rotated or some such thing, we convert the rect to a path
1375         // and clip against that, since it can handle any matrix. However, to
1376         // avoid recursion in the case where we are subclassed (e.g. Pictures)
1377         // we explicitly call "our" version of clipPath.
1378         SkPath  path;
1379
1380         path.addRect(rect);
1381         this->SkCanvas::onClipPath(path, op, edgeStyle);
1382     }
1383 }
1384
1385 static void rasterclip_path(SkRasterClip* rc, const SkCanvas* canvas, const SkPath& devPath,
1386                             SkRegion::Op op, bool doAA) {
1387     rc->op(devPath, canvas->getBaseLayerSize(), op, doAA);
1388 }
1389
1390 void SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
1391     ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle;
1392     if (rrect.isRect()) {
1393         this->onClipRect(rrect.getBounds(), op, edgeStyle);
1394     } else {
1395         this->onClipRRect(rrect, op, edgeStyle);
1396     }
1397 }
1398
1399 void SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
1400     SkRRect transformedRRect;
1401     if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) {
1402         AutoValidateClip avc(this);
1403
1404         fDeviceCMDirty = true;
1405         fCachedLocalClipBoundsDirty = true;
1406         if (!fAllowSoftClip) {
1407             edgeStyle = kHard_ClipEdgeStyle;
1408         }
1409
1410         fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle);
1411
1412         SkPath devPath;
1413         devPath.addRRect(transformedRRect);
1414
1415         rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, kSoft_ClipEdgeStyle == edgeStyle);
1416         return;
1417     }
1418
1419     SkPath path;
1420     path.addRRect(rrect);
1421     // call the non-virtual version
1422     this->SkCanvas::onClipPath(path, op, edgeStyle);
1423 }
1424
1425 void SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
1426     ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle;
1427     SkRect r;
1428     if (!path.isInverseFillType() && path.isRect(&r)) {
1429         this->onClipRect(r, op, edgeStyle);
1430     } else {
1431         this->onClipPath(path, op, edgeStyle);
1432     }
1433 }
1434
1435 void SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
1436 #ifdef SK_ENABLE_CLIP_QUICKREJECT
1437     if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) {
1438         if (fMCRec->fRasterClip.isEmpty()) {
1439             return false;
1440         }
1441
1442         if (this->quickReject(path.getBounds())) {
1443             fDeviceCMDirty = true;
1444             fCachedLocalClipBoundsDirty = true;
1445
1446             fClipStack.clipEmpty();
1447             return fMCRec->fRasterClip.setEmpty();
1448         }
1449     }
1450 #endif
1451
1452     AutoValidateClip avc(this);
1453
1454     fDeviceCMDirty = true;
1455     fCachedLocalClipBoundsDirty = true;
1456     if (!fAllowSoftClip) {
1457         edgeStyle = kHard_ClipEdgeStyle;
1458     }
1459
1460     SkPath devPath;
1461     path.transform(fMCRec->fMatrix, &devPath);
1462
1463     // Check if the transfomation, or the original path itself
1464     // made us empty. Note this can also happen if we contained NaN
1465     // values. computing the bounds detects this, and will set our
1466     // bounds to empty if that is the case. (see SkRect::set(pts, count))
1467     if (devPath.getBounds().isEmpty()) {
1468         // resetting the path will remove any NaN or other wanky values
1469         // that might upset our scan converter.
1470         devPath.reset();
1471     }
1472
1473     // if we called path.swap() we could avoid a deep copy of this path
1474     fClipStack.clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle);
1475
1476     if (fAllowSimplifyClip) {
1477         devPath.reset();
1478         devPath.setFillType(SkPath::kInverseEvenOdd_FillType);
1479         const SkClipStack* clipStack = getClipStack();
1480         SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart);
1481         const SkClipStack::Element* element;
1482         while ((element = iter.next())) {
1483             SkClipStack::Element::Type type = element->getType();
1484             SkPath operand;
1485             if (type != SkClipStack::Element::kEmpty_Type) {
1486                 element->asPath(&operand);
1487             }
1488             SkRegion::Op elementOp = element->getOp();
1489             if (elementOp == SkRegion::kReplace_Op) {
1490                 devPath = operand;
1491             } else {
1492                 Op(devPath, operand, (SkPathOp) elementOp, &devPath);
1493             }
1494             // if the prev and curr clips disagree about aa -vs- not, favor the aa request.
1495             // perhaps we need an API change to avoid this sort of mixed-signals about
1496             // clipping.
1497             if (element->isAA()) {
1498                 edgeStyle = kSoft_ClipEdgeStyle;
1499             }
1500         }
1501         op = SkRegion::kReplace_Op;
1502     }
1503
1504     rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle);
1505 }
1506
1507 void SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) {
1508     this->onClipRegion(rgn, op);
1509 }
1510
1511 void SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) {
1512     AutoValidateClip avc(this);
1513
1514     fDeviceCMDirty = true;
1515     fCachedLocalClipBoundsDirty = true;
1516
1517     // todo: signal fClipStack that we have a region, and therefore (I guess)
1518     // we have to ignore it, and use the region directly?
1519     fClipStack.clipDevRect(rgn.getBounds(), op);
1520
1521     fMCRec->fRasterClip.op(rgn, op);
1522 }
1523
1524 #ifdef SK_DEBUG
1525 void SkCanvas::validateClip() const {
1526     // construct clipRgn from the clipstack
1527     const SkBaseDevice* device = this->getDevice();
1528     if (!device) {
1529         SkASSERT(this->isClipEmpty());
1530         return;
1531     }
1532
1533     SkIRect ir;
1534     ir.set(0, 0, device->width(), device->height());
1535     SkRasterClip tmpClip(ir, fConservativeRasterClip);
1536
1537     SkClipStack::B2TIter                iter(fClipStack);
1538     const SkClipStack::Element* element;
1539     while ((element = iter.next()) != NULL) {
1540         switch (element->getType()) {
1541             case SkClipStack::Element::kRect_Type:
1542                 element->getRect().round(&ir);
1543                 tmpClip.op(ir, element->getOp());
1544                 break;
1545             case SkClipStack::Element::kEmpty_Type:
1546                 tmpClip.setEmpty();
1547                 break;
1548             default: {
1549                 SkPath path;
1550                 element->asPath(&path);
1551                 rasterclip_path(&tmpClip, this, path, element->getOp(), element->isAA());
1552                 break;
1553             }
1554         }
1555     }
1556 }
1557 #endif
1558
1559 void SkCanvas::replayClips(ClipVisitor* visitor) const {
1560     SkClipStack::B2TIter                iter(fClipStack);
1561     const SkClipStack::Element*         element;
1562
1563     while ((element = iter.next()) != NULL) {
1564         element->replay(visitor);
1565     }
1566 }
1567
1568 ///////////////////////////////////////////////////////////////////////////////
1569
1570 bool SkCanvas::isClipEmpty() const {
1571     return fMCRec->fRasterClip.isEmpty();
1572 }
1573
1574 bool SkCanvas::isClipRect() const {
1575     return fMCRec->fRasterClip.isRect();
1576 }
1577
1578 bool SkCanvas::quickReject(const SkRect& rect) const {
1579     if (!rect.isFinite())
1580         return true;
1581
1582     if (fMCRec->fRasterClip.isEmpty()) {
1583         return true;
1584     }
1585
1586     if (fMCRec->fMatrix.hasPerspective()) {
1587         SkRect dst;
1588         fMCRec->fMatrix.mapRect(&dst, rect);
1589         SkIRect idst;
1590         dst.roundOut(&idst);
1591         return !SkIRect::Intersects(idst, fMCRec->fRasterClip.getBounds());
1592     } else {
1593         const SkRect& clipR = this->getLocalClipBounds();
1594
1595         // for speed, do the most likely reject compares first
1596         // TODO: should we use | instead, or compare all 4 at once?
1597         if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) {
1598             return true;
1599         }
1600         if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) {
1601             return true;
1602         }
1603         return false;
1604     }
1605 }
1606
1607 bool SkCanvas::quickReject(const SkPath& path) const {
1608     return path.isEmpty() || this->quickReject(path.getBounds());
1609 }
1610
1611 bool SkCanvas::getClipBounds(SkRect* bounds) const {
1612     SkIRect ibounds;
1613     if (!this->getClipDeviceBounds(&ibounds)) {
1614         return false;
1615     }
1616
1617     SkMatrix inverse;
1618     // if we can't invert the CTM, we can't return local clip bounds
1619     if (!fMCRec->fMatrix.invert(&inverse)) {
1620         if (bounds) {
1621             bounds->setEmpty();
1622         }
1623         return false;
1624     }
1625
1626     if (bounds) {
1627         SkRect r;
1628         // adjust it outwards in case we are antialiasing
1629         const int inset = 1;
1630
1631         r.iset(ibounds.fLeft - inset, ibounds.fTop - inset,
1632                ibounds.fRight + inset, ibounds.fBottom + inset);
1633         inverse.mapRect(bounds, r);
1634     }
1635     return true;
1636 }
1637
1638 bool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const {
1639     const SkRasterClip& clip = fMCRec->fRasterClip;
1640     if (clip.isEmpty()) {
1641         if (bounds) {
1642             bounds->setEmpty();
1643         }
1644         return false;
1645     }
1646
1647     if (bounds) {
1648         *bounds = clip.getBounds();
1649     }
1650     return true;
1651 }
1652
1653 const SkMatrix& SkCanvas::getTotalMatrix() const {
1654     return fMCRec->fMatrix;
1655 }
1656
1657 const SkRegion& SkCanvas::internal_private_getTotalClip() const {
1658     return fMCRec->fRasterClip.forceGetBW();
1659 }
1660
1661 GrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() {
1662     SkBaseDevice* dev = this->getTopDevice();
1663     return dev ? dev->accessRenderTarget() : NULL;
1664 }
1665
1666 SkBaseDevice* SkCanvas::createLayerDevice(const SkImageInfo& info) {
1667     SkBaseDevice* device = this->getTopDevice();
1668     return device ? device->createCompatibleDeviceForSaveLayer(info) : NULL;
1669 }
1670
1671 GrContext* SkCanvas::getGrContext() {
1672 #if SK_SUPPORT_GPU
1673     SkBaseDevice* device = this->getTopDevice();
1674     if (device) {
1675         GrRenderTarget* renderTarget = device->accessRenderTarget();
1676         if (renderTarget) {
1677             return renderTarget->getContext();
1678         }
1679     }
1680 #endif
1681
1682     return NULL;
1683
1684 }
1685
1686 void SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner,
1687                           const SkPaint& paint) {
1688     if (outer.isEmpty()) {
1689         return;
1690     }
1691     if (inner.isEmpty()) {
1692         this->drawRRect(outer, paint);
1693         return;
1694     }
1695
1696     // We don't have this method (yet), but technically this is what we should
1697     // be able to assert...
1698     // SkASSERT(outer.contains(inner));
1699     //
1700     // For now at least check for containment of bounds
1701     SkASSERT(outer.getBounds().contains(inner.getBounds()));
1702
1703     this->onDrawDRRect(outer, inner, paint);
1704 }
1705
1706 //////////////////////////////////////////////////////////////////////////////
1707 //  These are the virtual drawing methods
1708 //////////////////////////////////////////////////////////////////////////////
1709
1710 void SkCanvas::clear(SkColor color) {
1711     SkDrawIter  iter(this);
1712     this->predrawNotify();
1713     while (iter.next()) {
1714         iter.fDevice->clear(color);
1715     }
1716 }
1717
1718 void SkCanvas::onDiscard() {
1719     if (fSurfaceBase) {
1720         fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode);
1721     }
1722 }
1723
1724 void SkCanvas::drawPaint(const SkPaint& paint) {
1725     this->internalDrawPaint(paint);
1726 }
1727
1728 void SkCanvas::internalDrawPaint(const SkPaint& paint) {
1729     LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL)
1730
1731     while (iter.next()) {
1732         iter.fDevice->drawPaint(iter, looper.paint());
1733     }
1734
1735     LOOPER_END
1736 }
1737
1738 void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
1739                           const SkPaint& paint) {
1740     if ((long)count <= 0) {
1741         return;
1742     }
1743
1744     SkRect r, storage;
1745     const SkRect* bounds = NULL;
1746     if (paint.canComputeFastBounds()) {
1747         // special-case 2 points (common for drawing a single line)
1748         if (2 == count) {
1749             r.set(pts[0], pts[1]);
1750         } else {
1751             r.set(pts, SkToInt(count));
1752         }
1753         bounds = &paint.computeFastStrokeBounds(r, &storage);
1754         if (this->quickReject(*bounds)) {
1755             return;
1756         }
1757     }
1758
1759     SkASSERT(pts != NULL);
1760
1761     LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds)
1762
1763     while (iter.next()) {
1764         iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint());
1765     }
1766
1767     LOOPER_END
1768 }
1769
1770 void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) {
1771     SkRect storage;
1772     const SkRect* bounds = NULL;
1773     if (paint.canComputeFastBounds()) {
1774         bounds = &paint.computeFastBounds(r, &storage);
1775         if (this->quickReject(*bounds)) {
1776             return;
1777         }
1778     }
1779
1780     LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds)
1781
1782     while (iter.next()) {
1783         iter.fDevice->drawRect(iter, r, looper.paint());
1784     }
1785
1786     LOOPER_END
1787 }
1788
1789 void SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) {
1790     SkRect storage;
1791     const SkRect* bounds = NULL;
1792     if (paint.canComputeFastBounds()) {
1793         bounds = &paint.computeFastBounds(oval, &storage);
1794         if (this->quickReject(*bounds)) {
1795             return;
1796         }
1797     }
1798
1799     LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds)
1800
1801     while (iter.next()) {
1802         iter.fDevice->drawOval(iter, oval, looper.paint());
1803     }
1804
1805     LOOPER_END
1806 }
1807
1808 void SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
1809     SkRect storage;
1810     const SkRect* bounds = NULL;
1811     if (paint.canComputeFastBounds()) {
1812         bounds = &paint.computeFastBounds(rrect.getBounds(), &storage);
1813         if (this->quickReject(*bounds)) {
1814             return;
1815         }
1816     }
1817
1818     if (rrect.isRect()) {
1819         // call the non-virtual version
1820         this->SkCanvas::drawRect(rrect.getBounds(), paint);
1821         return;
1822     } else if (rrect.isOval()) {
1823         // call the non-virtual version
1824         this->SkCanvas::drawOval(rrect.getBounds(), paint);
1825         return;
1826     }
1827
1828     LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds)
1829
1830     while (iter.next()) {
1831         iter.fDevice->drawRRect(iter, rrect, looper.paint());
1832     }
1833
1834     LOOPER_END
1835 }
1836
1837 void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
1838                             const SkPaint& paint) {
1839     SkRect storage;
1840     const SkRect* bounds = NULL;
1841     if (paint.canComputeFastBounds()) {
1842         bounds = &paint.computeFastBounds(outer.getBounds(), &storage);
1843         if (this->quickReject(*bounds)) {
1844             return;
1845         }
1846     }
1847
1848     LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds)
1849
1850     while (iter.next()) {
1851         iter.fDevice->drawDRRect(iter, outer, inner, looper.paint());
1852     }
1853
1854     LOOPER_END
1855 }
1856
1857 void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
1858     if (!path.isFinite()) {
1859         return;
1860     }
1861
1862     SkRect storage;
1863     const SkRect* bounds = NULL;
1864     if (!path.isInverseFillType() && paint.canComputeFastBounds()) {
1865         const SkRect& pathBounds = path.getBounds();
1866         bounds = &paint.computeFastBounds(pathBounds, &storage);
1867         if (this->quickReject(*bounds)) {
1868             return;
1869         }
1870     }
1871
1872     const SkRect& r = path.getBounds();
1873     if (r.width() <= 0 && r.height() <= 0) {
1874         if (path.isInverseFillType()) {
1875             this->internalDrawPaint(paint);
1876         }
1877         return;
1878     }
1879
1880     LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds)
1881
1882     while (iter.next()) {
1883         iter.fDevice->drawPath(iter, path, looper.paint());
1884     }
1885
1886     LOOPER_END
1887 }
1888
1889 void SkCanvas::drawImage(const SkImage* image, SkScalar left, SkScalar top,
1890                        const SkPaint* paint) {
1891     image->draw(this, left, top, paint);
1892 }
1893
1894 void SkCanvas::drawImageRect(const SkImage* image, const SkRect* src,
1895                            const SkRect& dst,
1896                            const SkPaint* paint) {
1897     image->draw(this, src, dst, paint);
1898 }
1899
1900 void SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
1901                           const SkPaint* paint) {
1902     SkDEBUGCODE(bitmap.validate();)
1903
1904     if (NULL == paint || paint->canComputeFastBounds()) {
1905         SkRect bounds = {
1906             x, y,
1907             x + SkIntToScalar(bitmap.width()),
1908             y + SkIntToScalar(bitmap.height())
1909         };
1910         if (paint) {
1911             (void)paint->computeFastBounds(bounds, &bounds);
1912         }
1913         if (this->quickReject(bounds)) {
1914             return;
1915         }
1916     }
1917
1918     SkMatrix matrix;
1919     matrix.setTranslate(x, y);
1920     this->internalDrawBitmap(bitmap, matrix, paint);
1921 }
1922
1923 // this one is non-virtual, so it can be called safely by other canvas apis
1924 void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
1925                                       const SkRect& dst, const SkPaint* paint,
1926                                       DrawBitmapRectFlags flags) {
1927     if (bitmap.drawsNothing() || dst.isEmpty()) {
1928         return;
1929     }
1930
1931     SkRect storage;
1932     const SkRect* bounds = &dst;
1933     if (NULL == paint || paint->canComputeFastBounds()) {
1934         if (paint) {
1935             bounds = &paint->computeFastBounds(dst, &storage);
1936         }
1937         if (this->quickReject(*bounds)) {
1938             return;
1939         }
1940     }
1941
1942     SkLazyPaint lazy;
1943     if (NULL == paint) {
1944         paint = lazy.init();
1945     }
1946
1947     LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds)
1948
1949     while (iter.next()) {
1950         iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), flags);
1951     }
1952
1953     LOOPER_END
1954 }
1955
1956 void SkCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
1957                                     const SkRect& dst, const SkPaint* paint,
1958                                     DrawBitmapRectFlags flags) {
1959     SkDEBUGCODE(bitmap.validate();)
1960     this->internalDrawBitmapRect(bitmap, src, dst, paint, flags);
1961 }
1962
1963 void SkCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix,
1964                                 const SkPaint* paint) {
1965     SkDEBUGCODE(bitmap.validate();)
1966     this->internalDrawBitmap(bitmap, matrix, paint);
1967 }
1968
1969 void SkCanvas::internalDrawBitmapNine(const SkBitmap& bitmap,
1970                                       const SkIRect& center, const SkRect& dst,
1971                                       const SkPaint* paint) {
1972     if (bitmap.drawsNothing()) {
1973         return;
1974     }
1975     if (NULL == paint || paint->canComputeFastBounds()) {
1976         SkRect storage;
1977         const SkRect* bounds = &dst;
1978         if (paint) {
1979             bounds = &paint->computeFastBounds(dst, &storage);
1980         }
1981         if (this->quickReject(*bounds)) {
1982             return;
1983         }
1984     }
1985
1986     const int32_t w = bitmap.width();
1987     const int32_t h = bitmap.height();
1988
1989     SkIRect c = center;
1990     // pin center to the bounds of the bitmap
1991     c.fLeft = SkMax32(0, center.fLeft);
1992     c.fTop = SkMax32(0, center.fTop);
1993     c.fRight = SkPin32(center.fRight, c.fLeft, w);
1994     c.fBottom = SkPin32(center.fBottom, c.fTop, h);
1995
1996     const SkScalar srcX[4] = {
1997         0, SkIntToScalar(c.fLeft), SkIntToScalar(c.fRight), SkIntToScalar(w)
1998     };
1999     const SkScalar srcY[4] = {
2000         0, SkIntToScalar(c.fTop), SkIntToScalar(c.fBottom), SkIntToScalar(h)
2001     };
2002     SkScalar dstX[4] = {
2003         dst.fLeft, dst.fLeft + SkIntToScalar(c.fLeft),
2004         dst.fRight - SkIntToScalar(w - c.fRight), dst.fRight
2005     };
2006     SkScalar dstY[4] = {
2007         dst.fTop, dst.fTop + SkIntToScalar(c.fTop),
2008         dst.fBottom - SkIntToScalar(h - c.fBottom), dst.fBottom
2009     };
2010
2011     if (dstX[1] > dstX[2]) {
2012         dstX[1] = dstX[0] + (dstX[3] - dstX[0]) * c.fLeft / (w - c.width());
2013         dstX[2] = dstX[1];
2014     }
2015
2016     if (dstY[1] > dstY[2]) {
2017         dstY[1] = dstY[0] + (dstY[3] - dstY[0]) * c.fTop / (h - c.height());
2018         dstY[2] = dstY[1];
2019     }
2020
2021     for (int y = 0; y < 3; y++) {
2022         SkRect s, d;
2023
2024         s.fTop = srcY[y];
2025         s.fBottom = srcY[y+1];
2026         d.fTop = dstY[y];
2027         d.fBottom = dstY[y+1];
2028         for (int x = 0; x < 3; x++) {
2029             s.fLeft = srcX[x];
2030             s.fRight = srcX[x+1];
2031             d.fLeft = dstX[x];
2032             d.fRight = dstX[x+1];
2033             this->internalDrawBitmapRect(bitmap, &s, d, paint,
2034                                          kNone_DrawBitmapRectFlag);
2035         }
2036     }
2037 }
2038
2039 void SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
2040                               const SkRect& dst, const SkPaint* paint) {
2041     SkDEBUGCODE(bitmap.validate();)
2042
2043     // Need a device entry-point, so gpu can use a mesh
2044     this->internalDrawBitmapNine(bitmap, center, dst, paint);
2045 }
2046
2047 class SkDeviceFilteredPaint {
2048 public:
2049     SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) {
2050         SkBaseDevice::TextFlags flags;
2051         if (device->filterTextFlags(paint, &flags)) {
2052             SkPaint* newPaint = fLazy.set(paint);
2053             newPaint->setFlags(flags.fFlags);
2054             fPaint = newPaint;
2055         } else {
2056             fPaint = &paint;
2057         }
2058     }
2059
2060     const SkPaint& paint() const { return *fPaint; }
2061
2062 private:
2063     const SkPaint*  fPaint;
2064     SkLazyPaint     fLazy;
2065 };
2066
2067 void SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint,
2068                         const SkRect& r, SkScalar textSize) {
2069     if (paint.getStyle() == SkPaint::kFill_Style) {
2070         draw.fDevice->drawRect(draw, r, paint);
2071     } else {
2072         SkPaint p(paint);
2073         p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth()));
2074         draw.fDevice->drawRect(draw, r, p);
2075     }
2076 }
2077
2078 void SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint,
2079                                    const char text[], size_t byteLength,
2080                                    SkScalar x, SkScalar y) {
2081     SkASSERT(byteLength == 0 || text != NULL);
2082
2083     // nothing to draw
2084     if (text == NULL || byteLength == 0 ||
2085         draw.fClip->isEmpty() ||
2086         (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) {
2087         return;
2088     }
2089
2090     SkScalar    width = 0;
2091     SkPoint     start;
2092
2093     start.set(0, 0);    // to avoid warning
2094     if (paint.getFlags() & (SkPaint::kUnderlineText_Flag |
2095                             SkPaint::kStrikeThruText_Flag)) {
2096         width = paint.measureText(text, byteLength);
2097
2098         SkScalar offsetX = 0;
2099         if (paint.getTextAlign() == SkPaint::kCenter_Align) {
2100             offsetX = SkScalarHalf(width);
2101         } else if (paint.getTextAlign() == SkPaint::kRight_Align) {
2102             offsetX = width;
2103         }
2104         start.set(x - offsetX, y);
2105     }
2106
2107     if (0 == width) {
2108         return;
2109     }
2110
2111     uint32_t flags = paint.getFlags();
2112
2113     if (flags & (SkPaint::kUnderlineText_Flag |
2114                  SkPaint::kStrikeThruText_Flag)) {
2115         SkScalar textSize = paint.getTextSize();
2116         SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness);
2117         SkRect   r;
2118
2119         r.fLeft = start.fX;
2120         r.fRight = start.fX + width;
2121
2122         if (flags & SkPaint::kUnderlineText_Flag) {
2123             SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset,
2124                                              start.fY);
2125             r.fTop = offset;
2126             r.fBottom = offset + height;
2127             DrawRect(draw, paint, r, textSize);
2128         }
2129         if (flags & SkPaint::kStrikeThruText_Flag) {
2130             SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset,
2131                                              start.fY);
2132             r.fTop = offset;
2133             r.fBottom = offset + height;
2134             DrawRect(draw, paint, r, textSize);
2135         }
2136     }
2137 }
2138
2139 void SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
2140                           const SkPaint& paint) {
2141     LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL)
2142
2143     while (iter.next()) {
2144         SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
2145         iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint());
2146         DrawTextDecorations(iter, dfp.paint(),
2147                             static_cast<const char*>(text), byteLength, x, y);
2148     }
2149
2150     LOOPER_END
2151 }
2152
2153 void SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
2154                              const SkPaint& paint) {
2155     LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL)
2156
2157     while (iter.next()) {
2158         SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
2159         iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 0, 2,
2160                                   dfp.paint());
2161     }
2162
2163     LOOPER_END
2164 }
2165
2166 void SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
2167                               SkScalar constY, const SkPaint& paint) {
2168     LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL)
2169
2170     while (iter.next()) {
2171         SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
2172         iter.fDevice->drawPosText(iter, text, byteLength, xpos, constY, 1,
2173                                   dfp.paint());
2174     }
2175
2176     LOOPER_END
2177 }
2178
2179 void SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
2180                                 const SkMatrix* matrix, const SkPaint& paint) {
2181     LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL)
2182
2183     while (iter.next()) {
2184         iter.fDevice->drawTextOnPath(iter, text, byteLength, path,
2185                                      matrix, looper.paint());
2186     }
2187
2188     LOOPER_END
2189 }
2190
2191 void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
2192                               const SkPaint& paint) {
2193
2194     // FIXME: temporarily disable quickreject for empty bounds,
2195     // pending implicit blob bounds implementation.
2196     if (!blob->bounds().isEmpty() && paint.canComputeFastBounds()) {
2197         SkRect storage;
2198
2199         if (this->quickReject(paint.computeFastBounds(blob->bounds().makeOffset(x, y), &storage))) {
2200             return;
2201         }
2202     }
2203
2204     LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL)
2205
2206     while (iter.next()) {
2207         SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
2208         iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint());
2209     }
2210
2211     LOOPER_END
2212 }
2213
2214 // These will become non-virtual, so they always call the (virtual) onDraw... method
2215 void SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
2216                         const SkPaint& paint) {
2217     this->onDrawText(text, byteLength, x, y, paint);
2218 }
2219 void SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
2220                            const SkPaint& paint) {
2221     this->onDrawPosText(text, byteLength, pos, paint);
2222 }
2223 void SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
2224                             SkScalar constY, const SkPaint& paint) {
2225     this->onDrawPosTextH(text, byteLength, xpos, constY, paint);
2226 }
2227 void SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
2228                               const SkMatrix* matrix, const SkPaint& paint) {
2229     this->onDrawTextOnPath(text, byteLength, path, matrix, paint);
2230 }
2231 void SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
2232                             const SkPaint& paint) {
2233     if (blob) {
2234         this->onDrawTextBlob(blob, x, y, paint);
2235     }
2236 }
2237
2238 void SkCanvas::drawVertices(VertexMode vmode, int vertexCount,
2239                             const SkPoint verts[], const SkPoint texs[],
2240                             const SkColor colors[], SkXfermode* xmode,
2241                             const uint16_t indices[], int indexCount,
2242                             const SkPaint& paint) {
2243     LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL)
2244
2245     while (iter.next()) {
2246         iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs,
2247                                    colors, xmode, indices, indexCount,
2248                                    looper.paint());
2249     }
2250
2251     LOOPER_END
2252 }
2253
2254 void SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
2255                          const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
2256     if (NULL == cubics) {
2257         return;
2258     }
2259
2260     // Since a patch is always within the convex hull of the control points, we discard it when its
2261     // bounding rectangle is completely outside the current clip.
2262     SkRect bounds;
2263     bounds.set(cubics, SkPatchUtils::kNumCtrlPts);
2264     if (this->quickReject(bounds)) {
2265         return;
2266     }
2267
2268     this->onDrawPatch(cubics, colors, texCoords, xmode, paint);
2269 }
2270
2271 void SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
2272                            const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
2273
2274     LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL)
2275
2276     while (iter.next()) {
2277         iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint);
2278     }
2279
2280     LOOPER_END
2281 }
2282
2283 //////////////////////////////////////////////////////////////////////////////
2284 // These methods are NOT virtual, and therefore must call back into virtual
2285 // methods, rather than actually drawing themselves.
2286 //////////////////////////////////////////////////////////////////////////////
2287
2288 void SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
2289                         SkXfermode::Mode mode) {
2290     SkPaint paint;
2291
2292     paint.setARGB(a, r, g, b);
2293     if (SkXfermode::kSrcOver_Mode != mode) {
2294         paint.setXfermodeMode(mode);
2295     }
2296     this->drawPaint(paint);
2297 }
2298
2299 void SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) {
2300     SkPaint paint;
2301
2302     paint.setColor(c);
2303     if (SkXfermode::kSrcOver_Mode != mode) {
2304         paint.setXfermodeMode(mode);
2305     }
2306     this->drawPaint(paint);
2307 }
2308
2309 void SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) {
2310     SkPoint pt;
2311
2312     pt.set(x, y);
2313     this->drawPoints(kPoints_PointMode, 1, &pt, paint);
2314 }
2315
2316 void SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) {
2317     SkPoint pt;
2318     SkPaint paint;
2319
2320     pt.set(x, y);
2321     paint.setColor(color);
2322     this->drawPoints(kPoints_PointMode, 1, &pt, paint);
2323 }
2324
2325 void SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
2326                         const SkPaint& paint) {
2327     SkPoint pts[2];
2328
2329     pts[0].set(x0, y0);
2330     pts[1].set(x1, y1);
2331     this->drawPoints(kLines_PointMode, 2, pts, paint);
2332 }
2333
2334 void SkCanvas::drawRectCoords(SkScalar left, SkScalar top,
2335                               SkScalar right, SkScalar bottom,
2336                               const SkPaint& paint) {
2337     SkRect  r;
2338
2339     r.set(left, top, right, bottom);
2340     this->drawRect(r, paint);
2341 }
2342
2343 void SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
2344                           const SkPaint& paint) {
2345     if (radius < 0) {
2346         radius = 0;
2347     }
2348
2349     SkRect  r;
2350     r.set(cx - radius, cy - radius, cx + radius, cy + radius);
2351     this->drawOval(r, paint);
2352 }
2353
2354 void SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry,
2355                              const SkPaint& paint) {
2356     if (rx > 0 && ry > 0) {
2357         if (paint.canComputeFastBounds()) {
2358             SkRect storage;
2359             if (this->quickReject(paint.computeFastBounds(r, &storage))) {
2360                 return;
2361             }
2362         }
2363         SkRRect rrect;
2364         rrect.setRectXY(r, rx, ry);
2365         this->drawRRect(rrect, paint);
2366     } else {
2367         this->drawRect(r, paint);
2368     }
2369 }
2370
2371 void SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle,
2372                        SkScalar sweepAngle, bool useCenter,
2373                        const SkPaint& paint) {
2374     if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) {
2375         this->drawOval(oval, paint);
2376     } else {
2377         SkPath  path;
2378         if (useCenter) {
2379             path.moveTo(oval.centerX(), oval.centerY());
2380         }
2381         path.arcTo(oval, startAngle, sweepAngle, !useCenter);
2382         if (useCenter) {
2383             path.close();
2384         }
2385         this->drawPath(path, paint);
2386     }
2387 }
2388
2389 void SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength,
2390                                 const SkPath& path, SkScalar hOffset,
2391                                 SkScalar vOffset, const SkPaint& paint) {
2392     SkMatrix    matrix;
2393
2394     matrix.setTranslate(hOffset, vOffset);
2395     this->drawTextOnPath(text, byteLength, path, &matrix, paint);
2396 }
2397
2398 ///////////////////////////////////////////////////////////////////////////////
2399 void SkCanvas::EXPERIMENTAL_optimize(const SkPicture* picture) {
2400     SkBaseDevice* device = this->getDevice();
2401     if (device) {
2402         device->EXPERIMENTAL_optimize(picture);
2403     }
2404 }
2405
2406 void SkCanvas::drawPicture(const SkPicture* picture) {
2407     if (picture) {
2408         this->onDrawPicture(picture, NULL, NULL);
2409     }
2410 }
2411
2412 void SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) {
2413     if (picture) {
2414         if (matrix && matrix->isIdentity()) {
2415             matrix = NULL;
2416         }
2417         this->onDrawPicture(picture, matrix, paint);
2418     }
2419 }
2420
2421 void SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
2422                              const SkPaint* paint) {
2423     SkBaseDevice* device = this->getTopDevice();
2424     if (device) {
2425         // Canvas has to first give the device the opportunity to render
2426         // the picture itself.
2427         if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) {
2428             return; // the device has rendered the entire picture
2429         }
2430     }
2431
2432     SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
2433
2434     picture->playback(this);
2435 }
2436
2437 ///////////////////////////////////////////////////////////////////////////////
2438 ///////////////////////////////////////////////////////////////////////////////
2439
2440 SkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) {
2441     SK_COMPILE_ASSERT(sizeof(fStorage) >= sizeof(SkDrawIter), fStorage_too_small);
2442
2443     SkASSERT(canvas);
2444
2445     fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips);
2446     fDone = !fImpl->next();
2447 }
2448
2449 SkCanvas::LayerIter::~LayerIter() {
2450     fImpl->~SkDrawIter();
2451 }
2452
2453 void SkCanvas::LayerIter::next() {
2454     fDone = !fImpl->next();
2455 }
2456
2457 SkBaseDevice* SkCanvas::LayerIter::device() const {
2458     return fImpl->getDevice();
2459 }
2460
2461 const SkMatrix& SkCanvas::LayerIter::matrix() const {
2462     return fImpl->getMatrix();
2463 }
2464
2465 const SkPaint& SkCanvas::LayerIter::paint() const {
2466     const SkPaint* paint = fImpl->getPaint();
2467     if (NULL == paint) {
2468         paint = &fDefaultPaint;
2469     }
2470     return *paint;
2471 }
2472
2473 const SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); }
2474 int SkCanvas::LayerIter::x() const { return fImpl->getX(); }
2475 int SkCanvas::LayerIter::y() const { return fImpl->getY(); }
2476
2477 ///////////////////////////////////////////////////////////////////////////////
2478
2479 SkCanvasClipVisitor::~SkCanvasClipVisitor() { }
2480
2481 ///////////////////////////////////////////////////////////////////////////////
2482
2483 static bool supported_for_raster_canvas(const SkImageInfo& info) {
2484     switch (info.alphaType()) {
2485         case kPremul_SkAlphaType:
2486         case kOpaque_SkAlphaType:
2487             break;
2488         default:
2489             return false;
2490     }
2491
2492     switch (info.colorType()) {
2493         case kAlpha_8_SkColorType:
2494         case kRGB_565_SkColorType:
2495         case kN32_SkColorType:
2496             break;
2497         default:
2498             return false;
2499     }
2500
2501     return true;
2502 }
2503
2504 SkCanvas* SkCanvas::NewRaster(const SkImageInfo& info) {
2505     if (!supported_for_raster_canvas(info)) {
2506         return NULL;
2507     }
2508
2509     SkBitmap bitmap;
2510     if (!bitmap.tryAllocPixels(info)) {
2511         return NULL;
2512     }
2513
2514     // should this functionality be moved into allocPixels()?
2515     if (!bitmap.info().isOpaque()) {
2516         bitmap.eraseColor(0);
2517     }
2518     return SkNEW_ARGS(SkCanvas, (bitmap));
2519 }
2520
2521 SkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) {
2522     if (!supported_for_raster_canvas(info)) {
2523         return NULL;
2524     }
2525
2526     SkBitmap bitmap;
2527     if (!bitmap.installPixels(info, pixels, rowBytes)) {
2528         return NULL;
2529     }
2530     return SkNEW_ARGS(SkCanvas, (bitmap));
2531 }
2532
2533 ///////////////////////////////////////////////////////////////////////////////
2534
2535 SkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix,
2536                                                  const SkPaint* paint, const SkRect& bounds)
2537     : fCanvas(canvas)
2538     , fSaveCount(canvas->getSaveCount())
2539 {
2540     if (paint) {
2541         SkRect newBounds = bounds;
2542         if (matrix) {
2543             matrix->mapRect(&newBounds);
2544         }
2545         canvas->saveLayer(&newBounds, paint);
2546     } else if (matrix) {
2547         canvas->save();
2548     }
2549
2550     if (matrix) {
2551         canvas->concat(*matrix);
2552     }
2553 }
2554
2555 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() {
2556     fCanvas->restoreToCount(fSaveCount);
2557 }