• 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_shader_effect.h"
17 
18 #include <vector>
19 
20 #include "include/core/SkMatrix.h"
21 #include "include/core/SkTileMode.h"
22 #include "include/effects/SkGradientShader.h"
23 #if defined(USE_CANVASKIT0310_SKIA)
24 #include "include/core/SkSamplingOptions.h"
25 #endif
26 
27 #include "skia_image.h"
28 #include "skia_matrix.h"
29 #include "skia_picture.h"
30 
31 #include "effect/shader_effect.h"
32 #include "image/image.h"
33 #include "image/picture.h"
34 #include "utils/matrix.h"
35 
36 namespace OHOS {
37 namespace Rosen {
38 namespace Drawing {
SkiaShaderEffect()39 SkiaShaderEffect::SkiaShaderEffect() noexcept : shader_(nullptr) {}
40 
InitWithColor(ColorQuad color)41 void SkiaShaderEffect::InitWithColor(ColorQuad color)
42 {
43     shader_ = SkShaders::Color(color);
44 }
45 
InitWithBlend(const ShaderEffect & s1,const ShaderEffect & s2,BlendMode mode)46 void SkiaShaderEffect::InitWithBlend(const ShaderEffect& s1, const ShaderEffect& s2, BlendMode mode)
47 {
48     auto dst = s1.GetImpl<SkiaShaderEffect>();
49     auto src = s2.GetImpl<SkiaShaderEffect>();
50     if (dst != nullptr && src != nullptr) {
51         shader_ = SkShaders::Blend(static_cast<SkBlendMode>(mode), dst->GetShader(), src->GetShader());
52     }
53 }
54 
InitWithImage(const Image & image,TileMode tileX,TileMode tileY,const SamplingOptions & sampling,const Matrix & matrix)55 void SkiaShaderEffect::InitWithImage(
56     const Image& image, TileMode tileX, TileMode tileY, const SamplingOptions& sampling, const Matrix& matrix)
57 {
58     SkTileMode modeX = static_cast<SkTileMode>(tileX);
59     SkTileMode modeY = static_cast<SkTileMode>(tileY);
60 
61     auto m = matrix.GetImpl<SkiaMatrix>();
62     auto i = image.GetImpl<SkiaImage>();
63     SkMatrix skiaMatrix;
64     sk_sp<SkImage> skiaImage;
65     if (m != nullptr && i != nullptr) {
66         skiaMatrix = m->ExportSkiaMatrix();
67         skiaImage = i->GetImage();
68         if (skiaImage != nullptr) {
69 #if defined(USE_CANVASKIT0310_SKIA)
70             SkSamplingOptions samplingOptions;
71             if (sampling.GetUseCubic()) {
72                 samplingOptions = SkSamplingOptions({ sampling.GetCubicCoffB(), sampling.GetCubicCoffC() });
73             } else {
74                 samplingOptions = SkSamplingOptions(static_cast<SkFilterMode>(sampling.GetFilterMode()),
75                     static_cast<SkMipmapMode>(sampling.GetMipmapMode()));
76             }
77             shader_ = skiaImage->makeShader(modeX, modeY, samplingOptions, &skiaMatrix);
78 #else
79             shader_ = skiaImage->makeShader(modeX, modeY, &skiaMatrix);
80 #endif
81         }
82     }
83 }
84 
InitWithPicture(const Picture & picture,TileMode tileX,TileMode tileY,FilterMode mode,const Matrix & matrix,const Rect & rect)85 void SkiaShaderEffect::InitWithPicture(
86     const Picture& picture, TileMode tileX, TileMode tileY, FilterMode mode, const Matrix& matrix, const Rect& rect)
87 {
88     SkTileMode modeX = static_cast<SkTileMode>(tileX);
89     SkTileMode modeY = static_cast<SkTileMode>(tileY);
90     SkRect r = SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
91 
92     auto p = picture.GetImpl<SkiaPicture>();
93     auto m = matrix.GetImpl<SkiaMatrix>();
94     sk_sp<SkPicture> skiaPicture;
95     SkMatrix skiaMatrix;
96     if (p != nullptr && m != nullptr) {
97         skiaPicture = p->GetPicture();
98         skiaMatrix = m->ExportSkiaMatrix();
99         if (skiaPicture != nullptr) {
100 #if defined(USE_CANVASKIT0310_SKIA)
101             SkFilterMode m = static_cast<SkFilterMode>(mode);
102             shader_ = skiaPicture->makeShader(modeX, modeY, m, &skiaMatrix, &r);
103 #else
104             shader_ = skiaPicture->makeShader(modeX, modeY, &skiaMatrix, &r);
105 #endif
106         }
107     }
108 }
109 
InitWithLinearGradient(const Point & startPt,const Point & endPt,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode)110 void SkiaShaderEffect::InitWithLinearGradient(const Point& startPt, const Point& endPt,
111     const std::vector<ColorQuad>& colors, const std::vector<scalar>& pos, TileMode mode)
112 {
113     SkPoint pts[2];
114     pts[0].set(startPt.GetX(), startPt.GetY());
115     pts[1].set(endPt.GetX(), endPt.GetY());
116 
117     size_t count = (colors.size() == pos.size()) ? colors.size() : 0;
118     if (count == 0) {
119         return;
120     }
121     std::vector<SkColor> c;
122     std::vector<SkScalar> p;
123     for (size_t i = 0; i < count; ++i) {
124         c.emplace_back(colors[i]);
125         p.emplace_back(pos[i]);
126     }
127     shader_ = SkGradientShader::MakeLinear(pts, &c[0], &p[0], count, static_cast<SkTileMode>(mode));
128 }
129 
InitWithRadialGradient(const Point & centerPt,scalar radius,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode)130 void SkiaShaderEffect::InitWithRadialGradient(const Point& centerPt, scalar radius,
131     const std::vector<ColorQuad>& colors, const std::vector<scalar>& pos, TileMode mode)
132 {
133     SkPoint center;
134     center.set(centerPt.GetX(), centerPt.GetY());
135 
136     size_t count = (colors.size() == pos.size()) ? colors.size() : 0;
137     if (count == 0) {
138         return;
139     }
140     std::vector<SkColor> c;
141     std::vector<SkScalar> p;
142     for (size_t i = 0; i < count; ++i) {
143         c.emplace_back(colors[i]);
144         p.emplace_back(pos[i]);
145     }
146     shader_ = SkGradientShader::MakeRadial(center, radius, &c[0], &p[0], count, static_cast<SkTileMode>(mode));
147 }
148 
InitWithTwoPointConical(const Point & startPt,scalar startRadius,const Point & endPt,scalar endRadius,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode)149 void SkiaShaderEffect::InitWithTwoPointConical(const Point& startPt, scalar startRadius, const Point& endPt,
150     scalar endRadius, const std::vector<ColorQuad>& colors, const std::vector<scalar>& pos, TileMode mode)
151 {
152     SkPoint start;
153     SkPoint end;
154     start.set(startPt.GetX(), startPt.GetY());
155     end.set(endPt.GetX(), endPt.GetY());
156 
157     size_t count = (colors.size() == pos.size()) ? colors.size() : 0;
158     if (count == 0) {
159         return;
160     }
161     std::vector<SkColor> c;
162     std::vector<SkScalar> p;
163     for (size_t i = 0; i < count; ++i) {
164         c.emplace_back(colors[i]);
165         p.emplace_back(pos[i]);
166     }
167     shader_ = SkGradientShader::MakeTwoPointConical(
168         start, startRadius, end, endRadius, &c[0], &p[0], count, static_cast<SkTileMode>(mode));
169 }
170 
InitWithSweepGradient(const Point & centerPt,const std::vector<ColorQuad> & colors,const std::vector<scalar> & pos,TileMode mode,scalar startAngle,scalar endAngle)171 void SkiaShaderEffect::InitWithSweepGradient(const Point& centerPt, const std::vector<ColorQuad>& colors,
172     const std::vector<scalar>& pos, TileMode mode, scalar startAngle, scalar endAngle)
173 {
174     size_t count = (colors.size() == pos.size()) ? colors.size() : 0;
175     if (count == 0) {
176         return;
177     }
178     std::vector<SkColor> c;
179     std::vector<SkScalar> p;
180     for (size_t i = 0; i < count; ++i) {
181         c.emplace_back(colors[i]);
182         p.emplace_back(pos[i]);
183     }
184     shader_ = SkGradientShader::MakeSweep(centerPt.GetX(), centerPt.GetY(), &c[0], &p[0], count,
185         static_cast<SkTileMode>(mode), startAngle, endAngle, 0, nullptr);
186 }
187 
GetShader() const188 sk_sp<SkShader> SkiaShaderEffect::GetShader() const
189 {
190     return shader_;
191 }
192 } // namespace Drawing
193 } // namespace Rosen
194 } // namespace OHOS