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 | |
24 | BLVariantCore blNone[BL_IMPL_TYPE_COUNT]; |
25 | |
26 | // ============================================================================ |
27 | // [BLVariant - Internal] |
28 | // ============================================================================ |
29 | |
30 | struct BLVariantVirt { |
31 | BLResult (BL_CDECL* destroy)(void* impl) BL_NOEXCEPT; |
32 | }; |
33 | |
34 | BLResult 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 | |
89 | BLResult blVariantInit(void* self) noexcept { |
90 | static_cast<BLVariant*>(self)->impl = BLVariant::none().impl; |
91 | return BL_SUCCESS; |
92 | } |
93 | |
94 | BLResult 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 | |
103 | BLResult 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 | |
108 | BLResult 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 | |
121 | uint32_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 | |
130 | BLResult 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 | |
142 | BLResult 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 | |
157 | bool 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 | |