1 | // [Blend2D] |
2 | // 2D Vector Graphics Powered by a JIT Compiler. |
3 | // |
4 | // [License] |
5 | // Zlib - See LICENSE.md file in the package. |
6 | |
7 | #ifndef BLEND2D_BLVARIANT_H |
8 | #define BLEND2D_BLVARIANT_H |
9 | |
10 | #include "./blapi.h" |
11 | |
12 | //! \addtogroup blend2d_api_globals |
13 | //! \{ |
14 | |
15 | // ============================================================================ |
16 | // [Constants] |
17 | // ============================================================================ |
18 | |
19 | //! Impl type identifier used by to describe a Blend2D Impl. |
20 | BL_DEFINE_ENUM(BLImplType) { |
21 | //! Type is `Null`. |
22 | BL_IMPL_TYPE_NULL = 0, |
23 | //! Type is `BLBitArray`. |
24 | BL_IMPL_TYPE_BIT_ARRAY = 1, |
25 | //! Type is `BLString`. |
26 | BL_IMPL_TYPE_STRING = 2, |
27 | //! Type is `BLArray<T>` where `T` is `BLVariant` or other ref-counted type. |
28 | BL_IMPL_TYPE_ARRAY_VAR = 3, |
29 | //! Type is `BLArray<T>` where `T` matches 8-bit signed integral type. |
30 | BL_IMPL_TYPE_ARRAY_I8 = 4, |
31 | //! Type is `BLArray<T>` where `T` matches 8-bit unsigned integral type. |
32 | BL_IMPL_TYPE_ARRAY_U8 = 5, |
33 | //! Type is `BLArray<T>` where `T` matches 16-bit signed integral type. |
34 | BL_IMPL_TYPE_ARRAY_I16 = 6, |
35 | //! Type is `BLArray<T>` where `T` matches 16-bit unsigned integral type. |
36 | BL_IMPL_TYPE_ARRAY_U16 = 7, |
37 | //! Type is `BLArray<T>` where `T` matches 32-bit signed integral type. |
38 | BL_IMPL_TYPE_ARRAY_I32 = 8, |
39 | //! Type is `BLArray<T>` where `T` matches 32-bit unsigned integral type. |
40 | BL_IMPL_TYPE_ARRAY_U32 = 9, |
41 | //! Type is `BLArray<T>` where `T` matches 64-bit signed integral type. |
42 | BL_IMPL_TYPE_ARRAY_I64 = 10, |
43 | //! Type is `BLArray<T>` where `T` matches 64-bit unsigned integral type. |
44 | BL_IMPL_TYPE_ARRAY_U64 = 11, |
45 | //! Type is `BLArray<T>` where `T` matches 32-bit floating point type. |
46 | BL_IMPL_TYPE_ARRAY_F32 = 12, |
47 | //! Type is `BLArray<T>` where `T` matches 64-bit floating point type. |
48 | BL_IMPL_TYPE_ARRAY_F64 = 13, |
49 | //! Type is `BLArray<T>` where `T` is a struct of size 1. |
50 | BL_IMPL_TYPE_ARRAY_STRUCT_1 = 14, |
51 | //! Type is `BLArray<T>` where `T` is a struct of size 2. |
52 | BL_IMPL_TYPE_ARRAY_STRUCT_2 = 15, |
53 | //! Type is `BLArray<T>` where `T` is a struct of size 3. |
54 | BL_IMPL_TYPE_ARRAY_STRUCT_3 = 16, |
55 | //! Type is `BLArray<T>` where `T` is a struct of size 4. |
56 | BL_IMPL_TYPE_ARRAY_STRUCT_4 = 17, |
57 | //! Type is `BLArray<T>` where `T` is a struct of size 6. |
58 | BL_IMPL_TYPE_ARRAY_STRUCT_6 = 18, |
59 | //! Type is `BLArray<T>` where `T` is a struct of size 8. |
60 | BL_IMPL_TYPE_ARRAY_STRUCT_8 = 19, |
61 | //! Type is `BLArray<T>` where `T` is a struct of size 10. |
62 | BL_IMPL_TYPE_ARRAY_STRUCT_10 = 20, |
63 | //! Type is `BLArray<T>` where `T` is a struct of size 12. |
64 | BL_IMPL_TYPE_ARRAY_STRUCT_12 = 21, |
65 | //! Type is `BLArray<T>` where `T` is a struct of size 16. |
66 | BL_IMPL_TYPE_ARRAY_STRUCT_16 = 22, |
67 | //! Type is `BLArray<T>` where `T` is a struct of size 20. |
68 | BL_IMPL_TYPE_ARRAY_STRUCT_20 = 23, |
69 | //! Type is `BLArray<T>` where `T` is a struct of size 24. |
70 | BL_IMPL_TYPE_ARRAY_STRUCT_24 = 24, |
71 | //! Type is `BLArray<T>` where `T` is a struct of size 32. |
72 | BL_IMPL_TYPE_ARRAY_STRUCT_32 = 25, |
73 | //! Type is `BLPath`. |
74 | BL_IMPL_TYPE_PATH = 32, |
75 | //! Type is `BLRegion`. |
76 | BL_IMPL_TYPE_REGION = 33, |
77 | //! Type is `BLImage`. |
78 | BL_IMPL_TYPE_IMAGE = 34, |
79 | //! Type is `BLImageCodec`. |
80 | BL_IMPL_TYPE_IMAGE_CODEC = 35, |
81 | //! Type is `BLImageDecoder`. |
82 | BL_IMPL_TYPE_IMAGE_DECODER = 36, |
83 | //! Type is `BLImageEncoder`. |
84 | BL_IMPL_TYPE_IMAGE_ENCODER = 37, |
85 | //! Type is `BLGradient`. |
86 | BL_IMPL_TYPE_GRADIENT = 38, |
87 | //! Type is `BLPattern`. |
88 | BL_IMPL_TYPE_PATTERN = 39, |
89 | //! Type is `BLContext`. |
90 | BL_IMPL_TYPE_CONTEXT = 40, |
91 | //! Type is `BLFont`. |
92 | BL_IMPL_TYPE_FONT = 50, |
93 | //! Type is `BLFontFace`. |
94 | BL_IMPL_TYPE_FONT_FACE = 51, |
95 | //! Type is `BLFontData`. |
96 | BL_IMPL_TYPE_FONT_DATA = 52, |
97 | //! Type is `BLFontLoader`. |
98 | BL_IMPL_TYPE_FONT_LOADER = 53, |
99 | //! Type is `BLFontFeatureOptions`. |
100 | BL_IMPL_TYPE_FONT_FEATURE_OPTIONS = 54, |
101 | //! Type is `BLFontVariationOptions`. |
102 | BL_IMPL_TYPE_FONT_VARIATION_OPTIONS = 55, |
103 | |
104 | //! Count of type identifiers including all reserved ones. |
105 | BL_IMPL_TYPE_COUNT = 64 |
106 | }; |
107 | |
108 | //! Impl traits that describe some details about a Blend2D `Impl` data. |
109 | BL_DEFINE_ENUM(BLImplTraits) { |
110 | //! The data this container holds is mutable if `refCount == 1`. |
111 | BL_IMPL_TRAIT_MUTABLE = 0x01u, |
112 | //! The data this container holds is always immutable. |
113 | BL_IMPL_TRAIT_IMMUTABLE = 0x02u, |
114 | //! Set if the impl uses an external data (data is not part of impl). |
115 | BL_IMPL_TRAIT_EXTERNAL = 0x04u, |
116 | //! Set if the impl was not allocated by `blRuntimeAllocImpl()`. |
117 | BL_IMPL_TRAIT_FOREIGN = 0x08u, |
118 | //! Set if the impl provides a virtual function table (first member). |
119 | BL_IMPL_TRAIT_VIRT = 0x10u, |
120 | //! Set if the impl is a built-in null instance (default constructed). |
121 | BL_IMPL_TRAIT_NULL = 0x80u |
122 | }; |
123 | |
124 | // ============================================================================ |
125 | // [BLVariant - Core] |
126 | // ============================================================================ |
127 | |
128 | //! Variant [C Interface - Impl]. |
129 | //! |
130 | //! Please note that this impl defines just the layout of any Value-based or |
131 | //! Object-based Impl. Members not defined by the layout can be used to store |
132 | //! any data. |
133 | struct BLVariantImpl { |
134 | // IMPL HEADER |
135 | // ----------- |
136 | // |
137 | // [32-bit: 12 bytes] |
138 | // [64-bit: 24 bytes] |
139 | |
140 | //! Union that provides either one `virt` table pointer and two reserved |
141 | //! fields at index [1] and [2] in case of object or 3 reserved fields in |
142 | //! case of value. |
143 | union { |
144 | //! Virtual function table (only available to impls with BL_IMPL_TRAIT_VIRT trait). |
145 | const void* virt; |
146 | //! Space reserved for object/value header (must be array-view if the impl is container). |
147 | uintptr_t [3]; |
148 | }; |
149 | |
150 | // IMPL COMMON |
151 | // ----------- |
152 | // |
153 | // [32-bit: 8 bytes] |
154 | // [64-bit: 12 bytes] |
155 | |
156 | //! Reference count. |
157 | volatile size_t refCount; |
158 | //! Impl type, see `BLImplType`. |
159 | uint8_t implType; |
160 | //! Traits of this impl, see `BLImplTraits`. |
161 | uint8_t implTraits; |
162 | //! Memory pool data, zero if not mem-pooled. |
163 | uint16_t memPoolData; |
164 | |
165 | // IMPL BODY |
166 | // --------- |
167 | |
168 | //! Reserved data, free to be used by the impl (padding for us). |
169 | uint8_t reserved[4]; |
170 | }; |
171 | |
172 | //! Variant [C Interface - Core]. |
173 | struct BLVariantCore { |
174 | BLVariantImpl* impl; |
175 | }; |
176 | |
177 | #ifdef __cplusplus |
178 | extern "C" { |
179 | #endif |
180 | |
181 | //! Built-in none objects indexed by `BLImplType` |
182 | extern BL_API BLVariantCore blNone[BL_IMPL_TYPE_COUNT]; |
183 | |
184 | #ifdef __cplusplus |
185 | } // {Extern:C} |
186 | #endif |
187 | |
188 | // ============================================================================ |
189 | // [BLVariant - C++] |
190 | // ============================================================================ |
191 | |
192 | #ifdef __cplusplus |
193 | //! Variant [C++ API]. |
194 | //! |
195 | //! `BLVariant` defines a common interface that can be used to work with both |
196 | //! Blend2D values and objects in an abstract way without knowing their type. |
197 | //! Since both objects and values share the same common strucutre it's possible |
198 | //! to treat them as same at the lowest level (memory and lifetime management). |
199 | class BLVariant : public BLVariantCore { |
200 | public: |
201 | BL_INLINE BLVariant() noexcept { this->impl = none().impl; } |
202 | BL_INLINE BLVariant(BLVariant&& other) noexcept { blVariantInitMove(this, &other); } |
203 | BL_INLINE BLVariant(const BLVariant& other) noexcept { blVariantInitWeak(this, &other); } |
204 | BL_INLINE explicit BLVariant(BLVariantImpl* impl) noexcept { this->impl = impl; } |
205 | BL_INLINE ~BLVariant() noexcept { blVariantReset(this); } |
206 | |
207 | BL_INLINE BLVariant& operator=(BLVariant&& other) noexcept { blVariantAssignMove(this, &other); return *this; } |
208 | BL_INLINE BLVariant& operator=(const BLVariant& other) noexcept { blVariantAssignWeak(this, &other); return *this; } |
209 | |
210 | //! Tests whether the variant is a built-in null instance (of any impl-type). |
211 | BL_INLINE bool isNone() const noexcept { return (impl->implTraits & BL_IMPL_TRAIT_NULL) != 0; } |
212 | |
213 | BL_INLINE BLResult reset() noexcept { return blVariantReset(this); } |
214 | |
215 | BL_INLINE void swap(BLVariant& other) noexcept { std::swap(this->impl, other.impl); } |
216 | |
217 | BL_INLINE BLResult assign(BLVariant&& other) noexcept { return blVariantAssignMove(this, &other); } |
218 | BL_INLINE BLResult assign(const BLVariant& other) noexcept { return blVariantAssignWeak(this, &other); } |
219 | |
220 | BL_INLINE bool equals(const BLVariant& other) const noexcept { return blVariantEquals(this, &other); } |
221 | |
222 | static BL_INLINE const BLVariant& none() noexcept { return reinterpret_cast<const BLVariant*>(blNone)[BL_IMPL_TYPE_NULL]; } |
223 | }; |
224 | #endif |
225 | |
226 | //! \} |
227 | |
228 | #endif // BLEND2D_BLVARIANT_H |
229 | |