1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkPathEffect_DEFINED
18#define SkPathEffect_DEFINED
19
20#include "SkFlattenable.h"
21
22class SkPath;
23
24/** \class SkPathEffect
25
26    SkPathEffect is the base class for objects in the SkPaint that affect
27    the geometry of a drawing primitive before it is transformed by the
28    canvas' matrix and drawn.
29
30    Dashing is implemented as a subclass of SkPathEffect.
31*/
32class SkPathEffect : public SkFlattenable {
33public:
34    //  This method is not exported to java.
35    SkPathEffect() {}
36
37    /** Given a src path and a width value, return true if the patheffect
38        has produced a new path (dst) and a new width value. If false is returned,
39        ignore dst and width.
40        On input, width >= 0 means the src should be stroked
41        On output, width >= 0 means the dst should be stroked
42    */
43    virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width) = 0;
44
45private:
46    // illegal
47    SkPathEffect(const SkPathEffect&);
48    SkPathEffect& operator=(const SkPathEffect&);
49};
50
51/** \class SkPairPathEffect
52
53    Common baseclass for Compose and Sum. This subclass manages two pathEffects,
54    including flattening them. It does nothing in filterPath, and is only useful
55    for managing the lifetimes of its two arguments.
56*/
57class SkPairPathEffect : public SkPathEffect {
58public:
59    SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1);
60    virtual ~SkPairPathEffect();
61
62protected:
63    SkPairPathEffect(SkFlattenableReadBuffer&);
64    virtual void flatten(SkFlattenableWriteBuffer&);
65    // these are visible to our subclasses
66    SkPathEffect* fPE0, *fPE1;
67
68private:
69    typedef SkPathEffect INHERITED;
70};
71
72/** \class SkComposePathEffect
73
74    This subclass of SkPathEffect composes its two arguments, to create
75    a compound pathEffect.
76*/
77class SkComposePathEffect : public SkPairPathEffect {
78public:
79    /** Construct a pathEffect whose effect is to apply first the inner pathEffect
80        and the the outer pathEffect (e.g. outer(inner(path)))
81        The reference counts for outer and inner are both incremented in the constructor,
82        and decremented in the destructor.
83    */
84    SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner)
85        : INHERITED(outer, inner) {}
86
87    // overrides
88
89    //  This method is not exported to java.
90    virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
91
92protected:
93    virtual Factory getFactory() { return CreateProc; }
94
95private:
96    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
97        return SkNEW_ARGS(SkComposePathEffect, (buffer));
98    }
99    SkComposePathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
100
101    // illegal
102    SkComposePathEffect(const SkComposePathEffect&);
103    SkComposePathEffect& operator=(const SkComposePathEffect&);
104
105    typedef SkPairPathEffect INHERITED;
106};
107
108/** \class SkSumPathEffect
109
110    This subclass of SkPathEffect applies two pathEffects, one after the other.
111    Its filterPath() returns true if either of the effects succeeded.
112*/
113class SkSumPathEffect : public SkPairPathEffect {
114public:
115    /** Construct a pathEffect whose effect is to apply two effects, in sequence.
116        (e.g. first(path) + second(path))
117        The reference counts for first and second are both incremented in the constructor,
118        and decremented in the destructor.
119    */
120    SkSumPathEffect(SkPathEffect* first, SkPathEffect* second)
121        : INHERITED(first, second) {}
122
123    // overrides
124    //  This method is not exported to java.
125    virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
126
127protected:
128    virtual Factory getFactory() { return CreateProc; }
129
130private:
131    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)  {
132        return SkNEW_ARGS(SkSumPathEffect, (buffer));
133    }
134    SkSumPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
135
136    // illegal
137    SkSumPathEffect(const SkSumPathEffect&);
138    SkSumPathEffect& operator=(const SkSumPathEffect&);
139
140    typedef SkPairPathEffect INHERITED;
141};
142
143#endif
144
145