aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental/c-api-example/c.md
blob: ce2228995e7a5e13c0d45f34995557a7e2380ce6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
Skia's Stable C API
===================

<div style="text-align:center">
<strong>EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL<br>
DO NOT USE &mdash; FOR INTERNAL TESTING ONLY</strong>
</div>

Several issues hinder the development of a stable ABI (application
binary interface) for Skia:

1.  Skia's C++ API changes a lot from version to version.  Skia's two
    largest clients, Android and Chrome, are kept up to date by the
    Skia team, but that can not happen for every client.
2.  Skia's headers will only match the compiled skia libraries if
    configured identically.

To mitigate these two issues, Skia is experimenting with the
introduction of a C API.  This will change more slowly than the C++
interface and, once API version 1.0.0 is announced,
backwards-incompatable changes will be avoided whenever possible.

Here is an example program that uses the C api.  To try it out, get the file
[`skia-c-example.c`](./skia-c-example.c).

<!--?prettify lang=c?-->

    #include <stdio.h>

    #include "sk_data.h"
    #include "sk_image.h"
    #include "sk_canvas.h"
    #include "sk_surface.h"
    #include "sk_paint.h"
    #include "sk_path.h"

    static sk_surface_t* make_surface(int32_t w, int32_t h) {
        sk_imageinfo_t info;
        info.width = w;
        info.height = h;
        info.colorType = sk_colortype_get_default_8888();
        info.alphaType = PREMUL_SK_ALPHATYPE;
        return sk_surface_new_raster(&info, NULL);
    }

    static void emit_png(const char* path, sk_surface_t* surface) {
        sk_image_t* image = sk_surface_new_image_snapshot(surface);
        sk_data_t* data = sk_image_encode(image);
        sk_image_unref(image);
        FILE* f = fopen(path, "wb");
        fwrite(sk_data_get_data(data), sk_data_get_size(data), 1, f);
        fclose(f);
        sk_data_unref(data);
    }

    void draw(sk_canvas_t* canvas) {
        sk_paint_t* fill = sk_paint_new();
        sk_paint_set_color(fill, sk_color_set_argb(0xFF, 0x00, 0x00, 0xFF));
        sk_canvas_draw_paint(canvas, fill);

        sk_paint_set_color(fill, sk_color_set_argb(0xFF, 0x00, 0xFF, 0xFF));
        sk_rect_t rect;
        rect.left = 100.0f;
        rect.top = 100.0f;
        rect.right = 540.0f;
        rect.bottom = 380.0f;
        sk_canvas_draw_rect(canvas, &rect, fill);

        sk_paint_t* stroke = sk_paint_new();
        sk_paint_set_color(stroke, sk_color_set_argb(0xFF, 0xFF, 0x00, 0x00));
        sk_paint_set_antialias(stroke, true);
        sk_paint_set_stroke(stroke, true);
        sk_paint_set_stroke_width(stroke, 5.0f);
        sk_path_t* path = sk_path_new();

        sk_path_move_to(path, 50.0f, 50.0f);
        sk_path_line_to(path, 590.0f, 50.0f);
        sk_path_cubic_to(path, -490.0f, 50.0f, 1130.0f, 430.0f, 50.0f, 430.0f);
        sk_path_line_to(path, 590.0f, 430.0f);
        sk_canvas_draw_path(canvas, path, stroke);

        sk_paint_set_color(fill, sk_color_set_argb(0x80, 0x00, 0xFF, 0x00));
        sk_rect_t rect2;
        rect2.left = 120.0f;
        rect2.top = 120.0f;
        rect2.right = 520.0f;
        rect2.bottom = 360.0f;
        sk_canvas_draw_oval(canvas, &rect2, fill);

        sk_path_delete(path);
        sk_paint_delete(stroke);
        sk_paint_delete(fill);
    }

    int main() {
        sk_surface_t* surface = make_surface(640, 480);
        sk_canvas_t* canvas = sk_surface_get_canvas(surface);
        draw(canvas);
        emit_png("skia-c-example.png", surface);
        sk_surface_unref(surface);
        return 0;
    }

<a href="https://fiddle.skia.org/c/6c6c01438d9c3d80e9c22e606359432e"><img src="https://fiddle.skia.org/i/6c6c01438d9c3d80e9c22e606359432e_raster.png" alt=""></a>

Gyp+Linux example
-----------------

The following proof-of-concept workflow currently works on Ubuntu 14.04:

1.  Aquire Skia and install dependencies (you may have already done this):

    <!--?prettify lang=sh?-->

        git clone 'https://chromium.googlesource.com/chromium/tools/depot_tools.git'
        export PATH="$PWD/depot_tools:$PATH"
        git clone 'https://skia.googlesource.com/skia'
        skia/tools/install_dependencies.sh
        SKIA_DIR="$PWD/skia"

2.  Compile Skia as a shared library:

    <!--?prettify lang=sh?-->

        GYP_DEFINES=skia_shared_lib=1 "$SKIA_DIR"/bin/sync-and-gyp
        ninja -C "$SKIA_DIR/out/Release" skia_lib

3.  Compile, link, and run the example program:

    <!--?prettify lang=sh?-->

        cd [Wherever you want the example]
        cp "$SKIA_DIR/experimental/c-api-example/skia-c-example.c" .
        cc -c -I "$SKIA_DIR/include/c" skia-c-example.c -o skia-c-example.o
        cc skia-c-example.o -L "$SKIA_DIR/out/Release/lib" -lskia -o skia-c-example
        LD_LIBRARY_PATH="$SKIA_DIR/out/Release/lib" ./skia-c-example
        xdg-open skia-c-example.png

Cmake+MacOS example
-------------------

The following proof-of-concept workflow currently works on MacOS

1.  Aquire Skia and install dependencies (you may have already done this):

    <!--?prettify lang=sh?-->

        cd [Wherever you want skia src code]
        git clone 'https://skia.googlesource.com/skia'
        SKIA_DIR="$PWD/skia"

2.  Compile Skia as a shared library:

    <!--?prettify lang=sh?-->

        cd [Wherever you want skia build files]
        mkdir build_skia
        cd build_skia
        SKIA_BUILD="$PWD"
        cmake "$SKIA_DIR/cmake" -G Ninja && ninja

3.  Compile, link, and run the example program:

    <!--?prettify lang=sh?-->

        cd [Wherever you want the example]
        cp "$SKIA_DIR/experimental/c-api-example/skia-c-example.c" .
        cc -c -I "$SKIA_DIR/include/c" skia-c-example.c -o skia-c-example.o
        c++ skia-c-example.o \
            "$SKIA_BUILD"/libskia.* -Wl,-rpath -Wl,"$SKIA_BUILD" \
            -o skia-c-example
        ./skia-c-example
        open skia-c-example.png