SkShadowTessellator.cpp revision 91af72703830f3946c538b47c6c7c96afc0adde2
1bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth/* 2bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth * Copyright 2017 Google Inc. 3bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth * 4bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth * Use of this source code is governed by a BSD-style license that can be 5bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth * found in the LICENSE file. 6bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth */ 7bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 858abc9e2c56464336472493745e91133819deb96Jim Van Verth#include "GrShadowTessellator.h" 9bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth#include "GrPathUtils.h" 10bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 1158abc9e2c56464336472493745e91133819deb96Jim Van Verth#include "SkGeometry.h" 1258abc9e2c56464336472493745e91133819deb96Jim Van Verth 13bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verthstatic bool compute_normal(const SkPoint& p0, const SkPoint& p1, SkScalar radius, SkScalar dir, 14bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkVector* newNormal) { 15bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkVector normal; 16bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // compute perpendicular 17bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth normal.fX = p0.fY - p1.fY; 18bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth normal.fY = p1.fX - p0.fX; 19bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (!normal.normalize()) { 20bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth return false; 21bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 22bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth normal *= radius*dir; 23bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *newNormal = normal; 24bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth return true; 25bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth} 26bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 27bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verthstatic void compute_radial_steps(const SkVector& v1, const SkVector& v2, SkScalar r, 28bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkScalar* rotSin, SkScalar* rotCos, int* n) { 29bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth const SkScalar kRecipPixelsPerArcSegment = 0.25f; 30bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 31bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkScalar rCos = v1.dot(v2); 32bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkScalar rSin = v1.cross(v2); 33bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkScalar theta = SkScalarATan2(rSin, rCos); 34bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 35bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkScalar steps = r*theta*kRecipPixelsPerArcSegment; 36bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 37bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkScalar dTheta = theta / steps; 38bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *rotSin = SkScalarSinCos(dTheta, rotCos); 39bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *n = SkScalarFloorToInt(steps); 40bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth} 41bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 4291af72703830f3946c538b47c6c7c96afc0adde2Jim Van VerthGrAmbientShadowTessellator::GrAmbientShadowTessellator(const SkPath& path, 43bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkScalar radius, 44bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth GrColor umbraColor, 45bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth GrColor penumbraColor, 46bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth bool transparent) 47bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth : fRadius(radius) 48bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth , fUmbraColor(umbraColor) 49bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth , fPenumbraColor(penumbraColor) 50bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth , fTransparent(transparent) 51bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth , fPrevInnerIndex(-1) { 52bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 53bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // Outer ring: 3*numPts 54bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // Middle ring: numPts 55bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPositions.setReserve(4 * path.countPoints()); 56bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fColors.setReserve(4 * path.countPoints()); 57bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // Outer ring: 12*numPts 58bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // Middle ring: 0 59bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fIndices.setReserve(12 * path.countPoints()); 60bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 61bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fInitPoints.setReserve(3); 62bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 63bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // walk around the path, tessellate and generate outer ring 64bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // if original path is transparent, will accumulate sum of points for centroid 65bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkPath::Iter iter(path, true); 66bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkPoint pts[4]; 67bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkPath::Verb verb; 68bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (fTransparent) { 69bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fPositions.push() = SkPoint::Make(0, 0); 70bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fColors.push() = umbraColor; 71bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fCentroidCount = 0; 72bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 73bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 74bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth switch (verb) { 75bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth case SkPath::kLine_Verb: 7691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleLine(pts[1]); 77bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth break; 78bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth case SkPath::kQuad_Verb: 7991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleQuad(pts); 80bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth break; 81bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth case SkPath::kCubic_Verb: 8291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleCubic(pts); 83bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth break; 84bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth case SkPath::kConic_Verb: 8591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleConic(pts, iter.conicWeight()); 86bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth break; 87bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth case SkPath::kMove_Verb: 88bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth case SkPath::kClose_Verb: 89bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth case SkPath::kDone_Verb: 90bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth break; 91bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 92bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 93bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 94bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkVector normal; 95bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (compute_normal(fPositions[fPrevInnerIndex], fPositions[fFirstVertex], fRadius, fDirection, 96bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth &normal)) { 97bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth this->addArc(normal); 98bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 99bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // close out previous arc 100bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fPositions.push() = fPositions[fPrevInnerIndex] + normal; 101bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fColors.push() = fPenumbraColor; 102bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPrevInnerIndex; 103bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 2; 104bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 1; 105bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 106bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // add final edge 107bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fPositions.push() = fPositions[fFirstVertex] + normal; 108bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fColors.push() = fPenumbraColor; 109bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 110bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPrevInnerIndex; 111bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 2; 112bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fFirstVertex; 113bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 114bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 2; 115bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 1; 116bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fFirstVertex; 117bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 118bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 119bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // finalize centroid 120bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (fTransparent) { 121bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPositions[0] *= SkScalarFastInvert(fCentroidCount); 122bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 123bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = 0; 124bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPrevInnerIndex; 125bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fFirstVertex; 126bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 127bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 128bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // final fan 129bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (fPositions.count() >= 3) { 130bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPrevInnerIndex = fFirstVertex; 131bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPrevNormal = normal; 132bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth this->addArc(fFirstNormal); 133bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 134bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fFirstVertex; 135bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 1; 136bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fFirstVertex + 1; 137bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 138bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth} 139bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 140bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth// tesselation tolerance values, in device space pixels 141bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verthstatic const SkScalar kQuadTolerance = 0.2f; 142bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verthstatic const SkScalar kCubicTolerance = 0.2f; 143bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verthstatic const SkScalar kConicTolerance = 0.5f; 144bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 14558abc9e2c56464336472493745e91133819deb96Jim Van Verthvoid GrAmbientShadowTessellator::handleLine(const SkPoint& p) { 146bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (fInitPoints.count() < 2) { 147bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fInitPoints.push() = p; 148bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth return; 149bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 150bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 151bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (fInitPoints.count() == 2) { 152bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // determine if cw or ccw 153bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkVector v0 = fInitPoints[1] - fInitPoints[0]; 154bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkVector v1 = p - fInitPoints[0]; 155bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkScalar perpDot = v0.fX*v1.fY - v0.fY*v1.fX; 156bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (SkScalarNearlyZero(perpDot)) { 157bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // nearly parallel, just treat as straight line and continue 158bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fInitPoints[1] = p; 159bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth return; 160bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 161bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 162bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // if perpDot > 0, winding is ccw 163bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fDirection = (perpDot > 0) ? -1 : 1; 164bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 165bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // add first quad 166bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (!compute_normal(fInitPoints[0], fInitPoints[1], fRadius, fDirection, 167bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth &fFirstNormal)) { 168bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // first two points are incident, make the third point the second and continue 169bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fInitPoints[1] = p; 170bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth return; 171bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 172bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 173bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fFirstVertex = fPositions.count(); 174bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPrevNormal = fFirstNormal; 175bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPrevInnerIndex = fFirstVertex; 176bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 177bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fPositions.push() = fInitPoints[0]; 178bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fColors.push() = fUmbraColor; 179bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fPositions.push() = fInitPoints[0] + fFirstNormal; 180bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fColors.push() = fPenumbraColor; 181bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (fTransparent) { 182bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPositions[0] += fInitPoints[0]; 183bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fCentroidCount = 1; 184bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 185bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth this->addEdge(fInitPoints[1], fFirstNormal); 186bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 187bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // to ensure we skip this block next time 188bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fInitPoints.push() = p; 189bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 190bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 191bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkVector normal; 192bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (compute_normal(fPositions[fPrevInnerIndex], p, fRadius, fDirection, &normal)) { 193bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth this->addArc(normal); 19491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->finishArcAndAddEdge(p, normal); 195bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 196bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth} 197bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 19858abc9e2c56464336472493745e91133819deb96Jim Van Verthvoid GrAmbientShadowTessellator::handleQuad(const SkPoint pts[3]) { 199bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth int maxCount = GrPathUtils::quadraticPointCount(pts, kQuadTolerance); 200bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPointBuffer.setReserve(maxCount); 201bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkPoint* target = fPointBuffer.begin(); 202bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth int count = GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2], 203bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth kQuadTolerance, &target, maxCount); 204bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPointBuffer.setCount(count); 205bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth for (int i = 0; i < count; i++) { 206bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth this->handleLine(fPointBuffer[i]); 207bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 208bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth} 209bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 21091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrAmbientShadowTessellator::handleCubic(SkPoint pts[4]) { 211bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth int maxCount = GrPathUtils::cubicPointCount(pts, kCubicTolerance); 212bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPointBuffer.setReserve(maxCount); 213bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkPoint* target = fPointBuffer.begin(); 214bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth int count = GrPathUtils::generateCubicPoints(pts[0], pts[1], pts[2], pts[3], 215bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth kCubicTolerance, &target, maxCount); 216bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPointBuffer.setCount(count); 217bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth for (int i = 0; i < count; i++) { 218bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth this->handleLine(fPointBuffer[i]); 219bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 220bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth} 221bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 22291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrAmbientShadowTessellator::handleConic(SkPoint pts[3], SkScalar w) { 223bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkAutoConicToQuads quadder; 224bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth const SkPoint* quads = quadder.computeQuads(pts, w, kConicTolerance); 225bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkPoint lastPoint = *(quads++); 226bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth int count = quadder.countQuads(); 227bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth for (int i = 0; i < count; ++i) { 228bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkPoint quadPts[3]; 229bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth quadPts[0] = lastPoint; 230bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth quadPts[1] = quads[0]; 231bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth quadPts[2] = i == count - 1 ? pts[2] : quads[1]; 232bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth this->handleQuad(quadPts); 233bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth lastPoint = quadPts[2]; 234bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth quads += 2; 235bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 236bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth} 237bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 23858abc9e2c56464336472493745e91133819deb96Jim Van Verthvoid GrAmbientShadowTessellator::addArc(const SkVector& nextNormal) { 239bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // fill in fan from previous quad 240bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkScalar rotSin, rotCos; 241bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth int numSteps; 242bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth compute_radial_steps(fPrevNormal, nextNormal, fRadius, &rotSin, &rotCos, &numSteps); 243bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkVector prevNormal = fPrevNormal; 244bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth for (int i = 0; i < numSteps; ++i) { 245bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth SkVector nextNormal; 246bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth nextNormal.fX = prevNormal.fX*rotCos - prevNormal.fY*rotSin; 247bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth nextNormal.fY = prevNormal.fY*rotCos + prevNormal.fX*rotSin; 248bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fPositions.push() = fPositions[fPrevInnerIndex] + nextNormal; 249bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fColors.push() = fPenumbraColor; 250bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPrevInnerIndex; 251bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 2; 252bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 1; 253bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 254bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth prevNormal = nextNormal; 255bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 256bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth} 257bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 25858abc9e2c56464336472493745e91133819deb96Jim Van Verthvoid GrAmbientShadowTessellator::finishArcAndAddEdge(const SkPoint& nextPoint, 259bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth const SkVector& nextNormal) { 260bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // close out previous arc 261bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fPositions.push() = fPositions[fPrevInnerIndex] + nextNormal; 262bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fColors.push() = fPenumbraColor; 263bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPrevInnerIndex; 264bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 2; 265bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 1; 266bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 267bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth this->addEdge(nextPoint, nextNormal); 268bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth} 269bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 27058abc9e2c56464336472493745e91133819deb96Jim Van Verthvoid GrAmbientShadowTessellator::addEdge(const SkPoint& nextPoint, const SkVector& nextNormal) { 271bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // add next quad 272bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fPositions.push() = nextPoint; 273bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fColors.push() = fUmbraColor; 274bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fPositions.push() = nextPoint + nextNormal; 275bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fColors.push() = fPenumbraColor; 276bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 277bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPrevInnerIndex; 278bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 3; 279bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 2; 280bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 281bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 3; 282bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 1; 283bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 2; 284bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 285bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth // if transparent, add point to first one in array and add to center fan 286bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth if (fTransparent) { 287bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPositions[0] += nextPoint; 288bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth ++fCentroidCount; 289bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 290bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = 0; 291bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPrevInnerIndex; 292bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth *fIndices.push() = fPositions.count() - 2; 293bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth } 294bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth 295bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPrevInnerIndex = fPositions.count() - 2; 296bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth fPrevNormal = nextNormal; 297bce7496d7dd9131cc7121389a55f6d512ee7661eJim Van Verth} 29891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 29991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth/////////////////////////////////////////////////////////////////////////////////////////////////// 30091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 30191af72703830f3946c538b47c6c7c96afc0adde2Jim Van VerthGrSpotShadowTessellator::GrSpotShadowTessellator(const SkPath& path, 30291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkScalar scale, const SkVector& translate, 30391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkScalar radius, 30491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth GrColor umbraColor, GrColor penumbraColor, 30591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth bool /* transparent */) 30691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth : fRadius(radius) 30791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth , fUmbraColor(umbraColor) 30891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth , fPenumbraColor(penumbraColor) 30991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth , fPrevInnerIndex(-1) { 31091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 31191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // TODO: calculate these better 31291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // Outer ring: 3*numPts 31391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // Inner ring: numPts 31491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPositions.setReserve(4 * path.countPoints()); 31591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fColors.setReserve(4 * path.countPoints()); 31691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // Outer ring: 12*numPts 31791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // Inner ring: 0 31891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fIndices.setReserve(12 * path.countPoints()); 31991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 32091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fInitPoints.setReserve(3); 32191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 32291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fClipPolygon.setReserve(path.countPoints()); 32391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->computeClipBounds(path); 32491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid *= scale; 32591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid += translate; 32691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 32791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // walk around the path, tessellate and generate inner and outer rings 32891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPath::Iter iter(path, true); 32991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint pts[4]; 33091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPath::Verb verb; 33191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fPositions.push() = fCentroid; 33291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fColors.push() = fUmbraColor; 33391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 33491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth switch (verb) { 33591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kLine_Verb: 33691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleLine(scale, translate, pts[1]); 33791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth break; 33891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kQuad_Verb: 33991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleQuad(scale, translate, pts); 34091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth break; 34191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kCubic_Verb: 34291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleCubic(scale, translate, pts); 34391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth break; 34491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kConic_Verb: 34591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleConic(scale, translate, pts, iter.conicWeight()); 34691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth break; 34791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kMove_Verb: 34891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kClose_Verb: 34991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kDone_Verb: 35091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth break; 35191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 35291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 35391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 35491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkVector normal; 35591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth if (compute_normal(fPrevPoint, fFirstPoint, fRadius, fDirection, 35691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth &normal)) { 35791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->addArc(normal); 35891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 35991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // close out previous arc 36091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fPositions.push() = fPrevPoint + normal; 36191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fColors.push() = fPenumbraColor; 36291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPrevInnerIndex; 36391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 2; 36491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 1; 36591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 36691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // add final edge 36791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fPositions.push() = fFirstPoint + normal; 36891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fColors.push() = fPenumbraColor; 36991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 37091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPrevInnerIndex; 37191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 2; 37291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fFirstVertex; 37391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 37491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 2; 37591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 1; 37691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fFirstVertex; 37791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 37891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // add to center fan 37991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = 0; 38091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPrevInnerIndex; 38191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fFirstVertex; 38291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 38391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 38491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // final fan 38591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth if (fPositions.count() >= 3) { 38691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPrevInnerIndex = fFirstVertex; 38791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPrevPoint = fFirstPoint; 38891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPrevNormal = normal; 38991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->addArc(fFirstNormal); 39091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 39191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fFirstVertex; 39291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 1; 39391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fFirstVertex + 1; 39491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 39591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 39691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 39791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::computeClipBounds(const SkPath& path) { 39891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // walk around the path and compute clip polygon 39991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // if original path is transparent, will accumulate sum of points for centroid 40091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPath::Iter iter(path, true); 40191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint pts[4]; 40291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPath::Verb verb; 40391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 40491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid = SkPoint::Make(0, 0); 40591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth int centroidCount = 0; 40691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fClipPolygon.reset(); 40791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 40891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 40991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth switch (verb) { 41091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kMove_Verb: 41191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth break; 41291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kLine_Verb: 41391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid += pts[1]; 41491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth centroidCount++; 41591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fClipPolygon.push() = pts[1]; 41691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth break; 41791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kQuad_Verb: 41891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid += pts[1]; 41991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid += pts[2]; 42091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth centroidCount += 2; 42191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fClipPolygon.push() = pts[2]; 42291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth break; 42391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kConic_Verb: 42491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid += pts[1]; 42591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid += pts[2]; 42691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth centroidCount += 2; 42791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fClipPolygon.push() = pts[2]; 42891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth break; 42991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kCubic_Verb: 43091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid += pts[1]; 43191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid += pts[2]; 43291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid += pts[3]; 43391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth centroidCount += 3; 43491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fClipPolygon.push() = pts[3]; 43591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth break; 43691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth case SkPath::kClose_Verb: 43791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth break; 43891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth default: 43991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkDEBUGFAIL("unknown verb"); 44091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 44191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 44291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 44391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fCentroid *= SkScalarInvert(centroidCount); 44491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 44591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 44691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::mapPoints(SkScalar scale, const SkVector& xlate, 44791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint* pts, int count) { 44891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // TODO: vectorize 44991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth for (int i = 0; i < count; ++i) { 45091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth pts[i] *= scale; 45191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth pts[i] += xlate; 45291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 45391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 45491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 45591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::handleLine(const SkPoint& p) { 45691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth if (fInitPoints.count() < 2) { 45791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fInitPoints.push() = p; 45891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth return; 45991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 46091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 46191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth if (fInitPoints.count() == 2) { 46291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // determine if cw or ccw 46391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkVector v0 = fInitPoints[1] - fInitPoints[0]; 46491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkVector v1 = p - fInitPoints[0]; 46591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkScalar perpDot = v0.fX*v1.fY - v0.fY*v1.fX; 46691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth if (SkScalarNearlyZero(perpDot)) { 46791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // nearly parallel, just treat as straight line and continue 46891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fInitPoints[1] = p; 46991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth return; 47091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 47191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 47291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // if perpDot > 0, winding is ccw 47391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fDirection = (perpDot > 0) ? -1 : 1; 47491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 47591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // add first quad 47691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth if (!compute_normal(fInitPoints[0], fInitPoints[1], fRadius, fDirection, 47791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth &fFirstNormal)) { 47891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // first two points are incident, make the third point the second and continue 47991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fInitPoints[1] = p; 48091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth return; 48191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 48291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 48391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fFirstPoint = fInitPoints[0]; 48491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fFirstVertex = fPositions.count(); 48591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPrevNormal = fFirstNormal; 48691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPrevPoint = fFirstPoint; 48791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPrevInnerIndex = fFirstVertex; 48891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 48991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->addInnerPoint(fFirstPoint, fUmbraColor, fRadius); 49091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint newPoint = fFirstPoint + fFirstNormal; 49191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fPositions.push() = newPoint; 49291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fColors.push() = fPenumbraColor; 49391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->addEdge(fInitPoints[1], fFirstNormal); 49491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 49591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // to ensure we skip this block next time 49691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fInitPoints.push() = p; 49791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 49891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 49991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkVector normal; 50091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth if (compute_normal(fPrevPoint, p, fRadius, fDirection, &normal)) { 50191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->addArc(normal); 50291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->finishArcAndAddEdge(p, normal); 50391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 50491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 50591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 50691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::handleLine(SkScalar scale, const SkVector& xlate, SkPoint p) { 50791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->mapPoints(scale, xlate, &p, 1); 50891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleLine(p); 50991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 51091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 51191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::handleQuad(const SkPoint pts[3]) { 51291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth int maxCount = GrPathUtils::quadraticPointCount(pts, kQuadTolerance); 51391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPointBuffer.setReserve(maxCount); 51491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint* target = fPointBuffer.begin(); 51591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth int count = GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2], 51691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth kQuadTolerance, &target, maxCount); 51791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPointBuffer.setCount(count); 51891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth for (int i = 0; i < count; i++) { 51991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleLine(fPointBuffer[i]); 52091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 52191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 52291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 52391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::handleQuad(SkScalar scale, const SkVector& xlate, SkPoint pts[3]) { 52491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->mapPoints(scale, xlate, pts, 3); 52591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleQuad(pts); 52691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 52791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 52891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::handleCubic(SkScalar scale, const SkVector& xlate, SkPoint pts[4]) { 52991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->mapPoints(scale, xlate, pts, 4); 53091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth int maxCount = GrPathUtils::cubicPointCount(pts, kCubicTolerance); 53191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPointBuffer.setReserve(maxCount); 53291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint* target = fPointBuffer.begin(); 53391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth int count = GrPathUtils::generateCubicPoints(pts[0], pts[1], pts[2], pts[3], 53491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth kCubicTolerance, &target, maxCount); 53591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPointBuffer.setCount(count); 53691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth for (int i = 0; i < count; i++) { 53791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleLine(fPointBuffer[i]); 53891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 53991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 54091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 54191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::handleConic(SkScalar scale, const SkVector& xlate, 54291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint pts[3], SkScalar w) { 54391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->mapPoints(scale, xlate, pts, 3); 54491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkAutoConicToQuads quadder; 54591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth const SkPoint* quads = quadder.computeQuads(pts, w, kConicTolerance); 54691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint lastPoint = *(quads++); 54791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth int count = quadder.countQuads(); 54891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth for (int i = 0; i < count; ++i) { 54991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint quadPts[3]; 55091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth quadPts[0] = lastPoint; 55191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth quadPts[1] = quads[0]; 55291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth quadPts[2] = i == count - 1 ? pts[2] : quads[1]; 55391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->handleQuad(quadPts); 55491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth lastPoint = quadPts[2]; 55591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth quads += 2; 55691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 55791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 55891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 55991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::addInnerPoint(const SkPoint& pathPoint, GrColor umbraColor, 56091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkScalar radius) { 56191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkVector v = fCentroid - pathPoint; 56291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkScalar distance = v.length(); 56391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth if (distance < radius) { 56491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fPositions.push() = fCentroid; 56591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fColors.push() = umbraColor; // fix this 56691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // TODO: deal with fanning from centroid 56791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } else { 56891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkScalar t = radius / distance; 56991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth v *= t; 57091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint innerPoint = pathPoint + v; 57191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fPositions.push() = innerPoint; 57291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fColors.push() = umbraColor; 57391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 57491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPrevPoint = pathPoint; 57591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 57691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 57791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::addArc(const SkVector& nextNormal) { 57891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // fill in fan from previous quad 57991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkScalar rotSin, rotCos; 58091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth int numSteps; 58191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth compute_radial_steps(fPrevNormal, nextNormal, fRadius, &rotSin, &rotCos, &numSteps); 58291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkVector prevNormal = fPrevNormal; 58391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth for (int i = 0; i < numSteps; ++i) { 58491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkVector nextNormal; 58591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth nextNormal.fX = prevNormal.fX*rotCos - prevNormal.fY*rotSin; 58691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth nextNormal.fY = prevNormal.fY*rotCos + prevNormal.fX*rotSin; 58791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fPositions.push() = fPrevPoint + nextNormal; 58891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fColors.push() = fPenumbraColor; 58991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPrevInnerIndex; 59091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 2; 59191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 1; 59291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 59391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth prevNormal = nextNormal; 59491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth } 59591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 59691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 59791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::finishArcAndAddEdge(const SkPoint& nextPoint, 59891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth const SkVector& nextNormal) { 59991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // close out previous arc 60091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint newPoint = fPrevPoint + nextNormal; 60191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fPositions.push() = newPoint; 60291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fColors.push() = fPenumbraColor; 60391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPrevInnerIndex; 60491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 2; 60591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 1; 60691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 60791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->addEdge(nextPoint, nextNormal); 60891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 60991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 61091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verthvoid GrSpotShadowTessellator::addEdge(const SkPoint& nextPoint, const SkVector& nextNormal) { 61191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // add next quad 61291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth this->addInnerPoint(nextPoint, fUmbraColor, fRadius); 61391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth SkPoint newPoint = nextPoint + nextNormal; 61491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fPositions.push() = newPoint; 61591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fColors.push() = fPenumbraColor; 61691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 61791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPrevInnerIndex; 61891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 3; 61991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 2; 62091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 62191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 3; 62291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 1; 62391af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 2; 62491af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 62591af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth // add to center fan 62691af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = 0; 62791af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPrevInnerIndex; 62891af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth *fIndices.push() = fPositions.count() - 2; 62991af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth 63091af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPrevInnerIndex = fPositions.count() - 2; 63191af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth fPrevNormal = nextNormal; 63291af72703830f3946c538b47c6c7c96afc0adde2Jim Van Verth} 633