1 /*
2 * Copyright (c) 2021-2023 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 "skia_image_filter.h"
17 #include "skia_helper.h"
18
19 #include "include/effects/SkImageFilters.h"
20 #include "include/core/SkTileMode.h"
21 #include "src/core/SkImageFilter_Base.h"
22
23 #if !defined(USE_CANVASKIT0310_SKIA) && !defined(NEW_SKIA)
24 #include "include/effects/SkBlurImageFilter.h"
25 #endif
26
27 #include "skia_color_filter.h"
28
29 #include "effect/color_filter.h"
30 #include "effect/image_filter.h"
31 #include "utils/data.h"
32 #include "utils/log.h"
33
34 namespace OHOS {
35 namespace Rosen {
36 namespace Drawing {
37 static constexpr size_t numberOfCoefficients = 4;
38
SkiaImageFilter()39 SkiaImageFilter::SkiaImageFilter() noexcept : filter_(nullptr) {}
40
ConvertToSkTileMode(const TileMode & mode)41 static inline SkTileMode ConvertToSkTileMode(const TileMode& mode)
42 {
43 switch (mode) {
44 case TileMode::CLAMP:
45 return SkTileMode::kClamp;
46 case TileMode::REPEAT:
47 return SkTileMode::kRepeat;
48 case TileMode::MIRROR:
49 return SkTileMode::kMirror;
50 case TileMode::DECAL:
51 return SkTileMode::kDecal;
52 default:
53 return SkTileMode::kClamp;
54 }
55 }
56
InitWithBlur(scalar sigmaX,scalar sigmaY,TileMode mode,const std::shared_ptr<ImageFilter> f)57 void SkiaImageFilter::InitWithBlur(scalar sigmaX, scalar sigmaY, TileMode mode, const std::shared_ptr<ImageFilter> f)
58 {
59 sk_sp<SkImageFilter> input = nullptr;
60 if (f != nullptr && f->GetImpl<SkiaImageFilter>() != nullptr) {
61 input = f->GetImpl<SkiaImageFilter>()->GetImageFilter();
62 }
63 #if defined(USE_CANVASKIT0310_SKIA) || defined(NEW_SKIA)
64 filter_ = SkImageFilters::Blur(sigmaX, sigmaY, ConvertToSkTileMode(mode), input);
65 #else
66 filter_ = SkBlurImageFilter::Make(sigmaX, sigmaY, ConvertToSkTileMode(mode), input);
67 #endif
68 }
69
InitWithColor(const ColorFilter & colorFilter,const std::shared_ptr<ImageFilter> f)70 void SkiaImageFilter::InitWithColor(const ColorFilter& colorFilter, const std::shared_ptr<ImageFilter> f)
71 {
72 sk_sp<SkImageFilter> input = nullptr;
73 if (f != nullptr && f->GetImpl<SkiaImageFilter>() != nullptr) {
74 input = f->GetImpl<SkiaImageFilter>()->GetImageFilter();
75 }
76 auto skColorFilterImpl = colorFilter.GetImpl<SkiaColorFilter>();
77 if (skColorFilterImpl != nullptr) {
78 filter_ = SkImageFilters::ColorFilter(skColorFilterImpl->GetColorFilter(), input);
79 }
80 }
81
InitWithOffset(scalar dx,scalar dy,const std::shared_ptr<ImageFilter> f)82 void SkiaImageFilter::InitWithOffset(scalar dx, scalar dy, const std::shared_ptr<ImageFilter> f)
83 {
84 sk_sp<SkImageFilter> input = nullptr;
85 if (f != nullptr && f->GetImpl<SkiaImageFilter>() != nullptr) {
86 input = f->GetImpl<SkiaImageFilter>()->GetImageFilter();
87 }
88 filter_ = SkImageFilters::Offset(dx, dy, input);
89 }
90
InitWithColorBlur(const ColorFilter & colorFilter,scalar sigmaX,scalar sigmaY)91 void SkiaImageFilter::InitWithColorBlur(const ColorFilter& colorFilter, scalar sigmaX, scalar sigmaY)
92 {
93 auto skColorFilterImpl = colorFilter.GetImpl<SkiaColorFilter>();
94 filter_ = SkImageFilters::ColorFilter(
95 skColorFilterImpl->GetColorFilter(), SkImageFilters::Blur(sigmaX, sigmaY, SkTileMode::kClamp, nullptr));
96 }
97
InitWithArithmetic(const std::vector<scalar> & coefficients,bool enforcePMColor,const std::shared_ptr<ImageFilter> f1,const std::shared_ptr<ImageFilter> f2)98 void SkiaImageFilter::InitWithArithmetic(const std::vector<scalar>& coefficients,
99 bool enforcePMColor, const std::shared_ptr<ImageFilter> f1, const std::shared_ptr<ImageFilter> f2)
100 {
101 if (coefficients.size() != numberOfCoefficients) {
102 LOGD("SkiaImageFilter::InitWithArithmetic: the number of coefficients must be 4");
103 return;
104 }
105
106 sk_sp<SkImageFilter> background = nullptr;
107 sk_sp<SkImageFilter> foreground = nullptr;
108 if (f1 != nullptr && f1->GetImpl<SkiaImageFilter>() != nullptr) {
109 background = f1->GetImpl<SkiaImageFilter>()->GetImageFilter();
110 }
111 if (f2 != nullptr && f2->GetImpl<SkiaImageFilter>() != nullptr) {
112 foreground = f2->GetImpl<SkiaImageFilter>()->GetImageFilter();
113 }
114 filter_ = SkImageFilters::Arithmetic(
115 coefficients[0], coefficients[1], coefficients[2], coefficients[3], enforcePMColor, background, foreground);
116 }
117
InitWithCompose(const std::shared_ptr<ImageFilter> f1,const std::shared_ptr<ImageFilter> f2)118 void SkiaImageFilter::InitWithCompose(const std::shared_ptr<ImageFilter> f1, const std::shared_ptr<ImageFilter> f2)
119 {
120 sk_sp<SkImageFilter> outer = nullptr;
121 sk_sp<SkImageFilter> inner = nullptr;
122 if (f1 != nullptr && f1->GetImpl<SkiaImageFilter>() != nullptr) {
123 outer = f1->GetImpl<SkiaImageFilter>()->GetImageFilter();
124 }
125 if (f2 != nullptr && f2->GetImpl<SkiaImageFilter>() != nullptr) {
126 inner = f2->GetImpl<SkiaImageFilter>()->GetImageFilter();
127 }
128 filter_ = SkImageFilters::Compose(outer, inner);
129 }
130
GetImageFilter() const131 sk_sp<SkImageFilter> SkiaImageFilter::GetImageFilter() const
132 {
133 return filter_;
134 }
135
SetSkImageFilter(const sk_sp<SkImageFilter> & filter)136 void SkiaImageFilter::SetSkImageFilter(const sk_sp<SkImageFilter>& filter)
137 {
138 filter_ = filter;
139 }
140
Serialize() const141 std::shared_ptr<Data> SkiaImageFilter::Serialize() const
142 {
143 if (filter_ == nullptr) {
144 return nullptr;
145 }
146
147 return SkiaHelper::FlattenableSerialize(filter_.get());
148 }
149
Deserialize(std::shared_ptr<Data> data)150 bool SkiaImageFilter::Deserialize(std::shared_ptr<Data> data)
151 {
152 if (data == nullptr) {
153 LOGD("SkiaImageFilter::Deserialize, data is invalid!");
154 return false;
155 }
156
157 filter_ = SkiaHelper::FlattenableDeserialize<SkImageFilter_Base>(data);
158 return true;
159 }
160
161 } // namespace Drawing
162 } // namespace Rosen
163 } // namespace OHOS
164