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#include "./blapi-build_p.h"
8#include "./blarray_p.h"
9#include "./blfont_p.h"
10#include "./blgradient_p.h"
11#include "./blimage_p.h"
12#include "./blpath_p.h"
13#include "./blpattern_p.h"
14#include "./blpixelconverter_p.h"
15#include "./blregion_p.h"
16#include "./blruntime_p.h"
17#include "./blstring_p.h"
18#include "./blvariant_p.h"
19
20// ============================================================================
21// [BLVariant - None]
22// ============================================================================
23
24BLVariantCore blNone[BL_IMPL_TYPE_COUNT];
25
26// ============================================================================
27// [BLVariant - Internal]
28// ============================================================================
29
30struct BLVariantVirt {
31 BLResult (BL_CDECL* destroy)(void* impl) BL_NOEXCEPT;
32};
33
34BLResult blVariantImplDelete(BLVariantImpl* impl) noexcept {
35 uint32_t implType = impl->implType;
36 switch (implType) {
37 case BL_IMPL_TYPE_NULL:
38 return BL_SUCCESS;
39
40 case BL_IMPL_TYPE_STRING:
41 return blStringImplDelete(reinterpret_cast<BLStringImpl*>(impl));
42
43 case BL_IMPL_TYPE_ARRAY_I8:
44 case BL_IMPL_TYPE_ARRAY_U8:
45 case BL_IMPL_TYPE_ARRAY_I16:
46 case BL_IMPL_TYPE_ARRAY_U16:
47 case BL_IMPL_TYPE_ARRAY_I32:
48 case BL_IMPL_TYPE_ARRAY_U32:
49 case BL_IMPL_TYPE_ARRAY_I64:
50 case BL_IMPL_TYPE_ARRAY_U64:
51 case BL_IMPL_TYPE_ARRAY_F32:
52 case BL_IMPL_TYPE_ARRAY_F64:
53 case BL_IMPL_TYPE_ARRAY_VAR:
54 return blArrayImplDelete(reinterpret_cast<BLArrayImpl*>(impl));
55
56 case BL_IMPL_TYPE_PATH:
57 return blPathImplDelete(reinterpret_cast<BLPathImpl*>(impl));
58
59 case BL_IMPL_TYPE_REGION:
60 return blRegionImplDelete(reinterpret_cast<BLRegionImpl*>(impl));
61
62 case BL_IMPL_TYPE_IMAGE:
63 return blImageImplDelete(reinterpret_cast<BLImageImpl*>(impl));
64
65 case BL_IMPL_TYPE_GRADIENT:
66 return blGradientImplDelete(reinterpret_cast<BLGradientImpl*>(impl));
67
68 case BL_IMPL_TYPE_PATTERN:
69 return blPatternImplDelete(reinterpret_cast<BLPatternImpl*>(impl));
70
71 case BL_IMPL_TYPE_FONT:
72 return blFontImplDelete(reinterpret_cast<BLFontImpl*>(impl));
73
74 default: {
75 uint32_t implTraits = impl->implTraits;
76 if (implTraits & BL_IMPL_TRAIT_VIRT)
77 return static_cast<const BLVariantVirt*>(impl->virt)->destroy(impl);
78
79 // FATAL ERROR: Either a new impl-type was introduced or memory corrupted.
80 blRuntimeFailure("[Blend2D] blVariantImplDelete(): Cannot delete Impl of impl-type #<%u>", implType);
81 }
82 }
83}
84
85// ============================================================================
86// [BLVariant - Init / Reset]
87// ============================================================================
88
89BLResult blVariantInit(void* self) noexcept {
90 static_cast<BLVariant*>(self)->impl = BLVariant::none().impl;
91 return BL_SUCCESS;
92}
93
94BLResult blVariantInitMove(void* self, void* other) noexcept {
95 BLVariantImpl* otherI = static_cast<BLVariant*>(other)->impl;
96
97 static_cast<BLVariant*>(other)->impl = blNone[otherI->implType].impl;
98 static_cast<BLVariant*>(self)->impl = otherI;
99
100 return BL_SUCCESS;
101}
102
103BLResult blVariantInitWeak(void* self, const void* other) noexcept {
104 static_cast<BLVariant*>(self)->impl = blImplIncRef(static_cast<const BLVariant*>(other)->impl);
105 return BL_SUCCESS;
106}
107
108BLResult blVariantReset(void* self) noexcept {
109 BLVariantImpl* selfI = static_cast<BLVariant*>(self)->impl;
110 static_cast<BLVariant*>(self)->impl = blNone[selfI->implType].impl;
111
112 if (blImplDecRefAndTest(selfI))
113 return blVariantImplDelete(selfI);
114 return BL_SUCCESS;
115}
116
117// ============================================================================
118// [BLVariant - Introspection]
119// ============================================================================
120
121uint32_t blVariantGetImplType(const void* self) noexcept {
122 BLVariantImpl* selfI = static_cast<const BLVariant*>(self)->impl;
123 return selfI->implType;
124}
125
126// ============================================================================
127// [BLVariant - Assign]
128// ============================================================================
129
130BLResult blVariantAssignMove(void* self, void* other) noexcept {
131 BLVariantImpl* otherI = static_cast<BLVariant*>(other)->impl;
132 static_cast<BLVariant*>(other)->impl = blNone[otherI->implType].impl;
133
134 BLVariantImpl* selfI = static_cast<BLVariant*>(self)->impl;
135 static_cast<BLVariant*>(self)->impl = otherI;
136
137 if (blImplDecRefAndTest(selfI))
138 return blVariantImplDelete(selfI);
139 return BL_SUCCESS;
140}
141
142BLResult blVariantAssignWeak(void* self, const void* other) noexcept {
143 BLVariantImpl* selfI = static_cast<BLVariant*>(self)->impl;
144 BLVariantImpl* otherI = blImplIncRef(static_cast<const BLVariant*>(other)->impl);
145
146 static_cast<BLVariant*>(self)->impl = otherI;
147
148 if (blImplDecRefAndTest(selfI))
149 return blVariantImplDelete(selfI);
150 return BL_SUCCESS;
151}
152
153// ============================================================================
154// [BLVariant - Equals]
155// ============================================================================
156
157bool blVariantEquals(const void* a, const void* b) noexcept {
158 const BLVariantImpl* aI = static_cast<const BLVariant*>(a)->impl;
159 const BLVariantImpl* bI = static_cast<const BLVariant*>(b)->impl;
160
161 uint32_t implType = aI->implType;
162 if (implType != bI->implType)
163 return false;
164
165 switch (implType) {
166 case BL_IMPL_TYPE_NULL:
167 return true;
168
169 case BL_IMPL_TYPE_STRING:
170 return blStringEquals(reinterpret_cast<const BLStringCore*>(a), reinterpret_cast<const BLStringCore*>(b));
171
172 case BL_IMPL_TYPE_ARRAY_I8:
173 case BL_IMPL_TYPE_ARRAY_U8:
174 case BL_IMPL_TYPE_ARRAY_I16:
175 case BL_IMPL_TYPE_ARRAY_U16:
176 case BL_IMPL_TYPE_ARRAY_I32:
177 case BL_IMPL_TYPE_ARRAY_U32:
178 case BL_IMPL_TYPE_ARRAY_I64:
179 case BL_IMPL_TYPE_ARRAY_U64:
180 case BL_IMPL_TYPE_ARRAY_F32:
181 case BL_IMPL_TYPE_ARRAY_F64:
182 case BL_IMPL_TYPE_ARRAY_VAR:
183 return blArrayEquals(reinterpret_cast<const BLArrayCore*>(a), reinterpret_cast<const BLArrayCore*>(b));
184
185 case BL_IMPL_TYPE_PATH:
186 return blPathEquals(reinterpret_cast<const BLPathCore*>(a), reinterpret_cast<const BLPathCore*>(b));
187
188 case BL_IMPL_TYPE_REGION:
189 return blRegionEquals(reinterpret_cast<const BLRegionCore*>(a), reinterpret_cast<const BLRegionCore*>(b));
190
191 case BL_IMPL_TYPE_IMAGE:
192 return blImageEquals(reinterpret_cast<const BLImageCore*>(a), reinterpret_cast<const BLImageCore*>(b));
193
194 case BL_IMPL_TYPE_GRADIENT:
195 return blGradientEquals(reinterpret_cast<const BLGradientCore*>(a), reinterpret_cast<const BLGradientCore*>(b));
196
197 case BL_IMPL_TYPE_PATTERN:
198 return blPatternEquals(reinterpret_cast<const BLPatternCore*>(a), reinterpret_cast<const BLPatternCore*>(b));
199
200 default:
201 return aI == bI;
202 }
203}
204