1 /*
2 * Copyright 2014 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_canvas.h"
9 #include "sk_data.h"
10 #include "sk_image.h"
11 #include "sk_paint.h"
12 #include "sk_path.h"
13 #include "sk_surface.h"
14 #include "sk_types_priv.h"
15
16 #include "SkCanvas.h"
17 #include "SkData.h"
18 #include "SkImage.h"
19 #include "SkMaskFilter.h"
20 #include "SkMatrix.h"
21 #include "SkPaint.h"
22 #include "SkPath.h"
23 #include "SkPictureRecorder.h"
24 #include "SkSurface.h"
25
26 const struct {
27 sk_colortype_t fC;
28 SkColorType fSK;
29 } gColorTypeMap[] = {
30 { UNKNOWN_SK_COLORTYPE, kUnknown_SkColorType },
31 { RGBA_8888_SK_COLORTYPE, kRGBA_8888_SkColorType },
32 { BGRA_8888_SK_COLORTYPE, kBGRA_8888_SkColorType },
33 { ALPHA_8_SK_COLORTYPE, kAlpha_8_SkColorType },
34 };
35
36 const struct {
37 sk_alphatype_t fC;
38 SkAlphaType fSK;
39 } gAlphaTypeMap[] = {
40 { OPAQUE_SK_ALPHATYPE, kOpaque_SkAlphaType },
41 { PREMUL_SK_ALPHATYPE, kPremul_SkAlphaType },
42 { UNPREMUL_SK_ALPHATYPE, kUnpremul_SkAlphaType },
43 };
44
from_c_colortype(sk_colortype_t cCT,SkColorType * skCT)45 static bool from_c_colortype(sk_colortype_t cCT, SkColorType* skCT) {
46 for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypeMap); ++i) {
47 if (gColorTypeMap[i].fC == cCT) {
48 if (skCT) {
49 *skCT = gColorTypeMap[i].fSK;
50 }
51 return true;
52 }
53 }
54 return false;
55 }
56
to_c_colortype(SkColorType skCT,sk_colortype_t * cCT)57 static bool to_c_colortype(SkColorType skCT, sk_colortype_t* cCT) {
58 for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypeMap); ++i) {
59 if (gColorTypeMap[i].fSK == skCT) {
60 if (cCT) {
61 *cCT = gColorTypeMap[i].fC;
62 }
63 return true;
64 }
65 }
66 return false;
67 }
68
from_c_alphatype(sk_alphatype_t cAT,SkAlphaType * skAT)69 static bool from_c_alphatype(sk_alphatype_t cAT, SkAlphaType* skAT) {
70 for (size_t i = 0; i < SK_ARRAY_COUNT(gAlphaTypeMap); ++i) {
71 if (gAlphaTypeMap[i].fC == cAT) {
72 if (skAT) {
73 *skAT = gAlphaTypeMap[i].fSK;
74 }
75 return true;
76 }
77 }
78 return false;
79 }
80
from_c_info(const sk_imageinfo_t & cinfo,SkImageInfo * info)81 static bool from_c_info(const sk_imageinfo_t& cinfo, SkImageInfo* info) {
82 SkColorType ct;
83 SkAlphaType at;
84
85 if (!from_c_colortype(cinfo.colorType, &ct)) {
86 // optionally report error to client?
87 return false;
88 }
89 if (!from_c_alphatype(cinfo.alphaType, &at)) {
90 // optionally report error to client?
91 return false;
92 }
93 if (info) {
94 *info = SkImageInfo::Make(cinfo.width, cinfo.height, ct, at);
95 }
96 return true;
97 }
98
from_c_matrix(const sk_matrix_t * cmatrix,SkMatrix * matrix)99 static void from_c_matrix(const sk_matrix_t* cmatrix, SkMatrix* matrix) {
100 matrix->setAll(cmatrix->mat[0], cmatrix->mat[1], cmatrix->mat[2],
101 cmatrix->mat[3], cmatrix->mat[4], cmatrix->mat[5],
102 cmatrix->mat[6], cmatrix->mat[7], cmatrix->mat[8]);
103 }
104
105 const struct {
106 sk_path_direction_t fC;
107 SkPath::Direction fSk;
108 } gPathDirMap[] = {
109 { CW_SK_PATH_DIRECTION, SkPath::kCW_Direction },
110 { CCW_SK_PATH_DIRECTION, SkPath::kCCW_Direction },
111 };
112
from_c_path_direction(sk_path_direction_t cdir,SkPath::Direction * dir)113 static bool from_c_path_direction(sk_path_direction_t cdir, SkPath::Direction* dir) {
114 for (size_t i = 0; i < SK_ARRAY_COUNT(gPathDirMap); ++i) {
115 if (gPathDirMap[i].fC == cdir) {
116 if (dir) {
117 *dir = gPathDirMap[i].fSk;
118 }
119 return true;
120 }
121 }
122 return false;
123 }
124
AsData(const sk_data_t * cdata)125 static SkData* AsData(const sk_data_t* cdata) {
126 return reinterpret_cast<SkData*>(const_cast<sk_data_t*>(cdata));
127 }
128
ToData(SkData * data)129 static sk_data_t* ToData(SkData* data) {
130 return reinterpret_cast<sk_data_t*>(data);
131 }
132
ToRect(const SkRect & rect)133 static sk_rect_t ToRect(const SkRect& rect) {
134 return reinterpret_cast<const sk_rect_t&>(rect);
135 }
136
AsRect(const sk_rect_t & crect)137 static const SkRect& AsRect(const sk_rect_t& crect) {
138 return reinterpret_cast<const SkRect&>(crect);
139 }
140
AsRect(const sk_rect_t * crect)141 static const SkRect* AsRect(const sk_rect_t* crect) {
142 return reinterpret_cast<const SkRect*>(crect);
143 }
144
AsPath(const sk_path_t & cpath)145 static const SkPath& AsPath(const sk_path_t& cpath) {
146 return reinterpret_cast<const SkPath&>(cpath);
147 }
148
as_path(sk_path_t * cpath)149 static SkPath* as_path(sk_path_t* cpath) {
150 return reinterpret_cast<SkPath*>(cpath);
151 }
152
AsImage(const sk_image_t * cimage)153 static const SkImage* AsImage(const sk_image_t* cimage) {
154 return reinterpret_cast<const SkImage*>(cimage);
155 }
156
ToImage(SkImage * cimage)157 static sk_image_t* ToImage(SkImage* cimage) {
158 return reinterpret_cast<sk_image_t*>(cimage);
159 }
160
ToCanvas(SkCanvas * canvas)161 static sk_canvas_t* ToCanvas(SkCanvas* canvas) {
162 return reinterpret_cast<sk_canvas_t*>(canvas);
163 }
164
AsCanvas(sk_canvas_t * ccanvas)165 static SkCanvas* AsCanvas(sk_canvas_t* ccanvas) {
166 return reinterpret_cast<SkCanvas*>(ccanvas);
167 }
168
AsPictureRecorder(sk_picture_recorder_t * crec)169 static SkPictureRecorder* AsPictureRecorder(sk_picture_recorder_t* crec) {
170 return reinterpret_cast<SkPictureRecorder*>(crec);
171 }
172
ToPictureRecorder(SkPictureRecorder * rec)173 static sk_picture_recorder_t* ToPictureRecorder(SkPictureRecorder* rec) {
174 return reinterpret_cast<sk_picture_recorder_t*>(rec);
175 }
176
AsPicture(const sk_picture_t * cpic)177 static const SkPicture* AsPicture(const sk_picture_t* cpic) {
178 return reinterpret_cast<const SkPicture*>(cpic);
179 }
180
AsPicture(sk_picture_t * cpic)181 static SkPicture* AsPicture(sk_picture_t* cpic) {
182 return reinterpret_cast<SkPicture*>(cpic);
183 }
184
ToPicture(SkPicture * pic)185 static sk_picture_t* ToPicture(SkPicture* pic) {
186 return reinterpret_cast<sk_picture_t*>(pic);
187 }
188
189 ///////////////////////////////////////////////////////////////////////////////////////////
190
sk_colortype_get_default_8888()191 sk_colortype_t sk_colortype_get_default_8888() {
192 sk_colortype_t ct;
193 if (!to_c_colortype(kN32_SkColorType, &ct)) {
194 ct = UNKNOWN_SK_COLORTYPE;
195 }
196 return ct;
197 }
198
199 ///////////////////////////////////////////////////////////////////////////////////////////
200
sk_image_new_raster_copy(const sk_imageinfo_t * cinfo,const void * pixels,size_t rowBytes)201 sk_image_t* sk_image_new_raster_copy(const sk_imageinfo_t* cinfo, const void* pixels,
202 size_t rowBytes) {
203 SkImageInfo info;
204 if (!from_c_info(*cinfo, &info)) {
205 return NULL;
206 }
207 return (sk_image_t*)SkImage::NewRasterCopy(info, pixels, rowBytes);
208 }
209
sk_image_new_from_data(const sk_data_t * cdata)210 sk_image_t* sk_image_new_from_data(const sk_data_t* cdata) {
211 return ToImage(SkImage::NewFromData(AsData(cdata)));
212 }
213
sk_image_encode(const sk_image_t * cimage)214 sk_data_t* sk_image_encode(const sk_image_t* cimage) {
215 return ToData(AsImage(cimage)->encode());
216 }
217
sk_image_ref(const sk_image_t * cimage)218 void sk_image_ref(const sk_image_t* cimage) {
219 AsImage(cimage)->ref();
220 }
221
sk_image_unref(const sk_image_t * cimage)222 void sk_image_unref(const sk_image_t* cimage) {
223 AsImage(cimage)->unref();
224 }
225
sk_image_get_width(const sk_image_t * cimage)226 int sk_image_get_width(const sk_image_t* cimage) {
227 return AsImage(cimage)->width();
228 }
229
sk_image_get_height(const sk_image_t * cimage)230 int sk_image_get_height(const sk_image_t* cimage) {
231 return AsImage(cimage)->height();
232 }
233
sk_image_get_unique_id(const sk_image_t * cimage)234 uint32_t sk_image_get_unique_id(const sk_image_t* cimage) {
235 return AsImage(cimage)->uniqueID();
236 }
237
238 ///////////////////////////////////////////////////////////////////////////////////////////
239
sk_path_new()240 sk_path_t* sk_path_new() {
241 return (sk_path_t*)SkNEW(SkPath);
242 }
243
sk_path_delete(sk_path_t * cpath)244 void sk_path_delete(sk_path_t* cpath) {
245 SkDELETE(as_path(cpath));
246 }
247
sk_path_move_to(sk_path_t * cpath,float x,float y)248 void sk_path_move_to(sk_path_t* cpath, float x, float y) {
249 as_path(cpath)->moveTo(x, y);
250 }
251
sk_path_line_to(sk_path_t * cpath,float x,float y)252 void sk_path_line_to(sk_path_t* cpath, float x, float y) {
253 as_path(cpath)->lineTo(x, y);
254 }
255
sk_path_quad_to(sk_path_t * cpath,float x0,float y0,float x1,float y1)256 void sk_path_quad_to(sk_path_t* cpath, float x0, float y0, float x1, float y1) {
257 as_path(cpath)->quadTo(x0, y0, x1, y1);
258 }
259
sk_path_conic_to(sk_path_t * cpath,float x0,float y0,float x1,float y1,float w)260 void sk_path_conic_to(sk_path_t* cpath, float x0, float y0, float x1, float y1, float w) {
261 as_path(cpath)->conicTo(x0, y0, x1, y1, w);
262 }
263
sk_path_cubic_to(sk_path_t * cpath,float x0,float y0,float x1,float y1,float x2,float y2)264 void sk_path_cubic_to(sk_path_t* cpath, float x0, float y0, float x1, float y1, float x2, float y2) {
265 as_path(cpath)->cubicTo(x0, y0, x1, y1, x2, y2);
266 }
267
sk_path_close(sk_path_t * cpath)268 void sk_path_close(sk_path_t* cpath) {
269 as_path(cpath)->close();
270 }
271
sk_path_add_rect(sk_path_t * cpath,const sk_rect_t * crect,sk_path_direction_t cdir)272 void sk_path_add_rect(sk_path_t* cpath, const sk_rect_t* crect, sk_path_direction_t cdir) {
273 SkPath::Direction dir;
274 if (!from_c_path_direction(cdir, &dir)) {
275 return;
276 }
277 as_path(cpath)->addRect(AsRect(*crect), dir);
278 }
279
sk_path_add_oval(sk_path_t * cpath,const sk_rect_t * crect,sk_path_direction_t cdir)280 void sk_path_add_oval(sk_path_t* cpath, const sk_rect_t* crect, sk_path_direction_t cdir) {
281 SkPath::Direction dir;
282 if (!from_c_path_direction(cdir, &dir)) {
283 return;
284 }
285 as_path(cpath)->addOval(AsRect(*crect), dir);
286 }
287
sk_path_get_bounds(const sk_path_t * cpath,sk_rect_t * crect)288 bool sk_path_get_bounds(const sk_path_t* cpath, sk_rect_t* crect) {
289 const SkPath& path = AsPath(*cpath);
290
291 if (path.isEmpty()) {
292 if (crect) {
293 *crect = ToRect(SkRect::MakeEmpty());
294 }
295 return false;
296 }
297
298 if (crect) {
299 *crect = ToRect(path.getBounds());
300 }
301 return true;
302 }
303
304 ///////////////////////////////////////////////////////////////////////////////////////////
305
sk_canvas_save(sk_canvas_t * ccanvas)306 void sk_canvas_save(sk_canvas_t* ccanvas) {
307 AsCanvas(ccanvas)->save();
308 }
309
sk_canvas_save_layer(sk_canvas_t * ccanvas,const sk_rect_t * crect,const sk_paint_t * cpaint)310 void sk_canvas_save_layer(sk_canvas_t* ccanvas, const sk_rect_t* crect, const sk_paint_t* cpaint) {
311 AsCanvas(ccanvas)->drawRect(AsRect(*crect), AsPaint(*cpaint));
312 }
313
sk_canvas_restore(sk_canvas_t * ccanvas)314 void sk_canvas_restore(sk_canvas_t* ccanvas) {
315 AsCanvas(ccanvas)->restore();
316 }
317
sk_canvas_translate(sk_canvas_t * ccanvas,float dx,float dy)318 void sk_canvas_translate(sk_canvas_t* ccanvas, float dx, float dy) {
319 AsCanvas(ccanvas)->translate(dx, dy);
320 }
321
sk_canvas_scale(sk_canvas_t * ccanvas,float sx,float sy)322 void sk_canvas_scale(sk_canvas_t* ccanvas, float sx, float sy) {
323 AsCanvas(ccanvas)->scale(sx, sy);
324 }
325
sk_canvas_rotate_degress(sk_canvas_t * ccanvas,float degrees)326 void sk_canvas_rotate_degress(sk_canvas_t* ccanvas, float degrees) {
327 AsCanvas(ccanvas)->rotate(degrees);
328 }
329
sk_canvas_rotate_radians(sk_canvas_t * ccanvas,float radians)330 void sk_canvas_rotate_radians(sk_canvas_t* ccanvas, float radians) {
331 AsCanvas(ccanvas)->rotate(SkRadiansToDegrees(radians));
332 }
333
sk_canvas_skew(sk_canvas_t * ccanvas,float sx,float sy)334 void sk_canvas_skew(sk_canvas_t* ccanvas, float sx, float sy) {
335 AsCanvas(ccanvas)->skew(sx, sy);
336 }
337
sk_canvas_concat(sk_canvas_t * ccanvas,const sk_matrix_t * cmatrix)338 void sk_canvas_concat(sk_canvas_t* ccanvas, const sk_matrix_t* cmatrix) {
339 SkASSERT(cmatrix);
340 SkMatrix matrix;
341 from_c_matrix(cmatrix, &matrix);
342 AsCanvas(ccanvas)->concat(matrix);
343 }
344
sk_canvas_clip_rect(sk_canvas_t * ccanvas,const sk_rect_t * crect)345 void sk_canvas_clip_rect(sk_canvas_t* ccanvas, const sk_rect_t* crect) {
346 AsCanvas(ccanvas)->clipRect(AsRect(*crect));
347 }
348
sk_canvas_clip_path(sk_canvas_t * ccanvas,const sk_path_t * cpath)349 void sk_canvas_clip_path(sk_canvas_t* ccanvas, const sk_path_t* cpath) {
350 AsCanvas(ccanvas)->clipPath(AsPath(*cpath));
351 }
352
sk_canvas_draw_paint(sk_canvas_t * ccanvas,const sk_paint_t * cpaint)353 void sk_canvas_draw_paint(sk_canvas_t* ccanvas, const sk_paint_t* cpaint) {
354 AsCanvas(ccanvas)->drawPaint(AsPaint(*cpaint));
355 }
356
sk_canvas_draw_rect(sk_canvas_t * ccanvas,const sk_rect_t * crect,const sk_paint_t * cpaint)357 void sk_canvas_draw_rect(sk_canvas_t* ccanvas, const sk_rect_t* crect, const sk_paint_t* cpaint) {
358 AsCanvas(ccanvas)->drawRect(AsRect(*crect), AsPaint(*cpaint));
359 }
360
sk_canvas_draw_oval(sk_canvas_t * ccanvas,const sk_rect_t * crect,const sk_paint_t * cpaint)361 void sk_canvas_draw_oval(sk_canvas_t* ccanvas, const sk_rect_t* crect, const sk_paint_t* cpaint) {
362 AsCanvas(ccanvas)->drawOval(AsRect(*crect), AsPaint(*cpaint));
363 }
364
sk_canvas_draw_path(sk_canvas_t * ccanvas,const sk_path_t * cpath,const sk_paint_t * cpaint)365 void sk_canvas_draw_path(sk_canvas_t* ccanvas, const sk_path_t* cpath, const sk_paint_t* cpaint) {
366 AsCanvas(ccanvas)->drawPath(AsPath(*cpath), AsPaint(*cpaint));
367 }
368
sk_canvas_draw_image(sk_canvas_t * ccanvas,const sk_image_t * cimage,float x,float y,const sk_paint_t * cpaint)369 void sk_canvas_draw_image(sk_canvas_t* ccanvas, const sk_image_t* cimage, float x, float y,
370 const sk_paint_t* cpaint) {
371 AsCanvas(ccanvas)->drawImage(AsImage(cimage), x, y, AsPaint(cpaint));
372 }
373
sk_canvas_draw_image_rect(sk_canvas_t * ccanvas,const sk_image_t * cimage,const sk_rect_t * csrcR,const sk_rect_t * cdstR,const sk_paint_t * cpaint)374 void sk_canvas_draw_image_rect(sk_canvas_t* ccanvas, const sk_image_t* cimage,
375 const sk_rect_t* csrcR, const sk_rect_t* cdstR,
376 const sk_paint_t* cpaint) {
377 AsCanvas(ccanvas)->drawImageRect(AsImage(cimage), AsRect(csrcR), AsRect(*cdstR), AsPaint(cpaint));
378 }
379
sk_canvas_draw_picture(sk_canvas_t * ccanvas,const sk_picture_t * cpicture,const sk_matrix_t * cmatrix,const sk_paint_t * cpaint)380 void sk_canvas_draw_picture(sk_canvas_t* ccanvas, const sk_picture_t* cpicture,
381 const sk_matrix_t* cmatrix, const sk_paint_t* cpaint) {
382 const SkMatrix* matrixPtr = NULL;
383 SkMatrix matrix;
384 if (cmatrix) {
385 from_c_matrix(cmatrix, &matrix);
386 matrixPtr = &matrix;
387 }
388 AsCanvas(ccanvas)->drawPicture(AsPicture(cpicture), matrixPtr, AsPaint(cpaint));
389 }
390
391 ///////////////////////////////////////////////////////////////////////////////////////////
392
sk_surface_new_raster(const sk_imageinfo_t * cinfo)393 sk_surface_t* sk_surface_new_raster(const sk_imageinfo_t* cinfo) {
394 SkImageInfo info;
395 if (!from_c_info(*cinfo, &info)) {
396 return NULL;
397 }
398 return (sk_surface_t*)SkSurface::NewRaster(info);
399 }
400
sk_surface_new_raster_direct(const sk_imageinfo_t * cinfo,void * pixels,size_t rowBytes)401 sk_surface_t* sk_surface_new_raster_direct(const sk_imageinfo_t* cinfo, void* pixels,
402 size_t rowBytes) {
403 SkImageInfo info;
404 if (!from_c_info(*cinfo, &info)) {
405 return NULL;
406 }
407 return (sk_surface_t*)SkSurface::NewRasterDirect(info, pixels, rowBytes);
408 }
409
sk_surface_unref(sk_surface_t * csurf)410 void sk_surface_unref(sk_surface_t* csurf) {
411 SkSafeUnref((SkSurface*)csurf);
412 }
413
sk_surface_get_canvas(sk_surface_t * csurf)414 sk_canvas_t* sk_surface_get_canvas(sk_surface_t* csurf) {
415 SkSurface* surf = (SkSurface*)csurf;
416 return (sk_canvas_t*)surf->getCanvas();
417 }
418
sk_surface_new_image_snapshot(sk_surface_t * csurf)419 sk_image_t* sk_surface_new_image_snapshot(sk_surface_t* csurf) {
420 SkSurface* surf = (SkSurface*)csurf;
421 return (sk_image_t*)surf->newImageSnapshot();
422 }
423
424 ///////////////////////////////////////////////////////////////////////////////////////////
425
sk_picture_recorder_new()426 sk_picture_recorder_t* sk_picture_recorder_new() {
427 return ToPictureRecorder(new SkPictureRecorder);
428 }
429
sk_picture_recorder_delete(sk_picture_recorder_t * crec)430 void sk_picture_recorder_delete(sk_picture_recorder_t* crec) {
431 delete AsPictureRecorder(crec);
432 }
433
sk_picture_recorder_begin_recording(sk_picture_recorder_t * crec,const sk_rect_t * cbounds)434 sk_canvas_t* sk_picture_recorder_begin_recording(sk_picture_recorder_t* crec,
435 const sk_rect_t* cbounds) {
436 return ToCanvas(AsPictureRecorder(crec)->beginRecording(AsRect(*cbounds)));
437 }
438
sk_picture_recorder_end_recording(sk_picture_recorder_t * crec)439 sk_picture_t* sk_picture_recorder_end_recording(sk_picture_recorder_t* crec) {
440 return ToPicture(AsPictureRecorder(crec)->endRecording());
441 }
442
sk_picture_ref(sk_picture_t * cpic)443 void sk_picture_ref(sk_picture_t* cpic) {
444 SkSafeRef(AsPicture(cpic));
445 }
446
sk_picture_unref(sk_picture_t * cpic)447 void sk_picture_unref(sk_picture_t* cpic) {
448 SkSafeUnref(AsPicture(cpic));
449 }
450
sk_picture_get_unique_id(sk_picture_t * cpic)451 uint32_t sk_picture_get_unique_id(sk_picture_t* cpic) {
452 return AsPicture(cpic)->uniqueID();
453 }
454
sk_picture_get_bounds(sk_picture_t * cpic)455 sk_rect_t sk_picture_get_bounds(sk_picture_t* cpic) {
456 return ToRect(AsPicture(cpic)->cullRect());
457 }
458
459 ///////////////////////////////////////////////////////////////////////////////////////////
460
461 #include "../../include/effects/SkGradientShader.h"
462 #include "sk_shader.h"
463
464 const struct {
465 sk_shader_tilemode_t fC;
466 SkShader::TileMode fSK;
467 } gTileModeMap[] = {
468 { CLAMP_SK_SHADER_TILEMODE, SkShader::kClamp_TileMode },
469 { REPEAT_SK_SHADER_TILEMODE, SkShader::kRepeat_TileMode },
470 { MIRROR_SK_SHADER_TILEMODE, SkShader::kMirror_TileMode },
471 };
472
from_c_tilemode(sk_shader_tilemode_t cMode,SkShader::TileMode * skMode)473 static bool from_c_tilemode(sk_shader_tilemode_t cMode, SkShader::TileMode* skMode) {
474 for (size_t i = 0; i < SK_ARRAY_COUNT(gTileModeMap); ++i) {
475 if (cMode == gTileModeMap[i].fC) {
476 if (skMode) {
477 *skMode = gTileModeMap[i].fSK;
478 }
479 return true;
480 }
481 }
482 return false;
483 }
484
sk_shader_ref(sk_shader_t * cshader)485 void sk_shader_ref(sk_shader_t* cshader) {
486 SkSafeRef(AsShader(cshader));
487 }
488
sk_shader_unref(sk_shader_t * cshader)489 void sk_shader_unref(sk_shader_t* cshader) {
490 SkSafeUnref(AsShader(cshader));
491 }
492
sk_shader_new_linear_gradient(const sk_point_t pts[2],const sk_color_t colors[],const float colorPos[],int colorCount,sk_shader_tilemode_t cmode,const sk_matrix_t * cmatrix)493 sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t pts[2],
494 const sk_color_t colors[],
495 const float colorPos[],
496 int colorCount,
497 sk_shader_tilemode_t cmode,
498 const sk_matrix_t* cmatrix) {
499 SkShader::TileMode mode;
500 if (!from_c_tilemode(cmode, &mode)) {
501 return NULL;
502 }
503 SkMatrix matrix;
504 if (cmatrix) {
505 from_c_matrix(cmatrix, &matrix);
506 } else {
507 matrix.setIdentity();
508 }
509 SkShader* s = SkGradientShader::CreateLinear(reinterpret_cast<const SkPoint*>(pts),
510 reinterpret_cast<const SkColor*>(colors),
511 colorPos, colorCount, mode, 0, &matrix);
512 return (sk_shader_t*)s;
513 }
514
515 ///////////////////////////////////////////////////////////////////////////////////////////
516
517 #include "../../include/effects/SkBlurMaskFilter.h"
518 #include "sk_maskfilter.h"
519
520 const struct {
521 sk_blurstyle_t fC;
522 SkBlurStyle fSk;
523 } gBlurStylePairs[] = {
524 { NORMAL_SK_BLUR_STYLE, kNormal_SkBlurStyle },
525 { SOLID_SK_BLUR_STYLE, kSolid_SkBlurStyle },
526 { OUTER_SK_BLUR_STYLE, kOuter_SkBlurStyle },
527 { INNER_SK_BLUR_STYLE, kInner_SkBlurStyle },
528 };
529
find_blurstyle(sk_blurstyle_t csrc,SkBlurStyle * dst)530 static bool find_blurstyle(sk_blurstyle_t csrc, SkBlurStyle* dst) {
531 for (size_t i = 0; i < SK_ARRAY_COUNT(gBlurStylePairs); ++i) {
532 if (gBlurStylePairs[i].fC == csrc) {
533 if (dst) {
534 *dst = gBlurStylePairs[i].fSk;
535 }
536 return true;
537 }
538 }
539 return false;
540 }
541
sk_maskfilter_ref(sk_maskfilter_t * cfilter)542 void sk_maskfilter_ref(sk_maskfilter_t* cfilter) {
543 SkSafeRef(AsMaskFilter(cfilter));
544 }
545
sk_maskfilter_unref(sk_maskfilter_t * cfilter)546 void sk_maskfilter_unref(sk_maskfilter_t* cfilter) {
547 SkSafeUnref(AsMaskFilter(cfilter));
548 }
549
sk_maskfilter_new_blur(sk_blurstyle_t cstyle,float sigma)550 sk_maskfilter_t* sk_maskfilter_new_blur(sk_blurstyle_t cstyle, float sigma) {
551 SkBlurStyle style;
552 if (!find_blurstyle(cstyle, &style)) {
553 return NULL;
554 }
555 return ToMaskFilter(SkBlurMaskFilter::Create(style, sigma));
556 }
557
558 ///////////////////////////////////////////////////////////////////////////////////////////
559
sk_data_new_with_copy(const void * src,size_t length)560 sk_data_t* sk_data_new_with_copy(const void* src, size_t length) {
561 return ToData(SkData::NewWithCopy(src, length));
562 }
563
sk_data_new_from_malloc(const void * memory,size_t length)564 sk_data_t* sk_data_new_from_malloc(const void* memory, size_t length) {
565 return ToData(SkData::NewFromMalloc(memory, length));
566 }
567
sk_data_new_subset(const sk_data_t * csrc,size_t offset,size_t length)568 sk_data_t* sk_data_new_subset(const sk_data_t* csrc, size_t offset, size_t length) {
569 return ToData(SkData::NewSubset(AsData(csrc), offset, length));
570 }
571
sk_data_ref(const sk_data_t * cdata)572 void sk_data_ref(const sk_data_t* cdata) {
573 SkSafeRef(AsData(cdata));
574 }
575
sk_data_unref(const sk_data_t * cdata)576 void sk_data_unref(const sk_data_t* cdata) {
577 SkSafeUnref(AsData(cdata));
578 }
579
sk_data_get_size(const sk_data_t * cdata)580 size_t sk_data_get_size(const sk_data_t* cdata) {
581 return AsData(cdata)->size();
582 }
583
sk_data_get_data(const sk_data_t * cdata)584 const void* sk_data_get_data(const sk_data_t* cdata) {
585 return AsData(cdata)->data();
586 }
587
588 ///////////////////////////////////////////////////////////////////////////////////////////
589 ///////////////////////////////////////////////////////////////////////////////////////////
590
sk_test_capi(SkCanvas * canvas)591 void sk_test_capi(SkCanvas* canvas) {
592 sk_imageinfo_t cinfo;
593 cinfo.width = 100;
594 cinfo.height = 100;
595 cinfo.colorType = (sk_colortype_t)kN32_SkColorType;
596 cinfo.alphaType = (sk_alphatype_t)kPremul_SkAlphaType;
597
598 sk_surface_t* csurface = sk_surface_new_raster(&cinfo);
599 sk_canvas_t* ccanvas = sk_surface_get_canvas(csurface);
600
601 sk_paint_t* cpaint = sk_paint_new();
602 sk_paint_set_antialias(cpaint, true);
603 sk_paint_set_color(cpaint, 0xFFFF0000);
604
605 sk_rect_t cr = { 5, 5, 95, 95 };
606 sk_canvas_draw_oval(ccanvas, &cr, cpaint);
607
608 cr.left += 25;
609 cr.top += 25;
610 cr.right -= 25;
611 cr.bottom -= 25;
612 sk_paint_set_color(cpaint, 0xFF00FF00);
613 sk_canvas_draw_rect(ccanvas, &cr, cpaint);
614
615 sk_path_t* cpath = sk_path_new();
616 sk_path_move_to(cpath, 50, 50);
617 sk_path_line_to(cpath, 100, 100);
618 sk_path_line_to(cpath, 50, 100);
619 sk_path_close(cpath);
620
621 sk_canvas_draw_path(ccanvas, cpath, cpaint);
622
623 sk_image_t* cimage = sk_surface_new_image_snapshot(csurface);
624
625 // HERE WE CROSS THE C..C++ boundary
626 canvas->drawImage((const SkImage*)cimage, 20, 20, NULL);
627
628 sk_path_delete(cpath);
629 sk_paint_delete(cpaint);
630 sk_image_unref(cimage);
631 sk_surface_unref(csurface);
632 }
633