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