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_matrix.h"
25 #include "skia_path.h"
26 #include "skia_path_effect.h"
27 #include "skia_shader_effect.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 namespace Drawing {
BrushToSkPaint(const Brush & brush,SkPaint & paint)32 void SkiaPaint::BrushToSkPaint(const Brush& brush, SkPaint& paint)
33 {
34     if (const ColorSpace* cs = brush.GetColorSpacePtr()) {
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     if (brush.GetAlpha() != Color::RGB_MAX) {
47         paint.setAlpha(brush.GetAlpha());
48     }
49     paint.setAntiAlias(brush.IsAntiAlias());
50 
51     if (const ShaderEffect* s = brush.GetShaderEffectPtr()) {
52         if (SkiaShaderEffect* skShaderImpl = s->GetImpl<SkiaShaderEffect>()) {
53             paint.setShader(skShaderImpl->GetShader());
54         }
55     }
56 
57     if (const Blender* b = brush.GetBlenderPtr()) {
58         if (SkiaBlender* skBlenderImpl = b->GetImpl<SkiaBlender>()) {
59             paint.setBlender(skBlenderImpl->GetBlender());
60         }
61     }
62 
63     if (brush.HasFilter()) {
64         ApplyFilter(paint, brush.GetFilter());
65     }
66     paint.setStyle(SkPaint::kFill_Style);
67 }
68 
PenToSkPaint(const Pen & pen,SkPaint & paint)69 void SkiaPaint::PenToSkPaint(const Pen& pen, SkPaint& paint)
70 {
71     if (const ColorSpace* cs = pen.GetColorSpacePtr()) {
72         auto skColorSpaceImpl = cs->GetImpl<SkiaColorSpace>();
73         sk_sp<SkColorSpace> colorSpace = (skColorSpaceImpl != nullptr) ? skColorSpaceImpl->GetColorSpace() : nullptr;
74         paint.setColor(SkColor4f::FromColor(pen.GetColor().CastToColorQuad()), colorSpace.get());
75     } else {
76         paint.setColor(pen.GetColor().CastToColorQuad());
77     }
78 
79     if (pen.GetBlendMode() != BlendMode::SRC_OVER) {
80         paint.setBlendMode(static_cast<SkBlendMode>(pen.GetBlendMode()));
81     }
82 
83     paint.setStrokeMiter(pen.GetMiterLimit());
84     paint.setStrokeWidth(pen.GetWidth());
85     paint.setAntiAlias(pen.IsAntiAlias());
86     paint.setAlpha(pen.GetAlpha());
87     paint.setStrokeCap(static_cast<SkPaint::Cap>(pen.GetCapStyle()));
88     paint.setStrokeJoin(static_cast<SkPaint::Join>(pen.GetJoinStyle()));
89 
90     if (const PathEffect* pe = pen.GetPathEffectPtr()) {
91         if (SkiaPathEffect* skPathEffectImpl = pe->GetImpl<SkiaPathEffect>()) {
92             paint.setPathEffect(skPathEffectImpl->GetPathEffect());
93         }
94     }
95 
96     if (const ShaderEffect* se = pen.GetShaderEffectPtr()) {
97         if (SkiaShaderEffect* skShaderImpl = se->GetImpl<SkiaShaderEffect>()) {
98             paint.setShader(skShaderImpl->GetShader());
99         }
100     }
101 
102     if (const Blender* blender = pen.GetBlenderPtr()) {
103         if (SkiaBlender* skBlenderImpl = blender->GetImpl<SkiaBlender>()) {
104             paint.setBlender(skBlenderImpl->GetBlender());
105         }
106     }
107 
108     if (pen.HasFilter()) {
109         ApplyFilter(paint, pen.GetFilter());
110     }
111     paint.setStyle(SkPaint::kStroke_Style);
112 }
113 
PaintToSkPaint(const Paint & paint,SkPaint & skPaint)114 void SkiaPaint::PaintToSkPaint(const Paint& paint, SkPaint& skPaint)
115 {
116     skPaint.setStyle(static_cast<SkPaint::Style>(paint.GetStyle() - Paint::PaintStyle::PAINT_FILL));
117 
118     if (const ColorSpace* cs = paint.GetColorSpacePtr()) {
119         auto skColorSpaceImpl = cs->GetImpl<SkiaColorSpace>();
120         sk_sp<SkColorSpace> colorSpace = (skColorSpaceImpl != nullptr) ? skColorSpaceImpl->GetColorSpace() : nullptr;
121         skPaint.setColor(SkColor4f::FromColor(paint.GetColor().CastToColorQuad()), colorSpace.get());
122     } else {
123         skPaint.setColor(paint.GetColor().CastToColorQuad());
124     }
125 
126     skPaint.setAntiAlias(paint.IsAntiAlias());
127     if (paint.GetBlendMode() != BlendMode::SRC_OVER) {
128         skPaint.setBlendMode(static_cast<SkBlendMode>(paint.GetBlendMode()));
129     }
130 
131     if (const ShaderEffect* se = paint.GetShaderEffectPtr()) {
132         if (SkiaShaderEffect* skShaderImpl = se->GetImpl<SkiaShaderEffect>()) {
133             skPaint.setShader(skShaderImpl->GetShader());
134         }
135     }
136 
137     if (paint.HasFilter()) {
138         ApplyFilter(skPaint, paint.GetFilter());
139     }
140 
141     if (paint.HasStrokeStyle()) {
142         ApplyStrokeParam(paint, skPaint);
143     }
144 
145     if (const Blender* blender = paint.GetBlenderPtr()) {
146         if (SkiaBlender* skBlenderImpl = blender->GetImpl<SkiaBlender>()) {
147             skPaint.setBlender(skBlenderImpl->GetBlender());
148         }
149     }
150 }
151 
ApplyStrokeParam(const Paint & paint,SkPaint & skPaint)152 void SkiaPaint::ApplyStrokeParam(const Paint& paint, SkPaint& skPaint)
153 {
154     if (!IsScalarAlmostEqual(paint.GetMiterLimit(), Paint::DEFAULT_MITER_VAL)) {
155         skPaint.setStrokeMiter(paint.GetMiterLimit());
156     }
157     skPaint.setStrokeWidth(paint.GetWidth());
158     if (paint.GetCapStyle() != Pen::CapStyle::DEFAULT_CAP) {
159         skPaint.setStrokeCap(static_cast<SkPaint::Cap>(paint.GetCapStyle()));
160     }
161     if (paint.GetJoinStyle() != Pen::JoinStyle::DEFAULT_JOIN) {
162         skPaint.setStrokeJoin(static_cast<SkPaint::Join>(paint.GetJoinStyle()));
163     }
164     if (const PathEffect* pe = paint.GetPathEffectPtr()) {
165         if (SkiaPathEffect* skPathEffectImpl = pe->GetImpl<SkiaPathEffect>()) {
166             skPaint.setPathEffect(skPathEffectImpl->GetPathEffect());
167         }
168     }
169 }
170 
SkiaPaint()171 SkiaPaint::SkiaPaint() noexcept {}
172 
~SkiaPaint()173 SkiaPaint::~SkiaPaint() {}
174 
ApplyFilter(SkPaint & paint,const Filter & filter)175 void SkiaPaint::ApplyFilter(SkPaint& paint, const Filter& filter)
176 {
177     if (const ColorFilter* cs = filter.GetColorFilterPtr()) {
178         if (SkiaColorFilter* skColorFilterImpl = cs->GetImpl<SkiaColorFilter>()) {
179             paint.setColorFilter(skColorFilterImpl->GetColorFilter());
180         }
181     }
182 
183     if (const ImageFilter* imageFilter = filter.GetImageFilterPtr()) {
184         if (SkiaImageFilter* skImageFilterImpl = imageFilter->GetImpl<SkiaImageFilter>()) {
185             paint.setImageFilter(skImageFilterImpl->GetImageFilter());
186         }
187     }
188 
189     if (const MaskFilter* mf = filter.GetMaskFilterPtr()) {
190         if (SkiaMaskFilter* skMaskFilterImpl = mf->GetImpl<SkiaMaskFilter>()) {
191             paint.setMaskFilter(skMaskFilterImpl->GetMaskFilter());
192         }
193     }
194 }
195 
GetFillPath(const Pen & pen,const Path & src,Path & dst,const Rect * rect,const Matrix & matrix)196 bool SkiaPaint::GetFillPath(const Pen& pen, const Path& src, Path& dst, const Rect* rect, const Matrix& matrix)
197 {
198     SkPaint skPaint;
199     PenToSkPaint(pen, skPaint);
200     auto srcPathImpl = src.GetImpl<SkiaPath>();
201     auto dstPathImpl = dst.GetImpl<SkiaPath>();
202     auto matrixImpl = matrix.GetImpl<SkiaMatrix>();
203     if (!srcPathImpl || !dstPathImpl || !matrixImpl) {
204         return false;
205     }
206     if (!rect) {
207         return skPaint.getFillPath(srcPathImpl->GetMutablePath(), &dstPathImpl->GetMutablePath(),
208                                    nullptr, matrixImpl->ExportMatrix());
209     }
210     SkRect skRect = SkRect::MakeLTRB(rect->GetLeft(), rect->GetTop(), rect->GetRight(), rect->GetBottom());
211     return skPaint.getFillPath(srcPathImpl->GetMutablePath(), &dstPathImpl->GetMutablePath(),
212                                &skRect, matrixImpl->ExportMatrix());
213 }
214 
CanComputeFastBounds(const Brush & brush)215 bool SkiaPaint::CanComputeFastBounds(const Brush& brush)
216 {
217     SkPaint skPaint;
218     BrushToSkPaint(brush, skPaint);
219     return skPaint.canComputeFastBounds();
220 }
221 
ComputeFastBounds(const Brush & brush,const Rect & orig,Rect * storage)222 const Rect& SkiaPaint::ComputeFastBounds(const Brush& brush, const Rect& orig, Rect* storage)
223 {
224     if (storage == nullptr) {
225         return orig;
226     }
227     SkPaint skPaint;
228     BrushToSkPaint(brush, skPaint);
229     SkRect skOrig, skStorage;
230     SkiaConvertUtils::DrawingRectCastToSkRect(orig, skOrig);
231     SkiaConvertUtils::DrawingRectCastToSkRect(*storage, skStorage);
232     const SkRect& skRect = skPaint.computeFastBounds(skOrig, &skStorage);
233     SkiaConvertUtils::SkRectCastToDrawingRect(skStorage, *storage);
234     if (&skRect == &skOrig) {
235         return orig;
236     }
237     return *storage;
238 }
239 
AsBlendMode(const Brush & brush)240 bool SkiaPaint::AsBlendMode(const Brush& brush)
241 {
242     SkPaint skPaint;
243     BrushToSkPaint(brush, skPaint);
244     return skPaint.asBlendMode().has_value();
245 }
246 } // namespace Drawing
247 } // namespace Rosen
248 } // namespace OHOS