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 */ 7package skia 8 9/* 10#cgo LDFLAGS: -L${SRCDIR}/../../out/Shared 11#cgo LDFLAGS: -Wl,-rpath=${SRCDIR}/../../out/Shared 12#cgo LDFLAGS: -lskia 13#cgo CFLAGS: -I../../include/c 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" 19#include "sk_surface.h" 20*/ 21import "C" 22 23import ( 24 "fmt" 25 "io" 26 "runtime" 27 "unsafe" 28) 29 30// TODO(stephana): Add proper documentation to the types defined here. 31 32////////////////////////////////////////////////////////////////////////// 33// Surface 34////////////////////////////////////////////////////////////////////////// 35type Surface struct { 36 ptr *C.sk_surface_t 37} 38 39// func NewRasterSurface(width, height int32, alphaType AlphaType) (*Surface, error) { 40func 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 53func (s *Surface) Canvas() *Canvas { 54 return &Canvas{ 55 ptr: C.sk_surface_get_canvas(s.ptr), 56 keepParentAlive: s, 57 } 58} 59 60func (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////////////////////////////////////////////////////////////////////////// 74type Image struct { 75 ptr *C.sk_image_t 76 keepParentAlive *Surface 77} 78 79func (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////////////////////////////////////////////////////////////////////////// 96type Canvas struct { 97 ptr *C.sk_canvas_t 98 keepParentAlive *Surface 99} 100 101func (c *Canvas) DrawPaint(paint *Paint) { 102 C.sk_canvas_draw_paint(c.ptr, paint.ptr) 103} 104 105func (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 110func (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 115func (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////////////////////////////////////////////////////////////////////////// 123type Paint struct { 124 ptr *C.sk_paint_t 125} 126 127func 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 135func (p *Paint) SetColor(color Color) { 136 C.sk_paint_set_color(p.ptr, C.sk_color_t(color)) 137} 138 139func (p *Paint) SetAntiAlias(antiAlias bool) { 140 C.sk_paint_set_antialias(p.ptr, C._Bool(antiAlias)) 141} 142 143func (p *Paint) SetStroke(val bool) { 144 C.sk_paint_set_stroke(p.ptr, C._Bool(val)) 145} 146 147func (p *Paint) SetStrokeWidth(width float32) { 148 C.sk_paint_set_stroke_width(p.ptr, C.float(width)) 149} 150 151////////////////////////////////////////////////////////////////////////// 152// Path 153////////////////////////////////////////////////////////////////////////// 154type Path struct { 155 ptr *C.sk_path_t 156} 157 158func 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 166func (p *Path) MoveTo(x, y float32) { 167 C.sk_path_move_to(p.ptr, C.float(x), C.float(y)) 168} 169 170func (p *Path) LineTo(x, y float32) { 171 C.sk_path_line_to(p.ptr, C.float(x), C.float(y)) 172} 173 174func (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 178func (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 182func (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 186func (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. 191func 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. 201func (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. 206func (i *ImageInfo) cPointer() *C.sk_imageinfo_t { 207 return (*C.sk_imageinfo_t)(unsafe.Pointer(i)) 208} 209 210// Utility functions. 211func GetDefaultColortype() ColorType { 212 return ColorType(C.sk_colortype_get_default_8888()) 213} 214