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