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_color_filter.h"
19 #include "skia_color_space.h"
20 #include "skia_image_filter.h"
21 #include "skia_mask_filter.h"
22 #include "skia_path.h"
23 #include "skia_path_effect.h"
24 #include "skia_shader_effect.h"
25
26 namespace OHOS {
27 namespace Rosen {
28 namespace Drawing {
SkiaPaint()29 SkiaPaint::SkiaPaint() noexcept
30 : stroke_(std::make_shared<PaintData>()), fill_(std::make_shared<PaintData>()), isStrokeFirst_(false)
31 {}
32
ApplyBrushToFill(const Brush & brush)33 void SkiaPaint::ApplyBrushToFill(const Brush& brush)
34 {
35 fill_->paint.reset();
36 fill_->isEnabled = true;
37 BrushToSkPaint(brush, fill_->paint);
38 }
39
ApplyPenToStroke(const Pen & pen)40 void SkiaPaint::ApplyPenToStroke(const Pen& pen)
41 {
42 stroke_->paint.reset();
43 stroke_->isEnabled = true;
44 PenToSkPaint(pen, stroke_->paint);
45 }
46
BrushToSkPaint(const Brush & brush,SkPaint & paint) const47 void SkiaPaint::BrushToSkPaint(const Brush& brush, SkPaint& paint) const
48 {
49 paint.setColor(brush.GetColor().CastToColorQuad());
50
51 auto cs = brush.GetColorSpace();
52 if (cs != nullptr) {
53 auto skColorSpaceImpl = cs->GetImpl<SkiaColorSpace>();
54 sk_sp<SkColorSpace> colorSpace = (skColorSpaceImpl != nullptr) ? skColorSpaceImpl->GetColorSpace() : nullptr;
55 paint.setColor(paint.getColor4f(), colorSpace.get());
56 }
57
58 paint.setAlpha(brush.GetAlpha());
59 paint.setBlendMode(static_cast<SkBlendMode>(brush.GetBlendMode()));
60 paint.setAntiAlias(brush.IsAntiAlias());
61
62 auto s = brush.GetShaderEffect();
63 if (s != nullptr) {
64 auto skShaderImpl = s->GetImpl<SkiaShaderEffect>();
65 sk_sp<SkShader> skShader = (skShaderImpl != nullptr) ? skShaderImpl->GetShader() : nullptr;
66 paint.setShader(skShader);
67 } else {
68 paint.setShader(nullptr);
69 }
70
71 auto filter = brush.GetFilter();
72 ApplyFilter(paint, filter);
73 paint.setStyle(SkPaint::kFill_Style);
74 }
75
PenToSkPaint(const Pen & pen,SkPaint & paint) const76 void SkiaPaint::PenToSkPaint(const Pen& pen, SkPaint& paint) const
77 {
78 paint.setColor(pen.GetColor().CastToColorQuad());
79
80 auto cs = pen.GetColorSpace();
81 if (cs != nullptr) {
82 auto skColorSpaceImpl = cs->GetImpl<SkiaColorSpace>();
83 sk_sp<SkColorSpace> colorSpace = (skColorSpaceImpl != nullptr) ? skColorSpaceImpl->GetColorSpace() : nullptr;
84 paint.setColor(paint.getColor4f(), colorSpace.get());
85 }
86
87 paint.setStrokeMiter(pen.GetMiterLimit());
88 paint.setStrokeWidth(pen.GetWidth());
89 paint.setAntiAlias(pen.IsAntiAlias());
90 paint.setAlpha(pen.GetAlpha());
91 paint.setBlendMode(static_cast<SkBlendMode>(pen.GetBlendMode()));
92
93 switch (pen.GetCapStyle()) {
94 case Pen::CapStyle::FLAT_CAP:
95 paint.setStrokeCap(SkPaint::kButt_Cap);
96 break;
97 case Pen::CapStyle::SQUARE_CAP:
98 paint.setStrokeCap(SkPaint::kSquare_Cap);
99 break;
100 case Pen::CapStyle::ROUND_CAP:
101 paint.setStrokeCap(SkPaint::kRound_Cap);
102 break;
103 default:
104 break;
105 }
106
107 switch (pen.GetJoinStyle()) {
108 case Pen::JoinStyle::MITER_JOIN:
109 paint.setStrokeJoin(SkPaint::kMiter_Join);
110 break;
111 case Pen::JoinStyle::ROUND_JOIN:
112 paint.setStrokeJoin(SkPaint::kRound_Join);
113 break;
114 case Pen::JoinStyle::BEVEL_JOIN:
115 paint.setStrokeJoin(SkPaint::kBevel_Join);
116 break;
117 default:
118 break;
119 }
120
121 auto p = pen.GetPathEffect();
122 if (p != nullptr) {
123 auto skPathEffectImpl = p->GetImpl<SkiaPathEffect>();
124 sk_sp<SkPathEffect> skPathEffect = (skPathEffectImpl != nullptr) ? skPathEffectImpl->GetPathEffect() : nullptr;
125 paint.setPathEffect(skPathEffect);
126 } else {
127 paint.setPathEffect(nullptr);
128 }
129
130 auto s = pen.GetShaderEffect();
131 if (s != nullptr) {
132 auto skShaderImpl = s->GetImpl<SkiaShaderEffect>();
133 sk_sp<SkShader> skShader = (skShaderImpl != nullptr) ? skShaderImpl->GetShader() : nullptr;
134 paint.setShader(skShader);
135 } else {
136 paint.setShader(nullptr);
137 }
138
139 auto filter = pen.GetFilter();
140 ApplyFilter(paint, filter);
141 paint.setStyle(SkPaint::kStroke_Style);
142 }
143
DisableStroke()144 void SkiaPaint::DisableStroke()
145 {
146 stroke_->isEnabled = false;
147 }
148
DisableFill()149 void SkiaPaint::DisableFill()
150 {
151 fill_->isEnabled = false;
152 }
153
GetSortedPaints() const154 std::vector<std::shared_ptr<PaintData>> SkiaPaint::GetSortedPaints() const
155 {
156 std::vector<std::shared_ptr<PaintData>> paints;
157 if (IsStrokeFirst() && stroke_->isEnabled && fill_->isEnabled) {
158 paints.push_back(stroke_);
159 paints.push_back(fill_);
160 return paints;
161 }
162
163 if (fill_->isEnabled) {
164 paints.push_back(fill_);
165 }
166 if (stroke_->isEnabled) {
167 paints.push_back(stroke_);
168 }
169 return paints;
170 }
171
SetStrokeFirst(bool isStrokeFirst)172 void SkiaPaint::SetStrokeFirst(bool isStrokeFirst)
173 {
174 isStrokeFirst_ = isStrokeFirst;
175 }
176
IsStrokeFirst() const177 bool SkiaPaint::IsStrokeFirst() const
178 {
179 return isStrokeFirst_;
180 }
181
ApplyFilter(SkPaint & paint,const Filter & filter) const182 void SkiaPaint::ApplyFilter(SkPaint& paint, const Filter& filter) const
183 {
184 #if !defined(USE_CANVASKIT0310_SKIA) && !defined(NEW_SKIA)
185 switch (filter.GetFilterQuality()) {
186 case Filter::FilterQuality::LOW:
187 paint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);
188 break;
189 case Filter::FilterQuality::MEDIUM:
190 paint.setFilterQuality(SkFilterQuality::kMedium_SkFilterQuality);
191 break;
192 case Filter::FilterQuality::HIGH:
193 paint.setFilterQuality(SkFilterQuality::kHigh_SkFilterQuality);
194 break;
195 case Filter::FilterQuality::NONE:
196 paint.setFilterQuality(SkFilterQuality::kNone_SkFilterQuality);
197 break;
198 default:
199 break;
200 }
201 #endif
202
203 auto c = filter.GetColorFilter();
204 if (c != nullptr) {
205 auto skColorFilterImpl = c->GetImpl<SkiaColorFilter>();
206 sk_sp<SkColorFilter> colorFilter =
207 (skColorFilterImpl != nullptr) ? skColorFilterImpl->GetColorFilter() : nullptr;
208 paint.setColorFilter(colorFilter);
209 } else {
210 paint.setColorFilter(nullptr);
211 }
212
213 auto i = filter.GetImageFilter();
214 if (i != nullptr) {
215 auto skImageFilterImpl = i->GetImpl<SkiaImageFilter>();
216 sk_sp<SkImageFilter> imageFilter =
217 (skImageFilterImpl != nullptr) ? skImageFilterImpl->GetImageFilter() : nullptr;
218 paint.setImageFilter(imageFilter);
219 } else {
220 paint.setImageFilter(nullptr);
221 }
222
223 auto m = filter.GetMaskFilter();
224 if (m != nullptr) {
225 auto skMaskFilterImpl = m->GetImpl<SkiaMaskFilter>();
226 sk_sp<SkMaskFilter> maskFilter = (skMaskFilterImpl != nullptr) ? skMaskFilterImpl->GetMaskFilter() : nullptr;
227 paint.setMaskFilter(maskFilter);
228 } else {
229 paint.setMaskFilter(nullptr);
230 }
231 }
232 } // namespace Drawing
233 } // namespace Rosen
234 } // namespace OHOS