• 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_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