| 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 #include "SkEdgeBuilder.h" | 8 #include "SkEdgeBuilder.h" |
| 9 #include "SkPath.h" | 9 #include "SkPath.h" |
| 10 #include "SkEdge.h" | 10 #include "SkEdge.h" |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 builder->addQuad(&monoX[i * 2]); | 160 builder->addQuad(&monoX[i * 2]); |
| 161 } | 161 } |
| 162 } | 162 } |
| 163 | 163 |
| 164 int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, | 164 int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, |
| 165 int shiftUp) { | 165 int shiftUp) { |
| 166 fAlloc.reset(); | 166 fAlloc.reset(); |
| 167 fList.reset(); | 167 fList.reset(); |
| 168 fShiftUp = shiftUp; | 168 fShiftUp = shiftUp; |
| 169 | 169 |
| 170 SkScalar conicTol = SK_ScalarHalf * (1 << shiftUp); | |
| 171 | |
| 172 if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) { | 170 if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) { |
| 173 return this->buildPoly(path, iclip, shiftUp); | 171 return this->buildPoly(path, iclip, shiftUp); |
| 174 } | 172 } |
| 175 | 173 |
| 174 SkAutoConicToQuads quadder; |
| 175 const SkScalar conicTol = (SK_Scalar1 / 4) * (1 << shiftUp); |
| 176 |
| 176 SkPath::Iter iter(path, true); | 177 SkPath::Iter iter(path, true); |
| 177 SkPoint pts[4]; | 178 SkPoint pts[4]; |
| 178 SkPath::Verb verb; | 179 SkPath::Verb verb; |
| 179 | 180 |
| 180 if (iclip) { | 181 if (iclip) { |
| 181 SkRect clip; | 182 SkRect clip; |
| 182 setShiftedClip(&clip, *iclip, shiftUp); | 183 setShiftedClip(&clip, *iclip, shiftUp); |
| 183 SkEdgeClipper clipper; | 184 SkEdgeClipper clipper; |
| 184 | 185 |
| 185 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { | 186 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 196 this->addLine(&lines[i]); | 197 this->addLine(&lines[i]); |
| 197 } | 198 } |
| 198 break; | 199 break; |
| 199 } | 200 } |
| 200 case SkPath::kQuad_Verb: | 201 case SkPath::kQuad_Verb: |
| 201 if (clipper.clipQuad(pts, clip)) { | 202 if (clipper.clipQuad(pts, clip)) { |
| 202 this->addClipper(&clipper); | 203 this->addClipper(&clipper); |
| 203 } | 204 } |
| 204 break; | 205 break; |
| 205 case SkPath::kConic_Verb: { | 206 case SkPath::kConic_Verb: { |
| 206 const int MAX_POW2 = 4; | 207 const SkPoint* quadPts = quadder.computeQuads( |
| 207 const int MAX_QUADS = 1 << MAX_POW2; | 208 pts, iter.conicWeight(), conicTol); |
| 208 const int MAX_QUAD_PTS = 1 + 2 * MAX_QUADS; | 209 for (int i = 0; i < quadder.countQuads(); ++i) { |
| 209 SkPoint storage[MAX_QUAD_PTS]; | 210 if (clipper.clipQuad(quadPts, clip)) { |
| 210 | |
| 211 SkConic conic; | |
| 212 conic.set(pts, iter.conicWeight()); | |
| 213 int pow2 = conic.computeQuadPOW2(conicTol); | |
| 214 pow2 = SkMin32(pow2, MAX_POW2); | |
| 215 int quadCount = conic.chopIntoQuadsPOW2(storage, pow2); | |
| 216 SkASSERT(quadCount <= MAX_QUADS); | |
| 217 for (int i = 0; i < quadCount; ++i) { | |
| 218 if (clipper.clipQuad(&storage[i * 2], clip)) { | |
| 219 this->addClipper(&clipper); | 211 this->addClipper(&clipper); |
| 220 } | 212 } |
| 213 quadPts += 2; |
| 221 } | 214 } |
| 222 } break; | 215 } break; |
| 223 case SkPath::kCubic_Verb: | 216 case SkPath::kCubic_Verb: |
| 224 if (clipper.clipCubic(pts, clip)) { | 217 if (clipper.clipCubic(pts, clip)) { |
| 225 this->addClipper(&clipper); | 218 this->addClipper(&clipper); |
| 226 } | 219 } |
| 227 break; | 220 break; |
| 228 default: | 221 default: |
| 229 SkDEBUGFAIL("unexpected verb"); | 222 SkDEBUGFAIL("unexpected verb"); |
| 230 break; | 223 break; |
| 231 } | 224 } |
| 232 } | 225 } |
| 233 } else { | 226 } else { |
| 234 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { | 227 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { |
| 235 switch (verb) { | 228 switch (verb) { |
| 236 case SkPath::kMove_Verb: | 229 case SkPath::kMove_Verb: |
| 237 case SkPath::kClose_Verb: | 230 case SkPath::kClose_Verb: |
| 238 // we ignore these, and just get the whole segment from | 231 // we ignore these, and just get the whole segment from |
| 239 // the corresponding line/quad/cubic verbs | 232 // the corresponding line/quad/cubic verbs |
| 240 break; | 233 break; |
| 241 case SkPath::kLine_Verb: | 234 case SkPath::kLine_Verb: |
| 242 this->addLine(pts); | 235 this->addLine(pts); |
| 243 break; | 236 break; |
| 244 case SkPath::kQuad_Verb: { | 237 case SkPath::kQuad_Verb: { |
| 245 handle_quad(this, pts); | 238 handle_quad(this, pts); |
| 246 break; | 239 break; |
| 247 } | 240 } |
| 248 case SkPath::kConic_Verb: { | 241 case SkPath::kConic_Verb: { |
| 249 const int MAX_POW2 = 4; | 242 const SkPoint* quadPts = quadder.computeQuads( |
| 250 const int MAX_QUADS = 1 << MAX_POW2; | 243 pts, iter.conicWeight(), conicTol); |
| 251 const int MAX_QUAD_PTS = 1 + 2 * MAX_QUADS; | 244 for (int i = 0; i < quadder.countQuads(); ++i) { |
| 252 SkPoint storage[MAX_QUAD_PTS]; | 245 handle_quad(this, quadPts); |
| 253 | 246 quadPts += 2; |
| 254 SkConic conic; | |
| 255 conic.set(pts, iter.conicWeight()); | |
| 256 int pow2 = conic.computeQuadPOW2(conicTol); | |
| 257 pow2 = SkMin32(pow2, MAX_POW2); | |
| 258 int quadCount = conic.chopIntoQuadsPOW2(storage, pow2); | |
| 259 SkASSERT(quadCount <= MAX_QUADS); | |
| 260 for (int i = 0; i < quadCount; ++i) { | |
| 261 handle_quad(this, &storage[i * 2]); | |
| 262 } | 247 } |
| 263 } break; | 248 } break; |
| 264 case SkPath::kCubic_Verb: { | 249 case SkPath::kCubic_Verb: { |
| 265 SkPoint monoY[10]; | 250 SkPoint monoY[10]; |
| 266 int n = SkChopCubicAtYExtrema(pts, monoY); | 251 int n = SkChopCubicAtYExtrema(pts, monoY); |
| 267 for (int i = 0; i <= n; i++) { | 252 for (int i = 0; i <= n; i++) { |
| 268 this->addCubic(&monoY[i * 3]); | 253 this->addCubic(&monoY[i * 3]); |
| 269 } | 254 } |
| 270 break; | 255 break; |
| 271 } | 256 } |
| 272 default: | 257 default: |
| 273 SkDEBUGFAIL("unexpected verb"); | 258 SkDEBUGFAIL("unexpected verb"); |
| 274 break; | 259 break; |
| 275 } | 260 } |
| 276 } | 261 } |
| 277 } | 262 } |
| 278 fEdgeList = fList.begin(); | 263 fEdgeList = fList.begin(); |
| 279 return fList.count(); | 264 return fList.count(); |
| 280 } | 265 } |
| OLD | NEW |