3 * Copyright 2006 The Android Open Source Project
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
10 #ifndef SkPathEffect_DEFINED
11 #define SkPathEffect_DEFINED
13 #include "SkFlattenable.h"
17 #include "SkStrokeRec.h"
18 #include "SkTDArray.h"
22 /** \class SkPathEffect
24 SkPathEffect is the base class for objects in the SkPaint that affect
25 the geometry of a drawing primitive before it is transformed by the
26 canvas' matrix and drawn.
28 Dashing is implemented as a subclass of SkPathEffect.
30 class SK_API SkPathEffect : public SkFlattenable {
32 SK_DECLARE_INST_COUNT(SkPathEffect)
35 * Given a src path (input) and a stroke-rec (input and output), apply
36 * this effect to the src path, returning the new path in dst, and return
37 * true. If this effect cannot be applied, return false and ignore dst
40 * The stroke-rec specifies the initial request for stroking (if any).
41 * The effect can treat this as input only, or it can choose to change
42 * the rec as well. For example, the effect can decide to change the
43 * stroke's width or join, or the effect can change the rec from stroke
44 * to fill (or fill to stroke) in addition to returning a new (dst) path.
46 * If this method returns true, the caller will apply (as needed) the
47 * resulting stroke-rec to dst and then draw.
49 virtual bool filterPath(SkPath* dst, const SkPath& src,
50 SkStrokeRec*, const SkRect* cullR) const = 0;
53 * Compute a conservative bounds for its effect, given the src bounds.
54 * The baseline implementation just assigns src to dst.
56 virtual void computeFastBounds(SkRect* dst, const SkRect& src) const;
60 PointData aggregates all the information needed to draw the point
61 primitives returned by an 'asPoints' call.
69 fSize.set(SK_Scalar1, SK_Scalar1);
70 // 'asPoints' needs to initialize/fill-in 'fClipRect' if it sets
77 // TODO: consider using passed-in flags to limit the work asPoints does.
78 // For example, a kNoPath flag could indicate don't bother generating
81 // Currently none of these flags are supported.
83 kCircles_PointFlag = 0x01, // draw points as circles (instead of rects)
84 kUsePath_PointFlag = 0x02, // draw points as stamps of the returned path
85 kUseClip_PointFlag = 0x04, // apply 'fClipRect' before drawing the points
88 uint32_t fFlags; // flags that impact the drawing of the points
89 SkPoint* fPoints; // the center point of each generated point
90 int fNumPoints; // number of points in fPoints
91 SkVector fSize; // the size to draw the points
92 SkRect fClipRect; // clip required to draw the points (if kUseClip is set)
93 SkPath fPath; // 'stamp' to be used at each point (if kUsePath is set)
95 SkPath fFirst; // If not empty, contains geometry for first point
96 SkPath fLast; // If not empty, contains geometry for last point
100 * Does applying this path effect to 'src' yield a set of points? If so,
101 * optionally return the points in 'results'.
103 virtual bool asPoints(PointData* results, const SkPath& src,
104 const SkStrokeRec&, const SkMatrix&,
105 const SkRect* cullR) const;
108 * If the PathEffect can be represented as a dash pattern, asADash will return kDash_DashType
109 * and None otherwise. If a non NULL info is passed in, the various DashInfo will be filled
110 * in if the PathEffect can be a dash pattern. If passed in info has an fCount equal or
111 * greater to that of the effect, it will memcpy the values of the dash intervals into the
112 * info. Thus the general approach will be call asADash once with default info to get DashType
113 * and fCount. If effect can be represented as a dash pattern, allocate space for the intervals
114 * in info, then call asADash again with the same info and the intervals will get copied in.
118 kNone_DashType, //!< ignores the info parameter
119 kDash_DashType, //!< fills in all of the info parameter
123 DashInfo() : fIntervals(NULL), fCount(0), fPhase(0) {}
125 SkScalar* fIntervals; //!< Length of on/off intervals for dashed lines
126 // Even values represent ons, and odds offs
127 int32_t fCount; //!< Number of intervals in the dash. Should be even number
128 SkScalar fPhase; //!< Offset into the dashed interval pattern
129 // mod the sum of all intervals
132 virtual DashType asADash(DashInfo* info) const;
134 SK_DEFINE_FLATTENABLE_TYPE(SkPathEffect)
138 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
139 SkPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
144 SkPathEffect(const SkPathEffect&);
145 SkPathEffect& operator=(const SkPathEffect&);
147 typedef SkFlattenable INHERITED;
150 /** \class SkPairPathEffect
152 Common baseclass for Compose and Sum. This subclass manages two pathEffects,
153 including flattening them. It does nothing in filterPath, and is only useful
154 for managing the lifetimes of its two arguments.
156 class SkPairPathEffect : public SkPathEffect {
158 virtual ~SkPairPathEffect();
161 SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1);
162 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
163 SkPairPathEffect(SkReadBuffer&);
166 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
168 // these are visible to our subclasses
169 SkPathEffect* fPE0, *fPE1;
172 typedef SkPathEffect INHERITED;
175 /** \class SkComposePathEffect
177 This subclass of SkPathEffect composes its two arguments, to create
178 a compound pathEffect.
180 class SkComposePathEffect : public SkPairPathEffect {
182 /** Construct a pathEffect whose effect is to apply first the inner pathEffect
183 and the the outer pathEffect (e.g. outer(inner(path)))
184 The reference counts for outer and inner are both incremented in the constructor,
185 and decremented in the destructor.
187 static SkComposePathEffect* Create(SkPathEffect* outer, SkPathEffect* inner) {
188 return SkNEW_ARGS(SkComposePathEffect, (outer, inner));
191 virtual bool filterPath(SkPath* dst, const SkPath& src,
192 SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
194 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect)
197 SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner)
198 : INHERITED(outer, inner) {}
200 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
201 explicit SkComposePathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
206 SkComposePathEffect(const SkComposePathEffect&);
207 SkComposePathEffect& operator=(const SkComposePathEffect&);
209 typedef SkPairPathEffect INHERITED;
212 /** \class SkSumPathEffect
214 This subclass of SkPathEffect applies two pathEffects, one after the other.
215 Its filterPath() returns true if either of the effects succeeded.
217 class SkSumPathEffect : public SkPairPathEffect {
219 /** Construct a pathEffect whose effect is to apply two effects, in sequence.
220 (e.g. first(path) + second(path))
221 The reference counts for first and second are both incremented in the constructor,
222 and decremented in the destructor.
224 static SkSumPathEffect* Create(SkPathEffect* first, SkPathEffect* second) {
225 return SkNEW_ARGS(SkSumPathEffect, (first, second));
228 virtual bool filterPath(SkPath* dst, const SkPath& src,
229 SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
231 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect)
234 SkSumPathEffect(SkPathEffect* first, SkPathEffect* second)
235 : INHERITED(first, second) {}
237 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
238 explicit SkSumPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
243 SkSumPathEffect(const SkSumPathEffect&);
244 SkSumPathEffect& operator=(const SkSumPathEffect&);
246 typedef SkPairPathEffect INHERITED;