SkDrawLooper.h revision 4991b8f23482afc1494fd17647421ce68de53331
1
2/*
3 * Copyright 2011 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#ifndef SkDrawLooper_DEFINED
11#define SkDrawLooper_DEFINED
12
13#include "SkFlattenable.h"
14
15class SkCanvas;
16class SkPaint;
17struct SkRect;
18class SkString;
19
20/** \class SkDrawLooper
21    Subclasses of SkDrawLooper can be attached to a SkPaint. Where they are,
22    and something is drawn to a canvas with that paint, the looper subclass will
23    be called, allowing it to modify the canvas and/or paint for that draw call.
24    More than that, via the next() method, the looper can modify the draw to be
25    invoked multiple times (hence the name loop-er), allow it to perform effects
26    like shadows or frame/fills, that require more than one pass.
27*/
28class SK_API SkDrawLooper : public SkFlattenable {
29public:
30    SK_DECLARE_INST_COUNT(SkDrawLooper)
31
32    /**
33     *  Called right before something is being drawn. This will be followed by
34     *  calls to next() until next() returns false.
35     */
36    virtual void init(SkCanvas*) = 0;
37
38    /**
39     *  Called in a loop (after init()). Each time true is returned, the object
40     *  is drawn (possibly with a modified canvas and/or paint). When false is
41     *  finally returned, drawing for the object stops.
42     *
43     *  On each call, the paint will be in its original state, but the canvas
44     *  will be as it was following the previous call to next() or init().
45     *
46     *  The implementation must ensure that, when next() finally returns false,
47     *  that the canvas has been restored to the state it was initially, before
48     *  init() was first called.
49     */
50    virtual bool next(SkCanvas*, SkPaint* paint) = 0;
51
52    /**
53     * The fast bounds functions are used to enable the paint to be culled early
54     * in the drawing pipeline. If a subclass can support this feature it must
55     * return true for the canComputeFastBounds() function.  If that function
56     * returns false then computeFastBounds behavior is undefined otherwise it
57     * is expected to have the following behavior. Given the parent paint and
58     * the parent's bounding rect the subclass must fill in and return the
59     * storage rect, where the storage rect is with the union of the src rect
60     * and the looper's bounding rect.
61     */
62    virtual bool canComputeFastBounds(const SkPaint& paint);
63    virtual void computeFastBounds(const SkPaint& paint,
64                                   const SkRect& src, SkRect* dst);
65
66    SkDEVCODE(virtual void toString(SkString* str) const = 0;)
67
68protected:
69    SkDrawLooper() {}
70    SkDrawLooper(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
71
72private:
73    typedef SkFlattenable INHERITED;
74};
75
76#endif
77