• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/SkBuffer.h"
17 #include "src/core/SkFontPriv.h"
18 #include "src/core/SkScalerContext.h"
19 
20 class SkDescriptor : SkNoncopyable {
21 public:
ComputeOverhead(int entryCount)22     static size_t ComputeOverhead(int entryCount) {
23         SkASSERT(entryCount >= 0);
24         return sizeof(SkDescriptor) + entryCount * sizeof(Entry);
25     }
26 
27     static std::unique_ptr<SkDescriptor> Alloc(size_t length);
28 
29     //
30     // Ensure the unsized delete is called.
31     void operator delete(void* p);
32     void* operator new(size_t);
new(size_t,void * p)33     void* operator new(size_t, void* p) { return p; }
34 
35     void flatten(SkWriteBuffer& buffer) const;
36 
getLength()37     uint32_t getLength() const { return fLength; }
38     void* addEntry(uint32_t tag, size_t length, const void* data = nullptr);
39     void computeChecksum();
40 
41     // Assumes that getLength <= capacity of this SkDescriptor.
42     bool isValid() const;
43 
44 #ifdef SK_DEBUG
assertChecksum()45     void assertChecksum() const {
46         SkASSERT(SkDescriptor::ComputeChecksum(this) == fChecksum);
47     }
48 #endif
49 
50     const void* findEntry(uint32_t tag, uint32_t* length) const;
51 
52     std::unique_ptr<SkDescriptor> copy() const;
53 
54     // This assumes that all memory added has a length that is a multiple of 4. This is checked
55     // by the assert in addEntry.
56     bool operator==(const SkDescriptor& other) const;
57     bool operator!=(const SkDescriptor& other) const { return !(*this == other); }
58 
getChecksum()59     uint32_t getChecksum() const { return fChecksum; }
60 
61     struct Entry {
62         uint32_t fTag;
63         uint32_t fLen;
64     };
65 
66 #ifdef SK_DEBUG
getCount()67     uint32_t getCount() const { return fCount; }
68 #endif
69 
70     SkString dumpRec() const;
71 
72 private:
73     SkDescriptor() = default;
74     friend class SkDescriptorTestHelper;
75     friend class SkAutoDescriptor;
76 
77     static uint32_t ComputeChecksum(const SkDescriptor* desc);
78 
79     uint32_t fChecksum{0};  // must be first
80     uint32_t fLength{sizeof(SkDescriptor)};    // must be second
81     uint32_t fCount{0};
82 };
83 
84 class SkAutoDescriptor {
85 public:
86     SkAutoDescriptor();
87     explicit SkAutoDescriptor(size_t size);
88     explicit SkAutoDescriptor(const SkDescriptor&);
89     SkAutoDescriptor(const SkAutoDescriptor&);
90     SkAutoDescriptor& operator=(const SkAutoDescriptor&);
91     SkAutoDescriptor(SkAutoDescriptor&&);
92     SkAutoDescriptor& operator=(SkAutoDescriptor&&);
93     ~SkAutoDescriptor();
94 
95     // Returns no value if there is an error.
96     static std::optional<SkAutoDescriptor> MakeFromBuffer(SkReadBuffer& buffer);
97 
98     void reset(size_t size);
99     void reset(const SkDescriptor& desc);
getDesc()100     SkDescriptor* getDesc() const { SkASSERT(fDesc); return fDesc; }
101 
102 private:
103     void free();
104     static constexpr size_t kStorageSize
105             = sizeof(SkDescriptor)
106               + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec) // for rec
107               + sizeof(SkDescriptor::Entry) + sizeof(void*)              // for typeface
108               + 32;   // slop for occasional small extras
109 
110     SkDescriptor*   fDesc{nullptr};
111     alignas(uint32_t) char fStorage[kStorageSize];
112 };
113 
114 #endif  //SkDescriptor_DEFINED
115