aboutsummaryrefslogtreecommitdiff
path: root/src/deps/skia/include/core/SkDrawLooper.h
blob: 69d341c25fd5e214e70b72a61e766bb743071283 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

/*
 * Copyright 2011 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkDrawLooper_DEFINED
#define SkDrawLooper_DEFINED

#include "include/core/SkBlurTypes.h"
#include "include/core/SkColor.h"
#include "include/core/SkFlattenable.h"
#include "include/core/SkPoint.h"
#include <functional>  // std::function

#ifndef SK_SUPPORT_LEGACY_DRAWLOOPER
#error "SkDrawLooper is unsupported"
#endif

class  SkArenaAlloc;
class  SkCanvas;
class  SkMatrix;
class  SkPaint;
struct SkRect;

/** \class SkDrawLooper
    DEPRECATED: No longer supported in Skia.
*/
class SK_API SkDrawLooper : public SkFlattenable {
public:
    /**
     *  Holds state during a draw. Users call next() until it returns false.
     *
     *  Subclasses of SkDrawLooper should create a subclass of this object to
     *  hold state specific to their subclass.
     */
    class SK_API Context {
    public:
        Context() {}
        virtual ~Context() {}

        struct Info {
            SkVector fTranslate;
            bool     fApplyPostCTM;

            void applyToCTM(SkMatrix* ctm) const;
            void applyToCanvas(SkCanvas*) const;
        };

        /**
         *  Called in a loop on objects returned by SkDrawLooper::createContext().
         *  Each time true is returned, the object is drawn (possibly with a modified
         *  canvas and/or paint). When false is finally returned, drawing for the object
         *  stops.
         *
         *  On each call, the paint will be in its original state, but the
         *  canvas will be as it was following the previous call to next() or
         *  createContext().
         *
         *  The implementation must ensure that, when next() finally returns
         *  false, the canvas has been restored to the state it was
         *  initially, before createContext() was first called.
         */
        virtual bool next(Info*, SkPaint*) = 0;

    private:
        Context(const Context&) = delete;
        Context& operator=(const Context&) = delete;
    };

    /**
     *  Called right before something is being drawn. Returns a Context
     *  whose next() method should be called until it returns false.
     */
    virtual Context* makeContext(SkArenaAlloc*) const = 0;

    /**
     * The fast bounds functions are used to enable the paint to be culled early
     * in the drawing pipeline. If a subclass can support this feature it must
     * return true for the canComputeFastBounds() function.  If that function
     * returns false then computeFastBounds behavior is undefined otherwise it
     * is expected to have the following behavior. Given the parent paint and
     * the parent's bounding rect the subclass must fill in and return the
     * storage rect, where the storage rect is with the union of the src rect
     * and the looper's bounding rect.
     */
    bool canComputeFastBounds(const SkPaint& paint) const;
    void computeFastBounds(const SkPaint& paint, const SkRect& src, SkRect* dst) const;

    struct BlurShadowRec {
        SkScalar        fSigma;
        SkVector        fOffset;
        SkColor         fColor;
        SkBlurStyle     fStyle;
    };
    /**
     *  If this looper can be interpreted as having two layers, such that
     *      1. The first layer (bottom most) just has a blur and translate
     *      2. The second layer has no modifications to either paint or canvas
     *      3. No other layers.
     *  then return true, and if not null, fill out the BlurShadowRec).
     *
     *  If any of the above are not met, return false and ignore the BlurShadowRec parameter.
     */
    virtual bool asABlurShadow(BlurShadowRec*) const;

    static SkFlattenable::Type GetFlattenableType() {
        return kSkDrawLooper_Type;
    }

    SkFlattenable::Type getFlattenableType() const override {
        return kSkDrawLooper_Type;
    }

    static sk_sp<SkDrawLooper> Deserialize(const void* data, size_t size,
                                          const SkDeserialProcs* procs = nullptr) {
        return sk_sp<SkDrawLooper>(static_cast<SkDrawLooper*>(
                                  SkFlattenable::Deserialize(
                                  kSkDrawLooper_Type, data, size, procs).release()));
    }

    void apply(SkCanvas* canvas, const SkPaint& paint,
               std::function<void(SkCanvas*, const SkPaint&)>);

protected:
    SkDrawLooper() {}

private:
    using INHERITED = SkFlattenable;
};

#endif