Home | History | Annotate | Download | only in c-api-example
      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 &mdash; 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