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* onNewImageSnapshot() SK_OVERRIDE;
     25     virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
     26                         const SkPaint*) SK_OVERRIDE;
     27     virtual void onCopyOnWrite(ContentChangeMode) SK_OVERRIDE;
     28 
     29 private:
     30     SkPicture*  fPicture;
     31 
     32     typedef SkSurface_Base INHERITED;
     33 };
     34 
     35 ///////////////////////////////////////////////////////////////////////////////
     36 
     37 SkSurface_Picture::SkSurface_Picture(int width, int height) : INHERITED(width, height) {
     38     fPicture = NULL;
     39 }
     40 
     41 SkSurface_Picture::~SkSurface_Picture() {
     42     SkSafeUnref(fPicture);
     43 }
     44 
     45 SkCanvas* SkSurface_Picture::onNewCanvas() {
     46     if (!fPicture) {
     47         fPicture = SkNEW(SkPicture);
     48     }
     49     SkCanvas* canvas = fPicture->beginRecording(this->width(), this->height());
     50     canvas->ref();  // our caller will call unref()
     51     return canvas;
     52 }
     53 
     54 SkSurface* SkSurface_Picture::onNewSurface(const SkImage::Info& info) {
     55     return SkSurface::NewPicture(info.fWidth, info.fHeight);
     56 }
     57 
     58 SkImage* SkSurface_Picture::onNewImageSnapshot() {
     59     if (fPicture) {
     60         return SkNewImageFromPicture(fPicture);
     61     } else {
     62         SkImage::Info info;
     63         info.fWidth = info.fHeight = 0;
     64         info.fColorType = SkImage::kPMColor_ColorType;
     65         info.fAlphaType = SkImage::kOpaque_AlphaType;
     66         return SkImage::NewRasterCopy(info, NULL, 0);
     67     }
     68 }
     69 
     70 void SkSurface_Picture::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
     71                                const SkPaint* paint) {
     72     if (!fPicture) {
     73         return;
     74     }
     75     SkImagePrivDrawPicture(canvas, fPicture, x, y, paint);
     76 }
     77 
     78 void SkSurface_Picture::onCopyOnWrite(ContentChangeMode /*mode*/) {
     79     // We always spawn a copy of the recording picture when we
     80     // are asked for a snapshot, so we never need to do anything here.
     81 }
     82 
     83 ///////////////////////////////////////////////////////////////////////////////
     84 
     85 
     86 SkSurface* SkSurface::NewPicture(int width, int height) {
     87     if ((width | height) < 0) {
     88         return NULL;
     89     }
     90 
     91     return SkNEW_ARGS(SkSurface_Picture, (width, height));
     92 }
     93