| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrDefaultPathRenderer.h" | 8 #include "GrDefaultPathRenderer.h" |
| 9 | 9 |
| 10 #include "GrContext.h" | 10 #include "GrContext.h" |
| 11 #include "GrDefaultGeoProcFactory.h" | 11 #include "GrDefaultGeoProcFactory.h" |
| 12 #include "GrDrawState.h" | 12 #include "GrDrawState.h" |
| 13 #include "GrPathUtils.h" | 13 #include "GrPathUtils.h" |
| 14 #include "SkGeometry.h" |
| 14 #include "SkString.h" | 15 #include "SkString.h" |
| 15 #include "SkStrokeRec.h" | 16 #include "SkStrokeRec.h" |
| 16 #include "SkTLazy.h" | 17 #include "SkTLazy.h" |
| 17 #include "SkTraceEvent.h" | 18 #include "SkTraceEvent.h" |
| 18 | 19 |
| 19 | |
| 20 GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport, | 20 GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport, |
| 21 bool stencilWrapOpsSupport) | 21 bool stencilWrapOpsSupport) |
| 22 : fSeparateStencil(separateStencilSupport) | 22 : fSeparateStencil(separateStencilSupport) |
| 23 , fStencilWrapOps(stencilWrapOpsSupport) { | 23 , fStencilWrapOps(stencilWrapOpsSupport) { |
| 24 } | 24 } |
| 25 | 25 |
| 26 | 26 |
| 27 //////////////////////////////////////////////////////////////////////////////// | 27 //////////////////////////////////////////////////////////////////////////////// |
| 28 // Stencil rules for paths | 28 // Stencil rules for paths |
| 29 | 29 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 // when drawing lines we're appending line segments along | 182 // when drawing lines we're appending line segments along |
| 183 // the contour. When applying the other fill rules we're | 183 // the contour. When applying the other fill rules we're |
| 184 // drawing triangle fans around fanCenterIdx. | 184 // drawing triangle fans around fanCenterIdx. |
| 185 if (!hairLine) { | 185 if (!hairLine) { |
| 186 *((*indices)++) = fanCenterIdx; | 186 *((*indices)++) = fanCenterIdx; |
| 187 } | 187 } |
| 188 *((*indices)++) = edgeV0Idx; | 188 *((*indices)++) = edgeV0Idx; |
| 189 *((*indices)++) = edgeV0Idx + 1; | 189 *((*indices)++) = edgeV0Idx + 1; |
| 190 } | 190 } |
| 191 | 191 |
| 192 static inline void add_quad(SkPoint** vert, const SkPoint* base, const SkPoint p
ts[], |
| 193 SkScalar srcSpaceTolSqd, SkScalar srcSpaceTol, bool
indexed, |
| 194 bool isHairline, uint16_t subpathIdxStart, uint16_t*
* idx) { |
| 195 // first pt of quad is the pt we ended on in previous step |
| 196 uint16_t firstQPtIdx = (uint16_t)(*vert - base) - 1; |
| 197 uint16_t numPts = (uint16_t) |
| 198 GrPathUtils::generateQuadraticPoints( |
| 199 pts[0], pts[1], pts[2], |
| 200 srcSpaceTolSqd, vert, |
| 201 GrPathUtils::quadraticPointCount(pts, srcSpaceTol)); |
| 202 if (indexed) { |
| 203 for (uint16_t i = 0; i < numPts; ++i) { |
| 204 append_countour_edge_indices(isHairline, subpathIdxStart, |
| 205 firstQPtIdx + i, idx); |
| 206 } |
| 207 } |
| 208 } |
| 209 |
| 192 bool GrDefaultPathRenderer::createGeom(GrDrawTarget* target, | 210 bool GrDefaultPathRenderer::createGeom(GrDrawTarget* target, |
| 193 GrDrawState* drawState, | 211 GrDrawState* drawState, |
| 194 GrPrimitiveType* primType, | 212 GrPrimitiveType* primType, |
| 195 int* vertexCnt, | 213 int* vertexCnt, |
| 196 int* indexCnt, | 214 int* indexCnt, |
| 197 GrDrawTarget::AutoReleaseGeometry* arg, | 215 GrDrawTarget::AutoReleaseGeometry* arg, |
| 198 const SkPath& path, | 216 const SkPath& path, |
| 199 const SkStrokeRec& stroke, | 217 const SkStrokeRec& stroke, |
| 200 SkScalar srcSpaceTol) { | 218 SkScalar srcSpaceTol) { |
| 201 { | 219 { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 SkPoint pts[4]; | 267 SkPoint pts[4]; |
| 250 | 268 |
| 251 bool first = true; | 269 bool first = true; |
| 252 int subpath = 0; | 270 int subpath = 0; |
| 253 | 271 |
| 254 SkPath::Iter iter(path, false); | 272 SkPath::Iter iter(path, false); |
| 255 | 273 |
| 256 for (;;) { | 274 for (;;) { |
| 257 SkPath::Verb verb = iter.next(pts); | 275 SkPath::Verb verb = iter.next(pts); |
| 258 switch (verb) { | 276 switch (verb) { |
| 259 case SkPath::kConic_Verb: | |
| 260 SkASSERT(0); | |
| 261 break; | |
| 262 case SkPath::kMove_Verb: | 277 case SkPath::kMove_Verb: |
| 263 if (!first) { | 278 if (!first) { |
| 264 uint16_t currIdx = (uint16_t) (vert - base); | 279 uint16_t currIdx = (uint16_t) (vert - base); |
| 265 subpathIdxStart = currIdx; | 280 subpathIdxStart = currIdx; |
| 266 ++subpath; | 281 ++subpath; |
| 267 } | 282 } |
| 268 *vert = pts[0]; | 283 *vert = pts[0]; |
| 269 vert++; | 284 vert++; |
| 270 break; | 285 break; |
| 271 case SkPath::kLine_Verb: | 286 case SkPath::kLine_Verb: |
| 272 if (indexed) { | 287 if (indexed) { |
| 273 uint16_t prevIdx = (uint16_t)(vert - base) - 1; | 288 uint16_t prevIdx = (uint16_t)(vert - base) - 1; |
| 274 append_countour_edge_indices(isHairline, subpathIdxStart, | 289 append_countour_edge_indices(isHairline, subpathIdxStart, |
| 275 prevIdx, &idx); | 290 prevIdx, &idx); |
| 276 } | 291 } |
| 277 *(vert++) = pts[1]; | 292 *(vert++) = pts[1]; |
| 278 break; | 293 break; |
| 279 case SkPath::kQuad_Verb: { | 294 case SkPath::kConic_Verb: { |
| 280 // first pt of quad is the pt we ended on in previous step | 295 SkScalar weight = iter.conicWeight(); |
| 281 uint16_t firstQPtIdx = (uint16_t)(vert - base) - 1; | 296 SkAutoConicToQuads converter; |
| 282 uint16_t numPts = (uint16_t) | 297 // Converting in src-space, hance the finer tolerance (0.25) |
| 283 GrPathUtils::generateQuadraticPoints( | 298 // TODO: find a way to do this in dev-space so the tolerance mea
ns something |
| 284 pts[0], pts[1], pts[2], | 299 const SkPoint* quadPts = converter.computeQuads(pts, weight, 0.2
5f); |
| 285 srcSpaceTolSqd, &vert, | 300 for (int i = 0; i < converter.countQuads(); ++i) { |
| 286 GrPathUtils::quadraticPointCount(pts, srcSpaceTol)); | 301 add_quad(&vert, base, quadPts + i*2, srcSpaceTolSqd, srcSpac
eTol, indexed, |
| 287 if (indexed) { | 302 isHairline, subpathIdxStart, &idx); |
| 288 for (uint16_t i = 0; i < numPts; ++i) { | |
| 289 append_countour_edge_indices(isHairline, subpathIdxStart
, | |
| 290 firstQPtIdx + i, &idx); | |
| 291 } | |
| 292 } | 303 } |
| 293 break; | 304 break; |
| 294 } | 305 } |
| 306 case SkPath::kQuad_Verb: |
| 307 add_quad(&vert, base, pts, srcSpaceTolSqd, srcSpaceTol, indexed, |
| 308 isHairline, subpathIdxStart, &idx); |
| 309 break; |
| 295 case SkPath::kCubic_Verb: { | 310 case SkPath::kCubic_Verb: { |
| 296 // first pt of cubic is the pt we ended on in previous step | 311 // first pt of cubic is the pt we ended on in previous step |
| 297 uint16_t firstCPtIdx = (uint16_t)(vert - base) - 1; | 312 uint16_t firstCPtIdx = (uint16_t)(vert - base) - 1; |
| 298 uint16_t numPts = (uint16_t) GrPathUtils::generateCubicPoints( | 313 uint16_t numPts = (uint16_t) GrPathUtils::generateCubicPoints( |
| 299 pts[0], pts[1], pts[2], pts[3], | 314 pts[0], pts[1], pts[2], pts[3], |
| 300 srcSpaceTolSqd, &vert, | 315 srcSpaceTolSqd, &vert, |
| 301 GrPathUtils::cubicPointCount(pts, srcSpaceTol)); | 316 GrPathUtils::cubicPointCount(pts, srcSpaceTol)); |
| 302 if (indexed) { | 317 if (indexed) { |
| 303 for (uint16_t i = 0; i < numPts; ++i) { | 318 for (uint16_t i = 0; i < numPts; ++i) { |
| 304 append_countour_edge_indices(isHairline, subpathIdxStart
, | 319 append_countour_edge_indices(isHairline, subpathIdxStart
, |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 return true; | 538 return true; |
| 524 } | 539 } |
| 525 | 540 |
| 526 bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target, | 541 bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target, |
| 527 const GrDrawState* drawState, | 542 const GrDrawState* drawState, |
| 528 const SkMatrix& viewMatrix, | 543 const SkMatrix& viewMatrix, |
| 529 const SkPath& path, | 544 const SkPath& path, |
| 530 const SkStrokeRec& stroke, | 545 const SkStrokeRec& stroke, |
| 531 bool antiAlias) const { | 546 bool antiAlias) const { |
| 532 // this class can draw any path with any fill but doesn't do any anti-aliasi
ng. | 547 // this class can draw any path with any fill but doesn't do any anti-aliasi
ng. |
| 533 | 548 return !antiAlias && (stroke.isFillStyle() || IsStrokeHairlineOrEquivalent(s
troke, |
| 534 return !antiAlias && !(SkPath::kConic_SegmentMask & path.getSegmentMasks())
&& | 549 v
iewMatrix, |
| 535 (stroke.isFillStyle() || IsStrokeHairlineOrEquivalent(stroke, viewMatrix
, NULL)); | 550 N
ULL)); |
| 536 } | 551 } |
| 537 | 552 |
| 538 bool GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, | 553 bool GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, |
| 539 GrDrawState* drawState, | 554 GrDrawState* drawState, |
| 540 GrColor color, | 555 GrColor color, |
| 541 const SkMatrix& viewMatrix, | 556 const SkMatrix& viewMatrix, |
| 542 const SkPath& path, | 557 const SkPath& path, |
| 543 const SkStrokeRec& stroke, | 558 const SkStrokeRec& stroke, |
| 544 bool antiAlias) { | 559 bool antiAlias) { |
| 545 return this->internalDrawPath(target, | 560 return this->internalDrawPath(target, |
| 546 drawState, | 561 drawState, |
| 547 color, | 562 color, |
| 548 viewMatrix, | 563 viewMatrix, |
| 549 path, | 564 path, |
| 550 stroke, | 565 stroke, |
| 551 false); | 566 false); |
| 552 } | 567 } |
| 553 | 568 |
| 554 void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target, | 569 void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target, |
| 555 GrDrawState* drawState, | 570 GrDrawState* drawState, |
| 556 const SkMatrix& viewMatrix, | 571 const SkMatrix& viewMatrix, |
| 557 const SkPath& path, | 572 const SkPath& path, |
| 558 const SkStrokeRec& stroke) { | 573 const SkStrokeRec& stroke) { |
| 559 SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType()); | 574 SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType()); |
| 560 SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType()); | 575 SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType()); |
| 561 this->internalDrawPath(target, drawState, GrColor_WHITE, viewMatrix, path, s
troke, true); | 576 this->internalDrawPath(target, drawState, GrColor_WHITE, viewMatrix, path, s
troke, true); |
| 562 } | 577 } |
| OLD | NEW |