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