Stephan Altmueller | efa48d5 | 2017-05-09 15:56:06 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2015 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 | package skia |
stephana | 0b5fc97 | 2014-10-31 07:11:19 -0700 | [diff] [blame] | 8 | |
| 9 | /* |
Stephan Altmueller | efa48d5 | 2017-05-09 15:56:06 -0400 | [diff] [blame] | 10 | #cgo LDFLAGS: -L${SRCDIR}/../../out/Shared |
Heather Miller | 72040d9 | 2018-03-19 15:19:36 -0400 | [diff] [blame] | 11 | #cgo LDFLAGS: -Wl,-rpath,${SRCDIR}/../../out/Shared |
mtklein | 3eeb156 | 2014-11-03 10:45:50 -0800 | [diff] [blame] | 12 | #cgo LDFLAGS: -lskia |
mtklein | 3eeb156 | 2014-11-03 10:45:50 -0800 | [diff] [blame] | 13 | #cgo CFLAGS: -I../../include/c |
Stephan Altmueller | efa48d5 | 2017-05-09 15:56:06 -0400 | [diff] [blame] | 14 | #include "sk_canvas.h" |
| 15 | #include "sk_data.h" |
| 16 | #include "sk_image.h" |
| 17 | #include "sk_paint.h" |
| 18 | #include "sk_path.h" |
stephana | 0b5fc97 | 2014-10-31 07:11:19 -0700 | [diff] [blame] | 19 | #include "sk_surface.h" |
| 20 | */ |
| 21 | import "C" |
| 22 | |
mtklein | 3eeb156 | 2014-11-03 10:45:50 -0800 | [diff] [blame] | 23 | import ( |
| 24 | "fmt" |
Stephan Altmueller | efa48d5 | 2017-05-09 15:56:06 -0400 | [diff] [blame] | 25 | "io" |
| 26 | "runtime" |
| 27 | "unsafe" |
mtklein | 3eeb156 | 2014-11-03 10:45:50 -0800 | [diff] [blame] | 28 | ) |
| 29 | |
Stephan Altmueller | efa48d5 | 2017-05-09 15:56:06 -0400 | [diff] [blame] | 30 | // TODO(stephana): Add proper documentation to the types defined here. |
| 31 | |
| 32 | ////////////////////////////////////////////////////////////////////////// |
| 33 | // Surface |
| 34 | ////////////////////////////////////////////////////////////////////////// |
| 35 | type Surface struct { |
| 36 | ptr *C.sk_surface_t |
stephana | 0b5fc97 | 2014-10-31 07:11:19 -0700 | [diff] [blame] | 37 | } |
| 38 | |
Stephan Altmueller | efa48d5 | 2017-05-09 15:56:06 -0400 | [diff] [blame] | 39 | // func NewRasterSurface(width, height int32, alphaType AlphaType) (*Surface, error) { |
| 40 | func NewRasterSurface(imgInfo *ImageInfo) (*Surface, error) { |
| 41 | ptr := C.sk_surface_new_raster(imgInfo.cPointer(), (*C.sk_surfaceprops_t)(nil)) |
| 42 | if ptr == nil { |
| 43 | return nil, fmt.Errorf("Unable to create raster surface.") |
| 44 | } |
| 45 | |
| 46 | ret := &Surface{ptr: ptr} |
| 47 | runtime.SetFinalizer(ret, func(s *Surface) { |
| 48 | C.sk_surface_unref(s.ptr) |
| 49 | }) |
| 50 | return ret, nil |
| 51 | } |
| 52 | |
| 53 | func (s *Surface) Canvas() *Canvas { |
| 54 | return &Canvas{ |
| 55 | ptr: C.sk_surface_get_canvas(s.ptr), |
| 56 | keepParentAlive: s, |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | func (s *Surface) Image() *Image { |
| 61 | ret := &Image{ |
| 62 | ptr: C.sk_surface_new_image_snapshot(s.ptr), |
| 63 | keepParentAlive: s, |
| 64 | } |
| 65 | runtime.SetFinalizer(ret, func(i *Image) { |
| 66 | C.sk_image_unref(i.ptr) |
| 67 | }) |
| 68 | return ret |
| 69 | } |
| 70 | |
| 71 | ////////////////////////////////////////////////////////////////////////// |
| 72 | // Image |
| 73 | ////////////////////////////////////////////////////////////////////////// |
| 74 | type Image struct { |
| 75 | ptr *C.sk_image_t |
| 76 | keepParentAlive *Surface |
| 77 | } |
| 78 | |
| 79 | func (i *Image) WritePNG(w io.Writer) error { |
| 80 | data := C.sk_image_encode(i.ptr) |
| 81 | defer C.sk_data_unref(data) |
| 82 | |
| 83 | dataPtr := C.sk_data_get_data(data) |
| 84 | dataSize := C.sk_data_get_size(data) |
| 85 | byteSlice := C.GoBytes(dataPtr, C.int(dataSize)) |
| 86 | _, err := w.Write(byteSlice) |
| 87 | if err != nil { |
| 88 | return err |
| 89 | } |
| 90 | return nil |
| 91 | } |
| 92 | |
| 93 | ////////////////////////////////////////////////////////////////////////// |
| 94 | // Canvas |
| 95 | ////////////////////////////////////////////////////////////////////////// |
| 96 | type Canvas struct { |
| 97 | ptr *C.sk_canvas_t |
| 98 | keepParentAlive *Surface |
| 99 | } |
| 100 | |
| 101 | func (c *Canvas) DrawPaint(paint *Paint) { |
| 102 | C.sk_canvas_draw_paint(c.ptr, paint.ptr) |
| 103 | } |
| 104 | |
| 105 | func (c *Canvas) DrawOval(rect *Rect, paint *Paint) { |
| 106 | // C.sk_canvas_draw_oval(c.ptr, (*C.sk_rect_t)(unsafe.Pointer(rect)), (*C.sk_paint_t)(paint.ptr)) |
| 107 | C.sk_canvas_draw_oval(c.ptr, rect.cPointer(), paint.ptr) |
| 108 | } |
| 109 | |
| 110 | func (c *Canvas) DrawRect(rect *Rect, paint *Paint) { |
| 111 | // C.sk_canvas_draw_rect(c.ptr, (*C.sk_rect_t)(unsafe.Pointer(rect)), (*C.sk_paint_t)(paint.ptr)) |
| 112 | C.sk_canvas_draw_rect(c.ptr, rect.cPointer(), paint.ptr) |
| 113 | } |
| 114 | |
| 115 | func (c *Canvas) DrawPath(path *Path, paint *Paint) { |
| 116 | // C.sk_canvas_draw_path(c.ptr, (*C.sk_path_t)(path.ptr), (*C.sk_paint_t)(paint.ptr)) |
| 117 | C.sk_canvas_draw_path(c.ptr, path.ptr, paint.ptr) |
| 118 | } |
| 119 | |
| 120 | ////////////////////////////////////////////////////////////////////////// |
| 121 | // Paint |
| 122 | ////////////////////////////////////////////////////////////////////////// |
| 123 | type Paint struct { |
| 124 | ptr *C.sk_paint_t |
| 125 | } |
| 126 | |
| 127 | func NewPaint() *Paint { |
| 128 | ret := &Paint{ptr: C.sk_paint_new()} |
| 129 | runtime.SetFinalizer(ret, func(p *Paint) { |
| 130 | C.sk_paint_delete(p.ptr) |
| 131 | }) |
| 132 | return ret |
| 133 | } |
| 134 | |
| 135 | func (p *Paint) SetColor(color Color) { |
| 136 | C.sk_paint_set_color(p.ptr, C.sk_color_t(color)) |
| 137 | } |
| 138 | |
| 139 | func (p *Paint) SetAntiAlias(antiAlias bool) { |
| 140 | C.sk_paint_set_antialias(p.ptr, C._Bool(antiAlias)) |
| 141 | } |
| 142 | |
| 143 | func (p *Paint) SetStroke(val bool) { |
| 144 | C.sk_paint_set_stroke(p.ptr, C._Bool(val)) |
| 145 | } |
| 146 | |
| 147 | func (p *Paint) SetStrokeWidth(width float32) { |
| 148 | C.sk_paint_set_stroke_width(p.ptr, C.float(width)) |
| 149 | } |
| 150 | |
| 151 | ////////////////////////////////////////////////////////////////////////// |
| 152 | // Path |
| 153 | ////////////////////////////////////////////////////////////////////////// |
| 154 | type Path struct { |
| 155 | ptr *C.sk_path_t |
| 156 | } |
| 157 | |
| 158 | func NewPath() *Path { |
| 159 | ret := &Path{ptr: C.sk_path_new()} |
| 160 | runtime.SetFinalizer(ret, func(p *Path) { |
| 161 | C.sk_path_delete(p.ptr) |
| 162 | }) |
| 163 | return ret |
| 164 | } |
| 165 | |
| 166 | func (p *Path) MoveTo(x, y float32) { |
| 167 | C.sk_path_move_to(p.ptr, C.float(x), C.float(y)) |
| 168 | } |
| 169 | |
| 170 | func (p *Path) LineTo(x, y float32) { |
| 171 | C.sk_path_line_to(p.ptr, C.float(x), C.float(y)) |
| 172 | } |
| 173 | |
| 174 | func (p *Path) QuadTo(x0, y0, x1, y1 float32) { |
| 175 | C.sk_path_quad_to(p.ptr, C.float(x0), C.float(y0), C.float(x1), C.float(y1)) |
| 176 | } |
| 177 | |
| 178 | func (p *Path) ConicTo(x0, y0, x1, y1, w float32) { |
| 179 | C.sk_path_conic_to(p.ptr, C.float(x0), C.float(y0), C.float(x1), C.float(y1), C.float(w)) |
| 180 | } |
| 181 | |
| 182 | func (p *Path) CubicTo(x0, y0, x1, y1, x2, y2 float32) { |
| 183 | C.sk_path_cubic_to(p.ptr, C.float(x0), C.float(y0), C.float(x1), C.float(y1), C.float(x2), C.float(y2)) |
| 184 | } |
| 185 | |
| 186 | func (p *Path) Close() { |
| 187 | C.sk_path_close(p.ptr) |
| 188 | } |
| 189 | |
| 190 | // NewRect is a convenience function to define a Rect in a single line. |
| 191 | func NewRect(left, top, right, bottom float32) *Rect { |
| 192 | return &Rect{ |
| 193 | Left: left, |
| 194 | Top: top, |
| 195 | Right: right, |
| 196 | Bottom: bottom, |
| 197 | } |
| 198 | } |
| 199 | |
| 200 | // cPointer casts the pointer to Rect to the corresponding C pointer. |
| 201 | func (r *Rect) cPointer() *C.sk_rect_t { |
| 202 | return (*C.sk_rect_t)(unsafe.Pointer(r)) |
| 203 | } |
| 204 | |
| 205 | // cPointer casts the pointer to ImageInfo to the corresponding C pointer. |
| 206 | func (i *ImageInfo) cPointer() *C.sk_imageinfo_t { |
| 207 | return (*C.sk_imageinfo_t)(unsafe.Pointer(i)) |
| 208 | } |
| 209 | |
| 210 | // Utility functions. |
| 211 | func GetDefaultColortype() ColorType { |
| 212 | return ColorType(C.sk_colortype_get_default_8888()) |
| 213 | } |