1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkDescriptor_DEFINED 9 #define SkDescriptor_DEFINED 10 11 #include <memory> 12 #include <new> 13 14 #include "include/private/SkMacros.h" 15 #include "include/private/SkNoncopyable.h" 16 #include "src/core/SkScalerContext.h" 17 18 class SkDescriptor : SkNoncopyable { 19 public: ComputeOverhead(int entryCount)20 static size_t ComputeOverhead(int entryCount) { 21 SkASSERT(entryCount >= 0); 22 return sizeof(SkDescriptor) + entryCount * sizeof(Entry); 23 } 24 25 static std::unique_ptr<SkDescriptor> Alloc(size_t length); 26 27 // 28 // Ensure the unsized delete is called. 29 void operator delete(void* p); 30 void* operator new(size_t); new(size_t,void * p)31 void* operator new(size_t, void* p) { return p; } 32 getLength()33 uint32_t getLength() const { return fLength; } 34 void* addEntry(uint32_t tag, size_t length, const void* data = nullptr); 35 void computeChecksum(); 36 37 // Assumes that getLength <= capacity of this SkDescriptor. 38 bool isValid() const; 39 40 #ifdef SK_DEBUG assertChecksum()41 void assertChecksum() const { 42 SkASSERT(SkDescriptor::ComputeChecksum(this) == fChecksum); 43 } 44 #endif 45 46 const void* findEntry(uint32_t tag, uint32_t* length) const; 47 48 std::unique_ptr<SkDescriptor> copy() const; 49 50 // This assumes that all memory added has a length that is a multiple of 4. This is checked 51 // by the assert in addEntry. 52 bool operator==(const SkDescriptor& other) const; 53 bool operator!=(const SkDescriptor& other) const { return !(*this == other); } 54 getChecksum()55 uint32_t getChecksum() const { return fChecksum; } 56 57 struct Entry { 58 uint32_t fTag; 59 uint32_t fLen; 60 }; 61 62 #ifdef SK_DEBUG getCount()63 uint32_t getCount() const { return fCount; } 64 #endif 65 66 SkString dumpRec() const; 67 68 private: 69 SkDescriptor() = default; 70 friend class SkDescriptorTestHelper; 71 friend class SkAutoDescriptor; 72 73 static uint32_t ComputeChecksum(const SkDescriptor* desc); 74 75 uint32_t fChecksum{0}; // must be first 76 uint32_t fLength{sizeof(SkDescriptor)}; // must be second 77 uint32_t fCount{0}; 78 }; 79 80 class SkAutoDescriptor { 81 public: 82 SkAutoDescriptor(); 83 explicit SkAutoDescriptor(size_t size); 84 explicit SkAutoDescriptor(const SkDescriptor&); 85 SkAutoDescriptor(const SkAutoDescriptor&); 86 SkAutoDescriptor& operator=(const SkAutoDescriptor&); 87 SkAutoDescriptor(SkAutoDescriptor&&); 88 SkAutoDescriptor& operator=(SkAutoDescriptor&&); 89 90 ~SkAutoDescriptor(); 91 92 void reset(size_t size); 93 void reset(const SkDescriptor& desc); getDesc()94 SkDescriptor* getDesc() const { SkASSERT(fDesc); return fDesc; } 95 96 private: 97 void free(); 98 static constexpr size_t kStorageSize 99 = sizeof(SkDescriptor) 100 + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec) // for rec 101 + sizeof(SkDescriptor::Entry) + sizeof(void*) // for typeface 102 + 32; // slop for occasional small extras 103 104 SkDescriptor* fDesc{nullptr}; 105 alignas(uint32_t) char fStorage[kStorageSize]; 106 }; 107 108 #endif //SkDescriptor_DEFINED 109