Modify SkDeferredCanvas so that it uses its inherited SkCanvas to track matrix and clipping state
Removed 'virtual' from a few canvas methods that no longer need it thanks to this change.

BUG=http://code.google.com/p/skia/issues/detail?id=506
TEST=Canvas unit test
REVIEW=http://codereview.appspot.com/5697052/



git-svn-id: http://skia.googlecode.com/svn/trunk@3261 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 6e061c2..5f97d68 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -707,19 +707,12 @@
     return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0;
 }
 
-int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
-                        SaveFlags flags) {
-    // do this before we create the layer. We don't call the public save() since
-    // that would invoke a possibly overridden virtual
-    int count = this->internalSave(flags);
-
-    fDeviceCMDirty = true;
-
+bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags,
+                               SkIRect* intersection) {
     SkIRect clipBounds;
     if (!this->getClipDeviceBounds(&clipBounds)) {
-        return count;
+        return false;
     }
-
     SkIRect ir;
     if (NULL != bounds) {
         SkRect r;
@@ -731,16 +724,36 @@
             if (bounds_affects_clip(flags)) {
                 fMCRec->fRasterClip->setEmpty();
             }
-            return count;
+            return false;
         }
     } else {    // no user bounds, so just use the clip
         ir = clipBounds;
     }
 
     fClipStack.clipDevRect(ir, SkRegion::kIntersect_Op);
+
     // early exit if the clip is now empty
     if (bounds_affects_clip(flags) &&
         !fMCRec->fRasterClip->op(ir, SkRegion::kIntersect_Op)) {
+        return false;
+    }
+
+    if (intersection) {
+        *intersection = ir;
+    }
+    return true;
+}
+
+int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
+                        SaveFlags flags) {
+    // do this before we create the layer. We don't call the public save() since
+    // that would invoke a possibly overridden virtual
+    int count = this->internalSave(flags);
+
+    fDeviceCMDirty = true;
+
+    SkIRect ir;
+    if (!this->clipRectBounds(bounds, flags, &ir)) {
         return count;
     }
 
@@ -1044,8 +1057,8 @@
             return currClip->op(clip, op);
         }
     } else {
-        const SkBitmap& bm = canvas->getDevice()->accessBitmap(false);
-        base.setRect(0, 0, bm.width(), bm.height());
+        const SkDevice* device = canvas->getDevice();
+        base.setRect(0, 0, device->width(), device->height());
 
         if (SkRegion::kReplace_Op == op) {
             return currClip->setPath(devPath, base, doAA);
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index c56c104..ba49b72 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -62,7 +62,9 @@
         clip starts out the size of the picture, which is often much larger
         than the size of the actual device we'll use during playback).
      */
-    return this->INHERITED::save(flags);
+    int count = this->INHERITED::save(flags);
+    this->clipRectBounds(bounds, flags, NULL);
+    return count;
 }
 
 bool SkPictureRecord::isDrawingToLayer() const {
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index 00a26b9..1254392 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -101,7 +101,6 @@
 void SkDeferredCanvas::validate() const
 {
     SkASSERT(getDevice());
-    SkASSERT(INHERITED::getTotalMatrix().isIdentity());
 }
 
 SkCanvas* SkDeferredCanvas::drawingCanvas() const
@@ -216,78 +215,87 @@
 
 int SkDeferredCanvas::save(SaveFlags flags)
 {
-    return drawingCanvas()->save(flags);
+    drawingCanvas()->save(flags);
+    return this->INHERITED::save(flags);
 }
 
 int SkDeferredCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
                           SaveFlags flags)
 {
-    return drawingCanvas()->saveLayer(bounds, paint, flags);
+    drawingCanvas()->saveLayer(bounds, paint, flags);
+    int count = this->INHERITED::save(flags);
+    this->clipRectBounds(bounds, flags, NULL);
+    return count;
 }
 
 void SkDeferredCanvas::restore()
 {
     drawingCanvas()->restore();
+    this->INHERITED::restore();
 }
 
-int SkDeferredCanvas::getSaveCount() const
+bool SkDeferredCanvas::isDrawingToLayer() const
 {
-    return drawingCanvas()->getSaveCount();
+    return drawingCanvas()->isDrawingToLayer();
 }
 
 bool SkDeferredCanvas::translate(SkScalar dx, SkScalar dy)
 {
-    return drawingCanvas()->translate(dx, dy);
+    drawingCanvas()->translate(dx, dy);
+    return this->INHERITED::translate(dx, dy);
 }
 
 bool SkDeferredCanvas::scale(SkScalar sx, SkScalar sy)
 {
-    return drawingCanvas()->scale(sx, sy);
+    drawingCanvas()->scale(sx, sy);
+    return this->INHERITED::scale(sx, sy);
 }
 
 bool SkDeferredCanvas::rotate(SkScalar degrees)
 {
-    return drawingCanvas()->rotate(degrees);
+    drawingCanvas()->rotate(degrees);
+    return this->INHERITED::rotate(degrees);
 }
 
 bool SkDeferredCanvas::skew(SkScalar sx, SkScalar sy)
 {
-    return drawingCanvas()->skew(sx, sy);
+    drawingCanvas()->skew(sx, sy);
+    return this->INHERITED::skew(sx, sy);
 }
 
 bool SkDeferredCanvas::concat(const SkMatrix& matrix)
 {
-    return drawingCanvas()->concat(matrix);
+    drawingCanvas()->concat(matrix);
+    return this->INHERITED::concat(matrix);
 }
 
 void SkDeferredCanvas::setMatrix(const SkMatrix& matrix)
 {
     drawingCanvas()->setMatrix(matrix);
-}
-
-const SkMatrix& SkDeferredCanvas::getTotalMatrix() const 
-{
-    return drawingCanvas()->getTotalMatrix();
+    this->INHERITED::setMatrix(matrix);
 }
 
 bool SkDeferredCanvas::clipRect(const SkRect& rect,
                                 SkRegion::Op op,
                                 bool doAntiAlias)
 {
-    return drawingCanvas()->clipRect(rect, op, doAntiAlias);
+    drawingCanvas()->clipRect(rect, op, doAntiAlias);
+    return this->INHERITED::clipRect(rect, op, doAntiAlias);
 }
 
 bool SkDeferredCanvas::clipPath(const SkPath& path,
                                 SkRegion::Op op,
                                 bool doAntiAlias)
 {
-    return drawingCanvas()->clipPath(path, op, doAntiAlias);
+    drawingCanvas()->clipPath(path, op, doAntiAlias);
+    return this->INHERITED::clipPath(path, op, doAntiAlias);
 }
 
 bool SkDeferredCanvas::clipRegion(const SkRegion& deviceRgn,
                                   SkRegion::Op op)
 {
-    return drawingCanvas()->clipRegion(deviceRgn, op);
+    drawingCanvas()->clipRegion(deviceRgn, op);
+    return this->INHERITED::clipRegion(deviceRgn, op);
 }
 
 void SkDeferredCanvas::clear(SkColor color)
@@ -454,14 +462,14 @@
 
 SkBounder* SkDeferredCanvas::setBounder(SkBounder* bounder)
 {
-    INHERITED::setBounder(bounder); // So non-virtual getBounder works
-    return drawingCanvas()->setBounder(bounder);
+    drawingCanvas()->setBounder(bounder);
+    return INHERITED::setBounder(bounder);
 }
 
 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter)
 {
-    INHERITED::setDrawFilter(filter); // So non-virtual getDrawFilter works
-    return drawingCanvas()->setDrawFilter(filter); 
+    drawingCanvas()->setDrawFilter(filter); 
+    return INHERITED::setDrawFilter(filter); // So non-virtual getDrawFilter works
 }
 
 SkCanvas* SkDeferredCanvas::canvasForDrawIter() {
@@ -482,8 +490,7 @@
     fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas
     fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice));
     fRecordingCanvas = fPicture.beginRecording(fImmediateDevice->width(),
-        fImmediateDevice->height(),
-        SkPicture::kUsePathBoundsForClip_RecordingFlag);
+        fImmediateDevice->height(), 0);
 }
 
 SkDeferredCanvas::DeferredDevice::~DeferredDevice()
@@ -518,8 +525,7 @@
             // old one, hence purging deferred draw ops.
             fRecordingCanvas = fPicture.beginRecording(
                 fImmediateDevice->width(),
-                fImmediateDevice->height(),
-                SkPicture::kUsePathBoundsForClip_RecordingFlag);
+                fImmediateDevice->height(), 0);
 
             // Restore pre-purge state
             if (!clipRegion.isEmpty()) {
@@ -548,8 +554,7 @@
     }
     fPicture.draw(fImmediateCanvas);
     fRecordingCanvas = fPicture.beginRecording(fImmediateDevice->width(), 
-        fImmediateDevice->height(),
-        SkPicture::kUsePathBoundsForClip_RecordingFlag);
+        fImmediateDevice->height(), 0);
 }
 
 void SkDeferredCanvas::DeferredDevice::flush()