1package cairo
2
3// #include <stdlib.h>
4// #include <cairo.h>
5// #include <cairo-gobject.h>
6import "C"
7
8import (
9	"runtime"
10	"unsafe"
11)
12
13//--------------------------------------------[ cairo_pattern_t  ==  Pattern ]--
14
15// Pattern is a representation of Cairo's cairo_pattern_t.
16type Pattern struct {
17	pattern *C.cairo_pattern_t
18}
19
20// NewPatternFromRGB is a wrapper around cairo_pattern_create_rgb().
21func NewPatternFromRGB(red, green, blue float64) (*Pattern, error) {
22	c := C.cairo_pattern_create_rgb(C.double(red), C.double(green), C.double(blue))
23	return newPatternFromNative(c)
24}
25
26// NewPatternFromRGBA is a wrapper around cairo_pattern_create_rgba().
27func NewPatternFromRGBA(red, green, blue, alpha float64) (*Pattern, error) {
28	c := C.cairo_pattern_create_rgba(C.double(red), C.double(green), C.double(blue), C.double(alpha))
29	return newPatternFromNative(c)
30}
31
32// NewPatternForSurface is a wrapper around cairo_pattern_create_for_surface().
33func NewPatternForSurface(s *Surface) (*Pattern, error) {
34	c := C.cairo_pattern_create_for_surface(s.native())
35	return newPatternFromNative(c)
36}
37
38// NewPatternLinear is a wrapper around cairo_pattern_create_linear().
39func NewPatternLinear(x0, y0, x1, y1 float64) (*Pattern, error) {
40	c := C.cairo_pattern_create_linear(C.double(x0), C.double(y0), C.double(x1), C.double(y1))
41	return newPatternFromNative(c)
42}
43
44// NewPatternRadial is a wrapper around cairo_pattern_create_radial().
45func NewPatternRadial(x0, y0, r0, x1, y1, r1 float64) (*Pattern, error) {
46	c := C.cairo_pattern_create_radial(C.double(x0), C.double(y0), C.double(r0),
47		C.double(x1), C.double(y1), C.double(r1))
48	return newPatternFromNative(c)
49}
50
51func newPatternFromNative(patternNative *C.cairo_pattern_t) (*Pattern, error) {
52	ptr := wrapPattern(patternNative)
53	e := ptr.Status().ToError()
54	if e != nil {
55		return nil, e
56	}
57	runtime.SetFinalizer(ptr, (*Pattern).destroy)
58	return ptr, nil
59}
60
61// native returns a pointer to the underlying cairo_pattern_t.
62func (v *Pattern) native() *C.cairo_pattern_t {
63	if v == nil {
64		return nil
65	}
66	return v.pattern
67}
68
69// Native returns a pointer to the underlying cairo_pattern_t.
70func (v *Pattern) Native() uintptr {
71	return uintptr(unsafe.Pointer(v.native()))
72}
73
74func marshalPattern(p uintptr) (interface{}, error) {
75	c := C.g_value_get_boxed((*C.GValue)(unsafe.Pointer(p)))
76	pattern := (*C.cairo_pattern_t)(unsafe.Pointer(c))
77	return wrapPattern(pattern), nil
78}
79
80func wrapPattern(pattern *C.cairo_pattern_t) *Pattern {
81	return &Pattern{pattern}
82}
83
84// reference is a wrapper around cairo_pattern_reference().
85func (v *Pattern) reference() {
86	v.pattern = C.cairo_pattern_reference(v.native())
87}
88
89// destroy is a wrapper around cairo_pattern_destroy().
90func (v *Pattern) destroy() {
91	C.cairo_pattern_destroy(v.native())
92}
93
94// Status is a wrapper around cairo_pattern_status().
95func (v *Pattern) Status() Status {
96	c := C.cairo_pattern_status(v.native())
97	return Status(c)
98}
99
100// AddColorStopRGB is a wrapper around cairo_pattern_add_color_stop_rgb().
101func (v *Pattern) AddColorStopRGB(offset, red, green, blue float64) error {
102	C.cairo_pattern_add_color_stop_rgb(v.native(), C.double(offset),
103		C.double(red), C.double(green), C.double(blue))
104	return v.Status().ToError()
105}
106
107// AddColorStopRGBA is a wrapper around cairo_pattern_add_color_stop_rgba().
108func (v *Pattern) AddColorStopRGBA(offset, red, green, blue, alpha float64) error {
109	C.cairo_pattern_add_color_stop_rgba(v.native(), C.double(offset),
110		C.double(red), C.double(green), C.double(blue), C.double(alpha))
111	return v.Status().ToError()
112}
113