Refactor SkCanvas so that backends don't need to override it.

Methods or classes that should go away are marked deprecated. The only thing I know of that breaks backward compatibility is SkCanvas((SkDevice*)NULL), but that is fairly unlikely to occur in the wild because that constructor had a default value of NULL.

Review URL: http://codereview.appspot.com/2103045

git-svn-id: http://skia.googlecode.com/svn/trunk@604 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 61998ec..7cda41e 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -404,8 +404,21 @@
     return this->setDevice(device);
 }
 
+SkCanvas::SkCanvas(SkDeviceFactory* factory)
+        : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)),
+          fDeviceFactory(factory) {
+    inc_canvas();
+
+    SkSafeRef(factory);
+    if (!factory)
+        fDeviceFactory = SkNEW(SkRasterDeviceFactory);
+
+    this->init(NULL);
+}
+
 SkCanvas::SkCanvas(SkDevice* device)
-        : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) {
+        : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)),
+          fDeviceFactory(device->getDeviceFactory()) {
     inc_canvas();
 
     this->init(device);
@@ -415,7 +428,9 @@
         : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) {
     inc_canvas();
 
-    this->init(SkNEW_ARGS(SkDevice, (bitmap)))->unref();
+    SkDevice* device = SkNEW_ARGS(SkDevice, (bitmap));
+    fDeviceFactory = device->getDeviceFactory();
+    this->init(device)->unref();
 }
 
 SkCanvas::~SkCanvas() {
@@ -423,7 +438,8 @@
     this->restoreToCount(1);    // restore everything but the last
     this->internalRestore();    // restore the last, since we're going away
 
-    fBounder->safeUnref();
+    SkSafeUnref(fBounder);
+    SkSafeUnref(fDeviceFactory);
     
     dec_canvas();
 }
@@ -521,11 +537,21 @@
 //////////////////////////////////////////////////////////////////////////////
 
 bool SkCanvas::getViewport(SkIPoint* size) const {
-    return false;
+    if ((fDeviceFactory->getDeviceCapabilities()
+            & SkDeviceFactory::kGL_Capability) == 0)
+        return false;
+    if (size)
+        size->set(getDevice()->width(), getDevice()->height());
+    return true;
 }
 
 bool SkCanvas::setViewport(int width, int height) {
-    return false;
+    if ((fDeviceFactory->getDeviceCapabilities()
+            & SkDeviceFactory::kGL_Capability) == 0)
+        return false;
+    this->setDevice(createDevice(SkBitmap::kARGB_8888_Config, width, height,
+                                 false, false))->unref();
+    return true;
 }
 
 void SkCanvas::updateDeviceCMCache() {
@@ -1004,18 +1030,9 @@
 
 SkDevice* SkCanvas::createDevice(SkBitmap::Config config, int width,
                                  int height, bool isOpaque, bool isForLayer) {
-    SkBitmap bitmap;
-    
-    bitmap.setConfig(config, width, height);
-    bitmap.setIsOpaque(isOpaque);
 
-    // should this happen in the device subclass?
-    bitmap.allocPixels();   
-    if (!bitmap.isOpaque()) {
-        bitmap.eraseARGB(0, 0, 0, 0);
-    }
-
-    return SkNEW_ARGS(SkDevice, (bitmap));
+    return fDeviceFactory->newDevice(config, width, height, isOpaque,
+                                     isForLayer);
 }
 
 //////////////////////////////////////////////////////////////////////////////