1 /*
2 * Copyright (c) 2021 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_paint.h"
17
18 #include "skia_blender.h"
19 #include "skia_color_filter.h"
20 #include "skia_color_space.h"
21 #include "skia_convert_utils.h"
22 #include "skia_image_filter.h"
23 #include "skia_mask_filter.h"
24 #include "skia_path.h"
25 #include "skia_path_effect.h"
26 #include "skia_shader_effect.h"
27
28 namespace OHOS {
29 namespace Rosen {
30 namespace Drawing {
BrushToSkPaint(const Brush & brush,SkPaint & paint)31 void SkiaPaint::BrushToSkPaint(const Brush& brush, SkPaint& paint)
32 {
33 auto cs = brush.GetColorSpace();
34 if (cs != nullptr) {
35 auto skColorSpaceImpl = cs->GetImpl<SkiaColorSpace>();
36 sk_sp<SkColorSpace> colorSpace = (skColorSpaceImpl != nullptr) ? skColorSpaceImpl->GetColorSpace() : nullptr;
37 paint.setColor(SkColor4f::FromColor(brush.GetColor().CastToColorQuad()), colorSpace.get());
38 } else {
39 paint.setColor(brush.GetColor().CastToColorQuad());
40 }
41
42 if (brush.GetBlendMode() != BlendMode::SRC_OVER) {
43 paint.setBlendMode(static_cast<SkBlendMode>(brush.GetBlendMode()));
44 }
45
46 paint.setAlpha(brush.GetAlpha());
47 paint.setAntiAlias(brush.IsAntiAlias());
48
49 auto s = brush.GetShaderEffect();
50 if (s != nullptr) {
51 auto skShaderImpl = s->GetImpl<SkiaShaderEffect>();
52 sk_sp<SkShader> skShader = (skShaderImpl != nullptr) ? skShaderImpl->GetShader() : nullptr;
53 paint.setShader(skShader);
54 }
55
56 if (brush.GetBlender() != nullptr) {
57 auto skBlenderImpl = brush.GetBlender()->GetImpl<SkiaBlender>();
58 sk_sp<SkBlender> skBlender = (skBlenderImpl != nullptr) ? skBlenderImpl->GetBlender() : nullptr;
59 paint.setBlender(skBlender);
60 }
61
62 auto filter = brush.GetFilter();
63 ApplyFilter(paint, filter);
64 paint.setStyle(SkPaint::kFill_Style);
65 }
66
PenToSkPaint(const Pen & pen,SkPaint & paint)67 void SkiaPaint::PenToSkPaint(const Pen& pen, SkPaint& paint)
68 {
69 auto cs = pen.GetColorSpace();
70 if (cs != nullptr) {
71 auto skColorSpaceImpl = cs->GetImpl<SkiaColorSpace>();
72 sk_sp<SkColorSpace> colorSpace = (skColorSpaceImpl != nullptr) ? skColorSpaceImpl->GetColorSpace() : nullptr;
73 paint.setColor(SkColor4f::FromColor(pen.GetColor().CastToColorQuad()), colorSpace.get());
74 } else {
75 paint.setColor(pen.GetColor().CastToColorQuad());
76 }
77
78 if (pen.GetBlendMode() != BlendMode::SRC_OVER) {
79 paint.setBlendMode(static_cast<SkBlendMode>(pen.GetBlendMode()));
80 }
81
82 paint.setStrokeMiter(pen.GetMiterLimit());
83 paint.setStrokeWidth(pen.GetWidth());
84 paint.setAntiAlias(pen.IsAntiAlias());
85 paint.setAlpha(pen.GetAlpha());
86
87 switch (pen.GetCapStyle()) {
88 case Pen::CapStyle::FLAT_CAP:
89 paint.setStrokeCap(SkPaint::kButt_Cap);
90 break;
91 case Pen::CapStyle::SQUARE_CAP:
92 paint.setStrokeCap(SkPaint::kSquare_Cap);
93 break;
94 case Pen::CapStyle::ROUND_CAP:
95 paint.setStrokeCap(SkPaint::kRound_Cap);
96 break;
97 default:
98 break;
99 }
100
101 switch (pen.GetJoinStyle()) {
102 case Pen::JoinStyle::MITER_JOIN:
103 paint.setStrokeJoin(SkPaint::kMiter_Join);
104 break;
105 case Pen::JoinStyle::ROUND_JOIN:
106 paint.setStrokeJoin(SkPaint::kRound_Join);
107 break;
108 case Pen::JoinStyle::BEVEL_JOIN:
109 paint.setStrokeJoin(SkPaint::kBevel_Join);
110 break;
111 default:
112 break;
113 }
114
115 auto p = pen.GetPathEffect();
116 if (p != nullptr) {
117 auto skPathEffectImpl = p->GetImpl<SkiaPathEffect>();
118 sk_sp<SkPathEffect> skPathEffect = (skPathEffectImpl != nullptr) ? skPathEffectImpl->GetPathEffect() : nullptr;
119 paint.setPathEffect(skPathEffect);
120 }
121
122 auto s = pen.GetShaderEffect();
123 if (s != nullptr) {
124 auto skShaderImpl = s->GetImpl<SkiaShaderEffect>();
125 sk_sp<SkShader> skShader = (skShaderImpl != nullptr) ? skShaderImpl->GetShader() : nullptr;
126 paint.setShader(skShader);
127 }
128
129 auto filter = pen.GetFilter();
130 ApplyFilter(paint, filter);
131 paint.setStyle(SkPaint::kStroke_Style);
132 }
133
PaintToSkPaint(const Paint & paint,SkPaint & skPaint)134 void SkiaPaint::PaintToSkPaint(const Paint& paint, SkPaint& skPaint)
135 {
136 switch (paint.GetStyle()) {
137 case Paint::PaintStyle::PAINT_FILL:
138 skPaint.setStyle(SkPaint::kFill_Style);
139 break;
140 case Paint::PaintStyle::PAINT_STROKE:
141 skPaint.setStyle(SkPaint::kStroke_Style);
142 break;
143 case Paint::PaintStyle::PAINT_FILL_STROKE:
144 skPaint.setStyle(SkPaint::kStrokeAndFill_Style);
145 break;
146 default:
147 break;
148 }
149
150 auto cs = paint.GetColorSpace();
151 if (cs != nullptr) {
152 auto skColorSpaceImpl = cs->GetImpl<SkiaColorSpace>();
153 sk_sp<SkColorSpace> colorSpace = (skColorSpaceImpl != nullptr) ? skColorSpaceImpl->GetColorSpace() : nullptr;
154 skPaint.setColor(SkColor4f::FromColor(paint.GetColor().CastToColorQuad()), colorSpace.get());
155 } else {
156 skPaint.setColor(paint.GetColor().CastToColorQuad());
157 }
158
159 skPaint.setAntiAlias(paint.IsAntiAlias());
160 if (paint.GetBlendMode() != BlendMode::SRC_OVER) {
161 skPaint.setBlendMode(static_cast<SkBlendMode>(paint.GetBlendMode()));
162 }
163
164 auto s = paint.GetShaderEffect();
165 if (s != nullptr) {
166 auto skShaderImpl = s->GetImpl<SkiaShaderEffect>();
167 sk_sp<SkShader> skShader = (skShaderImpl != nullptr) ? skShaderImpl->GetShader() : nullptr;
168 skPaint.setShader(skShader);
169 }
170
171 if (paint.HasFilter()) {
172 auto filter = paint.GetFilter();
173 ApplyFilter(skPaint, filter);
174 }
175
176 if (paint.HasStrokeStyle()) {
177 ApplyStrokeParam(paint, skPaint);
178 }
179 }
180
ApplyStrokeParam(const Paint & paint,SkPaint & skPaint)181 void SkiaPaint::ApplyStrokeParam(const Paint& paint, SkPaint& skPaint)
182 {
183 skPaint.setStrokeMiter(paint.GetMiterLimit());
184 skPaint.setStrokeWidth(paint.GetWidth());
185
186 switch (paint.GetCapStyle()) {
187 case Pen::CapStyle::FLAT_CAP:
188 skPaint.setStrokeCap(SkPaint::kButt_Cap);
189 break;
190 case Pen::CapStyle::SQUARE_CAP:
191 skPaint.setStrokeCap(SkPaint::kSquare_Cap);
192 break;
193 case Pen::CapStyle::ROUND_CAP:
194 skPaint.setStrokeCap(SkPaint::kRound_Cap);
195 break;
196 default:
197 break;
198 }
199
200 switch (paint.GetJoinStyle()) {
201 case Pen::JoinStyle::MITER_JOIN:
202 skPaint.setStrokeJoin(SkPaint::kMiter_Join);
203 break;
204 case Pen::JoinStyle::ROUND_JOIN:
205 skPaint.setStrokeJoin(SkPaint::kRound_Join);
206 break;
207 case Pen::JoinStyle::BEVEL_JOIN:
208 skPaint.setStrokeJoin(SkPaint::kBevel_Join);
209 break;
210 default:
211 break;
212 }
213
214 auto p = paint.GetPathEffect();
215 if (p != nullptr) {
216 auto skPathEffectImpl = p->GetImpl<SkiaPathEffect>();
217 sk_sp<SkPathEffect> skPathEffect = (skPathEffectImpl != nullptr) ? skPathEffectImpl->GetPathEffect() : nullptr;
218 skPaint.setPathEffect(skPathEffect);
219 }
220 }
221
SkiaPaint()222 SkiaPaint::SkiaPaint() noexcept {}
223
~SkiaPaint()224 SkiaPaint::~SkiaPaint() {}
225
ApplyPaint(const Paint & paint)226 void SkiaPaint::ApplyPaint(const Paint& paint)
227 {
228 if (paintInUse_ >= MAX_PAINTS_NUMBER || !paint.IsValid()) {
229 return;
230 }
231 SkPaint& skPaint = paints_[paintInUse_];
232 skPaint = defaultPaint_;
233 PaintToSkPaint(paint, skPaint);
234 paintInUse_++;
235 }
236
GetSortedPaints()237 SortedPaints& SkiaPaint::GetSortedPaints()
238 {
239 sortedPaints_.count_ = paintInUse_;
240 for (int i = 0; i < paintInUse_; i++) {
241 sortedPaints_.paints_[i] = &paints_[i];
242 }
243 paintInUse_ = 0;
244 return sortedPaints_;
245 }
246
ApplyFilter(SkPaint & paint,const Filter & filter)247 void SkiaPaint::ApplyFilter(SkPaint& paint, const Filter& filter)
248 {
249 auto c = filter.GetColorFilter();
250 if (c != nullptr) {
251 auto skColorFilterImpl = c->GetImpl<SkiaColorFilter>();
252 sk_sp<SkColorFilter> colorFilter =
253 (skColorFilterImpl != nullptr) ? skColorFilterImpl->GetColorFilter() : nullptr;
254 paint.setColorFilter(colorFilter);
255 }
256
257 auto i = filter.GetImageFilter();
258 if (i != nullptr) {
259 auto skImageFilterImpl = i->GetImpl<SkiaImageFilter>();
260 sk_sp<SkImageFilter> imageFilter =
261 (skImageFilterImpl != nullptr) ? skImageFilterImpl->GetImageFilter() : nullptr;
262 paint.setImageFilter(imageFilter);
263 }
264
265 auto m = filter.GetMaskFilter();
266 if (m != nullptr) {
267 auto skMaskFilterImpl = m->GetImpl<SkiaMaskFilter>();
268 sk_sp<SkMaskFilter> maskFilter = (skMaskFilterImpl != nullptr) ? skMaskFilterImpl->GetMaskFilter() : nullptr;
269 paint.setMaskFilter(maskFilter);
270 }
271 }
272
CanComputeFastBounds(const Brush & brush)273 bool SkiaPaint::CanComputeFastBounds(const Brush& brush)
274 {
275 SkPaint skPaint;
276 BrushToSkPaint(brush, skPaint);
277 return skPaint.canComputeFastBounds();
278 }
279
ComputeFastBounds(const Brush & brush,const Rect & orig,Rect * storage)280 const Rect& SkiaPaint::ComputeFastBounds(const Brush& brush, const Rect& orig, Rect* storage)
281 {
282 if (storage == nullptr) {
283 return orig;
284 }
285 SkPaint skPaint;
286 BrushToSkPaint(brush, skPaint);
287 SkRect skOrig, skStorage;
288 SkiaConvertUtils::DrawingRectCastToSkRect(orig, skOrig);
289 SkiaConvertUtils::DrawingRectCastToSkRect(*storage, skStorage);
290 const SkRect& skRect = skPaint.computeFastBounds(skOrig, &skStorage);
291 SkiaConvertUtils::SkRectCastToDrawingRect(skStorage, *storage);
292 if (&skRect == &skOrig) {
293 return orig;
294 }
295 return *storage;
296 }
297
AsBlendMode(const Brush & brush)298 bool SkiaPaint::AsBlendMode(const Brush& brush)
299 {
300 SkPaint skPaint;
301 BrushToSkPaint(brush, skPaint);
302 return skPaint.asBlendMode().has_value();
303 }
304
Reset()305 void SkiaPaint::Reset()
306 {
307 paintInUse_ = 0;
308 }
309 } // namespace Drawing
310 } // namespace Rosen
311 } // namespace OHOS