1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com#include "SkEdgeBuilder.h" 9909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com#include "SkPath.h" 10909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com#include "SkEdge.h" 11909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com#include "SkEdgeClipper.h" 12909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com#include "SkLineClipper.h" 13909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com#include "SkGeometry.h" 14909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 15909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.comtemplate <typename T> static T* typedAllocThrow(SkChunkAlloc& alloc) { 16909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com return static_cast<T*>(alloc.allocThrow(sizeof(T))); 17909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com} 18909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 19909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com/////////////////////////////////////////////////////////////////////////////// 20909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 21c8d640b1788822a8697816b645c327383a1d1f20reed@google.comSkEdgeBuilder::SkEdgeBuilder() : fAlloc(16*1024) { 22c8d640b1788822a8697816b645c327383a1d1f20reed@google.com fEdgeList = NULL; 23c8d640b1788822a8697816b645c327383a1d1f20reed@google.com} 24c8d640b1788822a8697816b645c327383a1d1f20reed@google.com 25909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.comvoid SkEdgeBuilder::addLine(const SkPoint pts[]) { 26909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkEdge* edge = typedAllocThrow<SkEdge>(fAlloc); 27b6a2ba7b483a164a59ec0ded0795590329eab923reed@google.com if (edge->setLine(pts[0], pts[1], fShiftUp)) { 28909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com fList.push(edge); 29909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } else { 30909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com // TODO: unallocate edge from storage... 31909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 32909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com} 33909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 34909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.comvoid SkEdgeBuilder::addQuad(const SkPoint pts[]) { 35909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkQuadraticEdge* edge = typedAllocThrow<SkQuadraticEdge>(fAlloc); 36909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com if (edge->setQuadratic(pts, fShiftUp)) { 37909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com fList.push(edge); 38909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } else { 39909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com // TODO: unallocate edge from storage... 40909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 41909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com} 42909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 43909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.comvoid SkEdgeBuilder::addCubic(const SkPoint pts[]) { 44909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkCubicEdge* edge = typedAllocThrow<SkCubicEdge>(fAlloc); 45e053ca4380713a5b9e6a31119a1bdd6d529208aareed if (edge->setCubic(pts, fShiftUp)) { 46909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com fList.push(edge); 47909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } else { 48909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com // TODO: unallocate edge from storage... 49909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 50909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com} 51909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 52909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.comvoid SkEdgeBuilder::addClipper(SkEdgeClipper* clipper) { 53909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkPoint pts[4]; 54909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkPath::Verb verb; 55909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 56909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com while ((verb = clipper->next(pts)) != SkPath::kDone_Verb) { 57909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com switch (verb) { 58909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kLine_Verb: 59909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com this->addLine(pts); 60909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 61909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kQuad_Verb: 62909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com this->addQuad(pts); 63909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 64909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kCubic_Verb: 65909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com this->addCubic(pts); 66909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 67909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com default: 68909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 69909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 70909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 71909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com} 72909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 73909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com/////////////////////////////////////////////////////////////////////////////// 74909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 75909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.comstatic void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) { 76909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com dst->set(SkIntToScalar(src.fLeft >> shift), 77909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkIntToScalar(src.fTop >> shift), 78909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkIntToScalar(src.fRight >> shift), 79909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkIntToScalar(src.fBottom >> shift)); 80909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com} 81909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 8201d3319b67b1ad404006a0026803efc1573f4570reedint SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shiftUp, 8331223e0cb74f47f63b094520a9830c525b72fe87reed bool canCullToTheRight) { 84c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkPath::Iter iter(path, true); 85c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkPoint pts[4]; 86c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkPath::Verb verb; 87fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 88c8d640b1788822a8697816b645c327383a1d1f20reed@google.com int maxEdgeCount = path.countPoints(); 89c8d640b1788822a8697816b645c327383a1d1f20reed@google.com if (iclip) { 90c8d640b1788822a8697816b645c327383a1d1f20reed@google.com // clipping can turn 1 line into (up to) kMaxClippedLineSegments, since 91c8d640b1788822a8697816b645c327383a1d1f20reed@google.com // we turn portions that are clipped out on the left/right into vertical 92c8d640b1788822a8697816b645c327383a1d1f20reed@google.com // segments. 93c8d640b1788822a8697816b645c327383a1d1f20reed@google.com maxEdgeCount *= SkLineClipper::kMaxClippedLineSegments; 94c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } 95c8d640b1788822a8697816b645c327383a1d1f20reed@google.com size_t maxEdgeSize = maxEdgeCount * sizeof(SkEdge); 96c8d640b1788822a8697816b645c327383a1d1f20reed@google.com size_t maxEdgePtrSize = maxEdgeCount * sizeof(SkEdge*); 97c8d640b1788822a8697816b645c327383a1d1f20reed@google.com 98c8d640b1788822a8697816b645c327383a1d1f20reed@google.com // lets store the edges and their pointers in the same block 99c8d640b1788822a8697816b645c327383a1d1f20reed@google.com char* storage = (char*)fAlloc.allocThrow(maxEdgeSize + maxEdgePtrSize); 100c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkEdge* edge = reinterpret_cast<SkEdge*>(storage); 101c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkEdge** edgePtr = reinterpret_cast<SkEdge**>(storage + maxEdgeSize); 102c8d640b1788822a8697816b645c327383a1d1f20reed@google.com // Record the beginning of our pointers, so we can return them to the caller 103c8d640b1788822a8697816b645c327383a1d1f20reed@google.com fEdgeList = edgePtr; 104c8d640b1788822a8697816b645c327383a1d1f20reed@google.com 105c8d640b1788822a8697816b645c327383a1d1f20reed@google.com if (iclip) { 106c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkRect clip; 107c8d640b1788822a8697816b645c327383a1d1f20reed@google.com setShiftedClip(&clip, *iclip, shiftUp); 108fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 109c8d640b1788822a8697816b645c327383a1d1f20reed@google.com while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { 110c8d640b1788822a8697816b645c327383a1d1f20reed@google.com switch (verb) { 111c8d640b1788822a8697816b645c327383a1d1f20reed@google.com case SkPath::kMove_Verb: 112c8d640b1788822a8697816b645c327383a1d1f20reed@google.com case SkPath::kClose_Verb: 113c8d640b1788822a8697816b645c327383a1d1f20reed@google.com // we ignore these, and just get the whole segment from 114c8d640b1788822a8697816b645c327383a1d1f20reed@google.com // the corresponding line/quad/cubic verbs 115c8d640b1788822a8697816b645c327383a1d1f20reed@google.com break; 116c8d640b1788822a8697816b645c327383a1d1f20reed@google.com case SkPath::kLine_Verb: { 117c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkPoint lines[SkLineClipper::kMaxPoints]; 11831223e0cb74f47f63b094520a9830c525b72fe87reed int lineCount = SkLineClipper::ClipLine(pts, clip, lines, canCullToTheRight); 119c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments); 120c8d640b1788822a8697816b645c327383a1d1f20reed@google.com for (int i = 0; i < lineCount; i++) { 121b6a2ba7b483a164a59ec0ded0795590329eab923reed@google.com if (edge->setLine(lines[i], lines[i + 1], shiftUp)) { 122c8d640b1788822a8697816b645c327383a1d1f20reed@google.com *edgePtr++ = edge++; 123c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } 124c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } 125c8d640b1788822a8697816b645c327383a1d1f20reed@google.com break; 126c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } 127c8d640b1788822a8697816b645c327383a1d1f20reed@google.com default: 128c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkDEBUGFAIL("unexpected verb"); 129c8d640b1788822a8697816b645c327383a1d1f20reed@google.com break; 130c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } 131c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } 132c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } else { 133c8d640b1788822a8697816b645c327383a1d1f20reed@google.com while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { 134c8d640b1788822a8697816b645c327383a1d1f20reed@google.com switch (verb) { 135c8d640b1788822a8697816b645c327383a1d1f20reed@google.com case SkPath::kMove_Verb: 136c8d640b1788822a8697816b645c327383a1d1f20reed@google.com case SkPath::kClose_Verb: 137c8d640b1788822a8697816b645c327383a1d1f20reed@google.com // we ignore these, and just get the whole segment from 138c8d640b1788822a8697816b645c327383a1d1f20reed@google.com // the corresponding line/quad/cubic verbs 139c8d640b1788822a8697816b645c327383a1d1f20reed@google.com break; 140c8d640b1788822a8697816b645c327383a1d1f20reed@google.com case SkPath::kLine_Verb: 141b6a2ba7b483a164a59ec0ded0795590329eab923reed@google.com if (edge->setLine(pts[0], pts[1], shiftUp)) { 142c8d640b1788822a8697816b645c327383a1d1f20reed@google.com *edgePtr++ = edge++; 143c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } 144c8d640b1788822a8697816b645c327383a1d1f20reed@google.com break; 145c8d640b1788822a8697816b645c327383a1d1f20reed@google.com default: 146c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkDEBUGFAIL("unexpected verb"); 147c8d640b1788822a8697816b645c327383a1d1f20reed@google.com break; 148c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } 149c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } 150c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } 151c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkASSERT((char*)edge <= (char*)fEdgeList); 152c8d640b1788822a8697816b645c327383a1d1f20reed@google.com SkASSERT(edgePtr - fEdgeList <= maxEdgeCount); 153a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org return SkToInt(edgePtr - fEdgeList); 154c8d640b1788822a8697816b645c327383a1d1f20reed@google.com} 155c8d640b1788822a8697816b645c327383a1d1f20reed@google.com 156277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.comstatic void handle_quad(SkEdgeBuilder* builder, const SkPoint pts[3]) { 157277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com SkPoint monoX[5]; 158277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com int n = SkChopQuadAtYExtrema(pts, monoX); 159277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com for (int i = 0; i <= n; i++) { 160277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com builder->addQuad(&monoX[i * 2]); 161277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com } 162277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com} 163277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com 16401d3319b67b1ad404006a0026803efc1573f4570reedint SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp, 16531223e0cb74f47f63b094520a9830c525b72fe87reed bool canCullToTheRight) { 166909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com fAlloc.reset(); 167909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com fList.reset(); 168909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com fShiftUp = shiftUp; 169909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 170c8d640b1788822a8697816b645c327383a1d1f20reed@google.com if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) { 17131223e0cb74f47f63b094520a9830c525b72fe87reed return this->buildPoly(path, iclip, shiftUp, canCullToTheRight); 172c8d640b1788822a8697816b645c327383a1d1f20reed@google.com } 173c8d640b1788822a8697816b645c327383a1d1f20reed@google.com 174220f926d9d4b38a9018c922c095847bbd261f583reed SkAutoConicToQuads quadder; 1753f4e045b4f8b97d189162d17c85b8410e083a3afreed const SkScalar conicTol = SK_Scalar1 / 4; 176220f926d9d4b38a9018c922c095847bbd261f583reed 177909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkPath::Iter iter(path, true); 178909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkPoint pts[4]; 179909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkPath::Verb verb; 180909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 181909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com if (iclip) { 182909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkRect clip; 183909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com setShiftedClip(&clip, *iclip, shiftUp); 18431223e0cb74f47f63b094520a9830c525b72fe87reed SkEdgeClipper clipper(canCullToTheRight); 185909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com 1864a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { 187909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com switch (verb) { 188909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kMove_Verb: 189909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kClose_Verb: 190909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com // we ignore these, and just get the whole segment from 191909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com // the corresponding line/quad/cubic verbs 192909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 193909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kLine_Verb: { 194909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkPoint lines[SkLineClipper::kMaxPoints]; 19531223e0cb74f47f63b094520a9830c525b72fe87reed int lineCount = SkLineClipper::ClipLine(pts, clip, lines, canCullToTheRight); 196909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com for (int i = 0; i < lineCount; i++) { 197909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com this->addLine(&lines[i]); 198909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 199909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 200909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 201909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kQuad_Verb: 202909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com if (clipper.clipQuad(pts, clip)) { 203909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com this->addClipper(&clipper); 204909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 205909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 206277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com case SkPath::kConic_Verb: { 207220f926d9d4b38a9018c922c095847bbd261f583reed const SkPoint* quadPts = quadder.computeQuads( 208220f926d9d4b38a9018c922c095847bbd261f583reed pts, iter.conicWeight(), conicTol); 209220f926d9d4b38a9018c922c095847bbd261f583reed for (int i = 0; i < quadder.countQuads(); ++i) { 210220f926d9d4b38a9018c922c095847bbd261f583reed if (clipper.clipQuad(quadPts, clip)) { 211277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com this->addClipper(&clipper); 212277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com } 213220f926d9d4b38a9018c922c095847bbd261f583reed quadPts += 2; 214277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com } 215277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com } break; 216909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kCubic_Verb: 217909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com if (clipper.clipCubic(pts, clip)) { 218909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com this->addClipper(&clipper); 219909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 220909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 221909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com default: 2220c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unexpected verb"); 223909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 224909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 225909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 226909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } else { 2274a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { 228909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com switch (verb) { 229909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kMove_Verb: 230909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kClose_Verb: 231909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com // we ignore these, and just get the whole segment from 232909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com // the corresponding line/quad/cubic verbs 233909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 234909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kLine_Verb: 235909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com this->addLine(pts); 236909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 237909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kQuad_Verb: { 238277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com handle_quad(this, pts); 239909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 240909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 241277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com case SkPath::kConic_Verb: { 242220f926d9d4b38a9018c922c095847bbd261f583reed const SkPoint* quadPts = quadder.computeQuads( 243220f926d9d4b38a9018c922c095847bbd261f583reed pts, iter.conicWeight(), conicTol); 244220f926d9d4b38a9018c922c095847bbd261f583reed for (int i = 0; i < quadder.countQuads(); ++i) { 245220f926d9d4b38a9018c922c095847bbd261f583reed handle_quad(this, quadPts); 246220f926d9d4b38a9018c922c095847bbd261f583reed quadPts += 2; 247277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com } 248277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com } break; 249909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com case SkPath::kCubic_Verb: { 250909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com SkPoint monoY[10]; 251909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com int n = SkChopCubicAtYExtrema(pts, monoY); 252909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com for (int i = 0; i <= n; i++) { 253909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com this->addCubic(&monoY[i * 3]); 254909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 255909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 256909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 257909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com default: 2580c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unexpected verb"); 259909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com break; 260909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 261909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 262909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com } 263c8d640b1788822a8697816b645c327383a1d1f20reed@google.com fEdgeList = fList.begin(); 264909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com return fList.count(); 265909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com} 266