Home | History | Annotate | Download | only in go-skia
      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