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 "SkRefCnt.h" | 12 #include "SkRefCnt.h" |
13 #include <stddef.h> // ptrdiff_t | 13 #include <stddef.h> // ptrdiff_t |
14 | 14 |
15 // When we're ready to break the picture format. Changes: | |
16 // * Write genID. | |
17 // * SkPathRef read/write counts (which will change the field order) | |
18 // * SkPathRef reads/writes verbs backwards. | |
19 #define NEW_PICTURE_FORMAT 0 | |
20 | |
21 /** | 15 /** |
22 * Holds the path verbs and points. It is versioned by a generation ID. None of
its public methods | 16 * Holds the path verbs and points. It is versioned by a generation ID. None of
its public methods |
23 * modify the contents. To modify or append to the verbs/points wrap the SkPathR
ef in an | 17 * modify the contents. To modify or append to the verbs/points wrap the SkPathR
ef in an |
24 * SkPathRef::Editor object. Installing the editor resets the generation ID. It
also performs | 18 * SkPathRef::Editor object. Installing the editor resets the generation ID. It
also performs |
25 * copy-on-write if the SkPathRef is shared by multipls SkPaths. The caller pass
es the Editor's | 19 * copy-on-write if the SkPathRef is shared by multipls SkPaths. The caller pass
es the Editor's |
26 * constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef
after the editor's | 20 * constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef
after the editor's |
27 * constructor returns. | 21 * constructor returns. |
28 * | 22 * |
29 * The points and verbs are stored in a single allocation. The points are at the
begining of the | 23 * The points and verbs are stored in a single allocation. The points are at the
begining of the |
30 * allocation while the verbs are stored at end of the allocation, in reverse or
der. Thus the points | 24 * allocation while the verbs are stored at end of the allocation, in reverse or
der. Thus the points |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 | 96 |
103 /** | 97 /** |
104 * Adds the verb and allocates space for the number of points indicated
by the verb. The | 98 * Adds the verb and allocates space for the number of points indicated
by the verb. The |
105 * return value is a pointer to where the points for the verb should be
written. | 99 * return value is a pointer to where the points for the verb should be
written. |
106 */ | 100 */ |
107 SkPoint* growForVerb(SkPath::Verb verb) { | 101 SkPoint* growForVerb(SkPath::Verb verb) { |
108 fPathRef->validate(); | 102 fPathRef->validate(); |
109 return fPathRef->growForVerb(verb); | 103 return fPathRef->growForVerb(verb); |
110 } | 104 } |
111 | 105 |
| 106 SkPoint* growForConic(SkScalar w) { |
| 107 fPathRef->validate(); |
| 108 SkPoint* pts = fPathRef->growForVerb(SkPath::kConic_Verb); |
| 109 *fPathRef->fConicWeights.append() = w; |
| 110 return pts; |
| 111 } |
| 112 |
112 /** | 113 /** |
113 * Allocates space for additional verbs and points and returns pointers
to the new verbs and | 114 * Allocates space for additional verbs and points and returns pointers
to the new verbs and |
114 * points. verbs will point one beyond the first new verb (index it usin
g [~<i>]). pts points | 115 * points. verbs will point one beyond the first new verb (index it usin
g [~<i>]). pts points |
115 * at the first new point (indexed normally [<i>]). | 116 * at the first new point (indexed normally [<i>]). |
116 */ | 117 */ |
117 void grow(int newVerbs, int newPts, uint8_t** verbs, SkPoint** pts) { | 118 void grow(int newVerbs, int newPts, uint8_t** verbs, SkPoint** pts) { |
118 SkASSERT(NULL != verbs); | 119 SkASSERT(NULL != verbs); |
119 SkASSERT(NULL != pts); | 120 SkASSERT(NULL != pts); |
120 fPathRef->validate(); | 121 fPathRef->validate(); |
121 int oldVerbCnt = fPathRef->fVerbCnt; | 122 int oldVerbCnt = fPathRef->fVerbCnt; |
122 int oldPointCnt = fPathRef->fPointCnt; | 123 int oldPointCnt = fPathRef->fPointCnt; |
123 SkASSERT(verbs && pts); | 124 SkASSERT(verbs && pts); |
124 fPathRef->grow(newVerbs, newPts); | 125 fPathRef->grow(newVerbs, newPts); |
125 *verbs = fPathRef->fVerbs - oldVerbCnt; | 126 *verbs = fPathRef->fVerbs - oldVerbCnt; |
126 *pts = fPathRef->fPoints + oldPointCnt; | 127 *pts = fPathRef->fPoints + oldPointCnt; |
127 fPathRef->validate(); | 128 fPathRef->validate(); |
128 } | 129 } |
129 | 130 |
130 /** | 131 /** |
131 * Resets the path ref to a new verb and point count. The new verbs and
points are | 132 * Resets the path ref to a new verb and point count. The new verbs and
points are |
132 * uninitialized. | 133 * uninitialized. |
133 */ | 134 */ |
134 void resetToSize(int newVerbCnt, int newPointCnt) { | 135 void resetToSize(int newVerbCnt, int newPointCnt, int newConicCount) { |
135 fPathRef->resetToSize(newVerbCnt, newPointCnt); | 136 fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount); |
136 } | 137 } |
137 /** | 138 /** |
138 * Gets the path ref that is wrapped in the Editor. | 139 * Gets the path ref that is wrapped in the Editor. |
139 */ | 140 */ |
140 SkPathRef* pathRef() { return fPathRef; } | 141 SkPathRef* pathRef() { return fPathRef; } |
141 | 142 |
142 private: | 143 private: |
143 SkPathRef* fPathRef; | 144 SkPathRef* fPathRef; |
144 }; | 145 }; |
145 | 146 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 } | 196 } |
196 return; | 197 return; |
197 } | 198 } |
198 int32_t rcnt = dst->get()->getRefCnt(); | 199 int32_t rcnt = dst->get()->getRefCnt(); |
199 if (&src == dst->get() && 1 == rcnt) { | 200 if (&src == dst->get() && 1 == rcnt) { |
200 matrix.mapPoints((*dst)->fPoints, (*dst)->fPointCnt); | 201 matrix.mapPoints((*dst)->fPoints, (*dst)->fPointCnt); |
201 return; | 202 return; |
202 } else if (rcnt > 1) { | 203 } else if (rcnt > 1) { |
203 dst->reset(SkNEW(SkPathRef)); | 204 dst->reset(SkNEW(SkPathRef)); |
204 } | 205 } |
205 (*dst)->resetToSize(src.fVerbCnt, src.fPointCnt); | 206 (*dst)->resetToSize(src.fVerbCnt, src.fPointCnt, src.fConicWeights.count
()); |
206 memcpy((*dst)->verbsMemWritable(), src.verbsMemBegin(), src.fVerbCnt * s
izeof(uint8_t)); | 207 memcpy((*dst)->verbsMemWritable(), src.verbsMemBegin(), src.fVerbCnt * s
izeof(uint8_t)); |
207 matrix.mapPoints((*dst)->fPoints, src.points(), src.fPointCnt); | 208 matrix.mapPoints((*dst)->fPoints, src.points(), src.fPointCnt); |
| 209 (*dst)->fConicWeights = src.fConicWeights; |
208 (*dst)->validate(); | 210 (*dst)->validate(); |
209 } | 211 } |
210 | 212 |
211 #if NEW_PICTURE_FORMAT | |
212 static SkPathRef* CreateFromBuffer(SkRBuffer* buffer) { | 213 static SkPathRef* CreateFromBuffer(SkRBuffer* buffer) { |
213 SkPathRef* ref = SkNEW(SkPathRef); | 214 SkPathRef* ref = SkNEW(SkPathRef); |
214 ref->fGenerationID = buffer->readU32(); | 215 ref->fGenerationID = buffer->readU32(); |
215 int32_t verbCount = buffer->readS32(); | 216 int32_t verbCount = buffer->readS32(); |
216 int32_t pointCount = buffer->readS32(); | 217 int32_t pointCount = buffer->readS32(); |
217 ref->resetToSize(verbCount, pointCount); | 218 int32_t conicCount = buffer->readS32(); |
| 219 ref->resetToSize(verbCount, pointCount, conicCount); |
218 | 220 |
219 SkASSERT(verbCount == ref->countVerbs()); | 221 SkASSERT(verbCount == ref->countVerbs()); |
220 SkASSERT(pointCount == ref->countPoints()); | 222 SkASSERT(pointCount == ref->countPoints()); |
| 223 SkASSERT(conicCount == ref->fConicWeights.count()); |
221 buffer->read(ref->verbsMemWritable(), verbCount * sizeof(uint8_t)); | 224 buffer->read(ref->verbsMemWritable(), verbCount * sizeof(uint8_t)); |
222 buffer->read(ref->fPoints, pointCount * sizeof(SkPoint)); | 225 buffer->read(ref->fPoints, pointCount * sizeof(SkPoint)); |
| 226 buffer->read(ref->fConicWeights.begin(), conicCount * sizeof(SkScalar)); |
223 return ref; | 227 return ref; |
224 } | 228 } |
225 #else | |
226 static SkPathRef* CreateFromBuffer(int verbCount, int pointCount, SkRBuffer*
buffer) { | |
227 SkPathRef* ref = SkNEW(SkPathRef); | |
228 | |
229 ref->resetToSize(verbCount, pointCount); | |
230 SkASSERT(verbCount == ref->countVerbs()); | |
231 SkASSERT(pointCount == ref->countPoints()); | |
232 buffer->read(ref->fPoints, pointCount * sizeof(SkPoint)); | |
233 for (int i = 0; i < verbCount; ++i) { | |
234 ref->fVerbs[~i] = buffer->readU8(); | |
235 } | |
236 return ref; | |
237 } | |
238 #endif | |
239 | 229 |
240 /** | 230 /** |
241 * Rollsback a path ref to zero verbs and points with the assumption that th
e path ref will be | 231 * Rollsback a path ref to zero verbs and points with the assumption that th
e path ref will be |
242 * repopulated with approximately the same number of verbs and points. A new
path ref is created | 232 * repopulated with approximately the same number of verbs and points. A new
path ref is created |
243 * only if necessary. | 233 * only if necessary. |
244 */ | 234 */ |
245 static void Rewind(PR_CONTAINER* pathRef) { | 235 static void Rewind(PR_CONTAINER* pathRef) { |
246 if (1 == (*pathRef)->getRefCnt()) { | 236 if (1 == (*pathRef)->getRefCnt()) { |
247 (*pathRef)->validate(); | 237 (*pathRef)->validate(); |
248 (*pathRef)->fVerbCnt = 0; | 238 (*pathRef)->fVerbCnt = 0; |
249 (*pathRef)->fPointCnt = 0; | 239 (*pathRef)->fPointCnt = 0; |
250 (*pathRef)->fFreeSpace = (*pathRef)->currSize(); | 240 (*pathRef)->fFreeSpace = (*pathRef)->currSize(); |
251 (*pathRef)->fGenerationID = 0; | 241 (*pathRef)->fGenerationID = 0; |
| 242 (*pathRef)->fConicWeights.rewind(); |
252 (*pathRef)->validate(); | 243 (*pathRef)->validate(); |
253 } else { | 244 } else { |
254 int oldVCnt = (*pathRef)->countVerbs(); | 245 int oldVCnt = (*pathRef)->countVerbs(); |
255 int oldPCnt = (*pathRef)->countPoints(); | 246 int oldPCnt = (*pathRef)->countPoints(); |
256 pathRef->reset(SkNEW(SkPathRef)); | 247 pathRef->reset(SkNEW(SkPathRef)); |
257 (*pathRef)->resetToSize(0, 0, oldVCnt, oldPCnt); | 248 (*pathRef)->resetToSize(0, 0, 0, oldVCnt, oldPCnt); |
258 } | 249 } |
259 } | 250 } |
260 | 251 |
261 virtual ~SkPathRef() { | 252 virtual ~SkPathRef() { |
262 SkASSERT_X(this != gEmptyPathRef); | 253 SkASSERT_X(this != gEmptyPathRef); |
263 #if SK_DEBUG_PATH_REF | 254 #if SK_DEBUG_PATH_REF |
264 SkASSERT_X(!fOwners.count()); | 255 SkASSERT_X(!fOwners.count()); |
265 #endif | 256 #endif |
266 | 257 |
267 this->validate(); | 258 this->validate(); |
(...skipping 24 matching lines...) Expand all Loading... |
292 /** | 283 /** |
293 * Returns a const pointer to the first point. | 284 * Returns a const pointer to the first point. |
294 */ | 285 */ |
295 const SkPoint* points() const { this->validate(); return fPoints; } | 286 const SkPoint* points() const { this->validate(); return fPoints; } |
296 | 287 |
297 /** | 288 /** |
298 * Shortcut for this->points() + this->countPoints() | 289 * Shortcut for this->points() + this->countPoints() |
299 */ | 290 */ |
300 const SkPoint* pointsEnd() const { return this->points() + this->countPoints
(); } | 291 const SkPoint* pointsEnd() const { return this->points() + this->countPoints
(); } |
301 | 292 |
| 293 const SkScalar* conicWeights() const { this->validate(); return fConicWeight
s.begin(); } |
| 294 const SkScalar* conicWeightsEnd() const { this->validate(); return fConicWei
ghts.end(); } |
| 295 |
302 /** | 296 /** |
303 * Convenience methods for getting to a verb or point by index. | 297 * Convenience methods for getting to a verb or point by index. |
304 */ | 298 */ |
305 uint8_t atVerb(int index) { | 299 uint8_t atVerb(int index) { |
306 SkASSERT((unsigned) index < (unsigned) fVerbCnt); | 300 SkASSERT((unsigned) index < (unsigned) fVerbCnt); |
307 return this->verbs()[~index]; | 301 return this->verbs()[~index]; |
308 } | 302 } |
309 const SkPoint& atPoint(int index) const { | 303 const SkPoint& atPoint(int index) const { |
310 SkASSERT((unsigned) index < (unsigned) fPointCnt); | 304 SkASSERT((unsigned) index < (unsigned) fPointCnt); |
311 return this->points()[index]; | 305 return this->points()[index]; |
(...skipping 18 matching lines...) Expand all Loading... |
330 ref.fVerbCnt * sizeof(uint8_t))) { | 324 ref.fVerbCnt * sizeof(uint8_t))) { |
331 SkASSERT(!genIDMatch); | 325 SkASSERT(!genIDMatch); |
332 return false; | 326 return false; |
333 } | 327 } |
334 if (0 != memcmp(this->points(), | 328 if (0 != memcmp(this->points(), |
335 ref.points(), | 329 ref.points(), |
336 ref.fPointCnt * sizeof(SkPoint))) { | 330 ref.fPointCnt * sizeof(SkPoint))) { |
337 SkASSERT(!genIDMatch); | 331 SkASSERT(!genIDMatch); |
338 return false; | 332 return false; |
339 } | 333 } |
| 334 if (fConicWeights != ref.fConicWeights) { |
| 335 SkASSERT(!genIDMatch); |
| 336 return false; |
| 337 } |
340 // We've done the work to determine that these are equal. If either has
a zero genID, copy | 338 // We've done the work to determine that these are equal. If either has
a zero genID, copy |
341 // the other's. If both are 0 then genID() will compute the next ID. | 339 // the other's. If both are 0 then genID() will compute the next ID. |
342 if (0 == fGenerationID) { | 340 if (0 == fGenerationID) { |
343 fGenerationID = ref.genID(); | 341 fGenerationID = ref.genID(); |
344 } else if (0 == ref.fGenerationID) { | 342 } else if (0 == ref.fGenerationID) { |
345 ref.fGenerationID = this->genID(); | 343 ref.fGenerationID = this->genID(); |
346 } | 344 } |
347 return true; | 345 return true; |
348 } | 346 } |
349 | 347 |
350 /** | 348 /** |
351 * Writes the path points and verbs to a buffer. | 349 * Writes the path points and verbs to a buffer. |
352 */ | 350 */ |
353 #if NEW_PICTURE_FORMAT | |
354 void writeToBuffer(SkWBuffer* buffer) { | 351 void writeToBuffer(SkWBuffer* buffer) { |
355 this->validate(); | 352 this->validate(); |
356 SkDEBUGCODE_X(size_t beforePos = buffer->pos();) | 353 SkDEBUGCODE_X(size_t beforePos = buffer->pos();) |
357 | 354 |
358 // TODO: write gen ID here. Problem: We don't know if we're cross proces
s or not from | 355 // TODO: write gen ID here. Problem: We don't know if we're cross proces
s or not from |
359 // SkWBuffer. Until this is fixed we write 0. | 356 // SkWBuffer. Until this is fixed we write 0. |
360 buffer->write32(0); | 357 buffer->write32(0); |
361 buffer->write32(this->fVerbCnt); | 358 buffer->write32(fVerbCnt); |
362 buffer->write32(this->fPointCnt); | 359 buffer->write32(fPointCnt); |
363 buffer->write(this->verbsMemBegin(), fVerbCnt * sizeof(uint8_t)); | 360 buffer->write32(fConicWeights.count()); |
| 361 buffer->write(verbsMemBegin(), fVerbCnt * sizeof(uint8_t)); |
364 buffer->write(fPoints, fPointCnt * sizeof(SkPoint)); | 362 buffer->write(fPoints, fPointCnt * sizeof(SkPoint)); |
| 363 buffer->write(fConicWeights.begin(), fConicWeights.bytes()); |
365 | 364 |
366 SkASSERT(buffer->pos() - beforePos == (size_t) this->writeSize()); | 365 SkASSERT(buffer->pos() - beforePos == (size_t) this->writeSize()); |
367 } | 366 } |
368 | 367 |
369 /** | 368 /** |
370 * Gets the number of bytes that would be written in writeBuffer() | 369 * Gets the number of bytes that would be written in writeBuffer() |
371 */ | 370 */ |
372 uint32_t writeSize() { | 371 uint32_t writeSize() { |
373 return 3 * sizeof(uint32_t) + fVerbCnt * sizeof(uint8_t) + fPointCnt * s
izeof(SkPoint); | 372 return 4 * sizeof(uint32_t) + |
| 373 fVerbCnt * sizeof(uint8_t) + |
| 374 fPointCnt * sizeof(SkPoint) + |
| 375 fConicWeights.bytes(); |
374 } | 376 } |
375 #else | |
376 void writeToBuffer(SkWBuffer* buffer) { | |
377 this->validate(); | |
378 buffer->write(fPoints, fPointCnt * sizeof(SkPoint)); | |
379 for (int i = 0; i < fVerbCnt; ++i) { | |
380 buffer->write8(fVerbs[~i]); | |
381 } | |
382 } | |
383 #endif | |
384 | 377 |
385 private: | 378 private: |
386 SkPathRef() { | 379 SkPathRef() { |
387 fPointCnt = 0; | 380 fPointCnt = 0; |
388 fVerbCnt = 0; | 381 fVerbCnt = 0; |
389 fVerbs = NULL; | 382 fVerbs = NULL; |
390 fPoints = NULL; | 383 fPoints = NULL; |
391 fFreeSpace = 0; | 384 fFreeSpace = 0; |
392 fGenerationID = kEmptyGenID; | 385 fGenerationID = kEmptyGenID; |
393 SkDEBUGCODE_X(fEditorsAttached = 0;) | 386 SkDEBUGCODE_X(fEditorsAttached = 0;) |
394 this->validate(); | 387 this->validate(); |
395 } | 388 } |
396 | 389 |
397 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe
servePoints) { | 390 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe
servePoints) { |
398 this->validate(); | 391 this->validate(); |
399 this->resetToSize(ref.fVerbCnt, ref.fPointCnt, | 392 this->resetToSize(ref.fVerbCnt, ref.fPointCnt, ref.fConicWeights.count()
, |
400 additionalReserveVerbs, additionalReservePoints); | 393 additionalReserveVerbs, additionalReservePoints); |
401 memcpy(this->verbsMemWritable(), ref.verbsMemBegin(), ref.fVerbCnt * siz
eof(uint8_t)); | 394 memcpy(this->verbsMemWritable(), ref.verbsMemBegin(), ref.fVerbCnt * siz
eof(uint8_t)); |
402 memcpy(this->fPoints, ref.fPoints, ref.fPointCnt * sizeof(SkPoint)); | 395 memcpy(this->fPoints, ref.fPoints, ref.fPointCnt * sizeof(SkPoint)); |
| 396 fConicWeights = ref.fConicWeights; |
403 // We could call genID() here to force a real ID (instead of 0). However
, if we're making | 397 // We could call genID() here to force a real ID (instead of 0). However
, if we're making |
404 // a copy then presumably we intend to make a modification immediately a
fterwards. | 398 // a copy then presumably we intend to make a modification immediately a
fterwards. |
405 fGenerationID = ref.fGenerationID; | 399 fGenerationID = ref.fGenerationID; |
406 this->validate(); | 400 this->validate(); |
407 } | 401 } |
408 | 402 |
409 /** Makes additional room but does not change the counts or change the genID
*/ | 403 /** Makes additional room but does not change the counts or change the genID
*/ |
410 void incReserve(int additionalVerbs, int additionalPoints) { | 404 void incReserve(int additionalVerbs, int additionalPoints) { |
411 this->validate(); | 405 this->validate(); |
412 size_t space = additionalVerbs * sizeof(uint8_t) + additionalPoints * si
zeof (SkPoint); | 406 size_t space = additionalVerbs * sizeof(uint8_t) + additionalPoints * si
zeof (SkPoint); |
413 this->makeSpace(space); | 407 this->makeSpace(space); |
414 this->validate(); | 408 this->validate(); |
415 } | 409 } |
416 | 410 |
417 /** Resets the path ref with verbCount verbs and pointCount points, all unit
ialized. Also | 411 /** Resets the path ref with verbCount verbs and pointCount points, all unit
ialized. Also |
418 * allocates space for reserveVerb additional verbs and reservePoints addit
ional points.*/ | 412 * allocates space for reserveVerb additional verbs and reservePoints addit
ional points.*/ |
419 void resetToSize(int verbCount, int pointCount, int reserveVerbs = 0, int re
servePoints = 0) { | 413 void resetToSize(int verbCount, int pointCount, int conicCount, |
| 414 int reserveVerbs = 0, int reservePoints = 0) { |
420 this->validate(); | 415 this->validate(); |
421 fGenerationID = 0; | 416 fGenerationID = 0; |
422 | 417 |
423 size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCo
unt; | 418 size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCo
unt; |
424 size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * r
eservePoints; | 419 size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * r
eservePoints; |
425 size_t minSize = newSize + newReserve; | 420 size_t minSize = newSize + newReserve; |
426 | 421 |
427 ptrdiff_t sizeDelta = this->currSize() - minSize; | 422 ptrdiff_t sizeDelta = this->currSize() - minSize; |
428 | 423 |
429 if (sizeDelta < 0 || static_cast<size_t>(sizeDelta) >= 3 * minSize) { | 424 if (sizeDelta < 0 || static_cast<size_t>(sizeDelta) >= 3 * minSize) { |
430 sk_free(fPoints); | 425 sk_free(fPoints); |
431 fPoints = NULL; | 426 fPoints = NULL; |
432 fVerbs = NULL; | 427 fVerbs = NULL; |
433 fFreeSpace = 0; | 428 fFreeSpace = 0; |
434 fVerbCnt = 0; | 429 fVerbCnt = 0; |
435 fPointCnt = 0; | 430 fPointCnt = 0; |
436 this->makeSpace(minSize); | 431 this->makeSpace(minSize); |
437 fVerbCnt = verbCount; | 432 fVerbCnt = verbCount; |
438 fPointCnt = pointCount; | 433 fPointCnt = pointCount; |
439 fFreeSpace -= newSize; | 434 fFreeSpace -= newSize; |
440 } else { | 435 } else { |
441 fPointCnt = pointCount; | 436 fPointCnt = pointCount; |
442 fVerbCnt = verbCount; | 437 fVerbCnt = verbCount; |
443 fFreeSpace = this->currSize() - minSize; | 438 fFreeSpace = this->currSize() - minSize; |
444 } | 439 } |
| 440 fConicWeights.setCount(conicCount); |
445 this->validate(); | 441 this->validate(); |
446 } | 442 } |
447 | 443 |
448 /** | 444 /** |
449 * Increases the verb count by newVerbs and the point count be newPoints. Ne
w verbs and points | 445 * Increases the verb count by newVerbs and the point count be newPoints. Ne
w verbs and points |
450 * are uninitialized. | 446 * are uninitialized. |
451 */ | 447 */ |
452 void grow(int newVerbs, int newPoints) { | 448 void grow(int newVerbs, int newPoints) { |
453 this->validate(); | 449 this->validate(); |
454 size_t space = newVerbs * sizeof(uint8_t) + newPoints * sizeof (SkPoint)
; | 450 size_t space = newVerbs * sizeof(uint8_t) + newPoints * sizeof (SkPoint)
; |
(...skipping 12 matching lines...) Expand all Loading... |
467 SkPoint* growForVerb(SkPath::Verb verb) { | 463 SkPoint* growForVerb(SkPath::Verb verb) { |
468 this->validate(); | 464 this->validate(); |
469 int pCnt; | 465 int pCnt; |
470 switch (verb) { | 466 switch (verb) { |
471 case SkPath::kMove_Verb: | 467 case SkPath::kMove_Verb: |
472 pCnt = 1; | 468 pCnt = 1; |
473 break; | 469 break; |
474 case SkPath::kLine_Verb: | 470 case SkPath::kLine_Verb: |
475 pCnt = 1; | 471 pCnt = 1; |
476 break; | 472 break; |
| 473 case SkPath::kConic_Verb: |
477 case SkPath::kQuad_Verb: | 474 case SkPath::kQuad_Verb: |
478 pCnt = 2; | 475 pCnt = 2; |
479 break; | 476 break; |
480 case SkPath::kCubic_Verb: | 477 case SkPath::kCubic_Verb: |
481 pCnt = 3; | 478 pCnt = 3; |
482 break; | 479 break; |
483 default: | 480 case SkPath::kDone_Verb: |
| 481 SkASSERT(!"growForVerb called for kDone"); |
| 482 // fall through |
| 483 case SkPath::kClose_Verb: |
484 pCnt = 0; | 484 pCnt = 0; |
485 } | 485 } |
486 size_t space = sizeof(uint8_t) + pCnt * sizeof (SkPoint); | 486 size_t space = sizeof(uint8_t) + pCnt * sizeof (SkPoint); |
487 this->makeSpace(space); | 487 this->makeSpace(space); |
488 this->fVerbs[~fVerbCnt] = verb; | 488 this->fVerbs[~fVerbCnt] = verb; |
489 SkPoint* ret = fPoints + fPointCnt; | 489 SkPoint* ret = fPoints + fPointCnt; |
490 fVerbCnt += 1; | 490 fVerbCnt += 1; |
491 fPointCnt += pCnt; | 491 fPointCnt += pCnt; |
492 fFreeSpace -= space; | 492 fFreeSpace -= space; |
493 this->validate(); | 493 this->validate(); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 | 581 |
582 enum { | 582 enum { |
583 kMinSize = 256, | 583 kMinSize = 256, |
584 }; | 584 }; |
585 | 585 |
586 SkPoint* fPoints; // points to begining of the allocation | 586 SkPoint* fPoints; // points to begining of the allocation |
587 uint8_t* fVerbs; // points just past the end of the allocation (v
erbs grow backwards) | 587 uint8_t* fVerbs; // points just past the end of the allocation (v
erbs grow backwards) |
588 int fVerbCnt; | 588 int fVerbCnt; |
589 int fPointCnt; | 589 int fPointCnt; |
590 size_t fFreeSpace; // redundant but saves computation | 590 size_t fFreeSpace; // redundant but saves computation |
| 591 SkTDArray<SkScalar> fConicWeights; |
| 592 |
591 enum { | 593 enum { |
592 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer
o verbs. | 594 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer
o verbs. |
593 }; | 595 }; |
594 mutable int32_t fGenerationID; | 596 mutable int32_t fGenerationID; |
595 SkDEBUGCODE_X(int32_t fEditorsAttached;) // assert that only one editor in u
se at any time. | 597 SkDEBUGCODE_X(int32_t fEditorsAttached;) // assert that only one editor in u
se at any time. |
596 | 598 |
597 #if SK_DEBUG_PATH_REF | 599 #if SK_DEBUG_PATH_REF |
598 SkTDArray<SkPath*> fOwners; | 600 SkTDArray<SkPath*> fOwners; |
599 #endif | 601 #endif |
600 | 602 |
601 typedef SkRefCnt INHERITED; | 603 typedef SkRefCnt INHERITED; |
602 }; | 604 }; |
603 | 605 |
604 SK_DEFINE_INST_COUNT(SkPathRef); | 606 SK_DEFINE_INST_COUNT(SkPathRef); |
605 | 607 |
606 #endif | 608 #endif |
OLD | NEW |