OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 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 #ifndef SkPictureFlat_DEFINED | 8 #ifndef SkPictureFlat_DEFINED |
9 #define SkPictureFlat_DEFINED | 9 #define SkPictureFlat_DEFINED |
10 | 10 |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 , fReady(false) { | 382 , fReady(false) { |
383 this->reset(); | 383 this->reset(); |
384 } | 384 } |
385 | 385 |
386 /** | 386 /** |
387 * Clears the dictionary of all entries. However, it does NOT free the | 387 * Clears the dictionary of all entries. However, it does NOT free the |
388 * memory that was allocated for each entry (that's owned by controller). | 388 * memory that was allocated for each entry (that's owned by controller). |
389 */ | 389 */ |
390 void reset() { | 390 void reset() { |
391 fIndexedData.rewind(); | 391 fIndexedData.rewind(); |
392 // TODO(mtklein): There's no reason to have the index start from 1. Cle
an this up. | |
393 // index 0 is always empty since it is used as a signal that find failed | |
394 fIndexedData.push(NULL); | |
395 } | 392 } |
396 | 393 |
397 ~SkFlatDictionary() { | 394 ~SkFlatDictionary() { |
398 sk_free(fScratch); | 395 sk_free(fScratch); |
399 } | 396 } |
400 | 397 |
401 int count() const { | 398 int count() const { |
402 SkASSERT(fHash.count() == fIndexedData.count() - 1); | 399 SkASSERT(fHash.count() == fIndexedData.count()); |
403 return fHash.count(); | 400 return fHash.count(); |
404 } | 401 } |
405 | 402 |
406 // For testing only. Index is zero-based. | 403 // For testing only. Index is zero-based. |
407 const SkFlatData* operator[](int index) { | 404 const SkFlatData* operator[](int index) { |
408 return fIndexedData[index+1]; | 405 return fIndexedData[index]; |
409 } | 406 } |
410 | 407 |
411 /** | 408 /** |
412 * Given an element of type T return its 1-based index in the dictionary. If | 409 * Given an element of type T return its 1-based index in the dictionary. If |
413 * the element wasn't previously in the dictionary it is automatically | 410 * the element wasn't previously in the dictionary it is automatically |
414 * added. | 411 * added. |
415 * | 412 * |
416 */ | 413 */ |
417 int find(const T& element) { | 414 int find(const T& element) { |
418 return this->findAndReturnFlat(element)->index(); | 415 return this->findAndReturnFlat(element)->index(); |
(...skipping 23 matching lines...) Expand all Loading... |
442 } | 439 } |
443 | 440 |
444 // If we don't have the thing to replace, we're done. | 441 // If we don't have the thing to replace, we're done. |
445 const SkFlatData* found = fHash.find(*toReplace); | 442 const SkFlatData* found = fHash.find(*toReplace); |
446 if (found == NULL) { | 443 if (found == NULL) { |
447 *replaced = false; | 444 *replaced = false; |
448 return flat; | 445 return flat; |
449 } | 446 } |
450 | 447 |
451 // findAndReturnMutableFlat put flat at the back. Swap it into found->i
ndex() instead. | 448 // findAndReturnMutableFlat put flat at the back. Swap it into found->i
ndex() instead. |
| 449 // indices in SkFlatData are 1-based, while fIndexedData is 0-based. Wa
tch out! |
452 SkASSERT(flat->index() == this->count()); | 450 SkASSERT(flat->index() == this->count()); |
453 flat->setIndex(found->index()); | 451 flat->setIndex(found->index()); |
454 fIndexedData.removeShuffle(found->index()); | 452 fIndexedData.removeShuffle(found->index()-1); |
455 SkASSERT(flat == fIndexedData[found->index()]); | 453 SkASSERT(flat == fIndexedData[found->index()-1]); |
456 | 454 |
457 // findAndReturnMutableFlat already called fHash.add(), so we just clean
up the old entry. | 455 // findAndReturnMutableFlat already called fHash.add(), so we just clean
up the old entry. |
458 fHash.remove(*found); | 456 fHash.remove(*found); |
459 fController->unalloc((void*)found); | 457 fController->unalloc((void*)found); |
460 SkASSERT(this->count() == oldCount); | 458 SkASSERT(this->count() == oldCount); |
461 | 459 |
462 *replaced = true; | 460 *replaced = true; |
463 return flat; | 461 return flat; |
464 } | 462 } |
465 | 463 |
466 /** | 464 /** |
467 * Unflatten the objects and return them in SkTRefArray, or return NULL | 465 * Unflatten the objects and return them in SkTRefArray, or return NULL |
468 * if there no objects. Caller takes ownership of result. | 466 * if there no objects. Caller takes ownership of result. |
469 */ | 467 */ |
470 SkTRefArray<T>* unflattenToArray() const { | 468 SkTRefArray<T>* unflattenToArray() const { |
471 const int count = this->count(); | 469 const int count = this->count(); |
472 if (count == 0) { | 470 if (count == 0) { |
473 return NULL; | 471 return NULL; |
474 } | 472 } |
475 SkTRefArray<T>* array = SkTRefArray<T>::Create(count); | 473 SkTRefArray<T>* array = SkTRefArray<T>::Create(count); |
476 for (int i = 0; i < count; i++) { | 474 for (int i = 0; i < count; i++) { |
477 this->unflatten(&array->writableAt(i), fIndexedData[i+1]); | 475 this->unflatten(&array->writableAt(i), fIndexedData[i]); |
478 } | 476 } |
479 return array; | 477 return array; |
480 } | 478 } |
481 | 479 |
482 /** | 480 /** |
483 * Unflatten the specific object at the given index. | 481 * Unflatten the specific object at the given index. |
484 * Caller takes ownership of the result. | 482 * Caller takes ownership of the result. |
485 */ | 483 */ |
486 T* unflatten(int index) const { | 484 T* unflatten(int index) const { |
487 const SkFlatData* element = fIndexedData[index]; | 485 // index is 1-based, while fIndexedData is 0-based. |
| 486 const SkFlatData* element = fIndexedData[index-1]; |
488 SkASSERT(index == element->index()); | 487 SkASSERT(index == element->index()); |
489 | 488 |
490 T* dst = new T; | 489 T* dst = new T; |
491 this->unflatten(dst, element); | 490 this->unflatten(dst, element); |
492 return dst; | 491 return dst; |
493 } | 492 } |
494 | 493 |
495 /** | 494 /** |
496 * Find or insert a flattened version of element into the dictionary. | 495 * Find or insert a flattened version of element into the dictionary. |
497 * Caller does not take ownership of the result. This will not return NULL. | 496 * Caller does not take ownership of the result. This will not return NULL. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 fController->getTypefacePlayback()); | 597 fController->getTypefacePlayback()); |
599 } | 598 } |
600 | 599 |
601 // All SkFlatData* stored in fIndexedData and fHash are owned by the control
ler. | 600 // All SkFlatData* stored in fIndexedData and fHash are owned by the control
ler. |
602 SkAutoTUnref<SkFlatController> fController; | 601 SkAutoTUnref<SkFlatController> fController; |
603 size_t fScratchSize; // How many bytes fScratch has allocated for data itse
lf. | 602 size_t fScratchSize; // How many bytes fScratch has allocated for data itse
lf. |
604 SkFlatData* fScratch; // Owned, lazily allocated, must be freed with sk_fre
e. | 603 SkFlatData* fScratch; // Owned, lazily allocated, must be freed with sk_fre
e. |
605 SkOrderedWriteBuffer fWriteBuffer; | 604 SkOrderedWriteBuffer fWriteBuffer; |
606 bool fReady; | 605 bool fReady; |
607 | 606 |
608 // For index -> SkFlatData. fIndexedData[0] is always NULL. | 607 // For index -> SkFlatData. 0-based, while all indices in the API are 1-bas
ed. Careful! |
609 SkTDArray<const SkFlatData*> fIndexedData; | 608 SkTDArray<const SkFlatData*> fIndexedData; |
610 | 609 |
611 // For SkFlatData -> cached SkFlatData, which has index(). | 610 // For SkFlatData -> cached SkFlatData, which has index(). |
612 SkTDynamicHash<SkFlatData, SkFlatData, | 611 SkTDynamicHash<SkFlatData, SkFlatData, |
613 SkFlatData::Identity, SkFlatData::Hash, SkFlatData::Equal> fH
ash; | 612 SkFlatData::Identity, SkFlatData::Hash, SkFlatData::Equal> fH
ash; |
614 }; | 613 }; |
615 | 614 |
616 /////////////////////////////////////////////////////////////////////////////// | 615 /////////////////////////////////////////////////////////////////////////////// |
617 // Some common dictionaries are defined here for both reference and convenience | 616 // Some common dictionaries are defined here for both reference and convenience |
618 /////////////////////////////////////////////////////////////////////////////// | 617 /////////////////////////////////////////////////////////////////////////////// |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 } | 678 } |
680 | 679 |
681 private: | 680 private: |
682 SkChunkAlloc fHeap; | 681 SkChunkAlloc fHeap; |
683 SkAutoTUnref<SkRefCntSet> fTypefaceSet; | 682 SkAutoTUnref<SkRefCntSet> fTypefaceSet; |
684 void* fLastAllocated; | 683 void* fLastAllocated; |
685 mutable SkTypefacePlayback fTypefacePlayback; | 684 mutable SkTypefacePlayback fTypefacePlayback; |
686 }; | 685 }; |
687 | 686 |
688 #endif | 687 #endif |
OLD | NEW |