1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components_ng/svg/parse/svg_fe_blend.h"
17
18 #include "base/utils/utils.h"
19
20 namespace OHOS::Ace::NG {
21
Create()22 RefPtr<SvgNode> SvgFeBlend::Create()
23 {
24 return AceType::MakeRefPtr<SvgFeBlend>();
25 }
26
SvgFeBlend()27 SvgFeBlend::SvgFeBlend() : SvgFe() {}
28
GetBlendMode(SvgFeBlendMode mode) const29 RSBlendMode SvgFeBlend::GetBlendMode(SvgFeBlendMode mode) const
30 {
31 switch (mode) {
32 case SvgFeBlendMode::NORMAL:
33 return RSBlendMode::SRC_OVER;
34 case SvgFeBlendMode::MULTIPLY:
35 return RSBlendMode::MULTIPLY;
36 case SvgFeBlendMode::SCREEN:
37 return RSBlendMode::SCREEN;
38 case SvgFeBlendMode::DARKEN:
39 return RSBlendMode::DARKEN;
40 case SvgFeBlendMode::LIGHTEN:
41 return RSBlendMode::LIGHTEN;
42 default:
43 return RSBlendMode::SRC_OVER;
44 };
45 }
46
OnAsImageFilter(std::shared_ptr<RSImageFilter> & imageFilter,const SvgColorInterpolationType & srcColor,SvgColorInterpolationType & currentColor,std::unordered_map<std::string,std::shared_ptr<RSImageFilter>> & resultHash) const47 void SvgFeBlend::OnAsImageFilter(std::shared_ptr<RSImageFilter>& imageFilter,
48 const SvgColorInterpolationType& srcColor, SvgColorInterpolationType& currentColor,
49 std::unordered_map<std::string, std::shared_ptr<RSImageFilter>>& resultHash) const
50 {
51 auto blendMode = feBlendAttr_.blendMode;
52
53 auto backImageFilter = MakeImageFilter(feBlendAttr_.in2, imageFilter, resultHash);
54 auto foreImageFilter = MakeImageFilter(feAttr_.in, imageFilter, resultHash);
55 ConverImageFilterColor(foreImageFilter, srcColor, currentColor);
56 ConverImageFilterColor(backImageFilter, srcColor, currentColor);
57
58 imageFilter =
59 RSRecordingImageFilter::CreateBlendImageFilter(GetBlendMode(blendMode), backImageFilter, foreImageFilter);
60 ConverImageFilterColor(imageFilter, srcColor, currentColor);
61 RegisterResult(feAttr_.result, imageFilter, resultHash);
62 }
63
ParseAndSetSpecializedAttr(const std::string & name,const std::string & value)64 bool SvgFeBlend::ParseAndSetSpecializedAttr(const std::string& name, const std::string& value)
65 {
66 static const LinearMapNode<void (*)(const std::string&, SvgFeBlendAttribute&)> attrs[] = {
67 { DOM_SVG_FE_IN2,
68 [](const std::string& val, SvgFeBlendAttribute& attr) {
69 static const LinearMapNode<SvgFeInType> IN_TABLE[] = {
70 { "BackgroundAlpha", SvgFeInType::BACKGROUND_ALPHA },
71 { "BackgroundImage", SvgFeInType::BACKGROUND_IMAGE },
72 { "FillPaint", SvgFeInType::FILL_PAINT },
73 { "SourceAlpha", SvgFeInType::SOURCE_ALPHA },
74 { "SourceGraphic", SvgFeInType::SOURCE_GRAPHIC },
75 { "StrokePaint", SvgFeInType::STROKE_PAINT },
76 };
77 int64_t inIndex = BinarySearchFindIndex(IN_TABLE, ArraySize(IN_TABLE), val.c_str());
78 if (inIndex != -1) {
79 attr.in2.in = IN_TABLE[inIndex].value;
80 } else {
81 attr.in2.id = val;
82 }
83 } },
84 { DOM_SVG_FE_MODE,
85 [](const std::string& val, SvgFeBlendAttribute& attr) {
86 static const LinearMapNode<SvgFeBlendMode> EDGE_MODE_TABLE[] = {
87 { "darken", SvgFeBlendMode::DARKEN },
88 { "lighten", SvgFeBlendMode::LIGHTEN },
89 { "multiply", SvgFeBlendMode::MULTIPLY },
90 { "normal", SvgFeBlendMode::NORMAL },
91 { "screen", SvgFeBlendMode::SCREEN }
92 };
93 int64_t inIndex = BinarySearchFindIndex(EDGE_MODE_TABLE, ArraySize(EDGE_MODE_TABLE), val.c_str());
94 if (inIndex != -1) {
95 attr.blendMode = EDGE_MODE_TABLE[inIndex].value;
96 }
97 } },
98 };
99 std::string key = name;
100 StringUtils::TransformStrCase(key, StringUtils::TEXT_CASE_LOWERCASE);
101 auto attrIter = BinarySearchFindIndex(attrs, ArraySize(attrs), key.c_str());
102 if (attrIter != -1) {
103 attrs[attrIter].value(value, feBlendAttr_);
104 return true;
105 }
106 return SvgFe::ParseAndSetSpecializedAttr(name, value);
107 }
108
109 } // namespace OHOS::Ace::NG
110