1 /*
2 * Copyright (c) 2023-2024 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 "drawing_shader_effect.h"
17
18 #include "drawing_canvas_utils.h"
19
20 #include "effect/shader_effect.h"
21
22 using namespace OHOS;
23 using namespace Rosen;
24 using namespace Drawing;
25
CastToPoint(const OH_Drawing_Point * cPoint)26 static const Point* CastToPoint(const OH_Drawing_Point* cPoint)
27 {
28 return reinterpret_cast<const Point*>(cPoint);
29 }
30
CastToPoint(const OH_Drawing_Point2D * cPoint)31 static const Point* CastToPoint(const OH_Drawing_Point2D* cPoint)
32 {
33 return reinterpret_cast<const Point*>(cPoint);
34 }
35
CastToImage(const OH_Drawing_Image & cImage)36 static const Image& CastToImage(const OH_Drawing_Image& cImage)
37 {
38 return reinterpret_cast<const Image&>(cImage);
39 }
40
CastToSamplingOptions(const OH_Drawing_SamplingOptions & cSamplingOptions)41 static const SamplingOptions& CastToSamplingOptions(const OH_Drawing_SamplingOptions& cSamplingOptions)
42 {
43 return reinterpret_cast<const SamplingOptions&>(cSamplingOptions);
44 }
45
CastToMatrix(const OH_Drawing_Matrix * cMatrix)46 static const Matrix* CastToMatrix(const OH_Drawing_Matrix* cMatrix)
47 {
48 return reinterpret_cast<const Matrix*>(cMatrix);
49 }
50
CastToShaderEffect(OH_Drawing_ShaderEffect * cShaderEffect)51 static ShaderEffect* CastToShaderEffect(OH_Drawing_ShaderEffect* cShaderEffect)
52 {
53 return reinterpret_cast<ShaderEffect*>(cShaderEffect);
54 }
55
OH_Drawing_ShaderEffectCreateColorShader(const uint32_t color)56 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateColorShader(const uint32_t color)
57 {
58 return (OH_Drawing_ShaderEffect*)new ShaderEffect(ShaderEffect::ShaderEffectType::COLOR_SHADER, color);
59 }
60
OH_Drawing_ShaderEffectCreateLinearGradient(const OH_Drawing_Point * cStartPt,const OH_Drawing_Point * cEndPt,const uint32_t * colors,const float * pos,uint32_t size,OH_Drawing_TileMode cTileMode)61 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateLinearGradient(const OH_Drawing_Point* cStartPt,
62 const OH_Drawing_Point* cEndPt, const uint32_t* colors, const float* pos, uint32_t size,
63 OH_Drawing_TileMode cTileMode)
64 {
65 if (cStartPt == nullptr || cEndPt == nullptr || colors == nullptr) {
66 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
67 return nullptr;
68 }
69 if (cTileMode < CLAMP || cTileMode > DECAL) {
70 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
71 return nullptr;
72 }
73 std::vector<ColorQuad> colorsVector;
74 std::vector<scalar> posVector;
75 for (uint32_t i = 0; i < size; i++) {
76 colorsVector.emplace_back(colors[i]);
77 }
78 if (pos != nullptr) {
79 for (uint32_t i = 0; i < size; i++) {
80 posVector.emplace_back(pos[i]);
81 }
82 }
83 return (OH_Drawing_ShaderEffect*)new ShaderEffect(ShaderEffect::ShaderEffectType::LINEAR_GRADIENT,
84 *CastToPoint(cStartPt), *CastToPoint(cEndPt), colorsVector, posVector, static_cast<TileMode>(cTileMode));
85 }
86
OH_Drawing_ShaderEffectCreateLinearGradientWithLocalMatrix(const OH_Drawing_Point2D * startPt,const OH_Drawing_Point2D * endPt,const uint32_t * colors,const float * pos,uint32_t size,OH_Drawing_TileMode cTileMode,const OH_Drawing_Matrix * cMatrix)87 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateLinearGradientWithLocalMatrix(
88 const OH_Drawing_Point2D* startPt, const OH_Drawing_Point2D* endPt, const uint32_t* colors, const float* pos,
89 uint32_t size, OH_Drawing_TileMode cTileMode, const OH_Drawing_Matrix* cMatrix)
90 {
91 if (startPt == nullptr || endPt == nullptr || colors == nullptr) {
92 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
93 return nullptr;
94 }
95 if (cTileMode < CLAMP || cTileMode > DECAL) {
96 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
97 return nullptr;
98 }
99 std::vector<ColorQuad> colorsVector;
100 std::vector<scalar> posVector;
101 for (uint32_t i = 0; i < size; i++) {
102 colorsVector.emplace_back(colors[i]);
103 }
104 if (pos != nullptr) {
105 for (uint32_t i = 0; i < size; i++) {
106 posVector.emplace_back(pos[i]);
107 }
108 }
109 return (OH_Drawing_ShaderEffect*)new ShaderEffect(
110 ShaderEffect::ShaderEffectType::LINEAR_GRADIENT, *CastToPoint(startPt), *CastToPoint(endPt), colorsVector,
111 posVector, static_cast<TileMode>(cTileMode), cMatrix ? CastToMatrix(cMatrix) : nullptr);
112 }
113
OH_Drawing_ShaderEffectCreateRadialGradient(const OH_Drawing_Point * cCenterPt,float radius,const uint32_t * colors,const float * pos,uint32_t size,OH_Drawing_TileMode cTileMode)114 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateRadialGradient(const OH_Drawing_Point* cCenterPt, float radius,
115 const uint32_t* colors, const float* pos, uint32_t size, OH_Drawing_TileMode cTileMode)
116 {
117 if (cCenterPt == nullptr || colors == nullptr) {
118 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
119 return nullptr;
120 }
121 if (cTileMode < CLAMP || cTileMode > DECAL) {
122 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
123 return nullptr;
124 }
125 std::vector<ColorQuad> colorsVector;
126 std::vector<scalar> posVector;
127 for (uint32_t i = 0; i < size; i++) {
128 colorsVector.emplace_back(colors[i]);
129 if (pos) {
130 posVector.emplace_back(pos[i]);
131 }
132 }
133 return (OH_Drawing_ShaderEffect*)new ShaderEffect(ShaderEffect::ShaderEffectType::RADIAL_GRADIENT,
134 *CastToPoint(cCenterPt), radius, colorsVector, posVector, static_cast<TileMode>(cTileMode));
135 }
136
OH_Drawing_ShaderEffectCreateRadialGradientWithLocalMatrix(const OH_Drawing_Point2D * centerPt,float radius,const uint32_t * colors,const float * pos,uint32_t size,OH_Drawing_TileMode cTileMode,const OH_Drawing_Matrix * cMatrix)137 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateRadialGradientWithLocalMatrix(
138 const OH_Drawing_Point2D* centerPt, float radius, const uint32_t* colors, const float* pos, uint32_t size,
139 OH_Drawing_TileMode cTileMode, const OH_Drawing_Matrix* cMatrix)
140 {
141 if (centerPt == nullptr || colors == nullptr) {
142 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
143 return nullptr;
144 }
145 if (cTileMode < CLAMP || cTileMode > DECAL) {
146 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
147 return nullptr;
148 }
149 std::vector<ColorQuad> colorsVector;
150 std::vector<scalar> posVector;
151 for (uint32_t i = 0; i < size; i++) {
152 colorsVector.emplace_back(colors[i]);
153 if (pos) {
154 posVector.emplace_back(pos[i]);
155 }
156 }
157 return (OH_Drawing_ShaderEffect*)new ShaderEffect(
158 ShaderEffect::ShaderEffectType::RADIAL_GRADIENT, *CastToPoint(centerPt), radius, colorsVector, posVector,
159 static_cast<TileMode>(cTileMode), cMatrix ? CastToMatrix(cMatrix) : nullptr);
160 }
161
OH_Drawing_ShaderEffectCreateSweepGradient(const OH_Drawing_Point * cCenterPt,const uint32_t * colors,const float * pos,uint32_t size,OH_Drawing_TileMode cTileMode)162 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateSweepGradient(const OH_Drawing_Point* cCenterPt,
163 const uint32_t* colors, const float* pos, uint32_t size, OH_Drawing_TileMode cTileMode)
164 {
165 if (cCenterPt == nullptr || colors == nullptr) {
166 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
167 return nullptr;
168 }
169 if (cTileMode < CLAMP || cTileMode > DECAL) {
170 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
171 return nullptr;
172 }
173 std::vector<ColorQuad> colorsVector;
174 std::vector<scalar> posVector;
175 for (uint32_t i = 0; i < size; i++) {
176 colorsVector.emplace_back(colors[i]);
177 if (pos) {
178 posVector.emplace_back(pos[i]);
179 }
180 }
181 return (OH_Drawing_ShaderEffect*)new ShaderEffect(ShaderEffect::ShaderEffectType::SWEEP_GRADIENT,
182 *CastToPoint(cCenterPt), colorsVector, posVector, static_cast<TileMode>(cTileMode), 0,
183 360, nullptr); // 360: endAngle
184 }
185
OH_Drawing_ShaderEffectCreateImageShader(OH_Drawing_Image * cImage,OH_Drawing_TileMode tileX,OH_Drawing_TileMode tileY,const OH_Drawing_SamplingOptions * cSampling,const OH_Drawing_Matrix * cMatrix)186 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateImageShader(OH_Drawing_Image* cImage, OH_Drawing_TileMode tileX,
187 OH_Drawing_TileMode tileY, const OH_Drawing_SamplingOptions* cSampling, const OH_Drawing_Matrix* cMatrix)
188 {
189 if (cImage == nullptr || cSampling == nullptr) {
190 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
191 return nullptr;
192 }
193 if (tileX < CLAMP || tileX > DECAL || tileY < CLAMP || tileY > DECAL) {
194 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
195 return nullptr;
196 }
197 if (cMatrix == nullptr) {
198 Matrix matrix;
199 return (OH_Drawing_ShaderEffect*)new ShaderEffect(ShaderEffect::ShaderEffectType::IMAGE, CastToImage(*cImage),
200 static_cast<TileMode>(tileX), static_cast<TileMode>(tileY), CastToSamplingOptions(*cSampling), matrix);
201 }
202 return (OH_Drawing_ShaderEffect*)new ShaderEffect(ShaderEffect::ShaderEffectType::IMAGE, CastToImage(*cImage),
203 static_cast<TileMode>(tileX), static_cast<TileMode>(tileY), CastToSamplingOptions(*cSampling),
204 *CastToMatrix(cMatrix));
205 }
206
OH_Drawing_ShaderEffectCreateTwoPointConicalGradient(const OH_Drawing_Point2D * startPt,float startRadius,const OH_Drawing_Point2D * endPt,float endRadius,const uint32_t * colors,const float * pos,uint32_t size,OH_Drawing_TileMode cTileMode,const OH_Drawing_Matrix * cMatrix)207 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateTwoPointConicalGradient(const OH_Drawing_Point2D* startPt,
208 float startRadius, const OH_Drawing_Point2D* endPt, float endRadius, const uint32_t* colors, const float* pos,
209 uint32_t size, OH_Drawing_TileMode cTileMode, const OH_Drawing_Matrix* cMatrix)
210 {
211 if (startPt == nullptr || endPt == nullptr || colors == nullptr) {
212 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
213 return nullptr;
214 }
215 if (cTileMode < CLAMP || cTileMode > DECAL) {
216 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
217 return nullptr;
218 }
219 std::vector<ColorQuad> colorsVector;
220 std::vector<scalar> posVector;
221 for (uint32_t i = 0; i < size; i++) {
222 colorsVector.emplace_back(colors[i]);
223 if (pos) {
224 posVector.emplace_back(pos[i]);
225 }
226 }
227 return (OH_Drawing_ShaderEffect*)new ShaderEffect(ShaderEffect::ShaderEffectType::CONICAL_GRADIENT,
228 *CastToPoint(startPt), startRadius, *CastToPoint(endPt), endRadius, colorsVector, posVector,
229 static_cast<TileMode>(cTileMode), cMatrix ? CastToMatrix(cMatrix) : nullptr);
230 }
231
OH_Drawing_ShaderEffectDestroy(OH_Drawing_ShaderEffect * cShaderEffect)232 void OH_Drawing_ShaderEffectDestroy(OH_Drawing_ShaderEffect* cShaderEffect)
233 {
234 if (!cShaderEffect) {
235 return;
236 }
237 delete CastToShaderEffect(cShaderEffect);
238 }
239