1/*
2 * Copyright 2014 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#ifndef SkDrawable_DEFINED
9#define SkDrawable_DEFINED
10
11#include "SkFlattenable.h"
12#include "SkScalar.h"
13
14class SkCanvas;
15class SkMatrix;
16class SkPicture;
17struct SkRect;
18
19/**
20 *  Base-class for objects that draw into SkCanvas.
21 *
22 *  The object has a generation ID, which is guaranteed to be unique across all drawables. To
23 *  allow for clients of the drawable that may want to cache the results, the drawable must
24 *  change its generation ID whenever its internal state changes such that it will draw differently.
25 */
26class SkDrawable : public SkFlattenable {
27public:
28    SkDrawable();
29
30    /**
31     *  Draws into the specified content. The drawing sequence will be balanced upon return
32     *  (i.e. the saveLevel() on the canvas will match what it was when draw() was called,
33     *  and the current matrix and clip settings will not be changed.
34     */
35    void draw(SkCanvas*, const SkMatrix* = NULL);
36    void draw(SkCanvas*, SkScalar x, SkScalar y);
37
38    SkPicture* newPictureSnapshot();
39
40    /**
41     *  Return a unique value for this instance. If two calls to this return the same value,
42     *  it is presumed that calling the draw() method will render the same thing as well.
43     *
44     *  Subclasses that change their state should call notifyDrawingChanged() to ensure that
45     *  a new value will be returned the next time it is called.
46     */
47    uint32_t getGenerationID();
48
49    /**
50     *  Return the (conservative) bounds of what the drawable will draw. If the drawable can
51     *  change what it draws (e.g. animation or in response to some external change), then this
52     *  must return a bounds that is always valid for all possible states.
53     */
54    SkRect getBounds();
55
56    /**
57     *  Calling this invalidates the previous generation ID, and causes a new one to be computed
58     *  the next time getGenerationID() is called. Typically this is called by the object itself,
59     *  in response to its internal state changing.
60     */
61    void notifyDrawingChanged();
62
63    SK_DEFINE_FLATTENABLE_TYPE(SkDrawable)
64    Factory getFactory() const override { return nullptr; }
65
66protected:
67    virtual SkRect onGetBounds() = 0;
68    virtual void onDraw(SkCanvas*) = 0;
69
70    /**
71     *  Default implementation calls onDraw() with a canvas that records into a picture. Subclasses
72     *  may override if they have a more efficient way to return a picture for the current state
73     *  of their drawable. Note: this picture must draw the same as what would be drawn from
74     *  onDraw().
75     */
76    virtual SkPicture* onNewPictureSnapshot();
77
78private:
79    int32_t fGenerationID;
80};
81
82#endif
83