1 Skia's Stable C API 2 =================== 3 4 <div style="text-align:center"> 5 <strong>EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL<br> 6 DO NOT USE — FOR INTERNAL TESTING ONLY</strong> 7 </div> 8 9 Several issues hinder the development of a stable ABI (application 10 binary interface) for Skia: 11 12 1. Skia's C++ API changes a lot from version to version. Skia's two 13 largest clients, Android and Chrome, are kept up to date by the 14 Skia team, but that can not happen for every client. 15 2. Skia's headers will only match the compiled skia libraries if 16 configured identically. 17 18 To mitigate these two issues, Skia is experimenting with the 19 introduction of a C API. This will change more slowly than the C++ 20 interface and, once API version 1.0.0 is announced, 21 backwards-incompatable changes will be avoided whenever possible. 22 23 Here is an example program that uses the C api. To try it out, get the file 24 [`skia-c-example.c`](./skia-c-example.c). 25 26 <!--?prettify lang=c?--> 27 28 #include <stdio.h> 29 30 #include "sk_data.h" 31 #include "sk_image.h" 32 #include "sk_canvas.h" 33 #include "sk_surface.h" 34 #include "sk_paint.h" 35 #include "sk_path.h" 36 37 static sk_surface_t* make_surface(int32_t w, int32_t h) { 38 sk_imageinfo_t info; 39 info.width = w; 40 info.height = h; 41 info.colorType = sk_colortype_get_default_8888(); 42 info.alphaType = PREMUL_SK_ALPHATYPE; 43 return sk_surface_new_raster(&info, NULL); 44 } 45 46 static void emit_png(const char* path, sk_surface_t* surface) { 47 sk_image_t* image = sk_surface_new_image_snapshot(surface); 48 sk_data_t* data = sk_image_encode(image); 49 sk_image_unref(image); 50 FILE* f = fopen(path, "wb"); 51 fwrite(sk_data_get_data(data), sk_data_get_size(data), 1, f); 52 fclose(f); 53 sk_data_unref(data); 54 } 55 56 void draw(sk_canvas_t* canvas) { 57 sk_paint_t* fill = sk_paint_new(); 58 sk_paint_set_color(fill, sk_color_set_argb(0xFF, 0x00, 0x00, 0xFF)); 59 sk_canvas_draw_paint(canvas, fill); 60 61 sk_paint_set_color(fill, sk_color_set_argb(0xFF, 0x00, 0xFF, 0xFF)); 62 sk_rect_t rect; 63 rect.left = 100.0f; 64 rect.top = 100.0f; 65 rect.right = 540.0f; 66 rect.bottom = 380.0f; 67 sk_canvas_draw_rect(canvas, &rect, fill); 68 69 sk_paint_t* stroke = sk_paint_new(); 70 sk_paint_set_color(stroke, sk_color_set_argb(0xFF, 0xFF, 0x00, 0x00)); 71 sk_paint_set_antialias(stroke, true); 72 sk_paint_set_stroke(stroke, true); 73 sk_paint_set_stroke_width(stroke, 5.0f); 74 sk_path_t* path = sk_path_new(); 75 76 sk_path_move_to(path, 50.0f, 50.0f); 77 sk_path_line_to(path, 590.0f, 50.0f); 78 sk_path_cubic_to(path, -490.0f, 50.0f, 1130.0f, 430.0f, 50.0f, 430.0f); 79 sk_path_line_to(path, 590.0f, 430.0f); 80 sk_canvas_draw_path(canvas, path, stroke); 81 82 sk_paint_set_color(fill, sk_color_set_argb(0x80, 0x00, 0xFF, 0x00)); 83 sk_rect_t rect2; 84 rect2.left = 120.0f; 85 rect2.top = 120.0f; 86 rect2.right = 520.0f; 87 rect2.bottom = 360.0f; 88 sk_canvas_draw_oval(canvas, &rect2, fill); 89 90 sk_path_delete(path); 91 sk_paint_delete(stroke); 92 sk_paint_delete(fill); 93 } 94 95 int main() { 96 sk_surface_t* surface = make_surface(640, 480); 97 sk_canvas_t* canvas = sk_surface_get_canvas(surface); 98 draw(canvas); 99 emit_png("skia-c-example.png", surface); 100 sk_surface_unref(surface); 101 return 0; 102 } 103 104 <a href="https://fiddle.skia.org/c/6c6c01438d9c3d80e9c22e606359432e"><img src="https://fiddle.skia.org/i/6c6c01438d9c3d80e9c22e606359432e_raster.png" alt=""></a> 105 106 Cmake example 107 ------------- 108 109 The following proof-of-concept workflow currently works on MacOS and 110 Ubuntu and depends on a C/C++ compiler, git, and cmake: 111 112 1. Aquire, compile, and install Skia as a shared library: 113 114 <!--?prettify lang=sh?--> 115 116 prefix="$HOME" 117 cd $(mktemp -d /tmp/skiaXXXX) 118 git clone 'https://skia.googlesource.com/skia' 119 cmake -DCMAKE_INSTALL_PREFIX:PATH="$prefix" skia/cmake 120 cmake --build . --target skia 121 cmake --build . --target install 122 123 2. Compile, link, and run the example program: 124 125 <!--?prettify lang=sh?--> 126 127 cc -o skia-c-example -I "$prefix/include" \ 128 skia/experimental/c-api-example/skia-c-example.c \ 129 "$prefix"/lib/libskia.* -Wl,-rpath -Wl,"$prefix/lib" 130 ./skia-c-example 131 [ $(uname) = Darwin ] && open skia-c-example.png 132 [ $(uname) = Linux ] && xdg-open skia-c-example.png 133