Use SkArithmeticImageFilter directly
[platform/upstream/libSkiaSharp.git] / src / c / sk_imagefilter.cpp
1 /*
2  * Copyright 2016 Xamarin 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 "SkImageFilter.h"
9 #include "SkColorFilter.h"
10 #include "SkAlphaThresholdFilter.h"
11 #include "SkBlurImageFilter.h"
12 #include "SkColorFilterImageFilter.h"
13 #include "SkComposeImageFilter.h"
14 #include "SkDisplacementMapEffect.h"
15 #include "SkDropShadowImageFilter.h"
16 #include "SkLightingImageFilter.h"
17 #include "SkMagnifierImageFilter.h"
18 #include "SkMatrixConvolutionImageFilter.h"
19 #include "SkMergeImageFilter.h"
20 #include "SkMorphologyImageFilter.h"
21 #include "SkOffsetImageFilter.h"
22 #include "SkPictureImageFilter.h"
23 #include "SkTileImageFilter.h"
24 #include "SkXfermodeImageFilter.h"
25 #include "SkArithmeticImageFilter.h"
26
27 #include "sk_imagefilter.h"
28
29 #include "sk_types_priv.h"
30
31 sk_imagefilter_croprect_t* sk_imagefilter_croprect_new() {
32     return (sk_imagefilter_croprect_t*) new SkImageFilter::CropRect();
33 }
34
35 sk_imagefilter_croprect_t* sk_imagefilter_croprect_new_with_rect(const sk_rect_t* rect, uint32_t flags) {
36     return (sk_imagefilter_croprect_t*) new SkImageFilter::CropRect(*AsRect(rect), flags);
37 }
38
39 void sk_imagefilter_croprect_destructor(sk_imagefilter_croprect_t* cropRect) {
40     delete AsImageFilterCropRect(cropRect);
41 }
42
43 void sk_imagefilter_croprect_get_rect(sk_imagefilter_croprect_t* cropRect, sk_rect_t* rect) {
44     if (rect) {
45         *rect = ToRect(AsImageFilterCropRect(cropRect)->rect());
46     }
47 }
48
49 uint32_t sk_imagefilter_croprect_get_flags(sk_imagefilter_croprect_t* cropRect) {
50     return AsImageFilterCropRect(cropRect)->flags();
51 }
52
53 void sk_imagefilter_unref(sk_imagefilter_t* cfilter) {
54     SkSafeUnref(AsImageFilter(cfilter));
55 }
56
57 sk_imagefilter_t* sk_imagefilter_new_matrix(
58     const sk_matrix_t* cmatrix,
59     sk_filter_quality_t cquality,
60     sk_imagefilter_t* input /*NULL*/) {
61
62     SkMatrix matrix;
63     from_c(cmatrix, &matrix);
64
65     sk_sp<SkImageFilter> filter = SkImageFilter::MakeMatrixFilter(matrix, (SkFilterQuality)cquality, sk_ref_sp(AsImageFilter(input)));
66     return ToImageFilter(filter.release());
67 }
68
69 sk_imagefilter_t* sk_imagefilter_new_alpha_threshold(
70     const sk_irect_t* region,
71     float innerThreshold,
72     float outerThreshold,
73     sk_imagefilter_t* input /*NULL*/) {
74
75     SkRegion r = SkRegion(AsIRect(*region));
76
77     sk_sp<SkImageFilter> filter = SkAlphaThresholdFilter::Make(r, innerThreshold, outerThreshold, sk_ref_sp(AsImageFilter(input)));
78     return ToImageFilter(filter.release());
79 }
80
81 sk_imagefilter_t* sk_imagefilter_new_blur(
82     float sigmaX,
83     float sigmaY,
84     sk_imagefilter_t* input /*NULL*/,
85     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
86
87     sk_sp<SkImageFilter> filter = SkImageFilter::MakeBlur(sigmaX, sigmaY, sk_ref_sp(AsImageFilter(input)), AsImageFilterCropRect(cropRect));
88     return ToImageFilter(filter.release());
89 }
90
91 sk_imagefilter_t* sk_imagefilter_new_color_filter(
92     sk_colorfilter_t* cf,
93     sk_imagefilter_t* input /*NULL*/,
94     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
95
96     sk_sp<SkImageFilter> filter = SkColorFilterImageFilter::Make(sk_ref_sp(AsColorFilter(cf)), sk_ref_sp(AsImageFilter(input)), AsImageFilterCropRect(cropRect));
97     return ToImageFilter(filter.release());
98 }
99
100 sk_imagefilter_t* sk_imagefilter_new_compose(
101     sk_imagefilter_t* outer,
102     sk_imagefilter_t* inner) {
103
104     sk_sp<SkImageFilter> filter = SkComposeImageFilter::Make(sk_ref_sp(AsImageFilter(outer)), sk_ref_sp(AsImageFilter(inner)));
105     return ToImageFilter(filter.release());
106 }
107
108 sk_imagefilter_t* sk_imagefilter_new_displacement_map_effect(
109     sk_displacement_map_effect_channel_selector_type_t xChannelSelector,
110     sk_displacement_map_effect_channel_selector_type_t yChannelSelector,
111     float scale,
112     sk_imagefilter_t* displacement,
113     sk_imagefilter_t* color /*NULL*/,
114     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
115
116     sk_sp<SkImageFilter> filter = SkDisplacementMapEffect::Make(
117         (SkDisplacementMapEffect::ChannelSelectorType)xChannelSelector,
118         (SkDisplacementMapEffect::ChannelSelectorType)yChannelSelector, 
119         scale, 
120         sk_ref_sp(AsImageFilter(displacement)),
121         sk_ref_sp(AsImageFilter(color)),
122         AsImageFilterCropRect(cropRect));
123     return ToImageFilter(filter.release());
124 }
125
126 sk_imagefilter_t* sk_imagefilter_new_drop_shadow(
127     float dx,
128     float dy,
129     float sigmaX,
130     float sigmaY,
131     sk_color_t color,
132     sk_drop_shadow_image_filter_shadow_mode_t cShadowMode,
133     sk_imagefilter_t* input /*NULL*/,
134     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
135
136     sk_sp<SkImageFilter> filter = SkDropShadowImageFilter::Make(
137         dx,
138         dy, 
139         sigmaX, 
140         sigmaY,
141         color,
142         (SkDropShadowImageFilter::ShadowMode)cShadowMode,
143         sk_ref_sp(AsImageFilter(input)),
144         AsImageFilterCropRect(cropRect));
145     return ToImageFilter(filter.release());
146 }
147
148 sk_imagefilter_t* sk_imagefilter_new_distant_lit_diffuse(
149     const sk_point3_t* direction,
150     sk_color_t lightColor,
151     float surfaceScale,
152     float kd,
153     sk_imagefilter_t* input /*NULL*/,
154     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
155
156     sk_sp<SkImageFilter> filter = SkLightingImageFilter::MakeDistantLitDiffuse(
157         *AsPoint3(direction),
158         lightColor,
159         surfaceScale,
160         kd,
161         sk_ref_sp(AsImageFilter(input)),
162         AsImageFilterCropRect(cropRect));
163     return ToImageFilter(filter.release());
164 }
165
166 sk_imagefilter_t* sk_imagefilter_new_point_lit_diffuse(
167     const sk_point3_t* location,
168     sk_color_t lightColor,
169     float surfaceScale,
170     float kd,
171     sk_imagefilter_t* input /*NULL*/,
172     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
173
174     sk_sp<SkImageFilter> filter = SkLightingImageFilter::MakePointLitDiffuse(
175         *AsPoint3(location),
176         lightColor,
177         surfaceScale,
178         kd,
179         sk_ref_sp(AsImageFilter(input)),
180         AsImageFilterCropRect(cropRect));
181     return ToImageFilter(filter.release());
182 }
183
184 sk_imagefilter_t* sk_imagefilter_new_spot_lit_diffuse(
185     const sk_point3_t* location,
186     const sk_point3_t* target,
187     float specularExponent,
188     float cutoffAngle,
189     sk_color_t lightColor,
190     float surfaceScale,
191     float kd,
192     sk_imagefilter_t* input /*NULL*/,
193     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
194
195     sk_sp<SkImageFilter> filter = SkLightingImageFilter::MakeSpotLitDiffuse(
196         *AsPoint3(location),
197         *AsPoint3(target),
198         specularExponent,
199         cutoffAngle,
200         lightColor,
201         surfaceScale,
202         kd,
203         sk_ref_sp(AsImageFilter(input)),
204         AsImageFilterCropRect(cropRect));
205     return ToImageFilter(filter.release());
206 }
207
208 sk_imagefilter_t* sk_imagefilter_new_distant_lit_specular(
209     const sk_point3_t* direction,
210     sk_color_t lightColor,
211     float surfaceScale,
212     float ks,
213     float shininess,
214     sk_imagefilter_t* input /*NULL*/,
215     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
216
217     sk_sp<SkImageFilter> filter = SkLightingImageFilter::MakeDistantLitSpecular(
218         *AsPoint3(direction),
219         lightColor,
220         surfaceScale,
221         ks,
222         shininess,
223         sk_ref_sp(AsImageFilter(input)),
224         AsImageFilterCropRect(cropRect));
225     return ToImageFilter(filter.release());
226 }
227
228 sk_imagefilter_t* sk_imagefilter_new_point_lit_specular(
229     const sk_point3_t* location,
230     sk_color_t lightColor,
231     float surfaceScale,
232     float ks,
233     float shininess,
234     sk_imagefilter_t* input /*NULL*/,
235     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
236
237     sk_sp<SkImageFilter> filter = SkLightingImageFilter::MakePointLitSpecular(
238         *AsPoint3(location),
239         lightColor,
240         surfaceScale,
241         ks,
242         shininess,
243         sk_ref_sp(AsImageFilter(input)),
244         AsImageFilterCropRect(cropRect));
245     return ToImageFilter(filter.release());
246 }
247
248 sk_imagefilter_t* sk_imagefilter_new_spot_lit_specular(
249     const sk_point3_t* location,
250     const sk_point3_t* target,
251     float specularExponent,
252     float cutoffAngle,
253     sk_color_t lightColor,
254     float surfaceScale,
255     float ks,
256     float shininess,
257     sk_imagefilter_t* input /*NULL*/,
258     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
259
260     sk_sp<SkImageFilter> filter = SkLightingImageFilter::MakeSpotLitSpecular(
261         *AsPoint3(location),
262         *AsPoint3(target),
263         specularExponent,
264         cutoffAngle,
265         lightColor,
266         surfaceScale,
267         ks,
268         shininess,
269         sk_ref_sp(AsImageFilter(input)),
270         AsImageFilterCropRect(cropRect));
271     return ToImageFilter(filter.release());
272 }
273
274 sk_imagefilter_t* sk_imagefilter_new_magnifier(
275     const sk_rect_t* src,
276     float inset,
277     sk_imagefilter_t* input /*NULL*/) {
278
279     sk_sp<SkImageFilter> filter = SkMagnifierImageFilter::Make(
280         *AsRect(src),
281         inset,
282         sk_ref_sp(AsImageFilter(input)));
283     return ToImageFilter(filter.release());
284 }
285
286 sk_imagefilter_t* sk_imagefilter_new_matrix_convolution(
287     const sk_isize_t* kernelSize,
288     const float kernel[],
289     float gain,
290     float bias,
291     const sk_ipoint_t* kernelOffset,
292     sk_matrix_convolution_tilemode_t ctileMode,
293     bool convolveAlpha,
294     sk_imagefilter_t* input /*NULL*/,
295     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
296
297     sk_sp<SkImageFilter> filter = SkMatrixConvolutionImageFilter::Make(
298         *AsISize(kernelSize),
299         kernel,
300         gain,
301         bias,
302         *AsIPoint(kernelOffset),
303         (SkMatrixConvolutionImageFilter::TileMode)ctileMode,
304         convolveAlpha,
305         sk_ref_sp(AsImageFilter(input)),
306         AsImageFilterCropRect(cropRect));
307     return ToImageFilter(filter.release());
308 }
309
310 sk_imagefilter_t* sk_imagefilter_new_merge(
311     sk_imagefilter_t* cfilters[],
312     int count,
313     const sk_blendmode_t cmodes[] /*NULL*/,
314     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
315
316     sk_sp<SkImageFilter>* filters = new sk_sp<SkImageFilter>[count];
317     for (int i = 0; i < count; i++) {
318         filters[i] = sk_ref_sp(AsImageFilter(cfilters[i]));
319     }
320     
321     sk_sp<SkImageFilter> filter = SkMergeImageFilter::MakeN(
322         filters,
323         count,
324         (SkBlendMode*)cmodes,
325         AsImageFilterCropRect(cropRect));
326
327     return ToImageFilter(filter.release());
328 }
329
330 sk_imagefilter_t* sk_imagefilter_new_dilate(
331     int radiusX,
332     int radiusY,
333     sk_imagefilter_t* input /*NULL*/,
334     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
335
336     sk_sp<SkImageFilter> filter = SkDilateImageFilter::Make(
337         radiusX,
338         radiusY,
339         sk_ref_sp(AsImageFilter(input)),
340         AsImageFilterCropRect(cropRect));
341     return ToImageFilter(filter.release());
342 }
343
344 sk_imagefilter_t* sk_imagefilter_new_erode(
345     int radiusX,
346     int radiusY,
347     sk_imagefilter_t* input /*NULL*/,
348     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
349
350     sk_sp<SkImageFilter> filter = SkErodeImageFilter::Make(
351         radiusX,
352         radiusY,
353         sk_ref_sp(AsImageFilter(input)),
354         AsImageFilterCropRect(cropRect));
355     return ToImageFilter(filter.release());
356 }
357
358 sk_imagefilter_t* sk_imagefilter_new_offset(
359     float dx,
360     float dy,
361     sk_imagefilter_t* input /*NULL*/,
362     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
363
364     sk_sp<SkImageFilter> filter = SkOffsetImageFilter::Make(
365         dx,
366         dy,
367         sk_ref_sp(AsImageFilter(input)),
368         AsImageFilterCropRect(cropRect));
369     return ToImageFilter(filter.release());
370 }
371
372 sk_imagefilter_t* sk_imagefilter_new_picture(
373     sk_picture_t* picture) {
374
375     sk_sp<SkImageFilter> filter = SkPictureImageFilter::Make(
376         sk_ref_sp(AsPicture(picture)));
377     return ToImageFilter(filter.release());
378 }
379
380 sk_imagefilter_t* sk_imagefilter_new_picture_with_croprect(
381     sk_picture_t* picture,
382     const sk_rect_t* cropRect) {
383
384     sk_sp<SkImageFilter> filter = SkPictureImageFilter::Make(
385         sk_ref_sp(AsPicture(picture)),
386         *AsRect(cropRect));
387     return ToImageFilter(filter.release());
388 }
389
390 sk_imagefilter_t* sk_imagefilter_new_picture_for_localspace(
391     sk_picture_t* picture,
392     const sk_rect_t* cropRect,
393     sk_filter_quality_t filterQuality) {
394
395     sk_sp<SkImageFilter> filter = SkPictureImageFilter::MakeForLocalSpace(
396         sk_ref_sp(AsPicture(picture)),
397         *AsRect(cropRect),
398         (SkFilterQuality)filterQuality);
399     return ToImageFilter(filter.release());
400 }
401
402 sk_imagefilter_t* sk_imagefilter_new_tile(
403     const sk_rect_t* src,
404     const sk_rect_t* dst,
405     sk_imagefilter_t* input) {
406
407     sk_sp<SkImageFilter> filter = SkTileImageFilter::Make(
408         *AsRect(src),
409         *AsRect(dst),
410         sk_ref_sp(AsImageFilter(input)));
411     return ToImageFilter(filter.release());
412 }
413
414 sk_imagefilter_t* sk_imagefilter_new_xfermode(
415     sk_blendmode_t cmode,
416     sk_imagefilter_t* background,
417     sk_imagefilter_t* foreground /*NULL*/,
418     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
419
420     sk_sp<SkImageFilter> filter = SkXfermodeImageFilter::Make(
421         (SkBlendMode)cmode,
422         sk_ref_sp(AsImageFilter(background)),
423         sk_ref_sp(AsImageFilter(foreground)),
424         AsImageFilterCropRect(cropRect));
425     return ToImageFilter(filter.release());
426 }
427
428 SK_API sk_imagefilter_t* sk_imagefilter_new_arithmetic(
429     float k1, float k2, float k3, float k4,
430     bool enforcePMColor,
431     sk_imagefilter_t* background,
432     sk_imagefilter_t* foreground /*NULL*/,
433     const sk_imagefilter_croprect_t* cropRect /*NULL*/) {
434
435     sk_sp<SkImageFilter> filter = SkArithmeticImageFilter::Make(
436         k1, k2, k3, k4,
437         enforcePMColor,
438         sk_ref_sp(AsImageFilter(background)),
439         sk_ref_sp(AsImageFilter(foreground)),
440         AsImageFilterCropRect(cropRect));
441     return ToImageFilter(filter.release());
442 }