forked from ungerik/go-cairo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
drawing_paths.go
164 lines (118 loc) · 4.37 KB
/
drawing_paths.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package cairo
// #cgo LDFLAGS: -lcairo
// #include <cairo/cairo.h>
// #include <stdlib.h>
// #include <string.h>
import "C"
import (
"unsafe"
"math"
)
type PathData []float64
type PathDataPoint struct { x, y float64 }
// cairo_path_t* cairo_copy_path (cairo_t *cr);
func (self *Surface) CopyPath() (PathData, Status) {
path := C.cairo_copy_path(self.context)
defer C.cairo_path_destroy(path)
raw_data := make(PathData, int(path.num_data*2))
C.memcpy(unsafe.Pointer(&raw_data[0]), unsafe.Pointer(path.data), C.size_t(path.num_data*16))
return raw_data, Status(path.status)
}
// cairo_path_t* cairo_copy_path_flat (cairo_t *cr);
func (self *Surface) CopyPathFlat() (PathData, Status) {
path := C.cairo_copy_path_flat(self.context)
defer C.cairo_path_destroy(path)
raw_data := make(PathData, int(path.num_data*2))
C.memcpy(unsafe.Pointer(&raw_data[0]), unsafe.Pointer(path.data), C.size_t(path.num_data*16))
return raw_data, Status(path.status)
}
type PathDataType int
// cairo_path_data_type_t values
const (
PATH_MOVE_TO PathDataType = iota
PATH_LINE_TO
PATH_CURVE_TO
PATH_CLOSE_PATH
)
type NextElement func()(PathDataType, []PathDataPoint)
func (self PathData) Interator() NextElement {
count := 0
num_data := len(self)
return func() (PathDataType, []PathDataPoint) {
if count >= num_data {return -1, nil}
length := int(math.Float64bits(self[count]) >> 32)
path_type := int( (math.Float64bits(self[count]) << 32) >> 32 )
count += 2
var pathPoints []PathDataPoint
if length >= 2 {
length--
pathPoints = make([]PathDataPoint, length)
for index := range pathPoints {
pathPoints[index].x = self[count]
pathPoints[index].y = self[count+1]
}
count += (length * 2)
} else {
pathPoints = []PathDataPoint{}
}
return PathDataType(path_type), pathPoints
}
}
// cairo_bool_t cairo_has_current_point (cairo_t *cr);
func (self *Surface) HasCurrentPoint() bool {
return C.cairo_has_current_point(self.context) != 0
}
// void cairo_get_current_point (cairo_t *cr, double *x, double *y);
func (self *Surface) GetCurrentPoint( x, y float64 ) (float64, float64) {
C.cairo_get_current_point( self.context, (*C.double)(unsafe.Pointer(&x)), (*C.double)(unsafe.Pointer(&y)) )
return x, y
}
func (self *Surface) NewPath() { C.cairo_new_path(self.context) }
func (self *Surface) NewSubPath() { C.cairo_new_sub_path(self.context) }
func (self *Surface) ClosePath() { C.cairo_close_path(self.context) }
func (self *Surface) PathExtents() (left, top, right, bottom float64) {
C.cairo_path_extents(self.context,
(*C.double)(&left), (*C.double)(&top),
(*C.double)(&right), (*C.double)(&bottom))
return left, top, right, bottom
}
func (self *Surface) MoveTo(x, y float64) { C.cairo_move_to(self.context, C.double(x), C.double(y)) }
func (self *Surface) LineTo(x, y float64) { C.cairo_line_to(self.context, C.double(x), C.double(y)) }
func (self *Surface) CurveTo(x1, y1, x2, y2, x3, y3 float64) {
C.cairo_curve_to(self.context,
C.double(x1), C.double(y1),
C.double(x2), C.double(y2),
C.double(x3), C.double(y3))
}
func (self *Surface) RelMoveTo(dx, dy float64) { C.cairo_rel_move_to(self.context, C.double(dx), C.double(dy)) }
func (self *Surface) RelLineTo(dx, dy float64) { C.cairo_rel_line_to(self.context, C.double(dx), C.double(dy)) }
func (self *Surface) RelCurveTo(dx1, dy1, dx2, dy2, dx3, dy3 float64) {
C.cairo_rel_curve_to(self.context,
C.double(dx1), C.double(dy1),
C.double(dx2), C.double(dy2),
C.double(dx3), C.double(dy3))
}
func (self *Surface) Arc(xc, yc, radius, angle1, angle2 float64) {
C.cairo_arc(self.context,
C.double(xc), C.double(yc),
C.double(radius),
C.double(angle1), C.double(angle2))
}
func (self *Surface) ArcNegative(xc, yc, radius, angle1, angle2 float64) {
C.cairo_arc_negative(self.context,
C.double(xc), C.double(yc),
C.double(radius),
C.double(angle1), C.double(angle2))
}
func (self *Surface) Rectangle(x, y, width, height float64) {
C.cairo_rectangle(self.context, C.double(x), C.double(y), C.double(width), C.double(height))
}
func (self *Surface) TextPath(text string) {
cs := C.CString(text)
defer C.free(unsafe.Pointer(cs))
C.cairo_text_path(self.context, cs)
}
// void cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs);
func (self *Surface) GlyphPath(glyphs []Glyph) {
C.cairo_glyph_path(self.context, (*C.cairo_glyph_t)(unsafe.Pointer(&glyphs[0])), C.int(len(glyphs)))
}