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