| 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 |