1 /*
2  * Copyright 2017 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "sk_types_priv.h"
9 #include "SkMatrix.h"
10 
11 static void from_c_matrix(const sk_matrix_t* cmatrix, SkMatrix* matrix) {
12     matrix->setAll(cmatrix->mat[0], cmatrix->mat[1], cmatrix->mat[2],
13                    cmatrix->mat[3], cmatrix->mat[4], cmatrix->mat[5],
14                    cmatrix->mat[6], cmatrix->mat[7], cmatrix->mat[8]);
15 }
16 
17 #include "../../include/effects/SkGradientShader.h"
18 #include "sk_shader.h"
19 
20 const struct {
21     sk_shader_tilemode_t    fC;
22     SkShader::TileMode      fSK;
23 } gTileModeMap[] = {
24     { CLAMP_SK_SHADER_TILEMODE,     SkShader::kClamp_TileMode },
25     { REPEAT_SK_SHADER_TILEMODE,    SkShader::kRepeat_TileMode },
26     { MIRROR_SK_SHADER_TILEMODE,    SkShader::kMirror_TileMode  },
27 };
28 
29 static bool from_c_tilemode(sk_shader_tilemode_t cMode, SkShader::TileMode* skMode) {
30     for (size_t i = 0; i < SK_ARRAY_COUNT(gTileModeMap); ++i) {
31         if (cMode == gTileModeMap[i].fC) {
32             if (skMode) {
33                 *skMode = gTileModeMap[i].fSK;
34             }
35             return true;
36         }
37     }
38     return false;
39 }
40 
41 void sk_shader_ref(sk_shader_t* cshader) {
42     SkSafeRef(AsShader(cshader));
43 }
44 
45 void sk_shader_unref(sk_shader_t* cshader) {
46     SkSafeUnref(AsShader(cshader));
47 }
48 
49 sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t pts[2],
50                                            const sk_color_t colors[],
51                                            const float colorPos[],
52                                            int colorCount,
53                                            sk_shader_tilemode_t cmode,
54                                            const sk_matrix_t* cmatrix) {
55     SkShader::TileMode mode;
56     if (!from_c_tilemode(cmode, &mode)) {
57         return nullptr;
58     }
59     SkMatrix matrix;
60     if (cmatrix) {
61         from_c_matrix(cmatrix, &matrix);
62     } else {
63         matrix.setIdentity();
64     }
65     return (sk_shader_t*)SkGradientShader::MakeLinear(reinterpret_cast<const SkPoint*>(pts),
66                                                       reinterpret_cast<const SkColor*>(colors),
67                                                       colorPos, colorCount,
68                                                       mode, 0, &matrix).release();
69 }
70 
71 static const SkPoint& to_skpoint(const sk_point_t& p) {
72     return reinterpret_cast<const SkPoint&>(p);
73 }
74 
75 sk_shader_t* sk_shader_new_radial_gradient(const sk_point_t* ccenter,
76                                            float radius,
77                                            const sk_color_t colors[],
78                                            const float colorPos[],
79                                            int colorCount,
80                                            sk_shader_tilemode_t cmode,
81                                            const sk_matrix_t* cmatrix) {
82     SkShader::TileMode mode;
83     if (!from_c_tilemode(cmode, &mode)) {
84         return nullptr;
85     }
86     SkMatrix matrix;
87     if (cmatrix) {
88         from_c_matrix(cmatrix, &matrix);
89     } else {
90         matrix.setIdentity();
91     }
92     SkPoint center = to_skpoint(*ccenter);
93     return (sk_shader_t*)SkGradientShader::MakeRadial(center, (SkScalar)radius,
94                                                       reinterpret_cast<const SkColor*>(colors),
95                                                       reinterpret_cast<const SkScalar*>(colorPos),
96                                                       colorCount, mode, 0, &matrix).release();
97 }
98 
99 sk_shader_t* sk_shader_new_sweep_gradient(const sk_point_t* ccenter,
100                                           const sk_color_t colors[],
101                                           const float colorPos[],
102                                           int colorCount,
103                                           const sk_matrix_t* cmatrix) {
104     SkMatrix matrix;
105     if (cmatrix) {
106         from_c_matrix(cmatrix, &matrix);
107     } else {
108         matrix.setIdentity();
109     }
110     return (sk_shader_t*)SkGradientShader::MakeSweep((SkScalar)(ccenter->x),
111                                                      (SkScalar)(ccenter->y),
112                                                      reinterpret_cast<const SkColor*>(colors),
113                                                      reinterpret_cast<const SkScalar*>(colorPos),
114                                                      colorCount, 0, &matrix).release();
115 }
116 
117 sk_shader_t* sk_shader_new_two_point_conical_gradient(const sk_point_t* start,
118                                                       float startRadius,
119                                                       const sk_point_t* end,
120                                                       float endRadius,
121                                                       const sk_color_t colors[],
122                                                       const float colorPos[],
123                                                       int colorCount,
124                                                       sk_shader_tilemode_t cmode,
125                                                       const sk_matrix_t* cmatrix) {
126     SkShader::TileMode mode;
127     if (!from_c_tilemode(cmode, &mode)) {
128         return nullptr;
129     }
130     SkMatrix matrix;
131     if (cmatrix) {
132         from_c_matrix(cmatrix, &matrix);
133     } else {
134         matrix.setIdentity();
135     }
136     SkPoint skstart = to_skpoint(*start);
137     SkPoint skend = to_skpoint(*end);
138     return (sk_shader_t*)SkGradientShader::MakeTwoPointConical(skstart, (SkScalar)startRadius,
139                                                         skend, (SkScalar)endRadius,
140                                                         reinterpret_cast<const SkColor*>(colors),
141                                                         reinterpret_cast<const SkScalar*>(colorPos),
142                                                         colorCount, mode, 0, &matrix).release();
143 }
144 
145 ///////////////////////////////////////////////////////////////////////////////////////////
146 
147 #include "sk_maskfilter.h"
148 #include "SkMaskFilter.h"
149 
150 const struct {
151     sk_blurstyle_t  fC;
152     SkBlurStyle     fSk;
153 } gBlurStylePairs[] = {
154     { NORMAL_SK_BLUR_STYLE, kNormal_SkBlurStyle },
155     { SOLID_SK_BLUR_STYLE,  kSolid_SkBlurStyle },
156     { OUTER_SK_BLUR_STYLE,  kOuter_SkBlurStyle },
157     { INNER_SK_BLUR_STYLE,  kInner_SkBlurStyle },
158 };
159 
160 static bool find_blurstyle(sk_blurstyle_t csrc, SkBlurStyle* dst) {
161     for (size_t i = 0; i < SK_ARRAY_COUNT(gBlurStylePairs); ++i) {
162         if (gBlurStylePairs[i].fC == csrc) {
163             if (dst) {
164                 *dst = gBlurStylePairs[i].fSk;
165             }
166             return true;
167         }
168     }
169     return false;
170 }
171 
172 void sk_maskfilter_ref(sk_maskfilter_t* cfilter) {
173     SkSafeRef(AsMaskFilter(cfilter));
174 }
175 
176 void sk_maskfilter_unref(sk_maskfilter_t* cfilter) {
177     SkSafeUnref(AsMaskFilter(cfilter));
178 }
179 
180 sk_maskfilter_t* sk_maskfilter_new_blur(sk_blurstyle_t cstyle, float sigma) {
181     SkBlurStyle style;
182     if (!find_blurstyle(cstyle, &style)) {
183         return nullptr;
184     }
185     return ToMaskFilter(SkMaskFilter::MakeBlur(style, sigma).release());
186 }
187