• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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