| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 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 | 8 |
| 9 | 9 |
| 10 #include "SkBuffer.h" | 10 #include "SkBuffer.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 dst->fRight = SkMaxScalar(dst->fRight, src.fRight); | 35 dst->fRight = SkMaxScalar(dst->fRight, src.fRight); |
| 36 dst->fBottom = SkMaxScalar(dst->fBottom, src.fBottom); | 36 dst->fBottom = SkMaxScalar(dst->fBottom, src.fBottom); |
| 37 } | 37 } |
| 38 | 38 |
| 39 static bool is_degenerate(const SkPath& path) { | 39 static bool is_degenerate(const SkPath& path) { |
| 40 SkPath::Iter iter(path, false); | 40 SkPath::Iter iter(path, false); |
| 41 SkPoint pts[4]; | 41 SkPoint pts[4]; |
| 42 return SkPath::kDone_Verb == iter.next(pts); | 42 return SkPath::kDone_Verb == iter.next(pts); |
| 43 } | 43 } |
| 44 | 44 |
| 45 class SkAutoDisableOvalCheck { | |
| 46 public: | |
| 47 SkAutoDisableOvalCheck(SkPath* path) : fPath(path) { | |
| 48 fSaved = fPath->fIsOval; | |
| 49 } | |
| 50 | |
| 51 ~SkAutoDisableOvalCheck() { | |
| 52 fPath->fIsOval = fSaved; | |
| 53 } | |
| 54 | |
| 55 private: | |
| 56 SkPath* fPath; | |
| 57 bool fSaved; | |
| 58 }; | |
| 59 #define SkAutoDisableOvalCheck(...) SK_REQUIRE_LOCAL_VAR(SkAutoDisableOvalCheck) | |
| 60 | |
| 61 class SkAutoDisableDirectionCheck { | 45 class SkAutoDisableDirectionCheck { |
| 62 public: | 46 public: |
| 63 SkAutoDisableDirectionCheck(SkPath* path) : fPath(path) { | 47 SkAutoDisableDirectionCheck(SkPath* path) : fPath(path) { |
| 64 fSaved = static_cast<SkPath::Direction>(fPath->fDirection); | 48 fSaved = static_cast<SkPath::Direction>(fPath->fDirection); |
| 65 } | 49 } |
| 66 | 50 |
| 67 ~SkAutoDisableDirectionCheck() { | 51 ~SkAutoDisableDirectionCheck() { |
| 68 fPath->fDirection = fSaved; | 52 fPath->fDirection = fSaved; |
| 69 } | 53 } |
| 70 | 54 |
| 71 private: | 55 private: |
| 72 SkPath* fPath; | 56 SkPath* fPath; |
| 73 SkPath::Direction fSaved; | 57 SkPath::Direction fSaved; |
| 74 }; | 58 }; |
| 75 #define SkAutoDisableDirectionCheck(...) SK_REQUIRE_LOCAL_VAR(SkAutoDisableDirec
tionCheck) | 59 #define SkAutoDisableDirectionCheck(...) SK_REQUIRE_LOCAL_VAR(SkAutoDisableDirec
tionCheck) |
| 76 | 60 |
| 77 /* This guy's constructor/destructor bracket a path editing operation. It is | 61 /* This guy's constructor/destructor bracket a path editing operation. It is |
| 78 used when we know the bounds of the amount we are going to add to the path | 62 used when we know the bounds of the amount we are going to add to the path |
| 79 (usually a new contour, but not required). | 63 (usually a new contour, but not required). |
| 80 | 64 |
| 81 It captures some state about the path up front (i.e. if it already has a | 65 It captures some state about the path up front (i.e. if it already has a |
| 82 cached bounds), and then if it can, it updates the cache bounds explicitly, | 66 cached bounds), and then if it can, it updates the cache bounds explicitly, |
| 83 avoiding the need to revisit all of the points in getBounds(). | 67 avoiding the need to revisit all of the points in getBounds(). |
| 84 | 68 |
| 85 It also notes if the path was originally degenerate, and if so, sets | 69 It also notes if the path was originally degenerate, and if so, sets |
| 86 isConvex to true. Thus it can only be used if the contour being added is | 70 isConvex to true. Thus it can only be used if the contour being added is |
| 87 convex (which is always true since we only allow the addition of rects). | 71 convex. |
| 88 */ | 72 */ |
| 89 class SkAutoPathBoundsUpdate { | 73 class SkAutoPathBoundsUpdate { |
| 90 public: | 74 public: |
| 91 SkAutoPathBoundsUpdate(SkPath* path, const SkRect& r) : fRect(r) { | 75 SkAutoPathBoundsUpdate(SkPath* path, const SkRect& r) : fRect(r) { |
| 92 this->init(path); | 76 this->init(path); |
| 93 } | 77 } |
| 94 | 78 |
| 95 SkAutoPathBoundsUpdate(SkPath* path, SkScalar left, SkScalar top, | 79 SkAutoPathBoundsUpdate(SkPath* path, SkScalar left, SkScalar top, |
| 96 SkScalar right, SkScalar bottom) { | 80 SkScalar right, SkScalar bottom) { |
| 97 fRect.set(left, top, right, bottom); | 81 fRect.set(left, top, right, bottom); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 this->resetFields(); | 141 this->resetFields(); |
| 158 } | 142 } |
| 159 | 143 |
| 160 void SkPath::resetFields() { | 144 void SkPath::resetFields() { |
| 161 //fPathRef is assumed to have been emptied by the caller. | 145 //fPathRef is assumed to have been emptied by the caller. |
| 162 fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE; | 146 fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE; |
| 163 fFillType = kWinding_FillType; | 147 fFillType = kWinding_FillType; |
| 164 fSegmentMask = 0; | 148 fSegmentMask = 0; |
| 165 fConvexity = kUnknown_Convexity; | 149 fConvexity = kUnknown_Convexity; |
| 166 fDirection = kUnknown_Direction; | 150 fDirection = kUnknown_Direction; |
| 167 fIsOval = false; | |
| 168 | 151 |
| 169 // We don't touch Android's fSourcePath. It's used to track texture garbage
collection, so we | 152 // We don't touch Android's fSourcePath. It's used to track texture garbage
collection, so we |
| 170 // don't want to muck with it if it's been set to something non-NULL. | 153 // don't want to muck with it if it's been set to something non-NULL. |
| 171 } | 154 } |
| 172 | 155 |
| 173 SkPath::SkPath(const SkPath& that) | 156 SkPath::SkPath(const SkPath& that) |
| 174 : fPathRef(SkRef(that.fPathRef.get())) { | 157 : fPathRef(SkRef(that.fPathRef.get())) { |
| 175 this->copyFields(that); | 158 this->copyFields(that); |
| 176 #ifdef SK_BUILD_FOR_ANDROID | 159 #ifdef SK_BUILD_FOR_ANDROID |
| 177 fSourcePath = that.fSourcePath; | 160 fSourcePath = that.fSourcePath; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 197 return *this; | 180 return *this; |
| 198 } | 181 } |
| 199 | 182 |
| 200 void SkPath::copyFields(const SkPath& that) { | 183 void SkPath::copyFields(const SkPath& that) { |
| 201 //fPathRef is assumed to have been set by the caller. | 184 //fPathRef is assumed to have been set by the caller. |
| 202 fLastMoveToIndex = that.fLastMoveToIndex; | 185 fLastMoveToIndex = that.fLastMoveToIndex; |
| 203 fFillType = that.fFillType; | 186 fFillType = that.fFillType; |
| 204 fSegmentMask = that.fSegmentMask; | 187 fSegmentMask = that.fSegmentMask; |
| 205 fConvexity = that.fConvexity; | 188 fConvexity = that.fConvexity; |
| 206 fDirection = that.fDirection; | 189 fDirection = that.fDirection; |
| 207 fIsOval = that.fIsOval; | |
| 208 } | 190 } |
| 209 | 191 |
| 210 bool operator==(const SkPath& a, const SkPath& b) { | 192 bool operator==(const SkPath& a, const SkPath& b) { |
| 211 // note: don't need to look at isConvex or bounds, since just comparing the | 193 // note: don't need to look at isConvex or bounds, since just comparing the |
| 212 // raw data is sufficient. | 194 // raw data is sufficient. |
| 213 | 195 |
| 214 // We explicitly check fSegmentMask as a quick-reject. We could skip it, | 196 // We explicitly check fSegmentMask as a quick-reject. We could skip it, |
| 215 // since it is only a cache of info in the fVerbs, but its a fast way to | 197 // since it is only a cache of info in the fVerbs, but its a fast way to |
| 216 // notice a difference | 198 // notice a difference |
| 217 | 199 |
| 218 return &a == &b || | 200 return &a == &b || |
| 219 (a.fFillType == b.fFillType && a.fSegmentMask == b.fSegmentMask && | 201 (a.fFillType == b.fFillType && a.fSegmentMask == b.fSegmentMask && |
| 220 *a.fPathRef.get() == *b.fPathRef.get()); | 202 *a.fPathRef.get() == *b.fPathRef.get()); |
| 221 } | 203 } |
| 222 | 204 |
| 223 void SkPath::swap(SkPath& that) { | 205 void SkPath::swap(SkPath& that) { |
| 224 SkASSERT(&that != NULL); | 206 SkASSERT(&that != NULL); |
| 225 | 207 |
| 226 if (this != &that) { | 208 if (this != &that) { |
| 227 fPathRef.swap(&that.fPathRef); | 209 fPathRef.swap(&that.fPathRef); |
| 228 SkTSwap<int>(fLastMoveToIndex, that.fLastMoveToIndex); | 210 SkTSwap<int>(fLastMoveToIndex, that.fLastMoveToIndex); |
| 229 SkTSwap<uint8_t>(fFillType, that.fFillType); | 211 SkTSwap<uint8_t>(fFillType, that.fFillType); |
| 230 SkTSwap<uint8_t>(fSegmentMask, that.fSegmentMask); | 212 SkTSwap<uint8_t>(fSegmentMask, that.fSegmentMask); |
| 231 SkTSwap<uint8_t>(fConvexity, that.fConvexity); | 213 SkTSwap<uint8_t>(fConvexity, that.fConvexity); |
| 232 SkTSwap<uint8_t>(fDirection, that.fDirection); | 214 SkTSwap<uint8_t>(fDirection, that.fDirection); |
| 233 SkTSwap<SkBool8>(fIsOval, that.fIsOval); | |
| 234 #ifdef SK_BUILD_FOR_ANDROID | 215 #ifdef SK_BUILD_FOR_ANDROID |
| 235 SkTSwap<const SkPath*>(fSourcePath, that.fSourcePath); | 216 SkTSwap<const SkPath*>(fSourcePath, that.fSourcePath); |
| 236 #endif | 217 #endif |
| 237 } | 218 } |
| 238 } | 219 } |
| 239 | 220 |
| 240 static inline bool check_edge_against_rect(const SkPoint& p0, | 221 static inline bool check_edge_against_rect(const SkPoint& p0, |
| 241 const SkPoint& p1, | 222 const SkPoint& p1, |
| 242 const SkRect& rect, | 223 const SkRect& rect, |
| 243 SkPath::Direction dir) { | 224 SkPath::Direction dir) { |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 return false; | 605 return false; |
| 625 } | 606 } |
| 626 | 607 |
| 627 void SkPath::setLastPt(SkScalar x, SkScalar y) { | 608 void SkPath::setLastPt(SkScalar x, SkScalar y) { |
| 628 SkDEBUGCODE(this->validate();) | 609 SkDEBUGCODE(this->validate();) |
| 629 | 610 |
| 630 int count = fPathRef->countPoints(); | 611 int count = fPathRef->countPoints(); |
| 631 if (count == 0) { | 612 if (count == 0) { |
| 632 this->moveTo(x, y); | 613 this->moveTo(x, y); |
| 633 } else { | 614 } else { |
| 634 fIsOval = false; | |
| 635 SkPathRef::Editor ed(&fPathRef); | 615 SkPathRef::Editor ed(&fPathRef); |
| 636 ed.atPoint(count-1)->set(x, y); | 616 ed.atPoint(count-1)->set(x, y); |
| 637 } | 617 } |
| 638 } | 618 } |
| 639 | 619 |
| 640 void SkPath::setConvexity(Convexity c) { | 620 void SkPath::setConvexity(Convexity c) { |
| 641 if (fConvexity != c) { | 621 if (fConvexity != c) { |
| 642 fConvexity = c; | 622 fConvexity = c; |
| 643 } | 623 } |
| 644 } | 624 } |
| 645 | 625 |
| 646 ////////////////////////////////////////////////////////////////////////////// | 626 ////////////////////////////////////////////////////////////////////////////// |
| 647 // Construction methods | 627 // Construction methods |
| 648 | 628 |
| 649 #define DIRTY_AFTER_EDIT \ | 629 #define DIRTY_AFTER_EDIT \ |
| 650 do { \ | 630 do { \ |
| 651 fConvexity = kUnknown_Convexity; \ | 631 fConvexity = kUnknown_Convexity; \ |
| 652 fDirection = kUnknown_Direction; \ | 632 fDirection = kUnknown_Direction; \ |
| 653 fIsOval = false; \ | |
| 654 } while (0) | 633 } while (0) |
| 655 | 634 |
| 656 void SkPath::incReserve(U16CPU inc) { | 635 void SkPath::incReserve(U16CPU inc) { |
| 657 SkDEBUGCODE(this->validate();) | 636 SkDEBUGCODE(this->validate();) |
| 658 SkPathRef::Editor(&fPathRef, inc, inc); | 637 SkPathRef::Editor(&fPathRef, inc, inc); |
| 659 SkDEBUGCODE(this->validate();) | 638 SkDEBUGCODE(this->validate();) |
| 660 } | 639 } |
| 661 | 640 |
| 662 void SkPath::moveTo(SkScalar x, SkScalar y) { | 641 void SkPath::moveTo(SkScalar x, SkScalar y) { |
| 663 SkDEBUGCODE(this->validate();) | 642 SkDEBUGCODE(this->validate();) |
| (...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 | 1235 |
| 1257 void SkPath::addOval(const SkRect& oval, Direction dir) { | 1236 void SkPath::addOval(const SkRect& oval, Direction dir) { |
| 1258 assert_known_direction(dir); | 1237 assert_known_direction(dir); |
| 1259 | 1238 |
| 1260 /* If addOval() is called after previous moveTo(), | 1239 /* If addOval() is called after previous moveTo(), |
| 1261 this path is still marked as an oval. This is used to | 1240 this path is still marked as an oval. This is used to |
| 1262 fit into WebKit's calling sequences. | 1241 fit into WebKit's calling sequences. |
| 1263 We can't simply check isEmpty() in this case, as additional | 1242 We can't simply check isEmpty() in this case, as additional |
| 1264 moveTo() would mark the path non empty. | 1243 moveTo() would mark the path non empty. |
| 1265 */ | 1244 */ |
| 1266 fIsOval = hasOnlyMoveTos(); | 1245 bool isOval = hasOnlyMoveTos(); |
| 1267 if (fIsOval) { | 1246 if (isOval) { |
| 1268 fDirection = dir; | 1247 fDirection = dir; |
| 1269 } else { | 1248 } else { |
| 1270 fDirection = kUnknown_Direction; | 1249 fDirection = kUnknown_Direction; |
| 1271 } | 1250 } |
| 1272 | 1251 |
| 1273 SkAutoDisableOvalCheck adoc(this); | |
| 1274 SkAutoDisableDirectionCheck addc(this); | 1252 SkAutoDisableDirectionCheck addc(this); |
| 1275 | 1253 |
| 1276 SkAutoPathBoundsUpdate apbu(this, oval); | 1254 SkAutoPathBoundsUpdate apbu(this, oval); |
| 1277 | 1255 |
| 1278 SkScalar cx = oval.centerX(); | 1256 SkScalar cx = oval.centerX(); |
| 1279 SkScalar cy = oval.centerY(); | 1257 SkScalar cy = oval.centerY(); |
| 1280 SkScalar rx = SkScalarHalf(oval.width()); | 1258 SkScalar rx = SkScalarHalf(oval.width()); |
| 1281 SkScalar ry = SkScalarHalf(oval.height()); | 1259 SkScalar ry = SkScalarHalf(oval.height()); |
| 1282 | 1260 |
| 1283 SkScalar sx = SkScalarMul(rx, SK_ScalarTanPIOver8); | 1261 SkScalar sx = SkScalarMul(rx, SK_ScalarTanPIOver8); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1311 this->quadTo( R, cy + sy, cx + mx, cy + my); | 1289 this->quadTo( R, cy + sy, cx + mx, cy + my); |
| 1312 this->quadTo(cx + sx, B, cx , B); | 1290 this->quadTo(cx + sx, B, cx , B); |
| 1313 this->quadTo(cx - sx, B, cx - mx, cy + my); | 1291 this->quadTo(cx - sx, B, cx - mx, cy + my); |
| 1314 this->quadTo( L, cy + sy, L, cy ); | 1292 this->quadTo( L, cy + sy, L, cy ); |
| 1315 this->quadTo( L, cy - sy, cx - mx, cy - my); | 1293 this->quadTo( L, cy - sy, cx - mx, cy - my); |
| 1316 this->quadTo(cx - sx, T, cx , T); | 1294 this->quadTo(cx - sx, T, cx , T); |
| 1317 this->quadTo(cx + sx, T, cx + mx, cy - my); | 1295 this->quadTo(cx + sx, T, cx + mx, cy - my); |
| 1318 this->quadTo( R, cy - sy, R, cy ); | 1296 this->quadTo( R, cy - sy, R, cy ); |
| 1319 } | 1297 } |
| 1320 this->close(); | 1298 this->close(); |
| 1321 } | |
| 1322 | 1299 |
| 1323 bool SkPath::isOval(SkRect* rect) const { | 1300 SkPathRef::Editor ed(&fPathRef); |
| 1324 if (fIsOval && rect) { | |
| 1325 *rect = getBounds(); | |
| 1326 } | |
| 1327 | 1301 |
| 1328 return fIsOval; | 1302 ed.setIsOval(isOval); |
| 1329 } | 1303 } |
| 1330 | 1304 |
| 1331 void SkPath::addCircle(SkScalar x, SkScalar y, SkScalar r, Direction dir) { | 1305 void SkPath::addCircle(SkScalar x, SkScalar y, SkScalar r, Direction dir) { |
| 1332 if (r > 0) { | 1306 if (r > 0) { |
| 1333 SkRect rect; | 1307 SkRect rect; |
| 1334 rect.set(x - r, y - r, x + r, y + r); | 1308 rect.set(x - r, y - r, x + r, y + r); |
| 1335 this->addOval(rect, dir); | 1309 this->addOval(rect, dir); |
| 1336 } | 1310 } |
| 1337 } | 1311 } |
| 1338 | 1312 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1452 void SkPath::addPath(const SkPath& path, SkScalar dx, SkScalar dy) { | 1426 void SkPath::addPath(const SkPath& path, SkScalar dx, SkScalar dy) { |
| 1453 SkMatrix matrix; | 1427 SkMatrix matrix; |
| 1454 | 1428 |
| 1455 matrix.setTranslate(dx, dy); | 1429 matrix.setTranslate(dx, dy); |
| 1456 this->addPath(path, matrix); | 1430 this->addPath(path, matrix); |
| 1457 } | 1431 } |
| 1458 | 1432 |
| 1459 void SkPath::addPath(const SkPath& path, const SkMatrix& matrix) { | 1433 void SkPath::addPath(const SkPath& path, const SkMatrix& matrix) { |
| 1460 SkPathRef::Editor(&fPathRef, path.countVerbs(), path.countPoints()); | 1434 SkPathRef::Editor(&fPathRef, path.countVerbs(), path.countPoints()); |
| 1461 | 1435 |
| 1462 fIsOval = false; | |
| 1463 | |
| 1464 RawIter iter(path); | 1436 RawIter iter(path); |
| 1465 SkPoint pts[4]; | 1437 SkPoint pts[4]; |
| 1466 Verb verb; | 1438 Verb verb; |
| 1467 | 1439 |
| 1468 SkMatrix::MapPtsProc proc = matrix.getMapPtsProc(); | 1440 SkMatrix::MapPtsProc proc = matrix.getMapPtsProc(); |
| 1469 | 1441 |
| 1470 while ((verb = iter.next(pts)) != kDone_Verb) { | 1442 while ((verb = iter.next(pts)) != kDone_Verb) { |
| 1471 switch (verb) { | 1443 switch (verb) { |
| 1472 case kMove_Verb: | 1444 case kMove_Verb: |
| 1473 proc(matrix, &pts[0], &pts[0], 1); | 1445 proc(matrix, &pts[0], &pts[0], 1); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1518 // ignore the last point of the 1st contour | 1490 // ignore the last point of the 1st contour |
| 1519 void SkPath::reversePathTo(const SkPath& path) { | 1491 void SkPath::reversePathTo(const SkPath& path) { |
| 1520 int i, vcount = path.fPathRef->countVerbs(); | 1492 int i, vcount = path.fPathRef->countVerbs(); |
| 1521 // exit early if the path is empty, or just has a moveTo. | 1493 // exit early if the path is empty, or just has a moveTo. |
| 1522 if (vcount < 2) { | 1494 if (vcount < 2) { |
| 1523 return; | 1495 return; |
| 1524 } | 1496 } |
| 1525 | 1497 |
| 1526 SkPathRef::Editor(&fPathRef, vcount, path.countPoints()); | 1498 SkPathRef::Editor(&fPathRef, vcount, path.countPoints()); |
| 1527 | 1499 |
| 1528 fIsOval = false; | |
| 1529 | |
| 1530 const uint8_t* verbs = path.fPathRef->verbs(); | 1500 const uint8_t* verbs = path.fPathRef->verbs(); |
| 1531 const SkPoint* pts = path.fPathRef->points(); | 1501 const SkPoint* pts = path.fPathRef->points(); |
| 1532 const SkScalar* conicWeights = path.fPathRef->conicWeights(); | 1502 const SkScalar* conicWeights = path.fPathRef->conicWeights(); |
| 1533 | 1503 |
| 1534 SkASSERT(verbs[~0] == kMove_Verb); | 1504 SkASSERT(verbs[~0] == kMove_Verb); |
| 1535 for (i = 1; i < vcount; ++i) { | 1505 for (i = 1; i < vcount; ++i) { |
| 1536 unsigned v = verbs[~i]; | 1506 unsigned v = verbs[~i]; |
| 1537 int n = pts_in_verb(v); | 1507 int n = pts_in_verb(v); |
| 1538 if (n == 0) { | 1508 if (n == 0) { |
| 1539 break; | 1509 break; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1567 | 1537 |
| 1568 void SkPath::reverseAddPath(const SkPath& src) { | 1538 void SkPath::reverseAddPath(const SkPath& src) { |
| 1569 SkPathRef::Editor ed(&fPathRef, src.fPathRef->countPoints(), src.fPathRef->c
ountVerbs()); | 1539 SkPathRef::Editor ed(&fPathRef, src.fPathRef->countPoints(), src.fPathRef->c
ountVerbs()); |
| 1570 | 1540 |
| 1571 const SkPoint* pts = src.fPathRef->pointsEnd(); | 1541 const SkPoint* pts = src.fPathRef->pointsEnd(); |
| 1572 // we will iterator through src's verbs backwards | 1542 // we will iterator through src's verbs backwards |
| 1573 const uint8_t* verbs = src.fPathRef->verbsMemBegin(); // points at the last
verb | 1543 const uint8_t* verbs = src.fPathRef->verbsMemBegin(); // points at the last
verb |
| 1574 const uint8_t* verbsEnd = src.fPathRef->verbs(); // points just past the fir
st verb | 1544 const uint8_t* verbsEnd = src.fPathRef->verbs(); // points just past the fir
st verb |
| 1575 const SkScalar* conicWeights = src.fPathRef->conicWeightsEnd(); | 1545 const SkScalar* conicWeights = src.fPathRef->conicWeightsEnd(); |
| 1576 | 1546 |
| 1577 fIsOval = false; | |
| 1578 | |
| 1579 bool needMove = true; | 1547 bool needMove = true; |
| 1580 bool needClose = false; | 1548 bool needClose = false; |
| 1581 while (verbs < verbsEnd) { | 1549 while (verbs < verbsEnd) { |
| 1582 uint8_t v = *(verbs++); | 1550 uint8_t v = *(verbs++); |
| 1583 int n = pts_in_verb(v); | 1551 int n = pts_in_verb(v); |
| 1584 | 1552 |
| 1585 if (needMove) { | 1553 if (needMove) { |
| 1586 --pts; | 1554 --pts; |
| 1587 this->moveTo(pts->fX, pts->fY); | 1555 this->moveTo(pts->fX, pts->fY); |
| 1588 needMove = false; | 1556 needMove = false; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1718 if (det2x2 < 0) { | 1686 if (det2x2 < 0) { |
| 1719 dst->fDirection = SkPath::OppositeDirection(static_cast<Directio
n>(fDirection)); | 1687 dst->fDirection = SkPath::OppositeDirection(static_cast<Directio
n>(fDirection)); |
| 1720 } else if (det2x2 > 0) { | 1688 } else if (det2x2 > 0) { |
| 1721 dst->fDirection = fDirection; | 1689 dst->fDirection = fDirection; |
| 1722 } else { | 1690 } else { |
| 1723 dst->fConvexity = kUnknown_Convexity; | 1691 dst->fConvexity = kUnknown_Convexity; |
| 1724 dst->fDirection = kUnknown_Direction; | 1692 dst->fDirection = kUnknown_Direction; |
| 1725 } | 1693 } |
| 1726 } | 1694 } |
| 1727 | 1695 |
| 1728 // It's an oval only if it stays a rect. | |
| 1729 dst->fIsOval = fIsOval && matrix.rectStaysRect(); | |
| 1730 | |
| 1731 SkDEBUGCODE(dst->validate();) | 1696 SkDEBUGCODE(dst->validate();) |
| 1732 } | 1697 } |
| 1733 } | 1698 } |
| 1734 | 1699 |
| 1735 /////////////////////////////////////////////////////////////////////////////// | 1700 /////////////////////////////////////////////////////////////////////////////// |
| 1736 /////////////////////////////////////////////////////////////////////////////// | 1701 /////////////////////////////////////////////////////////////////////////////// |
| 1737 | 1702 |
| 1738 enum SegmentState { | 1703 enum SegmentState { |
| 1739 kEmptyContour_SegmentState, // The current contour is empty. We may be | 1704 kEmptyContour_SegmentState, // The current contour is empty. We may be |
| 1740 // starting processing or we may have just | 1705 // starting processing or we may have just |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2073 size_t SkPath::writeToMemory(void* storage) const { | 2038 size_t SkPath::writeToMemory(void* storage) const { |
| 2074 SkDEBUGCODE(this->validate();) | 2039 SkDEBUGCODE(this->validate();) |
| 2075 | 2040 |
| 2076 if (NULL == storage) { | 2041 if (NULL == storage) { |
| 2077 const int byteCount = sizeof(int32_t) + fPathRef->writeSize(); | 2042 const int byteCount = sizeof(int32_t) + fPathRef->writeSize(); |
| 2078 return SkAlign4(byteCount); | 2043 return SkAlign4(byteCount); |
| 2079 } | 2044 } |
| 2080 | 2045 |
| 2081 SkWBuffer buffer(storage); | 2046 SkWBuffer buffer(storage); |
| 2082 | 2047 |
| 2083 int32_t packed = ((fIsOval & 1) << kIsOval_SerializationShift) | | 2048 int32_t packed = (fConvexity << kConvexity_SerializationShift) | |
| 2084 (fConvexity << kConvexity_SerializationShift) | | |
| 2085 (fFillType << kFillType_SerializationShift) | | 2049 (fFillType << kFillType_SerializationShift) | |
| 2086 (fSegmentMask << kSegmentMask_SerializationShift) | | 2050 (fSegmentMask << kSegmentMask_SerializationShift) | |
| 2087 (fDirection << kDirection_SerializationShift) | 2051 (fDirection << kDirection_SerializationShift) |
| 2088 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O | 2052 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O |
| 2089 | (0x1 << kNewFormat_SerializationShift) | 2053 | (0x1 << kNewFormat_SerializationShift) |
| 2090 #endif | 2054 #endif |
| 2055 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TO
O |
| 2056 | (0x1 << kNewFormat2_SerializationShift) |
| 2057 #endif |
| 2091 ; | 2058 ; |
| 2092 | 2059 |
| 2093 buffer.write32(packed); | 2060 buffer.write32(packed); |
| 2094 | 2061 |
| 2095 fPathRef->writeToBuffer(&buffer); | 2062 fPathRef->writeToBuffer(&buffer); |
| 2096 | 2063 |
| 2097 buffer.padToAlign4(); | 2064 buffer.padToAlign4(); |
| 2098 return buffer.pos(); | 2065 return buffer.pos(); |
| 2099 } | 2066 } |
| 2100 | 2067 |
| 2101 size_t SkPath::readFromMemory(const void* storage, size_t length) { | 2068 size_t SkPath::readFromMemory(const void* storage, size_t length) { |
| 2102 SkRBufferWithSizeCheck buffer(storage, length); | 2069 SkRBufferWithSizeCheck buffer(storage, length); |
| 2103 | 2070 |
| 2104 int32_t packed; | 2071 int32_t packed; |
| 2105 if (!buffer.readS32(&packed)) { | 2072 if (!buffer.readS32(&packed)) { |
| 2106 return 0; | 2073 return 0; |
| 2107 } | 2074 } |
| 2108 | 2075 |
| 2109 fIsOval = (packed >> kIsOval_SerializationShift) & 1; | |
| 2110 fConvexity = (packed >> kConvexity_SerializationShift) & 0xFF; | 2076 fConvexity = (packed >> kConvexity_SerializationShift) & 0xFF; |
| 2111 fFillType = (packed >> kFillType_SerializationShift) & 0xFF; | 2077 fFillType = (packed >> kFillType_SerializationShift) & 0xFF; |
| 2112 fSegmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF; | 2078 fSegmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF; |
| 2113 fDirection = (packed >> kDirection_SerializationShift) & 0x3; | 2079 fDirection = (packed >> kDirection_SerializationShift) & 0x3; |
| 2114 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O | 2080 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TO
O |
| 2115 bool newFormat = (packed >> kNewFormat_SerializationShift) & 1; | 2081 bool newFormat = (packed >> kNewFormat2_SerializationShift) & 1; |
| 2116 #endif | 2082 #endif |
| 2117 | 2083 |
| 2118 SkPathRef* pathRef = SkPathRef::CreateFromBuffer(&buffer | 2084 SkPathRef* pathRef = SkPathRef::CreateFromBuffer(&buffer |
| 2119 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O | 2085 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TO
O |
| 2120 , newFormat, packed | 2086 , newFormat, packed |
| 2121 #endif | 2087 #endif |
| 2122 ); | 2088 ); |
| 2123 | 2089 |
| 2124 size_t sizeRead = 0; | 2090 size_t sizeRead = 0; |
| 2125 if (buffer.isValid()) { | 2091 if (buffer.isValid()) { |
| 2126 fPathRef.reset(pathRef); | 2092 fPathRef.reset(pathRef); |
| 2127 SkDEBUGCODE(this->validate();) | 2093 SkDEBUGCODE(this->validate();) |
| 2128 buffer.skipToAlign4(); | 2094 buffer.skipToAlign4(); |
| 2129 sizeRead = buffer.pos(); | 2095 sizeRead = buffer.pos(); |
| (...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2941 switch (this->getFillType()) { | 2907 switch (this->getFillType()) { |
| 2942 case SkPath::kEvenOdd_FillType: | 2908 case SkPath::kEvenOdd_FillType: |
| 2943 case SkPath::kInverseEvenOdd_FillType: | 2909 case SkPath::kInverseEvenOdd_FillType: |
| 2944 w &= 1; | 2910 w &= 1; |
| 2945 break; | 2911 break; |
| 2946 default: | 2912 default: |
| 2947 break; | 2913 break; |
| 2948 } | 2914 } |
| 2949 return SkToBool(w); | 2915 return SkToBool(w); |
| 2950 } | 2916 } |
| OLD | NEW |