1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2011 The Android Open Source Project
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SkDrawLooper_DEFINED
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define SkDrawLooper_DEFINED
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBlurTypes.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkFlattenable.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPoint.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColor.h"
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass  SkArenaAlloc;
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass  SkCanvas;
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass  SkColorSpaceXformer;
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass  SkPaint;
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct SkRect;
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass  SkString;
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** \class SkDrawLooper
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Subclasses of SkDrawLooper can be attached to a SkPaint. Where they are,
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    and something is drawn to a canvas with that paint, the looper subclass will
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    be called, allowing it to modify the canvas and/or paint for that draw call.
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    More than that, via the next() method, the looper can modify the draw to be
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    invoked multiple times (hence the name loop-er), allow it to perform effects
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    like shadows or frame/fills, that require more than one pass.
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot*/
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SK_API SkDrawLooper : public SkFlattenable {
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  Holds state during a draw. Users call next() until it returns false.
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  Subclasses of SkDrawLooper should create a subclass of this object to
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  hold state specific to their subclass.
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    class SK_API Context : ::SkNoncopyable {
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    public:
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Context() {}
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        virtual ~Context() {}
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        /**
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *  Called in a loop on objects returned by SkDrawLooper::createContext().
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *  Each time true is returned, the object is drawn (possibly with a modified
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *  canvas and/or paint). When false is finally returned, drawing for the object
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *  stops.
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *  On each call, the paint will be in its original state, but the
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *  canvas will be as it was following the previous call to next() or
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *  createContext().
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *  The implementation must ensure that, when next() finally returns
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *  false, the canvas has been restored to the state it was
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         *  initially, before createContext() was first called.
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot         */
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        virtual bool next(SkCanvas* canvas, SkPaint* paint) = 0;
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  Called right before something is being drawn. Returns a Context
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  whose next() method should be called until it returns false.
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual Context* makeContext(SkCanvas*, SkArenaAlloc*) const = 0;
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * The fast bounds functions are used to enable the paint to be culled early
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * in the drawing pipeline. If a subclass can support this feature it must
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * return true for the canComputeFastBounds() function.  If that function
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * returns false then computeFastBounds behavior is undefined otherwise it
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * is expected to have the following behavior. Given the parent paint and
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * the parent's bounding rect the subclass must fill in and return the
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * storage rect, where the storage rect is with the union of the src rect
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * and the looper's bounding rect.
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool canComputeFastBounds(const SkPaint& paint) const;
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void computeFastBounds(const SkPaint& paint, const SkRect& src, SkRect* dst) const;
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    struct BlurShadowRec {
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar        fSigma;
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkVector        fOffset;
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkColor         fColor;
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkBlurStyle     fStyle;
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkBlurQuality   fQuality;
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  If this looper can be interpreted as having two layers, such that
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *      1. The first layer (bottom most) just has a blur and translate
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *      2. The second layer has no modifications to either paint or canvas
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *      3. No other layers.
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  then return true, and if not null, fill out the BlurShadowRec).
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  If any of the above are not met, return false and ignore the BlurShadowRec parameter.
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual bool asABlurShadow(BlurShadowRec*) const;
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_TO_STRING_PUREVIRT()
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper)
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkDrawLooper> makeColorSpace(SkColorSpaceXformer* xformer) const {
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return this->onMakeColorSpace(xformer);
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual sk_sp<SkDrawLooper> onMakeColorSpace(SkColorSpaceXformer*) const = 0;
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDrawLooper() {}
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    friend class SkColorSpaceXformer;
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef SkFlattenable INHERITED;
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
118