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