OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 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 | 8 |
9 #ifndef SkPathRef_DEFINED | 9 #ifndef SkPathRef_DEFINED |
10 #define SkPathRef_DEFINED | 10 #define SkPathRef_DEFINED |
11 | 11 |
12 #include "SkMatrix.h" | 12 #include "SkMatrix.h" |
13 #include "SkPoint.h" | 13 #include "SkPoint.h" |
14 #include "SkRect.h" | 14 #include "SkRect.h" |
15 #include "SkRefCnt.h" | 15 #include "SkRefCnt.h" |
16 #include "SkTDArray.h" | 16 #include "SkTDArray.h" |
17 #include <stddef.h> // ptrdiff_t | 17 #include <stddef.h> // ptrdiff_t |
18 | 18 |
19 class SkRBuffer; | 19 class SkRBuffer; |
20 class SkWBuffer; | 20 class SkWBuffer; |
21 | 21 |
22 /** | 22 /** |
23 * Holds the path verbs and points. It is versioned by a generation ID. None of
its public methods | 23 * Holds the path verbs and points. It is versioned by a generation ID. None of
its public methods |
24 * modify the contents. To modify or append to the verbs/points wrap the SkPathR
ef in an | 24 * modify the contents. To modify or append to the verbs/points wrap the SkPathR
ef in an |
25 * SkPathRef::Editor object. Installing the editor resets the generation ID. It
also performs | 25 * SkPathRef::Editor object. Installing the editor resets the generation ID. It
also performs |
26 * copy-on-write if the SkPathRef is shared by multipls SkPaths. The caller pass
es the Editor's | 26 * copy-on-write if the SkPathRef is shared by multiple SkPaths. The caller pass
es the Editor's |
27 * constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef
after the editor's | 27 * constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef
after the editor's |
28 * constructor returns. | 28 * constructor returns. |
29 * | 29 * |
30 * The points and verbs are stored in a single allocation. The points are at the
begining of the | 30 * The points and verbs are stored in a single allocation. The points are at the
begining of the |
31 * allocation while the verbs are stored at end of the allocation, in reverse or
der. Thus the points | 31 * allocation while the verbs are stored at end of the allocation, in reverse or
der. Thus the points |
32 * and verbs both grow into the middle of the allocation until the meet. To acce
ss verb i in the | 32 * and verbs both grow into the middle of the allocation until the meet. To acce
ss verb i in the |
33 * verb array use ref.verbs()[~i] (because verbs() returns a pointer just beyond
the first | 33 * verb array use ref.verbs()[~i] (because verbs() returns a pointer just beyond
the first |
34 * logical verb or the last verb in memory). | 34 * logical verb or the last verb in memory). |
35 */ | 35 */ |
36 | 36 |
(...skipping 27 matching lines...) Expand all Loading... |
64 * return value is a pointer to where the points for the verb should be
written. | 64 * return value is a pointer to where the points for the verb should be
written. |
65 */ | 65 */ |
66 SkPoint* growForVerb(int /*SkPath::Verb*/ verb) { | 66 SkPoint* growForVerb(int /*SkPath::Verb*/ verb) { |
67 SkDEBUGCODE(fPathRef->validate();) | 67 SkDEBUGCODE(fPathRef->validate();) |
68 return fPathRef->growForVerb(verb); | 68 return fPathRef->growForVerb(verb); |
69 } | 69 } |
70 | 70 |
71 SkPoint* growForConic(SkScalar w); | 71 SkPoint* growForConic(SkScalar w); |
72 | 72 |
73 /** | 73 /** |
74 * Allocates space for additional verbs and points and returns pointers
to the new verbs and | 74 * Allocates space for additional lines and returns a pointer to the new |
75 * points. verbs will point one beyond the first new verb (index it usin
g [~<i>]). pts points | 75 * points. The return pointer points at the first new point (indexed nor
mally [<i>]). |
76 * at the first new point (indexed normally [<i>]). | |
77 */ | 76 */ |
78 void grow(int newVerbs, int newPts, uint8_t** verbs, SkPoint** pts) { | 77 SkPoint* growForLines(int numLines) { |
79 SkASSERT(NULL != verbs); | |
80 SkASSERT(NULL != pts); | |
81 SkDEBUGCODE(fPathRef->validate();) | 78 SkDEBUGCODE(fPathRef->validate();) |
82 int oldVerbCnt = fPathRef->fVerbCnt; | 79 return fPathRef->growForLines(numLines); |
83 int oldPointCnt = fPathRef->fPointCnt; | |
84 SkASSERT(verbs && pts); | |
85 fPathRef->grow(newVerbs, newPts); | |
86 *verbs = fPathRef->fVerbs - oldVerbCnt; | |
87 *pts = fPathRef->fPoints + oldPointCnt; | |
88 SkDEBUGCODE(fPathRef->validate();) | |
89 } | 80 } |
90 | 81 |
91 /** | 82 /** |
92 * Resets the path ref to a new verb and point count. The new verbs and
points are | 83 * Resets the path ref to a new verb and point count. The new verbs and
points are |
93 * uninitialized. | 84 * uninitialized. |
94 */ | 85 */ |
95 void resetToSize(int newVerbCnt, int newPointCnt, int newConicCount) { | 86 void resetToSize(int newVerbCnt, int newPointCnt, int newConicCount) { |
96 fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount); | 87 fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount); |
97 } | 88 } |
| 89 |
98 /** | 90 /** |
99 * Gets the path ref that is wrapped in the Editor. | 91 * Gets the path ref that is wrapped in the Editor. |
100 */ | 92 */ |
101 SkPathRef* pathRef() { return fPathRef; } | 93 SkPathRef* pathRef() { return fPathRef; } |
102 | 94 |
| 95 void setDirection(int /* SkPath::Direction */ dir) { fPathRef->setDirect
ion(dir); } |
| 96 |
| 97 void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); } |
| 98 |
| 99 void setConvexity(int /*SkPath::Convexity*/ convexity) { |
| 100 fPathRef->setConvexity(convexity); |
| 101 } |
| 102 |
| 103 // 'rect' needs to be sorted |
| 104 void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); } |
| 105 |
103 private: | 106 private: |
104 SkPathRef* fPathRef; | 107 SkPathRef* fPathRef; |
105 }; | 108 }; |
106 | 109 |
107 public: | 110 public: |
108 /** | 111 /** |
109 * Gets a path ref with no verbs or points. | 112 * Gets a path ref with no verbs or points. |
110 */ | 113 */ |
111 static SkPathRef* CreateEmpty() { | 114 static SkPathRef* CreateEmpty() { |
112 static SkPathRef* gEmptyPathRef; | 115 static SkPathRef* gEmptyPathRef; |
113 if (!gEmptyPathRef) { | 116 if (!gEmptyPathRef) { |
114 gEmptyPathRef = SkNEW(SkPathRef); // leak! | 117 gEmptyPathRef = SkNEW(SkPathRef); // leak! |
115 gEmptyPathRef->computeBounds(); // Premptively avoid a race to cle
ar fBoundsIsDirty. | 118 gEmptyPathRef->computeBounds(); // Premptively avoid a race to cle
ar fBoundsIsDirty. |
116 } | 119 } |
117 return SkRef(gEmptyPathRef); | 120 return SkRef(gEmptyPathRef); |
118 } | 121 } |
119 | 122 |
| 123 uint8_t /*SkPath::Direction*/ getDirection() const { return fDirection; } |
| 124 |
| 125 /** |
| 126 * Tries to quickly compute the direction of the first non-degenerate |
| 127 * contour. If it can be computed, return true and set dir to that |
| 128 * direction. If it cannot be (quickly) determined, return false and ignore |
| 129 * the dir parameter. If the direction was determined, it is cached to make |
| 130 * subsequent calls return quickly. |
| 131 */ |
| 132 bool cheapComputeDirection(int* dir) const; |
| 133 |
| 134 /** |
| 135 * Return the path's convexity, as stored in the path. If it is currently u
nknown, |
| 136 * then this function will attempt to compute the convexity (and cache the
result). |
| 137 */ |
| 138 int /*SkPath::Convexity*/ getConvexity() const; |
| 139 |
| 140 /** |
| 141 * Return the currently cached value for convexity, even if that is set to |
| 142 * kUnknown_Convexity. Note: getConvexity() will automatically call |
| 143 * ComputeConvexity and cache its return value if the current setting is |
| 144 * kUnknown. |
| 145 */ |
| 146 int /*SkPath::Convexity*/ getConvexityOrUnknown() const { |
| 147 return fConvexity; |
| 148 } |
| 149 |
| 150 /** Returns true if the path is an oval. |
| 151 * |
| 152 * @param rect returns the bounding rect of this oval. It's a circle |
| 153 * if the height and width are the same. |
| 154 * |
| 155 * @return true if this path is an oval. |
| 156 * Tracking whether a path is an oval is considered an |
| 157 * optimization for performance and so some paths that are in |
| 158 * fact ovals can report false. |
| 159 */ |
| 160 bool isOval(SkRect* rect) const { |
| 161 if (fIsOval && NULL != rect) { |
| 162 *rect = this->getBounds(); |
| 163 } |
| 164 return SkToBool(fIsOval); |
| 165 } |
| 166 |
120 /** | 167 /** |
121 * Returns true if all of the points in this path are finite, meaning there | 168 * Returns true if all of the points in this path are finite, meaning there |
122 * are no infinities and no NaNs. | 169 * are no infinities and no NaNs. |
123 */ | 170 */ |
124 bool isFinite() const { | 171 bool isFinite() const { |
125 if (fBoundsIsDirty) { | 172 if (fBoundsIsDirty) { |
126 this->computeBounds(); | 173 this->computeBounds(); |
127 } | 174 } |
128 return SkToBool(fIsFinite); | 175 return SkToBool(fIsFinite); |
129 } | 176 } |
130 | 177 |
| 178 /** |
| 179 * Returns a mask, where each bit corresponding to a SegmentMask is |
| 180 * set if the path contains 1 or more segments of that type. |
| 181 * Returns 0 for an empty path (no segments). |
| 182 */ |
| 183 uint32_t getSegmentMasks() const { return fSegmentMask; } |
| 184 |
131 bool hasComputedBounds() const { | 185 bool hasComputedBounds() const { |
132 return !fBoundsIsDirty; | 186 return !fBoundsIsDirty; |
133 } | 187 } |
134 | 188 |
135 /** Returns the bounds of the path's points. If the path contains 0 or 1 | 189 /** Returns the bounds of the path's points. If the path contains 0 or 1 |
136 points, the bounds is set to (0,0,0,0), and isEmpty() will return true. | 190 points, the bounds is set to (0,0,0,0), and isEmpty() will return true. |
137 Note: this bounds may be larger than the actual shape, since curves | 191 Note: this bounds may be larger than the actual shape, since curves |
138 do not extend as far as their control points. | 192 do not extend as far as their control points. |
139 */ | 193 */ |
140 const SkRect& getBounds() const { | 194 const SkRect& getBounds() const { |
141 if (fBoundsIsDirty) { | 195 if (fBoundsIsDirty) { |
142 this->computeBounds(); | 196 this->computeBounds(); |
143 } | 197 } |
144 return fBounds; | 198 return fBounds; |
145 } | 199 } |
146 | 200 |
147 void setBounds(const SkRect& rect) { | |
148 SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom); | |
149 fBounds = rect; | |
150 fBoundsIsDirty = false; | |
151 fIsFinite = fBounds.isFinite(); | |
152 } | |
153 | |
154 /** | 201 /** |
155 * Transforms a path ref by a matrix, allocating a new one only if necessary
. | 202 * Transforms a path ref by a matrix, allocating a new one only if necessary
. |
156 */ | 203 */ |
157 static void CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, | 204 static void CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, |
158 const SkPathRef& src, | 205 const SkPathRef& src, |
159 const SkMatrix& matrix); | 206 const SkMatrix& matrix); |
160 | 207 |
161 static SkPathRef* CreateFromBuffer(SkRBuffer* buffer | 208 static SkPathRef* CreateFromBuffer(SkRBuffer* buffer |
162 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O | 209 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O |
163 , bool newFormat, int32_t oldPacked | 210 , bool newFormat, int32_t oldPacked |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 * Shortcut for this->points() + this->countPoints() | 253 * Shortcut for this->points() + this->countPoints() |
207 */ | 254 */ |
208 const SkPoint* pointsEnd() const { return this->points() + this->countPoints
(); } | 255 const SkPoint* pointsEnd() const { return this->points() + this->countPoints
(); } |
209 | 256 |
210 const SkScalar* conicWeights() const { SkDEBUGCODE(this->validate();) return
fConicWeights.begin(); } | 257 const SkScalar* conicWeights() const { SkDEBUGCODE(this->validate();) return
fConicWeights.begin(); } |
211 const SkScalar* conicWeightsEnd() const { SkDEBUGCODE(this->validate();) ret
urn fConicWeights.end(); } | 258 const SkScalar* conicWeightsEnd() const { SkDEBUGCODE(this->validate();) ret
urn fConicWeights.end(); } |
212 | 259 |
213 /** | 260 /** |
214 * Convenience methods for getting to a verb or point by index. | 261 * Convenience methods for getting to a verb or point by index. |
215 */ | 262 */ |
216 uint8_t atVerb(int index) { | 263 uint8_t atVerb(int index) const { |
217 SkASSERT((unsigned) index < (unsigned) fVerbCnt); | 264 SkASSERT((unsigned) index < (unsigned) fVerbCnt); |
218 return this->verbs()[~index]; | 265 return this->verbs()[~index]; |
219 } | 266 } |
220 const SkPoint& atPoint(int index) const { | 267 const SkPoint& atPoint(int index) const { |
221 SkASSERT((unsigned) index < (unsigned) fPointCnt); | 268 SkASSERT((unsigned) index < (unsigned) fPointCnt); |
222 return this->points()[index]; | 269 return this->points()[index]; |
223 } | 270 } |
224 | 271 |
225 bool operator== (const SkPathRef& ref) const; | 272 bool operator== (const SkPathRef& ref) const; |
226 | 273 |
227 /** | 274 /** |
228 * Writes the path points and verbs to a buffer. | 275 * Writes the path points and verbs to a buffer. |
229 */ | 276 */ |
230 void writeToBuffer(SkWBuffer* buffer); | 277 void writeToBuffer(SkWBuffer* buffer) const; |
231 | 278 |
232 /** | 279 /** |
233 * Gets the number of bytes that would be written in writeBuffer() | 280 * Gets the number of bytes that would be written in writeBuffer() |
234 */ | 281 */ |
235 uint32_t writeSize(); | 282 uint32_t writeSize() const; |
236 | 283 |
237 private: | 284 private: |
238 enum SerializationOffsets { | 285 enum SerializationOffsets { |
| 286 kDirection_SerializationShift = 26, // requires 2 bits |
239 kIsFinite_SerializationShift = 25, // requires 1 bit | 287 kIsFinite_SerializationShift = 25, // requires 1 bit |
| 288 kIsOval_SerializationShift = 24, // requires 1 bit |
| 289 kConvexity_SerializationShift = 16, // requires 8 bits |
| 290 // FillType (in SkPath) takes up 8 |
| 291 kSegmentMask_SerializationShift = 0 // requires 4 bits |
240 }; | 292 }; |
241 | 293 |
242 SkPathRef() { | 294 // flag to require a moveTo if we begin with something else, like lineTo etc
. |
243 fBoundsIsDirty = true; // this also invalidates fIsFinite | 295 static const int kINITIAL_LASTMOVETOINDEX_VALUE = ~0; |
244 fPointCnt = 0; | 296 |
245 fVerbCnt = 0; | 297 SkPathRef(); |
246 fVerbs = NULL; | 298 |
247 fPoints = NULL; | 299 /** |
248 fFreeSpace = 0; | 300 * Store a convexity setting in the path. There is no automatic check to |
249 fGenerationID = kEmptyGenID; | 301 * see if this value actually agrees with the return value that would be |
250 SkDEBUGCODE(fEditorsAttached = 0;) | 302 * computed by getConvexity(). |
251 SkDEBUGCODE(this->validate();) | 303 * |
| 304 * Note: even if this is set to a "known" value, if the path is later |
| 305 * changed (e.g. lineTo(), addRect(), etc.) then the cached value will be |
| 306 * reset to kUnknown_Convexity. |
| 307 */ |
| 308 void setConvexity(int /*SkPath::Convexity*/ convexity) { |
| 309 fConvexity = convexity; |
| 310 } |
| 311 |
| 312 // 'rect' needs to be sorted |
| 313 void setBounds(const SkRect& rect) { |
| 314 SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom); |
| 315 fBounds = rect; |
| 316 fBoundsIsDirty = false; |
| 317 fIsFinite = fBounds.isFinite(); |
252 } | 318 } |
253 | 319 |
254 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe
servePoints); | 320 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe
servePoints); |
255 | 321 |
256 // Return true if the computed bounds are finite. | 322 // Return true if the computed bounds are finite. |
257 static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) { | 323 static bool ComputePtBounds(SkRect* bounds, const SkPoint* points, int count
) { |
258 int count = ref.countPoints(); | |
259 if (count <= 1) { // we ignore just 1 point (moveto) | 324 if (count <= 1) { // we ignore just 1 point (moveto) |
260 bounds->setEmpty(); | 325 bounds->setEmpty(); |
261 return count ? ref.points()->isFinite() : true; | 326 return count ? points->isFinite() : true; |
262 } else { | 327 } else { |
263 return bounds->setBoundsCheck(ref.points(), count); | 328 return bounds->setBoundsCheck(points, count); |
264 } | 329 } |
265 } | 330 } |
266 | 331 |
267 // called, if dirty, by getBounds() | 332 // called, if dirty, by getBounds() |
268 void computeBounds() const { | 333 void computeBounds() const { |
269 SkDEBUGCODE(this->validate();) | 334 SkDEBUGCODE(this->validate();) |
270 SkASSERT(fBoundsIsDirty); | 335 SkASSERT(fBoundsIsDirty); |
271 | 336 |
272 fIsFinite = ComputePtBounds(&fBounds, *this); | 337 fIsFinite = ComputePtBounds(&fBounds, this->points(), this->countPoints(
)); |
273 fBoundsIsDirty = false; | 338 fBoundsIsDirty = false; |
274 } | 339 } |
275 | 340 |
276 /** Makes additional room but does not change the counts or change the genID
*/ | 341 /** Makes additional room but does not change the counts or change the genID
*/ |
277 void incReserve(int additionalVerbs, int additionalPoints) { | 342 void incReserve(int additionalVerbs, int additionalPoints) { |
278 SkDEBUGCODE(this->validate();) | 343 SkDEBUGCODE(this->validate();) |
279 size_t space = additionalVerbs * sizeof(uint8_t) + additionalPoints * si
zeof (SkPoint); | 344 size_t space = additionalVerbs * sizeof(uint8_t) + additionalPoints * si
zeof (SkPoint); |
280 this->makeSpace(space); | 345 this->makeSpace(space); |
281 SkDEBUGCODE(this->validate();) | 346 SkDEBUGCODE(this->validate();) |
282 } | 347 } |
283 | 348 |
284 /** Resets the path ref with verbCount verbs and pointCount points, all unin
itialized. Also | 349 /** Resets the path ref with verbCount verbs and pointCount points, all unin
itialized. Also |
285 * allocates space for reserveVerb additional verbs and reservePoints addit
ional points.*/ | 350 * allocates space for reserveVerb additional verbs and reservePoints addit
ional points.*/ |
286 void resetToSize(int verbCount, int pointCount, int conicCount, | 351 void resetToSize(int verbCount, int pointCount, int conicCount, |
287 int reserveVerbs = 0, int reservePoints = 0) { | 352 int reserveVerbs = 0, int reservePoints = 0); |
288 SkDEBUGCODE(this->validate();) | |
289 fBoundsIsDirty = true; // this also invalidates fIsFinite | |
290 fGenerationID = 0; | |
291 | 353 |
292 size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCo
unt; | 354 // This method assumes space has already been allocated for the new |
293 size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * r
eservePoints; | 355 // verb and point. |
294 size_t minSize = newSize + newReserve; | 356 void injectMove(); |
295 | |
296 ptrdiff_t sizeDelta = this->currSize() - minSize; | |
297 | |
298 if (sizeDelta < 0 || static_cast<size_t>(sizeDelta) >= 3 * minSize) { | |
299 sk_free(fPoints); | |
300 fPoints = NULL; | |
301 fVerbs = NULL; | |
302 fFreeSpace = 0; | |
303 fVerbCnt = 0; | |
304 fPointCnt = 0; | |
305 this->makeSpace(minSize); | |
306 fVerbCnt = verbCount; | |
307 fPointCnt = pointCount; | |
308 fFreeSpace -= newSize; | |
309 } else { | |
310 fPointCnt = pointCount; | |
311 fVerbCnt = verbCount; | |
312 fFreeSpace = this->currSize() - minSize; | |
313 } | |
314 fConicWeights.setCount(conicCount); | |
315 SkDEBUGCODE(this->validate();) | |
316 } | |
317 | 357 |
318 /** | 358 /** |
319 * Increases the verb count by newVerbs and the point count be newPoints. Ne
w verbs and points | 359 * Increases the verb and point count by numLines. The new points |
320 * are uninitialized. | 360 * are uninitialized. All the new verbs are set to kLine_SegmentMask. |
321 */ | 361 */ |
322 void grow(int newVerbs, int newPoints) { | 362 SkPoint* growForLines(int numLines); |
323 SkDEBUGCODE(this->validate();) | |
324 size_t space = newVerbs * sizeof(uint8_t) + newPoints * sizeof (SkPoint)
; | |
325 this->makeSpace(space); | |
326 fVerbCnt += newVerbs; | |
327 fPointCnt += newPoints; | |
328 fFreeSpace -= space; | |
329 fBoundsIsDirty = true; // this also invalidates fIsFinite | |
330 SkDEBUGCODE(this->validate();) | |
331 } | |
332 | 363 |
333 /** | 364 /** |
334 * Increases the verb count 1, records the new verb, and creates room for th
e requisite number | 365 * Increases the verb count 1, records the new verb, and creates room for th
e requisite number |
335 * of additional points. A pointer to the first point is returned. Any new p
oints are | 366 * of additional points. A pointer to the first point is returned. Any new p
oints are |
336 * uninitialized. | 367 * uninitialized. |
337 */ | 368 */ |
338 SkPoint* growForVerb(int /*SkPath::Verb*/ verb); | 369 SkPoint* growForVerb(int /* SkPath::Verb */ verb); |
339 | 370 |
340 /** | 371 /** |
341 * Ensures that the free space available in the path ref is >= size. The ver
b and point counts | 372 * Ensures that the free space available in the path ref is >= size. The ver
b and point counts |
342 * are not changed. | 373 * are not changed. |
343 */ | 374 */ |
344 void makeSpace(size_t size) { | 375 void makeSpace(size_t size) { |
345 SkDEBUGCODE(this->validate();) | 376 SkDEBUGCODE(this->validate();) |
346 ptrdiff_t growSize = size - fFreeSpace; | 377 ptrdiff_t growSize = size - fFreeSpace; |
347 if (growSize <= 0) { | 378 if (growSize <= 0) { |
348 return; | 379 return; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 /** | 421 /** |
391 * Gets an ID that uniquely identifies the contents of the path ref. If two
path refs have the | 422 * Gets an ID that uniquely identifies the contents of the path ref. If two
path refs have the |
392 * same ID then they have the same verbs and points. However, two path refs
may have the same | 423 * same ID then they have the same verbs and points. However, two path refs
may have the same |
393 * contents but different genIDs. Zero is reserved and means an ID has not y
et been determined | 424 * contents but different genIDs. Zero is reserved and means an ID has not y
et been determined |
394 * for the path ref. | 425 * for the path ref. |
395 */ | 426 */ |
396 int32_t genID() const; | 427 int32_t genID() const; |
397 | 428 |
398 SkDEBUGCODE(void validate() const;) | 429 SkDEBUGCODE(void validate() const;) |
399 | 430 |
| 431 int internalGetConvexity() const; |
| 432 |
| 433 void setIsOval(bool isOval) { fIsOval = isOval; } |
| 434 void setDirection(int direction) { fDirection = direction; } |
| 435 |
400 enum { | 436 enum { |
401 kMinSize = 256, | 437 kMinSize = 256, |
402 }; | 438 }; |
403 | 439 |
404 mutable SkRect fBounds; | 440 mutable SkRect fBounds; |
| 441 int fLastMoveToIndex; |
| 442 |
| 443 uint8_t fSegmentMask; |
405 mutable uint8_t fBoundsIsDirty; | 444 mutable uint8_t fBoundsIsDirty; |
| 445 mutable uint8_t fConvexity; |
| 446 mutable uint8_t fDirection; |
406 mutable SkBool8 fIsFinite; // only meaningful if bounds are valid | 447 mutable SkBool8 fIsFinite; // only meaningful if bounds are valid |
| 448 mutable SkBool8 fIsOval; |
407 | 449 |
408 SkPoint* fPoints; // points to begining of the allocation | 450 SkPoint* fPoints; // points to begining of the allocation |
409 uint8_t* fVerbs; // points just past the end of the allocation (v
erbs grow backwards) | 451 uint8_t* fVerbs; // points just past the end of the allocation (v
erbs grow backwards) |
410 int fVerbCnt; | 452 int fVerbCnt; |
411 int fPointCnt; | 453 int fPointCnt; |
412 size_t fFreeSpace; // redundant but saves computation | 454 size_t fFreeSpace; // redundant but saves computation |
413 SkTDArray<SkScalar> fConicWeights; | 455 SkTDArray<SkScalar> fConicWeights; |
414 | 456 |
415 enum { | 457 enum { |
416 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer
o verbs. | 458 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer
o verbs. |
417 }; | 459 }; |
418 mutable int32_t fGenerationID; | 460 mutable int32_t fGenerationID; |
419 SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use
at any time. | 461 SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use
at any time. |
420 | 462 |
421 typedef SkRefCnt INHERITED; | 463 typedef SkRefCnt INHERITED; |
422 }; | 464 }; |
423 | 465 |
424 #endif | 466 #endif |
OLD | NEW |