• 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/base/SkMacros.h"
15 #include "include/private/base/SkNoncopyable.h"
16 #include "src/base/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 
getCount()66     uint32_t getCount() const { return fCount; }
67 
68     SkString dumpRec() const;
69 
70 private:
71     SkDescriptor() = default;
72     friend class SkDescriptorTestHelper;
73     friend class SkAutoDescriptor;
74 
75     static uint32_t ComputeChecksum(const SkDescriptor* desc);
76 
77     uint32_t fChecksum{0};  // must be first
78     uint32_t fLength{sizeof(SkDescriptor)};    // must be second
79     uint32_t fCount{0};
80 };
81 
82 class SkAutoDescriptor {
83 public:
84     SkAutoDescriptor();
85     explicit SkAutoDescriptor(size_t size);
86     explicit SkAutoDescriptor(const SkDescriptor&);
87     SkAutoDescriptor(const SkAutoDescriptor&);
88     SkAutoDescriptor& operator=(const SkAutoDescriptor&);
89     SkAutoDescriptor(SkAutoDescriptor&&);
90     SkAutoDescriptor& operator=(SkAutoDescriptor&&);
91     ~SkAutoDescriptor();
92 
93     // Returns no value if there is an error.
94     static std::optional<SkAutoDescriptor> MakeFromBuffer(SkReadBuffer& buffer);
95 
96     void reset(size_t size);
97     void reset(const SkDescriptor& desc);
getDesc()98     SkDescriptor* getDesc() const { SkASSERT(fDesc); return fDesc; }
99 
100 private:
101     void free();
102     static constexpr size_t kStorageSize
103             = sizeof(SkDescriptor)
104               + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec) // for rec
105               + sizeof(SkDescriptor::Entry) + sizeof(void*)              // for typeface
106               + 32;   // slop for occasional small extras
107 
108     SkDescriptor*   fDesc{nullptr};
109     alignas(uint32_t) char fStorage[kStorageSize];
110 };
111 
112 #endif  //SkDescriptor_DEFINED
113