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 |