Home | History | Annotate | Download | only in image
      1 /*
      2  * Copyright 2012 Google Inc.
      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 "SkSurface_Base.h"
      9 #include "SkCanvas.h"
     10 #include "SkImagePriv.h"
     11 #include "SkPicture.h"
     12 
     13 /**
     14  *  What does it mean to ask for more than one canvas from a picture?
     15  *  How do we return an Image and then "continue" recording?
     16  */
     17 class SkSurface_Picture : public SkSurface_Base {
     18 public:
     19     SkSurface_Picture(int width, int height);
     20     virtual ~SkSurface_Picture();
     21 
     22     virtual SkCanvas* onNewCanvas() SK_OVERRIDE;
     23     virtual SkSurface* onNewSurface(const SkImage::Info&) SK_OVERRIDE;
     24     virtual SkImage* onNewImageShapshot() SK_OVERRIDE;
     25     virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
     26                         const SkPaint*) SK_OVERRIDE;
     27     virtual void onCopyOnWrite(SkImage*, SkCanvas*) SK_OVERRIDE;
     28 
     29 private:
     30     SkPicture*  fPicture;
     31     SkPicture*  fRecordingPicture;
     32 
     33     typedef SkSurface_Base INHERITED;
     34 };
     35 
     36 ///////////////////////////////////////////////////////////////////////////////
     37 
     38 SkSurface_Picture::SkSurface_Picture(int width, int height) : INHERITED(width, height) {
     39     fPicture = NULL;
     40 }
     41 
     42 SkSurface_Picture::~SkSurface_Picture() {
     43     SkSafeUnref(fPicture);
     44 }
     45 
     46 SkCanvas* SkSurface_Picture::onNewCanvas() {
     47     if (!fPicture) {
     48         fPicture = SkNEW(SkPicture);
     49     }
     50     SkCanvas* canvas = fPicture->beginRecording(this->width(), this->height());
     51     canvas->ref();  // our caller will call unref()
     52     return canvas;
     53 }
     54 
     55 SkSurface* SkSurface_Picture::onNewSurface(const SkImage::Info& info) {
     56     return SkSurface::NewPicture(info.fWidth, info.fHeight);
     57 }
     58 
     59 SkImage* SkSurface_Picture::onNewImageShapshot() {
     60     if (fPicture) {
     61         return SkNewImageFromPicture(fPicture);
     62     } else {
     63         SkImage::Info info;
     64         info.fWidth = info.fHeight = 0;
     65         info.fColorType = SkImage::kPMColor_ColorType;
     66         info.fAlphaType = SkImage::kOpaque_AlphaType;
     67         return SkImage::NewRasterCopy(info, NULL, 0);
     68     }
     69 }
     70 
     71 void SkSurface_Picture::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
     72                                const SkPaint* paint) {
     73     if (!fPicture) {
     74         return;
     75     }
     76     SkImagePrivDrawPicture(canvas, fPicture, x, y, paint);
     77 }
     78 
     79 void SkSurface_Picture::onCopyOnWrite(SkImage* cachedImage, SkCanvas*) {
     80     // We always spawn a copy of the recording picture when we
     81     // are asked for a snapshot, so we never need to do anything here.
     82 }
     83 
     84 ///////////////////////////////////////////////////////////////////////////////
     85 
     86 
     87 SkSurface* SkSurface::NewPicture(int width, int height) {
     88     if ((width | height) < 0) {
     89         return NULL;
     90     }
     91 
     92     return SkNEW_ARGS(SkSurface_Picture, (width, height));
     93 }
     94