OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #ifndef GrPathRenderer_DEFINED | 9 #ifndef GrPathRenderer_DEFINED |
10 #define GrPathRenderer_DEFINED | 10 #define GrPathRenderer_DEFINED |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 */ | 67 */ |
68 typedef GrPathRendererChain::StencilSupport StencilSupport; | 68 typedef GrPathRendererChain::StencilSupport StencilSupport; |
69 static const StencilSupport kNoSupport_StencilSupport = | 69 static const StencilSupport kNoSupport_StencilSupport = |
70 GrPathRendererChain::kNoSupport_StencilSupport; | 70 GrPathRendererChain::kNoSupport_StencilSupport; |
71 static const StencilSupport kStencilOnly_StencilSupport = | 71 static const StencilSupport kStencilOnly_StencilSupport = |
72 GrPathRendererChain::kStencilOnly_StencilSupport; | 72 GrPathRendererChain::kStencilOnly_StencilSupport; |
73 static const StencilSupport kNoRestriction_StencilSupport = | 73 static const StencilSupport kNoRestriction_StencilSupport = |
74 GrPathRendererChain::kNoRestriction_StencilSupport; | 74 GrPathRendererChain::kNoRestriction_StencilSupport; |
75 | 75 |
76 /** | 76 /** |
77 * This function is to get the stencil support for the current path. The pat
h's fill must | 77 * This function is to get the stencil support for a particular path. The pa
th's fill must |
78 * not be an inverse type. | 78 * not be an inverse type. |
79 * | 79 * |
| 80 * @param target target that the path will be rendered to |
| 81 * @param path the path that will be drawn |
80 * @param stroke the stroke information (width, join, cap). | 82 * @param stroke the stroke information (width, join, cap). |
81 * @param target target that the path will be rendered to | |
82 */ | 83 */ |
83 StencilSupport getStencilSupport(const SkStrokeRec& stroke, | 84 StencilSupport getStencilSupport(const SkPath& path, |
| 85 const SkStrokeRec& stroke, |
84 const GrDrawTarget* target) const { | 86 const GrDrawTarget* target) const { |
85 SkASSERT(!fPath.isInverseFillType()); | 87 SkASSERT(!path.isInverseFillType()); |
86 return this->onGetStencilSupport(stroke, target); | 88 return this->onGetStencilSupport(path, stroke, target); |
87 } | |
88 | |
89 // Set the path and fill type the path renderer is to use. | |
90 // 'fillType' is included as a parameter b.c. we often want to draw | |
91 // inverse filled paths normally filled. | |
92 void setPath(const SkPath& path, SkPath::FillType fillType) { | |
93 SkASSERT(fPath.isEmpty()); | |
94 fPath = path; | |
95 fPath.setFillType(fillType); | |
96 } | |
97 | |
98 void resetPath() { | |
99 fPath.reset(); | |
100 } | 89 } |
101 | 90 |
102 /** | 91 /** |
103 * Returns true if this path renderer is able to render the current path. Re
turning false | 92 * Returns true if this path renderer is able to render the path. Returning
false allows the |
104 * allows the caller to fallback to another path renderer This function is c
alled when | 93 * caller to fallback to another path renderer This function is called when
searching for a path |
105 * searching for a path renderer capable of rendering a path. | 94 * renderer capable of rendering a path. |
106 * | 95 * |
| 96 * @param path The path to draw |
107 * @param stroke The stroke information (width, join, cap) | 97 * @param stroke The stroke information (width, join, cap) |
108 * @param target The target that the path will be rendered to | 98 * @param target The target that the path will be rendered to |
109 * @param antiAlias True if anti-aliasing is required. | 99 * @param antiAlias True if anti-aliasing is required. |
110 * | 100 * |
111 * @return true if the path can be drawn by this object, false otherwise. | 101 * @return true if the path can be drawn by this object, false otherwise. |
112 */ | 102 */ |
113 virtual bool canDrawPath(const SkStrokeRec& stroke, | 103 virtual bool canDrawPath(const SkPath& path, |
| 104 const SkStrokeRec& rec, |
114 const GrDrawTarget* target, | 105 const GrDrawTarget* target, |
115 bool antiAlias) const = 0; | 106 bool antiAlias) const = 0; |
116 /** | 107 /** |
117 * Draws the current path into the draw target. If getStencilSupport() would
return | 108 * Draws the path into the draw target. If getStencilSupport() would return
kNoRestriction then |
118 * kNoRestriction then the subclass must respect the stencil settings of the
| 109 * the subclass must respect the stencil settings of the target's draw state
. |
119 * target's draw state. | |
120 * | 110 * |
| 111 * @param path the path to draw. |
121 * @param stroke the stroke information (width, join, cap) | 112 * @param stroke the stroke information (width, join, cap) |
122 * @param target target that the path will be rendered to | 113 * @param target target that the path will be rendered to |
123 * @param antiAlias true if anti-aliasing is required. | 114 * @param antiAlias true if anti-aliasing is required. |
124 */ | 115 */ |
125 bool drawPath(const SkStrokeRec& stroke, | 116 bool drawPath(const SkPath& path, |
| 117 const SkStrokeRec& stroke, |
126 GrDrawTarget* target, | 118 GrDrawTarget* target, |
127 bool antiAlias) { | 119 bool antiAlias) { |
128 SkASSERT(!fPath.isEmpty()); | 120 SkASSERT(!path.isEmpty()); |
129 SkASSERT(this->canDrawPath(stroke, target, antiAlias)); | 121 SkASSERT(this->canDrawPath(path, stroke, target, antiAlias)); |
130 SkASSERT(target->drawState()->getStencil().isDisabled() || | 122 SkASSERT(target->drawState()->getStencil().isDisabled() || |
131 kNoRestriction_StencilSupport == this->getStencilSupport(stroke
, target)); | 123 kNoRestriction_StencilSupport == this->getStencilSupport(path,
stroke, target)); |
132 return this->onDrawPath(stroke, target, antiAlias); | 124 return this->onDrawPath(path, stroke, target, antiAlias); |
133 } | 125 } |
134 | 126 |
135 /** | 127 /** |
136 * Draws the current path to the stencil buffer. Assume the writable stencil
bits are already | 128 * Draws the path to the stencil buffer. Assume the writable stencil bits ar
e already |
137 * initialized to zero. The pixels inside the path will have non-zero stenci
l values | 129 * initialized to zero. The pixels inside the path will have non-zero stenci
l values afterwards. |
138 * afterwards. | |
139 * | 130 * |
| 131 * @param path the path to draw. |
140 * @param stroke the stroke information (width, join, cap) | 132 * @param stroke the stroke information (width, join, cap) |
141 * @param target target that the path will be rendered to | 133 * @param target target that the path will be rendered to |
142 */ | 134 */ |
143 void stencilPath(const SkStrokeRec& stroke, GrDrawTarget* target) { | 135 void stencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget
* target) { |
144 SkASSERT(!fPath.isEmpty()); | 136 SkASSERT(!path.isEmpty()); |
145 SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(stroke, ta
rget)); | 137 SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(path, stro
ke, target)); |
146 this->onStencilPath(stroke, target); | 138 this->onStencilPath(path, stroke, target); |
147 } | 139 } |
148 | 140 |
149 class AutoClearPath : ::SkNoncopyable { | |
150 public: | |
151 AutoClearPath(GrPathRenderer* renderer) : fRenderer(renderer) {} | |
152 AutoClearPath() : fRenderer(NULL) {} | |
153 ~AutoClearPath() { | |
154 this->reset(); | |
155 } | |
156 | |
157 GrPathRenderer* renderer() { | |
158 return fRenderer; | |
159 } | |
160 | |
161 void set(GrPathRenderer* renderer) { | |
162 this->reset(); | |
163 fRenderer = renderer; | |
164 } | |
165 | |
166 GrPathRenderer* operator->() { return fRenderer; } | |
167 | |
168 private: | |
169 void reset() { | |
170 if (NULL != fRenderer) { | |
171 fRenderer->resetPath(); | |
172 } | |
173 fRenderer = NULL; | |
174 } | |
175 | |
176 GrPathRenderer* fRenderer; | |
177 }; | |
178 | |
179 // Helper for determining if we can treat a thin stroke as a hairline w/ cov
erage. | 141 // Helper for determining if we can treat a thin stroke as a hairline w/ cov
erage. |
180 // If we can, we draw lots faster (raster device does this same test). | 142 // If we can, we draw lots faster (raster device does this same test). |
181 static bool IsStrokeHairlineOrEquivalent(const SkStrokeRec& stroke, const Sk
Matrix& matrix, | 143 static bool IsStrokeHairlineOrEquivalent(const SkStrokeRec& stroke, const Sk
Matrix& matrix, |
182 SkScalar* outCoverage) { | 144 SkScalar* outCoverage) { |
183 if (stroke.isHairlineStyle()) { | 145 if (stroke.isHairlineStyle()) { |
184 if (NULL != outCoverage) { | 146 if (NULL != outCoverage) { |
185 *outCoverage = SK_Scalar1; | 147 *outCoverage = SK_Scalar1; |
186 } | 148 } |
187 return true; | 149 return true; |
188 } | 150 } |
189 return stroke.getStyle() == SkStrokeRec::kStroke_Style && | 151 return stroke.getStyle() == SkStrokeRec::kStroke_Style && |
190 SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage
); | 152 SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage
); |
191 } | 153 } |
192 | 154 |
193 protected: | 155 protected: |
194 const SkPath& path() const { | |
195 return fPath; | |
196 } | |
197 | |
198 /** | 156 /** |
199 * Subclass overrides if it has any limitations of stenciling support. | 157 * Subclass overrides if it has any limitations of stenciling support. |
200 */ | 158 */ |
201 virtual StencilSupport onGetStencilSupport(const SkStrokeRec&, | 159 virtual StencilSupport onGetStencilSupport(const SkPath&, |
| 160 const SkStrokeRec&, |
202 const GrDrawTarget*) const { | 161 const GrDrawTarget*) const { |
203 return kNoRestriction_StencilSupport; | 162 return kNoRestriction_StencilSupport; |
204 } | 163 } |
205 | 164 |
206 /** | 165 /** |
207 * Subclass implementation of drawPath() | 166 * Subclass implementation of drawPath() |
208 */ | 167 */ |
209 virtual bool onDrawPath(const SkStrokeRec& stroke, | 168 virtual bool onDrawPath(const SkPath& path, |
| 169 const SkStrokeRec& stroke, |
210 GrDrawTarget* target, | 170 GrDrawTarget* target, |
211 bool antiAlias) = 0; | 171 bool antiAlias) = 0; |
212 | 172 |
213 /** | 173 /** |
214 * Subclass implementation of stencilPath(). Subclass must override iff it e
ver returns | 174 * Subclass implementation of stencilPath(). Subclass must override iff it e
ver returns |
215 * kStencilOnly in onGetStencilSupport(). | 175 * kStencilOnly in onGetStencilSupport(). |
216 */ | 176 */ |
217 virtual void onStencilPath(const SkStrokeRec& stroke, GrDrawTarget* target)
{ | 177 virtual void onStencilPath(const SkPath& path, const SkStrokeRec& stroke, G
rDrawTarget* target) { |
218 GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRIn
it); | 178 GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRIn
it); |
219 GrDrawState* drawState = target->drawState(); | 179 GrDrawState* drawState = target->drawState(); |
220 GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil, | 180 GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil, |
221 kReplace_StencilOp, | 181 kReplace_StencilOp, |
222 kReplace_StencilOp, | 182 kReplace_StencilOp, |
223 kAlways_StencilFunc, | 183 kAlways_StencilFunc, |
224 0xffff, | 184 0xffff, |
225 0xffff, | 185 0xffff, |
226 0xffff); | 186 0xffff); |
227 drawState->setStencil(kIncrementStencil); | 187 drawState->setStencil(kIncrementStencil); |
228 drawState->enableState(GrDrawState::kNoColorWrites_StateBit); | 188 drawState->enableState(GrDrawState::kNoColorWrites_StateBit); |
229 this->drawPath(stroke, target, false); | 189 this->drawPath(path, stroke, target, false); |
230 } | 190 } |
231 | 191 |
232 // Helper for getting the device bounds of a path. Inverse filled paths will
have bounds set | 192 // Helper for getting the device bounds of a path. Inverse filled paths will
have bounds set |
233 // by devSize. Non-inverse path bounds will not necessarily be clipped to de
vSize. | 193 // by devSize. Non-inverse path bounds will not necessarily be clipped to de
vSize. |
234 static void GetPathDevBounds(const SkPath& path, | 194 static void GetPathDevBounds(const SkPath& path, |
235 int devW, | 195 int devW, |
236 int devH, | 196 int devH, |
237 const SkMatrix& matrix, | 197 const SkMatrix& matrix, |
238 SkRect* bounds); | 198 SkRect* bounds); |
239 | 199 |
240 // Helper version that gets the dev width and height from a GrSurface. | 200 // Helper version that gets the dev width and height from a GrSurface. |
241 static void GetPathDevBounds(const SkPath& path, | 201 static void GetPathDevBounds(const SkPath& path, |
242 const GrSurface* device, | 202 const GrSurface* device, |
243 const SkMatrix& matrix, | 203 const SkMatrix& matrix, |
244 SkRect* bounds) { | 204 SkRect* bounds) { |
245 GetPathDevBounds(path, device->width(), device->height(), matrix, bounds
); | 205 GetPathDevBounds(path, device->width(), device->height(), matrix, bounds
); |
246 } | 206 } |
247 | 207 |
248 private: | 208 private: |
249 SkPath fPath; | |
250 | 209 |
251 typedef SkRefCnt INHERITED; | 210 typedef SkRefCnt INHERITED; |
252 }; | 211 }; |
253 | 212 |
254 #endif | 213 #endif |
OLD | NEW |