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* 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
29private:
30    SkPicture*  fPicture;
31
32    typedef SkSurface_Base INHERITED;
33};
34
35///////////////////////////////////////////////////////////////////////////////
36
37SkSurface_Picture::SkSurface_Picture(int width, int height) : INHERITED(width, height) {
38    fPicture = NULL;
39}
40
41SkSurface_Picture::~SkSurface_Picture() {
42    SkSafeUnref(fPicture);
43}
44
45SkCanvas* 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
54SkSurface* SkSurface_Picture::onNewSurface(const SkImage::Info& info) {
55    return SkSurface::NewPicture(info.fWidth, info.fHeight);
56}
57
58SkImage* 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
70void 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
78void 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
86SkSurface* 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