OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 <cmath> | 8 #include <cmath> |
9 #include "SkBuffer.h" | 9 #include "SkBuffer.h" |
10 #include "SkCubicClipper.h" | 10 #include "SkCubicClipper.h" |
(...skipping 3231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3242 } | 3242 } |
3243 } while (!done); | 3243 } while (!done); |
3244 return SkToBool(tangents.count()) ^ isInverse; | 3244 return SkToBool(tangents.count()) ^ isInverse; |
3245 } | 3245 } |
3246 | 3246 |
3247 int SkPath::ConvertConicToQuads(const SkPoint& p0, const SkPoint& p1, const SkPo
int& p2, | 3247 int SkPath::ConvertConicToQuads(const SkPoint& p0, const SkPoint& p1, const SkPo
int& p2, |
3248 SkScalar w, SkPoint pts[], int pow2) { | 3248 SkScalar w, SkPoint pts[], int pow2) { |
3249 const SkConic conic(p0, p1, p2, w); | 3249 const SkConic conic(p0, p1, p2, w); |
3250 return conic.chopIntoQuadsPOW2(pts, pow2); | 3250 return conic.chopIntoQuadsPOW2(pts, pow2); |
3251 } | 3251 } |
| 3252 |
| 3253 bool SkPathPriv::IsSimpleClosedRect(const SkPath& path, SkRect* rect, SkPath::Di
rection* direction, |
| 3254 unsigned* start) { |
| 3255 if (path.getSegmentMasks() != SkPath::kLine_SegmentMask) { |
| 3256 return false; |
| 3257 } |
| 3258 SkPath::RawIter iter(path); |
| 3259 SkPoint verbPts[4]; |
| 3260 SkPath::Verb v; |
| 3261 SkPoint rectPts[5]; |
| 3262 int rectPtCnt = 0; |
| 3263 while ((v = iter.next(verbPts)) != SkPath::kDone_Verb) { |
| 3264 switch (v) { |
| 3265 case SkPath::kMove_Verb: |
| 3266 if (0 != rectPtCnt) { |
| 3267 return false; |
| 3268 } |
| 3269 rectPts[0] = verbPts[0]; |
| 3270 ++rectPtCnt; |
| 3271 break; |
| 3272 case SkPath::kLine_Verb: |
| 3273 if (5 == rectPtCnt) { |
| 3274 return false; |
| 3275 } |
| 3276 rectPts[rectPtCnt] = verbPts[1]; |
| 3277 ++rectPtCnt; |
| 3278 break; |
| 3279 case SkPath::kClose_Verb: |
| 3280 if (4 == rectPtCnt) { |
| 3281 rectPts[4] = rectPts[0]; |
| 3282 rectPtCnt = 5; |
| 3283 } |
| 3284 break; |
| 3285 default: |
| 3286 return false; |
| 3287 } |
| 3288 } |
| 3289 if (rectPtCnt < 5) { |
| 3290 return false; |
| 3291 } |
| 3292 if (rectPts[0] != rectPts[4]) { |
| 3293 return false; |
| 3294 } |
| 3295 int verticalCnt = 0; |
| 3296 int horizontalCnt = 0; |
| 3297 // dirs are 0 - right, 1 - down, 2 - left, 3 - up. |
| 3298 int firstDir; |
| 3299 int secondDir; |
| 3300 SkRect tempRect; |
| 3301 for (int i = 0; i < 4; ++i) { |
| 3302 int sameCnt = 0; |
| 3303 if (rectPts[i].fX == rectPts[i + 1].fX) { |
| 3304 verticalCnt += 1; |
| 3305 sameCnt = 1; |
| 3306 if (0 == i) { |
| 3307 if (rectPts[1].fY > rectPts[0].fY) { |
| 3308 firstDir = 1; |
| 3309 tempRect.fTop = rectPts[0].fY; |
| 3310 tempRect.fBottom = rectPts[1].fY; |
| 3311 } else { |
| 3312 firstDir = 3; |
| 3313 tempRect.fTop = rectPts[1].fY; |
| 3314 tempRect.fBottom = rectPts[0].fY; |
| 3315 } |
| 3316 } else if (1 == i) { |
| 3317 if (rectPts[2].fY > rectPts[1].fY) { |
| 3318 secondDir = 1; |
| 3319 tempRect.fTop = rectPts[1].fY; |
| 3320 tempRect.fBottom = rectPts[2].fY; |
| 3321 } else { |
| 3322 secondDir = 3; |
| 3323 tempRect.fTop = rectPts[2].fY; |
| 3324 tempRect.fBottom = rectPts[1].fY; |
| 3325 } |
| 3326 } |
| 3327 } |
| 3328 if (rectPts[i].fY == rectPts[i + 1].fY) { |
| 3329 horizontalCnt += 1; |
| 3330 sameCnt += 1; |
| 3331 if (0 == i) { |
| 3332 if (rectPts[1].fX > rectPts[0].fX) { |
| 3333 firstDir = 0; |
| 3334 tempRect.fLeft = rectPts[0].fX; |
| 3335 tempRect.fRight = rectPts[1].fX; |
| 3336 } else { |
| 3337 firstDir = 2; |
| 3338 tempRect.fLeft = rectPts[1].fX; |
| 3339 tempRect.fRight = rectPts[0].fX; |
| 3340 } |
| 3341 } else if (1 == i) { |
| 3342 if (rectPts[2].fX > rectPts[1].fX) { |
| 3343 secondDir = 0; |
| 3344 tempRect.fLeft = rectPts[1].fX; |
| 3345 tempRect.fRight = rectPts[2].fX; |
| 3346 } else { |
| 3347 secondDir = 2; |
| 3348 tempRect.fLeft = rectPts[2].fX; |
| 3349 tempRect.fRight = rectPts[1].fX; |
| 3350 } |
| 3351 } |
| 3352 } |
| 3353 if (sameCnt != 1) { |
| 3354 return false; |
| 3355 } |
| 3356 } |
| 3357 if (2 != horizontalCnt || 2 != verticalCnt) { |
| 3358 return false; |
| 3359 } |
| 3360 // low bit indicates a vertical dir |
| 3361 SkASSERT((firstDir ^ secondDir) & 0b1); |
| 3362 if (((firstDir + 1) & 0b11) == secondDir) { |
| 3363 *direction = SkPath::kCW_Direction; |
| 3364 *start = firstDir; |
| 3365 } else { |
| 3366 SkASSERT(((secondDir + 1) & 0b11) == firstDir); |
| 3367 *direction = SkPath::kCCW_Direction; |
| 3368 *start = secondDir; |
| 3369 } |
| 3370 *rect = tempRect; |
| 3371 return true; |
| 3372 } |
OLD | NEW |