• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 #include "native_pixel_map_manager.h"
21 
22 #include "effect/shader_effect.h"
23 #include "effect/shader_effect_lazy.h"
24 #include "render/rs_pixel_map_util.h"
25 #include "render/rs_pixel_map_shader_obj.h"
26 
27 using namespace OHOS;
28 using namespace Rosen;
29 using namespace Drawing;
30 
CastToPoint(const OH_Drawing_Point * cPoint)31 static const Point* CastToPoint(const OH_Drawing_Point* cPoint)
32 {
33     return reinterpret_cast<const Point*>(cPoint);
34 }
35 
CastToPoint(const OH_Drawing_Point2D * cPoint)36 static const Point* CastToPoint(const OH_Drawing_Point2D* cPoint)
37 {
38     return reinterpret_cast<const Point*>(cPoint);
39 }
40 
CastToImage(const OH_Drawing_Image & cImage)41 static const Image& CastToImage(const OH_Drawing_Image& cImage)
42 {
43     return reinterpret_cast<const Image&>(cImage);
44 }
45 
CastToSamplingOptions(const OH_Drawing_SamplingOptions & cSamplingOptions)46 static const SamplingOptions& CastToSamplingOptions(const OH_Drawing_SamplingOptions& cSamplingOptions)
47 {
48     return reinterpret_cast<const SamplingOptions&>(cSamplingOptions);
49 }
50 
CastToMatrix(const OH_Drawing_Matrix * cMatrix)51 static const Matrix* CastToMatrix(const OH_Drawing_Matrix* cMatrix)
52 {
53     return reinterpret_cast<const Matrix*>(cMatrix);
54 }
55 
CastShaderEffect(std::shared_ptr<ShaderEffect> shaderEffect)56 static OH_Drawing_ShaderEffect* CastShaderEffect(std::shared_ptr<ShaderEffect> shaderEffect)
57 {
58     NativeHandle<ShaderEffect>* shaderEffectHandle = new NativeHandle<ShaderEffect>;
59     shaderEffectHandle->value = shaderEffect;
60     return Helper::CastTo<NativeHandle<ShaderEffect>*, OH_Drawing_ShaderEffect*>(shaderEffectHandle);
61 }
62 
OH_Drawing_ShaderEffectCreateColorShader(const uint32_t color)63 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateColorShader(const uint32_t color)
64 {
65     return CastShaderEffect(ShaderEffect::CreateColorShader(color));
66 }
67 
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)68 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateLinearGradient(const OH_Drawing_Point* cStartPt,
69     const OH_Drawing_Point* cEndPt, const uint32_t* colors, const float* pos, uint32_t size,
70     OH_Drawing_TileMode cTileMode)
71 {
72     if (cStartPt == nullptr || cEndPt == nullptr || colors == nullptr) {
73         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
74         return nullptr;
75     }
76     if (cTileMode < CLAMP || cTileMode > DECAL) {
77         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
78         return nullptr;
79     }
80     std::vector<ColorQuad> colorsVector;
81     std::vector<scalar> posVector;
82     for (uint32_t i = 0; i < size; i++) {
83         colorsVector.emplace_back(colors[i]);
84     }
85     if (pos != nullptr) {
86         for (uint32_t i = 0; i < size; i++) {
87             posVector.emplace_back(pos[i]);
88         }
89     }
90     return CastShaderEffect(ShaderEffect::CreateLinearGradient(
91         *CastToPoint(cStartPt), *CastToPoint(cEndPt), colorsVector, posVector, static_cast<TileMode>(cTileMode)));
92 }
93 
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)94 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateLinearGradientWithLocalMatrix(
95     const OH_Drawing_Point2D* startPt, const OH_Drawing_Point2D* endPt, const uint32_t* colors, const float* pos,
96     uint32_t size, OH_Drawing_TileMode cTileMode, const OH_Drawing_Matrix* cMatrix)
97 {
98     if (startPt == nullptr || endPt == nullptr || colors == nullptr) {
99         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
100         return nullptr;
101     }
102     if (cTileMode < CLAMP || cTileMode > DECAL) {
103         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
104         return nullptr;
105     }
106     std::vector<ColorQuad> colorsVector;
107     std::vector<scalar> posVector;
108     for (uint32_t i = 0; i < size; i++) {
109         colorsVector.emplace_back(colors[i]);
110     }
111     if (pos != nullptr) {
112         for (uint32_t i = 0; i < size; i++) {
113             posVector.emplace_back(pos[i]);
114         }
115     }
116     return CastShaderEffect(ShaderEffect::CreateLinearGradient(
117         *CastToPoint(startPt), *CastToPoint(endPt), colorsVector,
118         posVector, static_cast<TileMode>(cTileMode), cMatrix ? CastToMatrix(cMatrix) : nullptr));
119 }
120 
OH_Drawing_ShaderEffectCreateRadialGradient(const OH_Drawing_Point * cCenterPt,float radius,const uint32_t * colors,const float * pos,uint32_t size,OH_Drawing_TileMode cTileMode)121 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateRadialGradient(const OH_Drawing_Point* cCenterPt, float radius,
122     const uint32_t* colors, const float* pos, uint32_t size, OH_Drawing_TileMode cTileMode)
123 {
124     if (cCenterPt == nullptr || colors == nullptr) {
125         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
126         return nullptr;
127     }
128     if (cTileMode < CLAMP || cTileMode > DECAL) {
129         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
130         return nullptr;
131     }
132     std::vector<ColorQuad> colorsVector;
133     std::vector<scalar> posVector;
134     for (uint32_t i = 0; i < size; i++) {
135         colorsVector.emplace_back(colors[i]);
136         if (pos) {
137             posVector.emplace_back(pos[i]);
138         }
139     }
140     return CastShaderEffect(ShaderEffect::CreateRadialGradient(
141         *CastToPoint(cCenterPt), radius, colorsVector, posVector, static_cast<TileMode>(cTileMode)));
142 }
143 
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)144 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateRadialGradientWithLocalMatrix(
145     const OH_Drawing_Point2D* centerPt, float radius, const uint32_t* colors, const float* pos, uint32_t size,
146     OH_Drawing_TileMode cTileMode, const OH_Drawing_Matrix* cMatrix)
147 {
148     if (centerPt == nullptr || colors == nullptr) {
149         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
150         return nullptr;
151     }
152     if (cTileMode < CLAMP || cTileMode > DECAL) {
153         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
154         return nullptr;
155     }
156     std::vector<ColorQuad> colorsVector;
157     std::vector<scalar> posVector;
158     for (uint32_t i = 0; i < size; i++) {
159         colorsVector.emplace_back(colors[i]);
160         if (pos) {
161             posVector.emplace_back(pos[i]);
162         }
163     }
164     return CastShaderEffect(ShaderEffect::CreateRadialGradient(
165         *CastToPoint(centerPt), radius, colorsVector, posVector,
166         static_cast<TileMode>(cTileMode), cMatrix ? CastToMatrix(cMatrix) : nullptr));
167 }
168 
OH_Drawing_ShaderEffectCreateSweepGradientWithLocalMatrix(const OH_Drawing_Point * centerPt,const uint32_t * colors,const float * pos,uint32_t size,OH_Drawing_TileMode tileMode,const OH_Drawing_Matrix * matrix)169 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateSweepGradientWithLocalMatrix(
170     const OH_Drawing_Point* centerPt, const uint32_t* colors, const float* pos, uint32_t size,
171     OH_Drawing_TileMode tileMode, const OH_Drawing_Matrix* matrix)
172 {
173     if (centerPt == nullptr || colors == nullptr) {
174         return nullptr;
175     }
176     if (tileMode < CLAMP || tileMode > DECAL) {
177         return nullptr;
178     }
179     std::vector<ColorQuad> colorsVector;
180     std::vector<scalar> posVector;
181     for (uint32_t i = 0; i < size; i++) {
182         colorsVector.emplace_back(colors[i]);
183         if (pos) {
184             posVector.emplace_back(pos[i]);
185         }
186     }
187     return CastShaderEffect(ShaderEffect::CreateSweepGradient(
188         *CastToPoint(centerPt), colorsVector, posVector, static_cast<TileMode>(tileMode), 0,
189         360, matrix ? CastToMatrix(matrix) : nullptr)); // 360: endAngle
190 }
191 
OH_Drawing_ShaderEffectCreateSweepGradient(const OH_Drawing_Point * cCenterPt,const uint32_t * colors,const float * pos,uint32_t size,OH_Drawing_TileMode cTileMode)192 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateSweepGradient(const OH_Drawing_Point* cCenterPt,
193     const uint32_t* colors, const float* pos, uint32_t size, OH_Drawing_TileMode cTileMode)
194 {
195     if (cCenterPt == nullptr || colors == nullptr) {
196         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
197         return nullptr;
198     }
199     if (cTileMode < CLAMP || cTileMode > DECAL) {
200         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
201         return nullptr;
202     }
203     std::vector<ColorQuad> colorsVector;
204     std::vector<scalar> posVector;
205     for (uint32_t i = 0; i < size; i++) {
206         colorsVector.emplace_back(colors[i]);
207         if (pos) {
208             posVector.emplace_back(pos[i]);
209         }
210     }
211     return CastShaderEffect(ShaderEffect::CreateSweepGradient(
212         *CastToPoint(cCenterPt), colorsVector, posVector, static_cast<TileMode>(cTileMode), 0,
213         360, nullptr)); // 360: endAngle
214 }
215 
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)216 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateImageShader(OH_Drawing_Image* cImage, OH_Drawing_TileMode tileX,
217     OH_Drawing_TileMode tileY, const OH_Drawing_SamplingOptions* cSampling, const OH_Drawing_Matrix* cMatrix)
218 {
219     if (cImage == nullptr || cSampling == nullptr) {
220         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
221         return nullptr;
222     }
223     if (tileX < CLAMP || tileX > DECAL || tileY < CLAMP || tileY > DECAL) {
224         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
225         return nullptr;
226     }
227     if (cMatrix == nullptr) {
228         Matrix matrix;
229         return CastShaderEffect(ShaderEffect::CreateImageShader(
230             CastToImage(*cImage), static_cast<TileMode>(tileX), static_cast<TileMode>(tileY),
231             CastToSamplingOptions(*cSampling), matrix));
232     }
233     return CastShaderEffect(ShaderEffect::CreateImageShader(
234         CastToImage(*cImage), static_cast<TileMode>(tileX), static_cast<TileMode>(tileY),
235         CastToSamplingOptions(*cSampling), *CastToMatrix(cMatrix)));
236 }
237 
OH_Drawing_ShaderEffectCreatePixelMapShader(OH_Drawing_PixelMap * pixelMap,OH_Drawing_TileMode tileX,OH_Drawing_TileMode tileY,const OH_Drawing_SamplingOptions * samplingOptions,const OH_Drawing_Matrix * matrix)238 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreatePixelMapShader(OH_Drawing_PixelMap* pixelMap,
239     OH_Drawing_TileMode tileX, OH_Drawing_TileMode tileY, const OH_Drawing_SamplingOptions* samplingOptions,
240     const OH_Drawing_Matrix* matrix)
241 {
242 #ifdef OHOS_PLATFORM
243     if (pixelMap == nullptr || samplingOptions == nullptr) {
244         return nullptr;
245     }
246     if (tileX < CLAMP || tileX > DECAL || tileY < CLAMP || tileY > DECAL) {
247         return nullptr;
248     }
249 
250     std::shared_ptr<Media::PixelMap> pixelMapPtr = OHOS::Rosen::GetPixelMapFromNativePixelMap(pixelMap);
251     if (!pixelMapPtr) {
252         return nullptr;
253     }
254 
255     Matrix defaultMatrix;
256     const Matrix& matrixRef = matrix ? *CastToMatrix(matrix) : defaultMatrix;
257 
258     return CastShaderEffect(RSPixelMapShaderObj::CreatePixelMapShader(
259         pixelMapPtr, static_cast<TileMode>(tileX), static_cast<TileMode>(tileY),
260         CastToSamplingOptions(*samplingOptions), matrixRef));
261 #else
262     return nullptr;
263 #endif
264 }
265 
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)266 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateTwoPointConicalGradient(const OH_Drawing_Point2D* startPt,
267     float startRadius, const OH_Drawing_Point2D* endPt, float endRadius, const uint32_t* colors, const float* pos,
268     uint32_t size, OH_Drawing_TileMode cTileMode, const OH_Drawing_Matrix* cMatrix)
269 {
270     if (startPt == nullptr || endPt == nullptr || colors == nullptr) {
271         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
272         return nullptr;
273     }
274     if (cTileMode < CLAMP || cTileMode > DECAL) {
275         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
276         return nullptr;
277     }
278     std::vector<ColorQuad> colorsVector;
279     std::vector<scalar> posVector;
280     for (uint32_t i = 0; i < size; i++) {
281         colorsVector.emplace_back(colors[i]);
282         if (pos) {
283             posVector.emplace_back(pos[i]);
284         }
285     }
286     return CastShaderEffect(ShaderEffect::CreateTwoPointConical(
287         *CastToPoint(startPt), startRadius, *CastToPoint(endPt), endRadius, colorsVector, posVector,
288         static_cast<TileMode>(cTileMode), cMatrix ? CastToMatrix(cMatrix) : nullptr));
289 }
290 
OH_Drawing_ShaderEffectCreateCompose(OH_Drawing_ShaderEffect * dst,OH_Drawing_ShaderEffect * src,OH_Drawing_BlendMode mode)291 OH_Drawing_ShaderEffect* OH_Drawing_ShaderEffectCreateCompose(OH_Drawing_ShaderEffect* dst,
292     OH_Drawing_ShaderEffect* src, OH_Drawing_BlendMode mode)
293 {
294     if (dst == nullptr || src == nullptr) {
295         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
296         return nullptr;
297     }
298     if (mode < BLEND_MODE_CLEAR || mode > BLEND_MODE_LUMINOSITY) {
299         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
300         return nullptr;
301     }
302     auto dstHandle = Helper::CastTo<OH_Drawing_ShaderEffect*, NativeHandle<ShaderEffect>*>(dst);
303     auto srcHandle = Helper::CastTo<OH_Drawing_ShaderEffect*, NativeHandle<ShaderEffect>*>(src);
304     if (dstHandle->value.get() == nullptr || srcHandle->value.get() == nullptr) {
305         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
306         return nullptr;
307     }
308     return CastShaderEffect(ShaderEffectLazy::CreateBlendShader(dstHandle->value,
309         srcHandle->value, static_cast<BlendMode>(mode)));
310 }
311 
OH_Drawing_ShaderEffectDestroy(OH_Drawing_ShaderEffect * cShaderEffect)312 void OH_Drawing_ShaderEffectDestroy(OH_Drawing_ShaderEffect* cShaderEffect)
313 {
314     if (!cShaderEffect) {
315         return;
316     }
317     delete Helper::CastTo<OH_Drawing_ShaderEffect*, NativeHandle<ShaderEffect>*>(cShaderEffect);
318 }