SkSurface_Picture.cpp revision d686ac77c2c485c4a3302eda9c1de597a6f8c568
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 */
17class SkSurface_Picture : public SkSurface_Base {
18public:
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
29private:
30    SkPicture*  fPicture;
31    SkPicture*  fRecordingPicture;
32
33    typedef SkSurface_Base INHERITED;
34};
35
36///////////////////////////////////////////////////////////////////////////////
37
38SkSurface_Picture::SkSurface_Picture(int width, int height) : INHERITED(width, height) {
39    fPicture = NULL;
40}
41
42SkSurface_Picture::~SkSurface_Picture() {
43    SkSafeUnref(fPicture);
44}
45
46SkCanvas* 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
55SkSurface* SkSurface_Picture::onNewSurface(const SkImage::Info& info) {
56    return SkSurface::NewPicture(info.fWidth, info.fHeight);
57}
58
59SkImage* 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
71void 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
79void 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
87SkSurface* 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