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