Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: src/core/SkPath.cpp

Issue 24350006: Move bound and isFinite into pathref (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Added TODO Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/core/SkPicture.h ('k') | src/core/SkPathRef.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 private: 70 private:
71 SkPath* fPath; 71 SkPath* fPath;
72 SkPath::Direction fSaved; 72 SkPath::Direction fSaved;
73 }; 73 };
74 74
75 /* This guy's constructor/destructor bracket a path editing operation. It is 75 /* This guy's constructor/destructor bracket a path editing operation. It is
76 used when we know the bounds of the amount we are going to add to the path 76 used when we know the bounds of the amount we are going to add to the path
77 (usually a new contour, but not required). 77 (usually a new contour, but not required).
78 78
79 It captures some state about the path up front (i.e. if it already has a 79 It captures some state about the path up front (i.e. if it already has a
80 cached bounds), and the if it can, it updates the cache bounds explicitly, 80 cached bounds), and then if it can, it updates the cache bounds explicitly,
81 avoiding the need to revisit all of the points in getBounds(). 81 avoiding the need to revisit all of the points in getBounds().
82 82
83 It also notes if the path was originally degenerate, and if so, sets 83 It also notes if the path was originally degenerate, and if so, sets
84 isConvex to true. Thus it can only be used if the contour being added is 84 isConvex to true. Thus it can only be used if the contour being added is
85 convex. 85 convex (which is always true since we only allow the addition of rects).
86 */ 86 */
87 class SkAutoPathBoundsUpdate { 87 class SkAutoPathBoundsUpdate {
88 public: 88 public:
89 SkAutoPathBoundsUpdate(SkPath* path, const SkRect& r) : fRect(r) { 89 SkAutoPathBoundsUpdate(SkPath* path, const SkRect& r) : fRect(r) {
90 this->init(path); 90 this->init(path);
91 } 91 }
92 92
93 SkAutoPathBoundsUpdate(SkPath* path, SkScalar left, SkScalar top, 93 SkAutoPathBoundsUpdate(SkPath* path, SkScalar left, SkScalar top,
94 SkScalar right, SkScalar bottom) { 94 SkScalar right, SkScalar bottom) {
95 fRect.set(left, top, right, bottom); 95 fRect.set(left, top, right, bottom);
96 this->init(path); 96 this->init(path);
97 } 97 }
98 98
99 ~SkAutoPathBoundsUpdate() { 99 ~SkAutoPathBoundsUpdate() {
100 fPath->setIsConvex(fDegenerate); 100 fPath->setIsConvex(fDegenerate);
101 if (fEmpty) { 101 if (fEmpty || fHasValidBounds) {
102 fPath->fBounds = fRect; 102 fPath->setBounds(fRect);
103 fPath->fBoundsIsDirty = false;
104 fPath->fIsFinite = fPath->fBounds.isFinite();
105 } else if (!fDirty) {
106 joinNoEmptyChecks(&fPath->fBounds, fRect);
107 fPath->fBoundsIsDirty = false;
108 fPath->fIsFinite = fPath->fBounds.isFinite();
109 } 103 }
110 } 104 }
111 105
112 private: 106 private:
113 SkPath* fPath; 107 SkPath* fPath;
114 SkRect fRect; 108 SkRect fRect;
115 bool fDirty; 109 bool fHasValidBounds;
116 bool fDegenerate; 110 bool fDegenerate;
117 bool fEmpty; 111 bool fEmpty;
118 112
119 // returns true if we should proceed
120 void init(SkPath* path) { 113 void init(SkPath* path) {
114 // Cannot use fRect for our bounds unless we know it is sorted
115 fRect.sort();
121 fPath = path; 116 fPath = path;
122 // Mark the path's bounds as dirty if (1) they are, or (2) the path 117 // Mark the path's bounds as dirty if (1) they are, or (2) the path
123 // is non-finite, and therefore its bounds are not meaningful 118 // is non-finite, and therefore its bounds are not meaningful
124 fDirty = SkToBool(path->fBoundsIsDirty) || !path->fIsFinite; 119 fHasValidBounds = path->hasComputedBounds() && path->isFinite();
120 fEmpty = path->isEmpty();
121 if (fHasValidBounds && !fEmpty) {
122 joinNoEmptyChecks(&fRect, fPath->getBounds());
123 }
125 fDegenerate = is_degenerate(*path); 124 fDegenerate = is_degenerate(*path);
126 fEmpty = path->isEmpty();
127 // Cannot use fRect for our bounds unless we know it is sorted
128 fRect.sort();
129 } 125 }
130 }; 126 };
131 127
132 // Return true if the computed bounds are finite.
133 static bool compute_pt_bounds(SkRect* bounds, const SkPathRef& ref) {
134 int count = ref.countPoints();
135 if (count <= 1) { // we ignore just 1 point (moveto)
136 bounds->setEmpty();
137 return count ? ref.points()->isFinite() : true;
138 } else {
139 return bounds->setBoundsCheck(ref.points(), count);
140 }
141 }
142
143 //////////////////////////////////////////////////////////////////////////// 128 ////////////////////////////////////////////////////////////////////////////
144 129
145 /* 130 /*
146 Stores the verbs and points as they are given to us, with exceptions: 131 Stores the verbs and points as they are given to us, with exceptions:
147 - we only record "Close" if it was immediately preceeded by Move | Line | Qu ad | Cubic 132 - we only record "Close" if it was immediately preceeded by Move | Line | Qu ad | Cubic
148 - we insert a Move(0,0) if Line | Quad | Cubic is our first command 133 - we insert a Move(0,0) if Line | Quad | Cubic is our first command
149 134
150 The iterator does more cleanup, especially if forceClose == true 135 The iterator does more cleanup, especially if forceClose == true
151 1. If we encounter degenerate segments, remove them 136 1. If we encounter degenerate segments, remove them
152 2. if we encounter Close, return a cons'd up Line() first (if the curr-pt != start-pt) 137 2. if we encounter Close, return a cons'd up Line() first (if the curr-pt != start-pt)
(...skipping 13 matching lines...) Expand all
166 #endif 151 #endif
167 { 152 {
168 this->resetFields(); 153 this->resetFields();
169 } 154 }
170 155
171 void SkPath::resetFields() { 156 void SkPath::resetFields() {
172 //fPathRef is assumed to have been emptied by the caller. 157 //fPathRef is assumed to have been emptied by the caller.
173 fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE; 158 fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE;
174 fFillType = kWinding_FillType; 159 fFillType = kWinding_FillType;
175 fSegmentMask = 0; 160 fSegmentMask = 0;
176 fBoundsIsDirty = true;
177 fConvexity = kUnknown_Convexity; 161 fConvexity = kUnknown_Convexity;
178 fDirection = kUnknown_Direction; 162 fDirection = kUnknown_Direction;
179 fIsFinite = false;
180 fIsOval = false; 163 fIsOval = false;
181 #ifdef SK_BUILD_FOR_ANDROID 164 #ifdef SK_BUILD_FOR_ANDROID
182 GEN_ID_INC; 165 GEN_ID_INC;
183 // We don't touch fSourcePath. It's used to track texture garbage collectio n, so we don't 166 // We don't touch fSourcePath. It's used to track texture garbage collectio n, so we don't
184 // want to muck with it if it's been set to something non-NULL. 167 // want to muck with it if it's been set to something non-NULL.
185 #endif 168 #endif
186 } 169 }
187 170
188 SkPath::SkPath(const SkPath& that) 171 SkPath::SkPath(const SkPath& that)
189 : fPathRef(SkRef(that.fPathRef.get())) { 172 : fPathRef(SkRef(that.fPathRef.get())) {
(...skipping 19 matching lines...) Expand all
209 GEN_ID_INC; // Similar to swap, we can't just copy this or it could go back in time. 192 GEN_ID_INC; // Similar to swap, we can't just copy this or it could go back in time.
210 fSourcePath = that.fSourcePath; 193 fSourcePath = that.fSourcePath;
211 #endif 194 #endif
212 } 195 }
213 SkDEBUGCODE(this->validate();) 196 SkDEBUGCODE(this->validate();)
214 return *this; 197 return *this;
215 } 198 }
216 199
217 void SkPath::copyFields(const SkPath& that) { 200 void SkPath::copyFields(const SkPath& that) {
218 //fPathRef is assumed to have been set by the caller. 201 //fPathRef is assumed to have been set by the caller.
219 fBounds = that.fBounds;
220 fLastMoveToIndex = that.fLastMoveToIndex; 202 fLastMoveToIndex = that.fLastMoveToIndex;
221 fFillType = that.fFillType; 203 fFillType = that.fFillType;
222 fSegmentMask = that.fSegmentMask; 204 fSegmentMask = that.fSegmentMask;
223 fBoundsIsDirty = that.fBoundsIsDirty;
224 fConvexity = that.fConvexity; 205 fConvexity = that.fConvexity;
225 fDirection = that.fDirection; 206 fDirection = that.fDirection;
226 fIsFinite = that.fIsFinite;
227 fIsOval = that.fIsOval; 207 fIsOval = that.fIsOval;
228 } 208 }
229 209
230 bool operator==(const SkPath& a, const SkPath& b) { 210 bool operator==(const SkPath& a, const SkPath& b) {
231 // note: don't need to look at isConvex or bounds, since just comparing the 211 // note: don't need to look at isConvex or bounds, since just comparing the
232 // raw data is sufficient. 212 // raw data is sufficient.
233 213
234 // We explicitly check fSegmentMask as a quick-reject. We could skip it, 214 // We explicitly check fSegmentMask as a quick-reject. We could skip it,
235 // since it is only a cache of info in the fVerbs, but its a fast way to 215 // since it is only a cache of info in the fVerbs, but its a fast way to
236 // notice a difference 216 // notice a difference
237 217
238 return &a == &b || 218 return &a == &b ||
239 (a.fFillType == b.fFillType && a.fSegmentMask == b.fSegmentMask && 219 (a.fFillType == b.fFillType && a.fSegmentMask == b.fSegmentMask &&
240 *a.fPathRef.get() == *b.fPathRef.get()); 220 *a.fPathRef.get() == *b.fPathRef.get());
241 } 221 }
242 222
243 void SkPath::swap(SkPath& that) { 223 void SkPath::swap(SkPath& that) {
244 SkASSERT(&that != NULL); 224 SkASSERT(&that != NULL);
245 225
246 if (this != &that) { 226 if (this != &that) {
247 fPathRef.swap(&that.fPathRef); 227 fPathRef.swap(&that.fPathRef);
248 SkTSwap<SkRect>(fBounds, that.fBounds);
249 SkTSwap<int>(fLastMoveToIndex, that.fLastMoveToIndex); 228 SkTSwap<int>(fLastMoveToIndex, that.fLastMoveToIndex);
250 SkTSwap<uint8_t>(fFillType, that.fFillType); 229 SkTSwap<uint8_t>(fFillType, that.fFillType);
251 SkTSwap<uint8_t>(fSegmentMask, that.fSegmentMask); 230 SkTSwap<uint8_t>(fSegmentMask, that.fSegmentMask);
252 SkTSwap<uint8_t>(fBoundsIsDirty, that.fBoundsIsDirty);
253 SkTSwap<uint8_t>(fConvexity, that.fConvexity); 231 SkTSwap<uint8_t>(fConvexity, that.fConvexity);
254 SkTSwap<uint8_t>(fDirection, that.fDirection); 232 SkTSwap<uint8_t>(fDirection, that.fDirection);
255 SkTSwap<SkBool8>(fIsFinite, that.fIsFinite);
256 SkTSwap<SkBool8>(fIsOval, that.fIsOval); 233 SkTSwap<SkBool8>(fIsOval, that.fIsOval);
257 #ifdef SK_BUILD_FOR_ANDROID 234 #ifdef SK_BUILD_FOR_ANDROID
258 // It doesn't really make sense to swap the generation IDs here, because they might go 235 // It doesn't really make sense to swap the generation IDs here, because they might go
259 // backwards. To be safe we increment both to mark them both as changed . 236 // backwards. To be safe we increment both to mark them both as changed .
260 GEN_ID_INC; 237 GEN_ID_INC;
261 GEN_ID_PTR_INC(&that); 238 GEN_ID_PTR_INC(&that);
262 SkTSwap<const SkPath*>(fSourcePath, that.fSourcePath); 239 SkTSwap<const SkPath*>(fSourcePath, that.fSourcePath);
263 #endif 240 #endif
264 } 241 }
265 } 242 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 this->resetFields(); 349 this->resetFields();
373 } 350 }
374 351
375 void SkPath::rewind() { 352 void SkPath::rewind() {
376 SkDEBUGCODE(this->validate();) 353 SkDEBUGCODE(this->validate();)
377 354
378 SkPathRef::Rewind(&fPathRef); 355 SkPathRef::Rewind(&fPathRef);
379 this->resetFields(); 356 this->resetFields();
380 } 357 }
381 358
382 bool SkPath::isEmpty() const {
383 SkDEBUGCODE(this->validate();)
384 return 0 == fPathRef->countVerbs();
385 }
386
387 bool SkPath::isLine(SkPoint line[2]) const { 359 bool SkPath::isLine(SkPoint line[2]) const {
388 int verbCount = fPathRef->countVerbs(); 360 int verbCount = fPathRef->countVerbs();
389 361
390 if (2 == verbCount) { 362 if (2 == verbCount) {
391 SkASSERT(kMove_Verb == fPathRef->atVerb(0)); 363 SkASSERT(kMove_Verb == fPathRef->atVerb(0));
392 if (kLine_Verb == fPathRef->atVerb(1)) { 364 if (kLine_Verb == fPathRef->atVerb(1)) {
393 SkASSERT(2 == fPathRef->countPoints()); 365 SkASSERT(2 == fPathRef->countPoints());
394 if (line) { 366 if (line) {
395 const SkPoint* pts = fPathRef->points(); 367 const SkPoint* pts = fPathRef->points();
396 line[0] = pts[0]; 368 line[0] = pts[0];
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 if (count == 0) { 630 if (count == 0) {
659 this->moveTo(x, y); 631 this->moveTo(x, y);
660 } else { 632 } else {
661 fIsOval = false; 633 fIsOval = false;
662 SkPathRef::Editor ed(&fPathRef); 634 SkPathRef::Editor ed(&fPathRef);
663 ed.atPoint(count-1)->set(x, y); 635 ed.atPoint(count-1)->set(x, y);
664 GEN_ID_INC; 636 GEN_ID_INC;
665 } 637 }
666 } 638 }
667 639
668 void SkPath::computeBounds() const {
669 SkDEBUGCODE(this->validate();)
670 SkASSERT(fBoundsIsDirty);
671
672 fIsFinite = compute_pt_bounds(&fBounds, *fPathRef.get());
673 fBoundsIsDirty = false;
674 }
675
676 void SkPath::setConvexity(Convexity c) { 640 void SkPath::setConvexity(Convexity c) {
677 if (fConvexity != c) { 641 if (fConvexity != c) {
678 fConvexity = c; 642 fConvexity = c;
679 GEN_ID_INC; 643 GEN_ID_INC;
680 } 644 }
681 } 645 }
682 646
683 ////////////////////////////////////////////////////////////////////////////// 647 //////////////////////////////////////////////////////////////////////////////
684 // Construction methods 648 // Construction methods
685 649
686 #define DIRTY_AFTER_EDIT \ 650 #define DIRTY_AFTER_EDIT \
687 do { \ 651 do { \
688 fBoundsIsDirty = true; \
689 fConvexity = kUnknown_Convexity; \ 652 fConvexity = kUnknown_Convexity; \
690 fDirection = kUnknown_Direction; \ 653 fDirection = kUnknown_Direction; \
691 fIsOval = false; \ 654 fIsOval = false; \
692 } while (0) 655 } while (0)
693 656
694 #define DIRTY_AFTER_EDIT_NO_CONVEXITY_OR_DIRECTION_CHANGE \
695 do { \
696 fBoundsIsDirty = true; \
697 } while (0)
698
699 void SkPath::incReserve(U16CPU inc) { 657 void SkPath::incReserve(U16CPU inc) {
700 SkDEBUGCODE(this->validate();) 658 SkDEBUGCODE(this->validate();)
701 SkPathRef::Editor(&fPathRef, inc, inc); 659 SkPathRef::Editor(&fPathRef, inc, inc);
702 SkDEBUGCODE(this->validate();) 660 SkDEBUGCODE(this->validate();)
703 } 661 }
704 662
705 void SkPath::moveTo(SkScalar x, SkScalar y) { 663 void SkPath::moveTo(SkScalar x, SkScalar y) {
706 SkDEBUGCODE(this->validate();) 664 SkDEBUGCODE(this->validate();)
707 665
708 SkPathRef::Editor ed(&fPathRef); 666 SkPathRef::Editor ed(&fPathRef);
709 667
710 // remember our index 668 // remember our index
711 fLastMoveToIndex = ed.pathRef()->countPoints(); 669 fLastMoveToIndex = ed.pathRef()->countPoints();
712 670
713 ed.growForVerb(kMove_Verb)->set(x, y); 671 ed.growForVerb(kMove_Verb)->set(x, y);
714 672
715 GEN_ID_INC; 673 GEN_ID_INC;
716 DIRTY_AFTER_EDIT_NO_CONVEXITY_OR_DIRECTION_CHANGE;
717 } 674 }
718 675
719 void SkPath::rMoveTo(SkScalar x, SkScalar y) { 676 void SkPath::rMoveTo(SkScalar x, SkScalar y) {
720 SkPoint pt; 677 SkPoint pt;
721 this->getLastPt(&pt); 678 this->getLastPt(&pt);
722 this->moveTo(pt.fX + x, pt.fY + y); 679 this->moveTo(pt.fX + x, pt.fY + y);
723 } 680 }
724 681
725 void SkPath::injectMoveToIfNeeded() { 682 void SkPath::injectMoveToIfNeeded() {
726 if (fLastMoveToIndex < 0) { 683 if (fLastMoveToIndex < 0) {
(...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 SkDEBUGFAIL("unknown verb"); 1632 SkDEBUGFAIL("unknown verb");
1676 break; 1633 break;
1677 } 1634 }
1678 } 1635 }
1679 1636
1680 dst->swap(tmp); 1637 dst->swap(tmp);
1681 SkPathRef::Editor ed(&dst->fPathRef); 1638 SkPathRef::Editor ed(&dst->fPathRef);
1682 matrix.mapPoints(ed.points(), ed.pathRef()->countPoints()); 1639 matrix.mapPoints(ed.points(), ed.pathRef()->countPoints());
1683 dst->fDirection = kUnknown_Direction; 1640 dst->fDirection = kUnknown_Direction;
1684 } else { 1641 } else {
1685 /*
1686 * If we're not in perspective, we can transform all of the points at
1687 * once.
1688 *
1689 * Here we also want to optimize bounds, by noting if the bounds are
1690 * already known, and if so, we just transform those as well and mark
1691 * them as "known", rather than force the transformed path to have to
1692 * recompute them.
1693 *
1694 * Special gotchas if the path is effectively empty (<= 1 point) or
1695 * if it is non-finite. In those cases bounds need to stay empty,
1696 * regardless of the matrix.
1697 */
1698 if (!fBoundsIsDirty && matrix.rectStaysRect() && fPathRef->countPoints() > 1) {
1699 dst->fBoundsIsDirty = false;
1700 if (fIsFinite) {
1701 matrix.mapRect(&dst->fBounds, fBounds);
1702 if (!(dst->fIsFinite = dst->fBounds.isFinite())) {
1703 dst->fBounds.setEmpty();
1704 }
1705 } else {
1706 dst->fIsFinite = false;
1707 dst->fBounds.setEmpty();
1708 }
1709 } else {
1710 GEN_ID_PTR_INC(dst);
1711 dst->fBoundsIsDirty = true;
1712 }
1713
1714 SkPathRef::CreateTransformedCopy(&dst->fPathRef, *fPathRef.get(), matrix ); 1642 SkPathRef::CreateTransformedCopy(&dst->fPathRef, *fPathRef.get(), matrix );
1715 1643
1716 if (this != dst) { 1644 if (this != dst) {
1717 dst->fFillType = fFillType; 1645 dst->fFillType = fFillType;
1718 dst->fSegmentMask = fSegmentMask; 1646 dst->fSegmentMask = fSegmentMask;
1719 dst->fConvexity = fConvexity; 1647 dst->fConvexity = fConvexity;
1720 } 1648 }
1721 1649
1722 #ifdef SK_BUILD_FOR_ANDROID 1650 #ifdef SK_BUILD_FOR_ANDROID
1723 if (!matrix.isIdentity()) { 1651 if (!matrix.isIdentity() && !dst->hasComputedBounds()) {
1724 GEN_ID_PTR_INC(dst); 1652 GEN_ID_PTR_INC(dst);
1725 } 1653 }
1726 #endif 1654 #endif
1727 1655
1728 if (kUnknown_Direction == fDirection) { 1656 if (kUnknown_Direction == fDirection) {
1729 dst->fDirection = kUnknown_Direction; 1657 dst->fDirection = kUnknown_Direction;
1730 } else { 1658 } else {
1731 SkScalar det2x2 = 1659 SkScalar det2x2 =
1732 SkScalarMul(matrix.get(SkMatrix::kMScaleX), matrix.get(SkMatrix: :kMScaleY)) - 1660 SkScalarMul(matrix.get(SkMatrix::kMScaleX), matrix.get(SkMatrix: :kMScaleY)) -
1733 SkScalarMul(matrix.get(SkMatrix::kMSkewX), matrix.get(SkMatrix:: kMSkewY)); 1661 SkScalarMul(matrix.get(SkMatrix::kMSkewX), matrix.get(SkMatrix:: kMSkewY));
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
2082 /////////////////////////////////////////////////////////////////////////////// 2010 ///////////////////////////////////////////////////////////////////////////////
2083 2011
2084 /* 2012 /*
2085 Format in compressed buffer: [ptCount, verbCount, pts[], verbs[]] 2013 Format in compressed buffer: [ptCount, verbCount, pts[], verbs[]]
2086 */ 2014 */
2087 2015
2088 uint32_t SkPath::writeToMemory(void* storage) const { 2016 uint32_t SkPath::writeToMemory(void* storage) const {
2089 SkDEBUGCODE(this->validate();) 2017 SkDEBUGCODE(this->validate();)
2090 2018
2091 if (NULL == storage) { 2019 if (NULL == storage) {
2092 const int byteCount = sizeof(int32_t) 2020 const int byteCount = sizeof(int32_t) + fPathRef->writeSize();
2093 + fPathRef->writeSize()
2094 + sizeof(SkRect);
2095 return SkAlign4(byteCount); 2021 return SkAlign4(byteCount);
2096 } 2022 }
2097 2023
2098 SkWBuffer buffer(storage); 2024 SkWBuffer buffer(storage);
2099 2025
2100 // Call getBounds() to ensure (as a side-effect) that fBounds 2026 int32_t packed = ((fIsOval & 1) << kIsOval_SerializationShift) |
2101 // and fIsFinite are computed.
2102 const SkRect& bounds = this->getBounds();
2103 SkASSERT(!fBoundsIsDirty);
2104
2105 int32_t packed = ((fIsFinite & 1) << kIsFinite_SerializationShift) |
2106 ((fIsOval & 1) << kIsOval_SerializationShift) |
2107 (fConvexity << kConvexity_SerializationShift) | 2027 (fConvexity << kConvexity_SerializationShift) |
2108 (fFillType << kFillType_SerializationShift) | 2028 (fFillType << kFillType_SerializationShift) |
2109 (fSegmentMask << kSegmentMask_SerializationShift) | 2029 (fSegmentMask << kSegmentMask_SerializationShift) |
2110 (fDirection << kDirection_SerializationShift); 2030 (fDirection << kDirection_SerializationShift)
2031 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO O
2032 | (0x1 << kNewFormat_SerializationShift);
2033 #endif
2111 2034
2112 buffer.write32(packed); 2035 buffer.write32(packed);
2113 2036
2114 fPathRef->writeToBuffer(&buffer); 2037 fPathRef->writeToBuffer(&buffer);
2115 2038
2116 buffer.write(&bounds, sizeof(bounds));
2117
2118 buffer.padToAlign4(); 2039 buffer.padToAlign4();
2119 return SkToU32(buffer.pos()); 2040 return SkToU32(buffer.pos());
2120 } 2041 }
2121 2042
2122 uint32_t SkPath::readFromMemory(const void* storage) { 2043 uint32_t SkPath::readFromMemory(const void* storage) {
2123 SkRBuffer buffer(storage); 2044 SkRBuffer buffer(storage);
2124 2045
2125 uint32_t packed = buffer.readS32(); 2046 uint32_t packed = buffer.readS32();
2126 fIsFinite = (packed >> kIsFinite_SerializationShift) & 1;
2127 fIsOval = (packed >> kIsOval_SerializationShift) & 1; 2047 fIsOval = (packed >> kIsOval_SerializationShift) & 1;
2128 fConvexity = (packed >> kConvexity_SerializationShift) & 0xFF; 2048 fConvexity = (packed >> kConvexity_SerializationShift) & 0xFF;
2129 fFillType = (packed >> kFillType_SerializationShift) & 0xFF; 2049 fFillType = (packed >> kFillType_SerializationShift) & 0xFF;
2130 fSegmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF; 2050 fSegmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF;
2131 fDirection = (packed >> kDirection_SerializationShift) & 0x3; 2051 fDirection = (packed >> kDirection_SerializationShift) & 0x3;
2052 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO O
2053 bool newFormat = (packed >> kNewFormat_SerializationShift) & 1;
2054 #endif
2132 2055
2133 fPathRef.reset(SkPathRef::CreateFromBuffer(&buffer)); 2056 fPathRef.reset(SkPathRef::CreateFromBuffer(&buffer
2134 2057 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO O
2135 buffer.read(&fBounds, sizeof(fBounds)); 2058 , newFormat, packed)
2136 fBoundsIsDirty = false; 2059 #endif
2060 );
2137 2061
2138 buffer.skipToAlign4(); 2062 buffer.skipToAlign4();
2139 2063
2140 GEN_ID_INC; 2064 GEN_ID_INC;
2141 2065
2142 SkDEBUGCODE(this->validate();) 2066 SkDEBUGCODE(this->validate();)
2143 return SkToU32(buffer.pos()); 2067 return SkToU32(buffer.pos());
2144 } 2068 }
2145 2069
2146 /////////////////////////////////////////////////////////////////////////////// 2070 ///////////////////////////////////////////////////////////////////////////////
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after
3005 switch (this->getFillType()) { 2929 switch (this->getFillType()) {
3006 case SkPath::kEvenOdd_FillType: 2930 case SkPath::kEvenOdd_FillType:
3007 case SkPath::kInverseEvenOdd_FillType: 2931 case SkPath::kInverseEvenOdd_FillType:
3008 w &= 1; 2932 w &= 1;
3009 break; 2933 break;
3010 default: 2934 default:
3011 break; 2935 break;
3012 } 2936 }
3013 return SkToBool(w); 2937 return SkToBool(w);
3014 } 2938 }
OLDNEW
« no previous file with comments | « include/core/SkPicture.h ('k') | src/core/SkPathRef.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698