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.
20BL_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.
109BL_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.
133struct 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 header[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].
173struct BLVariantCore {
174 BLVariantImpl* impl;
175};
176
177#ifdef __cplusplus
178extern "C" {
179#endif
180
181//! Built-in none objects indexed by `BLImplType`
182extern 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).
199class BLVariant : public BLVariantCore {
200public:
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