@react-native-ohos/react-native-svg 15.12.1-rc.1 → 15.12.1-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.OpenSource +10 -10
- package/README.md +13 -13
- package/css/package.json +5 -5
- package/harmony/svg/BuildProfile.ets +16 -16
- package/harmony/svg/build-profile.json5 +9 -9
- package/harmony/svg/hvigorfile.ts +1 -1
- package/harmony/svg/index.ets +6 -6
- package/harmony/svg/oh-package.json5 +13 -13
- package/harmony/svg/src/main/cpp/SVGPackage.h +4 -0
- package/harmony/svg/src/main/cpp/SvgArkUINode.cpp +3 -0
- package/harmony/svg/src/main/cpp/SvgArkUINode.h +15 -9
- package/harmony/svg/src/main/cpp/SvgFilter.cpp +505 -505
- package/harmony/svg/src/main/cpp/SvgFilter.h +112 -112
- package/harmony/svg/src/main/cpp/SvgForeignObjectNode.cpp +74 -0
- package/harmony/svg/src/main/cpp/SvgForeignObjectNode.h +54 -0
- package/harmony/svg/src/main/cpp/SvgForeignObjectNodeDelegate.h +30 -0
- package/harmony/svg/src/main/cpp/SvgNode.cpp +64 -0
- package/harmony/svg/src/main/cpp/SvgNode.h +17 -1
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeBlendComponentInstance.cpp +40 -40
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeBlendComponentInstance.h +48 -48
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeColorMatrixComponentInstance.cpp +33 -33
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeColorMatrixComponentInstance.h +48 -48
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeCompositeComponentInstance.cpp +39 -39
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeCompositeComponentInstance.h +55 -55
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeFloodComponentInstance.cpp +33 -33
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeFloodComponentInstance.h +49 -49
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeGaussianBlurComponentInstance.cpp +34 -34
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeGaussianBlurComponentInstance.h +48 -48
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeOffsetComponentInstance.cpp +35 -35
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFeOffsetComponentInstance.h +45 -45
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFilterComponentInstance.cpp +198 -198
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGFilterComponentInstance.h +48 -48
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGForeignObjectComponentInstance.cpp +65 -0
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGForeignObjectComponentInstance.h +50 -0
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGGroupComponentInstance.h +8 -4
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGImageComponentInstance.cpp +4 -1
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGSvgViewComponentInstance.cpp +37 -0
- package/harmony/svg/src/main/cpp/componentInstances/RNSVGSvgViewComponentInstance.h +10 -2
- package/harmony/svg/src/main/cpp/downloadUtils/ImageSourceResolver.cpp +36 -15
- package/harmony/svg/src/main/cpp/downloadUtils/ImageSourceResolver.h +6 -10
- package/harmony/svg/src/main/cpp/generated/RNOH/generated/components/RNSVGFeBlendJSIBinder.h +26 -26
- package/harmony/svg/src/main/cpp/generated/RNOH/generated/components/RNSVGFeColorMatrixJSIBinder.h +26 -26
- package/harmony/svg/src/main/cpp/generated/RNOH/generated/components/RNSVGFeCompositeJSIBinder.h +30 -30
- package/harmony/svg/src/main/cpp/generated/RNOH/generated/components/RNSVGFeFloodJSIBinder.h +26 -26
- package/harmony/svg/src/main/cpp/generated/RNOH/generated/components/RNSVGFeGaussianBlurJSIBinder.h +26 -26
- package/harmony/svg/src/main/cpp/generated/RNOH/generated/components/RNSVGFeOffsetJSIBinder.h +26 -26
- package/harmony/svg/src/main/cpp/generated/RNOH/generated/components/RNSVGFilterJSIBinder.h +44 -44
- package/harmony/svg/src/main/cpp/generated/react/renderer/components/react_native_svg/Props.cpp +977 -977
- package/harmony/svg/src/main/cpp/generated/react/renderer/components/react_native_svg/Props.h +1280 -1280
- package/harmony/svg/src/main/cpp/utils/DynamicUtils.h +55 -55
- package/harmony/svg/src/main/cpp/utils/FilterManager.h +190 -190
- package/harmony/svg/src/main/ets/RNSVGImageModule.ts +21 -21
- package/harmony/svg/src/main/ets/RNSVGRenderableModule.ts +16 -16
- package/harmony/svg/src/main/ets/RNSVGSvgViewModule.ts +18 -18
- package/harmony/svg/src/main/ets/SvgPackage.ts +57 -57
- package/harmony/svg/src/main/module.json5 +7 -7
- package/harmony/svg/src/main/resources/base/element/string.json +8 -8
- package/harmony/svg/src/main/resources/en_US/element/string.json +8 -8
- package/harmony/svg/src/main/resources/zh_CN/element/string.json +8 -8
- package/harmony/svg/ts.ts +7 -7
- package/harmony/svg.har +0 -0
- package/lib/commonjs/css/index.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/css/index.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/package.json +53 -54
- package/src/css/index.tsx +19 -19
- package/src/index.tsx +2 -2
- package/tsconfig.json +11 -11
|
@@ -1,505 +1,505 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
-
* Use of this source code is governed by a MIT license that can be
|
|
4
|
-
* found in the LICENSE file.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
#include "SvgFilter.h"
|
|
8
|
-
#include <native_drawing/drawing_mask_filter.h>
|
|
9
|
-
#include <native_drawing/drawing_color_filter.h>
|
|
10
|
-
#include <native_drawing/drawing_image_filter.h>
|
|
11
|
-
#include <native_drawing/drawing_shadow_layer.h>
|
|
12
|
-
#include <native_drawing/drawing_brush.h>
|
|
13
|
-
#include <native_drawing/drawing_pen.h>
|
|
14
|
-
#include <native_drawing/drawing_types.h>
|
|
15
|
-
#include <glog/logging.h>
|
|
16
|
-
#include <algorithm>
|
|
17
|
-
#include <cmath>
|
|
18
|
-
#include <string>
|
|
19
|
-
#include <stdexcept>
|
|
20
|
-
#include <sstream>
|
|
21
|
-
#include <vector>
|
|
22
|
-
#include <set>
|
|
23
|
-
#include <map>
|
|
24
|
-
#include <memory>
|
|
25
|
-
|
|
26
|
-
#ifndef M_PI
|
|
27
|
-
#define M_PI 3.14159265358979323846
|
|
28
|
-
#endif
|
|
29
|
-
|
|
30
|
-
namespace rnoh {
|
|
31
|
-
namespace svg {
|
|
32
|
-
|
|
33
|
-
struct InputSource {
|
|
34
|
-
std::string name;
|
|
35
|
-
OH_Drawing_ImageFilter* imageFilter = nullptr;
|
|
36
|
-
OH_Drawing_ColorFilter* colorFilter = nullptr;
|
|
37
|
-
OH_Drawing_MaskFilter* maskFilter = nullptr;
|
|
38
|
-
OH_Drawing_Filter* combinedFilter = nullptr;
|
|
39
|
-
bool ownsFilters = false;
|
|
40
|
-
|
|
41
|
-
~InputSource() {
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
void cleanup() {
|
|
45
|
-
if (ownsFilters) {
|
|
46
|
-
if (imageFilter) {
|
|
47
|
-
OH_Drawing_ImageFilterDestroy(imageFilter);
|
|
48
|
-
imageFilter = nullptr;
|
|
49
|
-
}
|
|
50
|
-
if (colorFilter) {
|
|
51
|
-
OH_Drawing_ColorFilterDestroy(colorFilter);
|
|
52
|
-
colorFilter = nullptr;
|
|
53
|
-
}
|
|
54
|
-
if (maskFilter) {
|
|
55
|
-
OH_Drawing_MaskFilterDestroy(maskFilter);
|
|
56
|
-
maskFilter = nullptr;
|
|
57
|
-
}
|
|
58
|
-
if (combinedFilter) {
|
|
59
|
-
OH_Drawing_FilterDestroy(combinedFilter);
|
|
60
|
-
combinedFilter = nullptr;
|
|
61
|
-
}
|
|
62
|
-
ownsFilters = false;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
class InputSourceManager {
|
|
68
|
-
private:
|
|
69
|
-
std::map<std::string, std::shared_ptr<InputSource>> sources_;
|
|
70
|
-
|
|
71
|
-
public:
|
|
72
|
-
void RegisterSource(const std::string& name, OH_Drawing_ImageFilter* imageFilter = nullptr,
|
|
73
|
-
OH_Drawing_ColorFilter* colorFilter = nullptr, OH_Drawing_MaskFilter* maskFilter = nullptr) {
|
|
74
|
-
auto source = std::make_shared<InputSource>();
|
|
75
|
-
source->name = name;
|
|
76
|
-
source->imageFilter = imageFilter;
|
|
77
|
-
source->colorFilter = colorFilter;
|
|
78
|
-
source->maskFilter = maskFilter;
|
|
79
|
-
|
|
80
|
-
if (imageFilter || colorFilter || maskFilter) {
|
|
81
|
-
source->combinedFilter = OH_Drawing_FilterCreate();
|
|
82
|
-
if (source->combinedFilter) {
|
|
83
|
-
if (imageFilter) OH_Drawing_FilterSetImageFilter(source->combinedFilter, imageFilter);
|
|
84
|
-
if (colorFilter) OH_Drawing_FilterSetColorFilter(source->combinedFilter, colorFilter);
|
|
85
|
-
if (maskFilter) OH_Drawing_FilterSetMaskFilter(source->combinedFilter, maskFilter);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
sources_[name] = source;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
std::shared_ptr<InputSource> GetSource(const std::string& name) {
|
|
93
|
-
if (name.empty()) {
|
|
94
|
-
return nullptr;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
auto it = sources_.find(name);
|
|
98
|
-
if (it != sources_.end()) {
|
|
99
|
-
return it->second;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (name == "SourceGraphic") {
|
|
103
|
-
return GetOrCreateStandardSource("SourceGraphic");
|
|
104
|
-
} else if (name == "SourceAlpha") {
|
|
105
|
-
return GetOrCreateStandardSource("SourceAlpha");
|
|
106
|
-
} else if (name == "BackgroundImage") {
|
|
107
|
-
return GetOrCreateStandardSource("BackgroundImage");
|
|
108
|
-
} else if (name == "BackgroundAlpha") {
|
|
109
|
-
return GetOrCreateStandardSource("BackgroundAlpha");
|
|
110
|
-
} else if (name == "FillPaint") {
|
|
111
|
-
return GetOrCreateStandardSource("FillPaint");
|
|
112
|
-
} else if (name == "StrokePaint") {
|
|
113
|
-
return GetOrCreateStandardSource("StrokePaint");
|
|
114
|
-
}
|
|
115
|
-
DLOG(WARNING) << "[SvgFilter] Input source not found: " << name;
|
|
116
|
-
return nullptr;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
void Clear() {
|
|
120
|
-
for (auto& pair : sources_) {
|
|
121
|
-
if (pair.second) {
|
|
122
|
-
pair.second->cleanup();
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
sources_.clear();
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private:
|
|
129
|
-
std::shared_ptr<InputSource> GetOrCreateStandardSource(const std::string& name) {
|
|
130
|
-
auto it = sources_.find(name);
|
|
131
|
-
if (it != sources_.end()) {
|
|
132
|
-
return it->second;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
auto source = std::make_shared<InputSource>();
|
|
136
|
-
source->name = name;
|
|
137
|
-
if (name == "SourceAlpha") {
|
|
138
|
-
float alphaMatrix[20] = {
|
|
139
|
-
0, 0, 0, 0, 0,
|
|
140
|
-
0, 0, 0, 0, 0,
|
|
141
|
-
0, 0, 0, 0, 0,
|
|
142
|
-
0, 0, 0, 1, 0
|
|
143
|
-
};
|
|
144
|
-
source->colorFilter = OH_Drawing_ColorFilterCreateMatrix(alphaMatrix);
|
|
145
|
-
} else if (name == "BackgroundImage") {
|
|
146
|
-
} else if (name == "BackgroundAlpha") {
|
|
147
|
-
float backgroundAlphaMatrix[20] = {
|
|
148
|
-
0, 0, 0, 0, 0,
|
|
149
|
-
0, 0, 0, 0, 0,
|
|
150
|
-
0, 0, 0, 0, 0,
|
|
151
|
-
0, 0, 0, 1, 0
|
|
152
|
-
};
|
|
153
|
-
source->colorFilter = OH_Drawing_ColorFilterCreateMatrix(backgroundAlphaMatrix);
|
|
154
|
-
} else if (name == "FillPaint" || name == "StrokePaint") {
|
|
155
|
-
float matrix[20] = {
|
|
156
|
-
1, 0, 0, 0, 0,
|
|
157
|
-
0, 1, 0, 0, 0,
|
|
158
|
-
0, 0, 1, 0, 0,
|
|
159
|
-
0, 0, 0, 1, 0
|
|
160
|
-
};
|
|
161
|
-
source->colorFilter = OH_Drawing_ColorFilterCreateMatrix(matrix);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
sources_[name] = source;
|
|
165
|
-
return source;
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
static InputSourceManager g_inputSourceManager;
|
|
170
|
-
OH_Drawing_ImageFilter* SvgFilter::GetInputImageFilter(const std::string& inputName) {
|
|
171
|
-
if (inputName.empty() || inputName == "SourceGraphic") {
|
|
172
|
-
return nullptr;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
auto source = g_inputSourceManager.GetSource(inputName);
|
|
176
|
-
return source ? source->imageFilter : nullptr;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
OH_Drawing_ColorFilter* SvgFilter::GetInputColorFilter(const std::string& inputName) {
|
|
180
|
-
if (inputName.empty() || inputName == "SourceGraphic") {
|
|
181
|
-
return nullptr;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
auto source = g_inputSourceManager.GetSource(inputName);
|
|
185
|
-
if (source) {
|
|
186
|
-
return source->colorFilter;
|
|
187
|
-
}
|
|
188
|
-
return nullptr;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
OH_Drawing_Filter* SvgFilter::GetInputFilter(const std::string& inputName) {
|
|
192
|
-
if (inputName.empty() || inputName == "SourceGraphic") {
|
|
193
|
-
return nullptr;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
auto source = g_inputSourceManager.GetSource(inputName);
|
|
197
|
-
return source ? source->combinedFilter : nullptr;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
OH_Drawing_ColorFilter* SvgFilter::CombineWithInputColor(OH_Drawing_ColorFilter* newFilter, const std::string& inputName) {
|
|
201
|
-
if (inputName.empty() || inputName == "SourceGraphic" || !newFilter) {
|
|
202
|
-
return newFilter;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
auto inputFilter = GetInputColorFilter(inputName);
|
|
206
|
-
if (inputFilter) {
|
|
207
|
-
return OH_Drawing_ColorFilterCreateCompose(newFilter, inputFilter);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return newFilter;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
void SvgFilter::RegisterFilterResult(const std::string& resultId, OH_Drawing_ImageFilter* imageFilter,
|
|
214
|
-
OH_Drawing_ColorFilter* colorFilter, OH_Drawing_MaskFilter* maskFilter) {
|
|
215
|
-
if (!resultId.empty()) {
|
|
216
|
-
g_inputSourceManager.RegisterSource(resultId, imageFilter, colorFilter, maskFilter);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
void SvgFilter::AddFilterEffect(const FilterEffect& effect) {
|
|
221
|
-
effects_.push_back(effect);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
void SvgFilter::ApplyToBrush(rnoh::drawing::Brush& brush, const std::string& extra) {
|
|
225
|
-
if (effects_.empty()) {
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
g_inputSourceManager.Clear();
|
|
230
|
-
auto* mainFilter = OH_Drawing_FilterCreate();
|
|
231
|
-
if (!mainFilter) {
|
|
232
|
-
DLOG(WARNING) << "[SvgFilter] Failed to create main filter";
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
for (const auto& effect : effects_) {
|
|
237
|
-
ApplySingleEffectToFilter(mainFilter, effect, &brush, nullptr, extra);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
OH_Drawing_BrushSetFilter(brush.get(), mainFilter);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
void SvgFilter::ApplyToPen(rnoh::drawing::Pen& pen) {
|
|
244
|
-
if (effects_.empty()) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
g_inputSourceManager.Clear();
|
|
249
|
-
auto* mainFilter = OH_Drawing_FilterCreate();
|
|
250
|
-
if (!mainFilter) {
|
|
251
|
-
DLOG(WARNING) << "[SvgFilter] Failed to create main filter";
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
for (const auto& effect : effects_) {
|
|
256
|
-
ApplySingleEffectToFilter(mainFilter, effect, nullptr, &pen);
|
|
257
|
-
}
|
|
258
|
-
OH_Drawing_PenSetFilter(pen.get(), mainFilter);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
void SvgFilter::ApplySingleEffectToFilter(OH_Drawing_Filter* filter, const FilterEffect& effect,
|
|
262
|
-
rnoh::drawing::Brush* brush, rnoh::drawing::Pen* pen, const std::string& extra) {
|
|
263
|
-
if (!filter) {
|
|
264
|
-
DLOG(WARNING) << "[SvgFilter] Null filter passed to ApplySingleEffectToFilter";
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
switch (effect.filterType) {
|
|
268
|
-
case FilterType::GAUSSIAN_BLUR: {
|
|
269
|
-
if (extra == "image") {
|
|
270
|
-
auto* imageFilter = CreateGaussianBlurFilter(effect);
|
|
271
|
-
if (imageFilter) {
|
|
272
|
-
OH_Drawing_FilterSetImageFilter(filter, imageFilter);
|
|
273
|
-
}
|
|
274
|
-
} else {
|
|
275
|
-
auto* maskFilter = CreateBlurFilter(effect);
|
|
276
|
-
if (maskFilter) {
|
|
277
|
-
OH_Drawing_FilterSetMaskFilter(filter, maskFilter);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
break;
|
|
281
|
-
}
|
|
282
|
-
case FilterType::COLOR_MATRIX: {
|
|
283
|
-
auto* colorFilter = CreateColorMatrixFilter(effect);
|
|
284
|
-
if (colorFilter) {
|
|
285
|
-
float identityMatrix[20] = {
|
|
286
|
-
1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0
|
|
287
|
-
};
|
|
288
|
-
OH_Drawing_ColorFilter* existingColorFilter = OH_Drawing_ColorFilterCreateMatrix(identityMatrix);
|
|
289
|
-
OH_Drawing_FilterGetColorFilter(filter,existingColorFilter);
|
|
290
|
-
if (existingColorFilter) {
|
|
291
|
-
auto* composedColorFilter = OH_Drawing_ColorFilterCreateCompose(colorFilter, existingColorFilter);
|
|
292
|
-
if (composedColorFilter) {
|
|
293
|
-
OH_Drawing_FilterSetColorFilter(filter, composedColorFilter);
|
|
294
|
-
}
|
|
295
|
-
} else {
|
|
296
|
-
OH_Drawing_FilterSetColorFilter(filter, colorFilter);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
break;
|
|
300
|
-
}
|
|
301
|
-
case FilterType::FEFLOOD: {
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
case FilterType::FEOFFSET: {
|
|
305
|
-
break;
|
|
306
|
-
}
|
|
307
|
-
case FilterType::BLUR: {
|
|
308
|
-
auto* maskFilter = CreateBlurFilter(effect);
|
|
309
|
-
if (maskFilter) {
|
|
310
|
-
OH_Drawing_FilterSetMaskFilter(filter, maskFilter);
|
|
311
|
-
}
|
|
312
|
-
break;
|
|
313
|
-
}
|
|
314
|
-
case FilterType::DROP_SHADOW: {
|
|
315
|
-
auto* shadowLayer = CreateDropShadowFilter(effect);
|
|
316
|
-
if (shadowLayer) {
|
|
317
|
-
if (brush) {
|
|
318
|
-
OH_Drawing_BrushSetShadowLayer(brush->get(), shadowLayer);
|
|
319
|
-
} else if (pen) {
|
|
320
|
-
OH_Drawing_PenSetShadowLayer(pen->get(), shadowLayer);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
break;
|
|
324
|
-
}
|
|
325
|
-
case FilterType::BLEND: {
|
|
326
|
-
break;
|
|
327
|
-
}
|
|
328
|
-
case FilterType::COMPOSITE: {
|
|
329
|
-
break;
|
|
330
|
-
}
|
|
331
|
-
case FilterType::MERGE:
|
|
332
|
-
break;
|
|
333
|
-
default:
|
|
334
|
-
DLOG(WARNING) << "[SvgFilter] Unsupported filter type: " << static_cast<int>(effect.filterType);
|
|
335
|
-
break;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
OH_Drawing_ImageFilter* SvgFilter::CreateGaussianBlurFilter(const FilterEffect& effect) {
|
|
340
|
-
auto inputFilter = GetInputImageFilter(effect.in);
|
|
341
|
-
auto* blurFilter = OH_Drawing_ImageFilterCreateBlur(
|
|
342
|
-
static_cast<double>(effect.stdDeviationX_),
|
|
343
|
-
static_cast<double>(effect.stdDeviationY_),
|
|
344
|
-
OH_Drawing_TileMode::CLAMP,
|
|
345
|
-
inputFilter
|
|
346
|
-
);
|
|
347
|
-
|
|
348
|
-
if (!effect.result.empty()) {
|
|
349
|
-
RegisterFilterResult(effect.result, blurFilter, nullptr, nullptr);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
return blurFilter;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
OH_Drawing_MaskFilter* SvgFilter::CreateBlurFilter(const FilterEffect& effect) {
|
|
356
|
-
if (effect.values.size() >= 1) {
|
|
357
|
-
auto* maskFilter = OH_Drawing_MaskFilterCreateBlur(
|
|
358
|
-
OH_Drawing_BlurType::NORMAL,
|
|
359
|
-
static_cast<double>(effect.values[0]),
|
|
360
|
-
false
|
|
361
|
-
);
|
|
362
|
-
|
|
363
|
-
if (!effect.result.empty()) {
|
|
364
|
-
RegisterFilterResult(effect.result, nullptr, nullptr, maskFilter);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
return maskFilter;
|
|
368
|
-
}
|
|
369
|
-
return nullptr;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
OH_Drawing_ColorFilter* SvgFilter::CreateColorMatrixFilter(const FilterEffect& effect) {
|
|
373
|
-
OH_Drawing_ColorFilter* colorFilter = nullptr;
|
|
374
|
-
if (effect.type == "matrix") {
|
|
375
|
-
colorFilter = CreateMatrixFilter(effect.values);
|
|
376
|
-
} else if (effect.type == "saturate") {
|
|
377
|
-
colorFilter = CreateSaturateFilter(effect.values);
|
|
378
|
-
} else if (effect.type == "hueRotate") {
|
|
379
|
-
colorFilter = CreateHueRotateFilter(effect.values);
|
|
380
|
-
} else if (effect.type == "luminanceToAlpha") {
|
|
381
|
-
colorFilter = CreateLuminanceToAlphaFilter();
|
|
382
|
-
} else {
|
|
383
|
-
float identityMatrix[20] = {
|
|
384
|
-
1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0
|
|
385
|
-
};
|
|
386
|
-
colorFilter = OH_Drawing_ColorFilterCreateMatrix(identityMatrix);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
colorFilter = CombineWithInputColor(colorFilter, effect.in);
|
|
390
|
-
if (!effect.result.empty()) {
|
|
391
|
-
RegisterFilterResult(effect.result, nullptr, colorFilter, nullptr);
|
|
392
|
-
}
|
|
393
|
-
return colorFilter;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
OH_Drawing_ColorFilter* SvgFilter::CreateMatrixFilter(const std::vector<float>& values) {
|
|
397
|
-
if (values.size() >= 20) {
|
|
398
|
-
return OH_Drawing_ColorFilterCreateMatrix(values.data());
|
|
399
|
-
} else {
|
|
400
|
-
float identityMatrix[20] = {
|
|
401
|
-
1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0
|
|
402
|
-
};
|
|
403
|
-
return OH_Drawing_ColorFilterCreateMatrix(identityMatrix);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
OH_Drawing_ColorFilter* SvgFilter::CreateSaturateFilter(const std::vector<float>& values) {
|
|
408
|
-
float saturation = values.empty() ? 1.0f : values[0];
|
|
409
|
-
saturation = std::max(0.0f, saturation);
|
|
410
|
-
const float rWeight = 0.213f;
|
|
411
|
-
const float gWeight = 0.715f;
|
|
412
|
-
const float bWeight = 0.072f;
|
|
413
|
-
|
|
414
|
-
float colorMatrix[20] = {
|
|
415
|
-
rWeight + (1.0f - rWeight) * saturation, gWeight * (1.0f - saturation), bWeight * (1.0f - saturation), 0.0f, 0.0f,
|
|
416
|
-
rWeight * (1.0f - saturation), gWeight + (1.0f - gWeight) * saturation, bWeight * (1.0f - saturation), 0.0f, 0.0f,
|
|
417
|
-
rWeight * (1.0f - saturation), gWeight * (1.0f - saturation), bWeight + (1.0f - bWeight) * saturation, 0.0f, 0.0f,
|
|
418
|
-
0.0f, 0.0f, 0.0f, 1.0f, 0.0f
|
|
419
|
-
};
|
|
420
|
-
|
|
421
|
-
return OH_Drawing_ColorFilterCreateMatrix(colorMatrix);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
OH_Drawing_ColorFilter* SvgFilter::CreateHueRotateFilter(const std::vector<float>& values) {
|
|
425
|
-
float angle = values.empty() ? 0.0f : values[0];
|
|
426
|
-
float radians = angle * M_PI / 180.0f;
|
|
427
|
-
float cosA = cos(radians);
|
|
428
|
-
float sinA = sin(radians);
|
|
429
|
-
float colorMatrix[20] = {
|
|
430
|
-
0.213f + 0.787f * cosA - 0.213f * sinA, 0.715f - 0.715f * cosA - 0.715f * sinA, 0.072f - 0.072f * cosA + 0.928f * sinA, 0.0f, 0.0f,
|
|
431
|
-
0.213f - 0.213f * cosA + 0.143f * sinA, 0.715f + 0.285f * cosA + 0.140f * sinA, 0.072f - 0.072f * cosA - 0.283f * sinA, 0.0f, 0.0f,
|
|
432
|
-
0.213f - 0.213f * cosA - 0.787f * sinA, 0.715f - 0.715f * cosA + 0.715f * sinA, 0.072f + 0.928f * cosA + 0.072f * sinA, 0.0f, 0.0f,
|
|
433
|
-
0.0f, 0.0f, 0.0f, 1.0f, 0.0f
|
|
434
|
-
};
|
|
435
|
-
|
|
436
|
-
return OH_Drawing_ColorFilterCreateMatrix(colorMatrix);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
OH_Drawing_ColorFilter* SvgFilter::CreateLuminanceToAlphaFilter() {
|
|
440
|
-
float colorMatrix[20] = {
|
|
441
|
-
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
442
|
-
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
443
|
-
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
444
|
-
0.2125f, 0.7154f, 0.0721f, 0.0f, 0.0f
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
return OH_Drawing_ColorFilterCreateMatrix(colorMatrix);
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
OH_Drawing_ShadowLayer* SvgFilter::CreateDropShadowFilter(const FilterEffect& effect) {
|
|
451
|
-
uint32_t shadowColor = 0xFF000000;
|
|
452
|
-
if (!effect.floodColor.empty() && effect.floodColor != "none") {
|
|
453
|
-
uint32_t baseColor = 0x000000;
|
|
454
|
-
|
|
455
|
-
if (effect.floodColor.find("0x") == 0 || effect.floodColor.find("0X") == 0) {
|
|
456
|
-
try {
|
|
457
|
-
baseColor = static_cast<uint32_t>(std::stoul(effect.floodColor, nullptr, 16));
|
|
458
|
-
if (effect.floodColor.length() > 8) {
|
|
459
|
-
baseColor = baseColor & 0x00FFFFFF;
|
|
460
|
-
}
|
|
461
|
-
} catch (const std::exception& e) {
|
|
462
|
-
baseColor = 0x000000;
|
|
463
|
-
}
|
|
464
|
-
} else if (effect.floodColor.front() == '#') {
|
|
465
|
-
std::string hex = effect.floodColor.substr(1);
|
|
466
|
-
try {
|
|
467
|
-
if (hex.length() == 6) {
|
|
468
|
-
baseColor = static_cast<uint32_t>(std::stoul(hex, nullptr, 16));
|
|
469
|
-
} else if (hex.length() == 3) {
|
|
470
|
-
uint32_t r = std::stoul(hex.substr(0, 1), nullptr, 16);
|
|
471
|
-
uint32_t g = std::stoul(hex.substr(1, 1), nullptr, 16);
|
|
472
|
-
uint32_t b = std::stoul(hex.substr(2, 1), nullptr, 16);
|
|
473
|
-
baseColor = (r << 20) | (r << 16) | (g << 12) | (g << 8) | (b << 4) | b;
|
|
474
|
-
}
|
|
475
|
-
} catch (const std::exception& e) {
|
|
476
|
-
baseColor = 0x000000;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
uint32_t red = (baseColor >> 16) & 0xFF;
|
|
481
|
-
uint32_t green = (baseColor >> 8) & 0xFF;
|
|
482
|
-
uint32_t blue = baseColor & 0xFF;
|
|
483
|
-
float opacity = std::max(0.0f, std::min(1.0f, effect.floodOpacity));
|
|
484
|
-
|
|
485
|
-
red = static_cast<uint32_t>(red * opacity + 255 * (1.0f - opacity));
|
|
486
|
-
green = static_cast<uint32_t>(green * opacity + 255 * (1.0f - opacity));
|
|
487
|
-
blue = static_cast<uint32_t>(blue * opacity + 255 * (1.0f - opacity));
|
|
488
|
-
|
|
489
|
-
red = std::min(red, 255u);
|
|
490
|
-
green = std::min(green, 255u);
|
|
491
|
-
blue = std::min(blue, 255u);
|
|
492
|
-
|
|
493
|
-
uint32_t alpha = 0xFF;
|
|
494
|
-
shadowColor = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
return OH_Drawing_ShadowLayerCreate(
|
|
498
|
-
static_cast<double>(effect.stdDeviationX_),
|
|
499
|
-
static_cast<double>(effect.dx_),
|
|
500
|
-
static_cast<double>(effect.dy_),
|
|
501
|
-
shadowColor
|
|
502
|
-
);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
#include "SvgFilter.h"
|
|
8
|
+
#include <native_drawing/drawing_mask_filter.h>
|
|
9
|
+
#include <native_drawing/drawing_color_filter.h>
|
|
10
|
+
#include <native_drawing/drawing_image_filter.h>
|
|
11
|
+
#include <native_drawing/drawing_shadow_layer.h>
|
|
12
|
+
#include <native_drawing/drawing_brush.h>
|
|
13
|
+
#include <native_drawing/drawing_pen.h>
|
|
14
|
+
#include <native_drawing/drawing_types.h>
|
|
15
|
+
#include <glog/logging.h>
|
|
16
|
+
#include <algorithm>
|
|
17
|
+
#include <cmath>
|
|
18
|
+
#include <string>
|
|
19
|
+
#include <stdexcept>
|
|
20
|
+
#include <sstream>
|
|
21
|
+
#include <vector>
|
|
22
|
+
#include <set>
|
|
23
|
+
#include <map>
|
|
24
|
+
#include <memory>
|
|
25
|
+
|
|
26
|
+
#ifndef M_PI
|
|
27
|
+
#define M_PI 3.14159265358979323846
|
|
28
|
+
#endif
|
|
29
|
+
|
|
30
|
+
namespace rnoh {
|
|
31
|
+
namespace svg {
|
|
32
|
+
|
|
33
|
+
struct InputSource {
|
|
34
|
+
std::string name;
|
|
35
|
+
OH_Drawing_ImageFilter* imageFilter = nullptr;
|
|
36
|
+
OH_Drawing_ColorFilter* colorFilter = nullptr;
|
|
37
|
+
OH_Drawing_MaskFilter* maskFilter = nullptr;
|
|
38
|
+
OH_Drawing_Filter* combinedFilter = nullptr;
|
|
39
|
+
bool ownsFilters = false;
|
|
40
|
+
|
|
41
|
+
~InputSource() {
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
void cleanup() {
|
|
45
|
+
if (ownsFilters) {
|
|
46
|
+
if (imageFilter) {
|
|
47
|
+
OH_Drawing_ImageFilterDestroy(imageFilter);
|
|
48
|
+
imageFilter = nullptr;
|
|
49
|
+
}
|
|
50
|
+
if (colorFilter) {
|
|
51
|
+
OH_Drawing_ColorFilterDestroy(colorFilter);
|
|
52
|
+
colorFilter = nullptr;
|
|
53
|
+
}
|
|
54
|
+
if (maskFilter) {
|
|
55
|
+
OH_Drawing_MaskFilterDestroy(maskFilter);
|
|
56
|
+
maskFilter = nullptr;
|
|
57
|
+
}
|
|
58
|
+
if (combinedFilter) {
|
|
59
|
+
OH_Drawing_FilterDestroy(combinedFilter);
|
|
60
|
+
combinedFilter = nullptr;
|
|
61
|
+
}
|
|
62
|
+
ownsFilters = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
class InputSourceManager {
|
|
68
|
+
private:
|
|
69
|
+
std::map<std::string, std::shared_ptr<InputSource>> sources_;
|
|
70
|
+
|
|
71
|
+
public:
|
|
72
|
+
void RegisterSource(const std::string& name, OH_Drawing_ImageFilter* imageFilter = nullptr,
|
|
73
|
+
OH_Drawing_ColorFilter* colorFilter = nullptr, OH_Drawing_MaskFilter* maskFilter = nullptr) {
|
|
74
|
+
auto source = std::make_shared<InputSource>();
|
|
75
|
+
source->name = name;
|
|
76
|
+
source->imageFilter = imageFilter;
|
|
77
|
+
source->colorFilter = colorFilter;
|
|
78
|
+
source->maskFilter = maskFilter;
|
|
79
|
+
|
|
80
|
+
if (imageFilter || colorFilter || maskFilter) {
|
|
81
|
+
source->combinedFilter = OH_Drawing_FilterCreate();
|
|
82
|
+
if (source->combinedFilter) {
|
|
83
|
+
if (imageFilter) OH_Drawing_FilterSetImageFilter(source->combinedFilter, imageFilter);
|
|
84
|
+
if (colorFilter) OH_Drawing_FilterSetColorFilter(source->combinedFilter, colorFilter);
|
|
85
|
+
if (maskFilter) OH_Drawing_FilterSetMaskFilter(source->combinedFilter, maskFilter);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
sources_[name] = source;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
std::shared_ptr<InputSource> GetSource(const std::string& name) {
|
|
93
|
+
if (name.empty()) {
|
|
94
|
+
return nullptr;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
auto it = sources_.find(name);
|
|
98
|
+
if (it != sources_.end()) {
|
|
99
|
+
return it->second;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (name == "SourceGraphic") {
|
|
103
|
+
return GetOrCreateStandardSource("SourceGraphic");
|
|
104
|
+
} else if (name == "SourceAlpha") {
|
|
105
|
+
return GetOrCreateStandardSource("SourceAlpha");
|
|
106
|
+
} else if (name == "BackgroundImage") {
|
|
107
|
+
return GetOrCreateStandardSource("BackgroundImage");
|
|
108
|
+
} else if (name == "BackgroundAlpha") {
|
|
109
|
+
return GetOrCreateStandardSource("BackgroundAlpha");
|
|
110
|
+
} else if (name == "FillPaint") {
|
|
111
|
+
return GetOrCreateStandardSource("FillPaint");
|
|
112
|
+
} else if (name == "StrokePaint") {
|
|
113
|
+
return GetOrCreateStandardSource("StrokePaint");
|
|
114
|
+
}
|
|
115
|
+
DLOG(WARNING) << "[SvgFilter] Input source not found: " << name;
|
|
116
|
+
return nullptr;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
void Clear() {
|
|
120
|
+
for (auto& pair : sources_) {
|
|
121
|
+
if (pair.second) {
|
|
122
|
+
pair.second->cleanup();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
sources_.clear();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private:
|
|
129
|
+
std::shared_ptr<InputSource> GetOrCreateStandardSource(const std::string& name) {
|
|
130
|
+
auto it = sources_.find(name);
|
|
131
|
+
if (it != sources_.end()) {
|
|
132
|
+
return it->second;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
auto source = std::make_shared<InputSource>();
|
|
136
|
+
source->name = name;
|
|
137
|
+
if (name == "SourceAlpha") {
|
|
138
|
+
float alphaMatrix[20] = {
|
|
139
|
+
0, 0, 0, 0, 0,
|
|
140
|
+
0, 0, 0, 0, 0,
|
|
141
|
+
0, 0, 0, 0, 0,
|
|
142
|
+
0, 0, 0, 1, 0
|
|
143
|
+
};
|
|
144
|
+
source->colorFilter = OH_Drawing_ColorFilterCreateMatrix(alphaMatrix);
|
|
145
|
+
} else if (name == "BackgroundImage") {
|
|
146
|
+
} else if (name == "BackgroundAlpha") {
|
|
147
|
+
float backgroundAlphaMatrix[20] = {
|
|
148
|
+
0, 0, 0, 0, 0,
|
|
149
|
+
0, 0, 0, 0, 0,
|
|
150
|
+
0, 0, 0, 0, 0,
|
|
151
|
+
0, 0, 0, 1, 0
|
|
152
|
+
};
|
|
153
|
+
source->colorFilter = OH_Drawing_ColorFilterCreateMatrix(backgroundAlphaMatrix);
|
|
154
|
+
} else if (name == "FillPaint" || name == "StrokePaint") {
|
|
155
|
+
float matrix[20] = {
|
|
156
|
+
1, 0, 0, 0, 0,
|
|
157
|
+
0, 1, 0, 0, 0,
|
|
158
|
+
0, 0, 1, 0, 0,
|
|
159
|
+
0, 0, 0, 1, 0
|
|
160
|
+
};
|
|
161
|
+
source->colorFilter = OH_Drawing_ColorFilterCreateMatrix(matrix);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
sources_[name] = source;
|
|
165
|
+
return source;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
static InputSourceManager g_inputSourceManager;
|
|
170
|
+
OH_Drawing_ImageFilter* SvgFilter::GetInputImageFilter(const std::string& inputName) {
|
|
171
|
+
if (inputName.empty() || inputName == "SourceGraphic") {
|
|
172
|
+
return nullptr;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
auto source = g_inputSourceManager.GetSource(inputName);
|
|
176
|
+
return source ? source->imageFilter : nullptr;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
OH_Drawing_ColorFilter* SvgFilter::GetInputColorFilter(const std::string& inputName) {
|
|
180
|
+
if (inputName.empty() || inputName == "SourceGraphic") {
|
|
181
|
+
return nullptr;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
auto source = g_inputSourceManager.GetSource(inputName);
|
|
185
|
+
if (source) {
|
|
186
|
+
return source->colorFilter;
|
|
187
|
+
}
|
|
188
|
+
return nullptr;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
OH_Drawing_Filter* SvgFilter::GetInputFilter(const std::string& inputName) {
|
|
192
|
+
if (inputName.empty() || inputName == "SourceGraphic") {
|
|
193
|
+
return nullptr;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
auto source = g_inputSourceManager.GetSource(inputName);
|
|
197
|
+
return source ? source->combinedFilter : nullptr;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
OH_Drawing_ColorFilter* SvgFilter::CombineWithInputColor(OH_Drawing_ColorFilter* newFilter, const std::string& inputName) {
|
|
201
|
+
if (inputName.empty() || inputName == "SourceGraphic" || !newFilter) {
|
|
202
|
+
return newFilter;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
auto inputFilter = GetInputColorFilter(inputName);
|
|
206
|
+
if (inputFilter) {
|
|
207
|
+
return OH_Drawing_ColorFilterCreateCompose(newFilter, inputFilter);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return newFilter;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
void SvgFilter::RegisterFilterResult(const std::string& resultId, OH_Drawing_ImageFilter* imageFilter,
|
|
214
|
+
OH_Drawing_ColorFilter* colorFilter, OH_Drawing_MaskFilter* maskFilter) {
|
|
215
|
+
if (!resultId.empty()) {
|
|
216
|
+
g_inputSourceManager.RegisterSource(resultId, imageFilter, colorFilter, maskFilter);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
void SvgFilter::AddFilterEffect(const FilterEffect& effect) {
|
|
221
|
+
effects_.push_back(effect);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
void SvgFilter::ApplyToBrush(rnoh::drawing::Brush& brush, const std::string& extra) {
|
|
225
|
+
if (effects_.empty()) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
g_inputSourceManager.Clear();
|
|
230
|
+
auto* mainFilter = OH_Drawing_FilterCreate();
|
|
231
|
+
if (!mainFilter) {
|
|
232
|
+
DLOG(WARNING) << "[SvgFilter] Failed to create main filter";
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
for (const auto& effect : effects_) {
|
|
237
|
+
ApplySingleEffectToFilter(mainFilter, effect, &brush, nullptr, extra);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
OH_Drawing_BrushSetFilter(brush.get(), mainFilter);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
void SvgFilter::ApplyToPen(rnoh::drawing::Pen& pen) {
|
|
244
|
+
if (effects_.empty()) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
g_inputSourceManager.Clear();
|
|
249
|
+
auto* mainFilter = OH_Drawing_FilterCreate();
|
|
250
|
+
if (!mainFilter) {
|
|
251
|
+
DLOG(WARNING) << "[SvgFilter] Failed to create main filter";
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
for (const auto& effect : effects_) {
|
|
256
|
+
ApplySingleEffectToFilter(mainFilter, effect, nullptr, &pen);
|
|
257
|
+
}
|
|
258
|
+
OH_Drawing_PenSetFilter(pen.get(), mainFilter);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
void SvgFilter::ApplySingleEffectToFilter(OH_Drawing_Filter* filter, const FilterEffect& effect,
|
|
262
|
+
rnoh::drawing::Brush* brush, rnoh::drawing::Pen* pen, const std::string& extra) {
|
|
263
|
+
if (!filter) {
|
|
264
|
+
DLOG(WARNING) << "[SvgFilter] Null filter passed to ApplySingleEffectToFilter";
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
switch (effect.filterType) {
|
|
268
|
+
case FilterType::GAUSSIAN_BLUR: {
|
|
269
|
+
if (extra == "image") {
|
|
270
|
+
auto* imageFilter = CreateGaussianBlurFilter(effect);
|
|
271
|
+
if (imageFilter) {
|
|
272
|
+
OH_Drawing_FilterSetImageFilter(filter, imageFilter);
|
|
273
|
+
}
|
|
274
|
+
} else {
|
|
275
|
+
auto* maskFilter = CreateBlurFilter(effect);
|
|
276
|
+
if (maskFilter) {
|
|
277
|
+
OH_Drawing_FilterSetMaskFilter(filter, maskFilter);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
case FilterType::COLOR_MATRIX: {
|
|
283
|
+
auto* colorFilter = CreateColorMatrixFilter(effect);
|
|
284
|
+
if (colorFilter) {
|
|
285
|
+
float identityMatrix[20] = {
|
|
286
|
+
1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0
|
|
287
|
+
};
|
|
288
|
+
OH_Drawing_ColorFilter* existingColorFilter = OH_Drawing_ColorFilterCreateMatrix(identityMatrix);
|
|
289
|
+
OH_Drawing_FilterGetColorFilter(filter,existingColorFilter);
|
|
290
|
+
if (existingColorFilter) {
|
|
291
|
+
auto* composedColorFilter = OH_Drawing_ColorFilterCreateCompose(colorFilter, existingColorFilter);
|
|
292
|
+
if (composedColorFilter) {
|
|
293
|
+
OH_Drawing_FilterSetColorFilter(filter, composedColorFilter);
|
|
294
|
+
}
|
|
295
|
+
} else {
|
|
296
|
+
OH_Drawing_FilterSetColorFilter(filter, colorFilter);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
case FilterType::FEFLOOD: {
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
case FilterType::FEOFFSET: {
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
case FilterType::BLUR: {
|
|
308
|
+
auto* maskFilter = CreateBlurFilter(effect);
|
|
309
|
+
if (maskFilter) {
|
|
310
|
+
OH_Drawing_FilterSetMaskFilter(filter, maskFilter);
|
|
311
|
+
}
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
case FilterType::DROP_SHADOW: {
|
|
315
|
+
auto* shadowLayer = CreateDropShadowFilter(effect);
|
|
316
|
+
if (shadowLayer) {
|
|
317
|
+
if (brush) {
|
|
318
|
+
OH_Drawing_BrushSetShadowLayer(brush->get(), shadowLayer);
|
|
319
|
+
} else if (pen) {
|
|
320
|
+
OH_Drawing_PenSetShadowLayer(pen->get(), shadowLayer);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
case FilterType::BLEND: {
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
case FilterType::COMPOSITE: {
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
case FilterType::MERGE:
|
|
332
|
+
break;
|
|
333
|
+
default:
|
|
334
|
+
DLOG(WARNING) << "[SvgFilter] Unsupported filter type: " << static_cast<int>(effect.filterType);
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
OH_Drawing_ImageFilter* SvgFilter::CreateGaussianBlurFilter(const FilterEffect& effect) {
|
|
340
|
+
auto inputFilter = GetInputImageFilter(effect.in);
|
|
341
|
+
auto* blurFilter = OH_Drawing_ImageFilterCreateBlur(
|
|
342
|
+
static_cast<double>(effect.stdDeviationX_),
|
|
343
|
+
static_cast<double>(effect.stdDeviationY_),
|
|
344
|
+
OH_Drawing_TileMode::CLAMP,
|
|
345
|
+
inputFilter
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
if (!effect.result.empty()) {
|
|
349
|
+
RegisterFilterResult(effect.result, blurFilter, nullptr, nullptr);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return blurFilter;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
OH_Drawing_MaskFilter* SvgFilter::CreateBlurFilter(const FilterEffect& effect) {
|
|
356
|
+
if (effect.values.size() >= 1) {
|
|
357
|
+
auto* maskFilter = OH_Drawing_MaskFilterCreateBlur(
|
|
358
|
+
OH_Drawing_BlurType::NORMAL,
|
|
359
|
+
static_cast<double>(effect.values[0]),
|
|
360
|
+
false
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
if (!effect.result.empty()) {
|
|
364
|
+
RegisterFilterResult(effect.result, nullptr, nullptr, maskFilter);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return maskFilter;
|
|
368
|
+
}
|
|
369
|
+
return nullptr;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
OH_Drawing_ColorFilter* SvgFilter::CreateColorMatrixFilter(const FilterEffect& effect) {
|
|
373
|
+
OH_Drawing_ColorFilter* colorFilter = nullptr;
|
|
374
|
+
if (effect.type == "matrix") {
|
|
375
|
+
colorFilter = CreateMatrixFilter(effect.values);
|
|
376
|
+
} else if (effect.type == "saturate") {
|
|
377
|
+
colorFilter = CreateSaturateFilter(effect.values);
|
|
378
|
+
} else if (effect.type == "hueRotate") {
|
|
379
|
+
colorFilter = CreateHueRotateFilter(effect.values);
|
|
380
|
+
} else if (effect.type == "luminanceToAlpha") {
|
|
381
|
+
colorFilter = CreateLuminanceToAlphaFilter();
|
|
382
|
+
} else {
|
|
383
|
+
float identityMatrix[20] = {
|
|
384
|
+
1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0
|
|
385
|
+
};
|
|
386
|
+
colorFilter = OH_Drawing_ColorFilterCreateMatrix(identityMatrix);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
colorFilter = CombineWithInputColor(colorFilter, effect.in);
|
|
390
|
+
if (!effect.result.empty()) {
|
|
391
|
+
RegisterFilterResult(effect.result, nullptr, colorFilter, nullptr);
|
|
392
|
+
}
|
|
393
|
+
return colorFilter;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
OH_Drawing_ColorFilter* SvgFilter::CreateMatrixFilter(const std::vector<float>& values) {
|
|
397
|
+
if (values.size() >= 20) {
|
|
398
|
+
return OH_Drawing_ColorFilterCreateMatrix(values.data());
|
|
399
|
+
} else {
|
|
400
|
+
float identityMatrix[20] = {
|
|
401
|
+
1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0
|
|
402
|
+
};
|
|
403
|
+
return OH_Drawing_ColorFilterCreateMatrix(identityMatrix);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
OH_Drawing_ColorFilter* SvgFilter::CreateSaturateFilter(const std::vector<float>& values) {
|
|
408
|
+
float saturation = values.empty() ? 1.0f : values[0];
|
|
409
|
+
saturation = std::max(0.0f, saturation);
|
|
410
|
+
const float rWeight = 0.213f;
|
|
411
|
+
const float gWeight = 0.715f;
|
|
412
|
+
const float bWeight = 0.072f;
|
|
413
|
+
|
|
414
|
+
float colorMatrix[20] = {
|
|
415
|
+
rWeight + (1.0f - rWeight) * saturation, gWeight * (1.0f - saturation), bWeight * (1.0f - saturation), 0.0f, 0.0f,
|
|
416
|
+
rWeight * (1.0f - saturation), gWeight + (1.0f - gWeight) * saturation, bWeight * (1.0f - saturation), 0.0f, 0.0f,
|
|
417
|
+
rWeight * (1.0f - saturation), gWeight * (1.0f - saturation), bWeight + (1.0f - bWeight) * saturation, 0.0f, 0.0f,
|
|
418
|
+
0.0f, 0.0f, 0.0f, 1.0f, 0.0f
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
return OH_Drawing_ColorFilterCreateMatrix(colorMatrix);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
OH_Drawing_ColorFilter* SvgFilter::CreateHueRotateFilter(const std::vector<float>& values) {
|
|
425
|
+
float angle = values.empty() ? 0.0f : values[0];
|
|
426
|
+
float radians = angle * M_PI / 180.0f;
|
|
427
|
+
float cosA = cos(radians);
|
|
428
|
+
float sinA = sin(radians);
|
|
429
|
+
float colorMatrix[20] = {
|
|
430
|
+
0.213f + 0.787f * cosA - 0.213f * sinA, 0.715f - 0.715f * cosA - 0.715f * sinA, 0.072f - 0.072f * cosA + 0.928f * sinA, 0.0f, 0.0f,
|
|
431
|
+
0.213f - 0.213f * cosA + 0.143f * sinA, 0.715f + 0.285f * cosA + 0.140f * sinA, 0.072f - 0.072f * cosA - 0.283f * sinA, 0.0f, 0.0f,
|
|
432
|
+
0.213f - 0.213f * cosA - 0.787f * sinA, 0.715f - 0.715f * cosA + 0.715f * sinA, 0.072f + 0.928f * cosA + 0.072f * sinA, 0.0f, 0.0f,
|
|
433
|
+
0.0f, 0.0f, 0.0f, 1.0f, 0.0f
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
return OH_Drawing_ColorFilterCreateMatrix(colorMatrix);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
OH_Drawing_ColorFilter* SvgFilter::CreateLuminanceToAlphaFilter() {
|
|
440
|
+
float colorMatrix[20] = {
|
|
441
|
+
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
442
|
+
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
443
|
+
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
444
|
+
0.2125f, 0.7154f, 0.0721f, 0.0f, 0.0f
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
return OH_Drawing_ColorFilterCreateMatrix(colorMatrix);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
OH_Drawing_ShadowLayer* SvgFilter::CreateDropShadowFilter(const FilterEffect& effect) {
|
|
451
|
+
uint32_t shadowColor = 0xFF000000;
|
|
452
|
+
if (!effect.floodColor.empty() && effect.floodColor != "none") {
|
|
453
|
+
uint32_t baseColor = 0x000000;
|
|
454
|
+
|
|
455
|
+
if (effect.floodColor.find("0x") == 0 || effect.floodColor.find("0X") == 0) {
|
|
456
|
+
try {
|
|
457
|
+
baseColor = static_cast<uint32_t>(std::stoul(effect.floodColor, nullptr, 16));
|
|
458
|
+
if (effect.floodColor.length() > 8) {
|
|
459
|
+
baseColor = baseColor & 0x00FFFFFF;
|
|
460
|
+
}
|
|
461
|
+
} catch (const std::exception& e) {
|
|
462
|
+
baseColor = 0x000000;
|
|
463
|
+
}
|
|
464
|
+
} else if (effect.floodColor.front() == '#') {
|
|
465
|
+
std::string hex = effect.floodColor.substr(1);
|
|
466
|
+
try {
|
|
467
|
+
if (hex.length() == 6) {
|
|
468
|
+
baseColor = static_cast<uint32_t>(std::stoul(hex, nullptr, 16));
|
|
469
|
+
} else if (hex.length() == 3) {
|
|
470
|
+
uint32_t r = std::stoul(hex.substr(0, 1), nullptr, 16);
|
|
471
|
+
uint32_t g = std::stoul(hex.substr(1, 1), nullptr, 16);
|
|
472
|
+
uint32_t b = std::stoul(hex.substr(2, 1), nullptr, 16);
|
|
473
|
+
baseColor = (r << 20) | (r << 16) | (g << 12) | (g << 8) | (b << 4) | b;
|
|
474
|
+
}
|
|
475
|
+
} catch (const std::exception& e) {
|
|
476
|
+
baseColor = 0x000000;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
uint32_t red = (baseColor >> 16) & 0xFF;
|
|
481
|
+
uint32_t green = (baseColor >> 8) & 0xFF;
|
|
482
|
+
uint32_t blue = baseColor & 0xFF;
|
|
483
|
+
float opacity = std::max(0.0f, std::min(1.0f, effect.floodOpacity));
|
|
484
|
+
|
|
485
|
+
red = static_cast<uint32_t>(red * opacity + 255 * (1.0f - opacity));
|
|
486
|
+
green = static_cast<uint32_t>(green * opacity + 255 * (1.0f - opacity));
|
|
487
|
+
blue = static_cast<uint32_t>(blue * opacity + 255 * (1.0f - opacity));
|
|
488
|
+
|
|
489
|
+
red = std::min(red, 255u);
|
|
490
|
+
green = std::min(green, 255u);
|
|
491
|
+
blue = std::min(blue, 255u);
|
|
492
|
+
|
|
493
|
+
uint32_t alpha = 0xFF;
|
|
494
|
+
shadowColor = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
return OH_Drawing_ShadowLayerCreate(
|
|
498
|
+
static_cast<double>(effect.stdDeviationX_),
|
|
499
|
+
static_cast<double>(effect.dx_),
|
|
500
|
+
static_cast<double>(effect.dy_),
|
|
501
|
+
shadowColor
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|