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 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 */ 21 import "C" 22 23 import ( 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 ////////////////////////////////////////////////////////////////////////// 35 type Surface struct { 36 ptr *C.sk_surface_t 37 } 38 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 } 214