transform_test.go raw
1 package rendertest
2
3 import (
4 "image"
5 "math"
6 "testing"
7
8 "golang.org/x/image/colornames"
9
10 "github.com/p9c/p9/pkg/gel/gio/f32"
11 "github.com/p9c/p9/pkg/gel/gio/op"
12 "github.com/p9c/p9/pkg/gel/gio/op/clip"
13 "github.com/p9c/p9/pkg/gel/gio/op/paint"
14 )
15
16 func TestPaintOffset(t *testing.T) {
17 run(t, func(o *op.Ops) {
18 op.Offset(f32.Pt(10, 20)).Add(o)
19 paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 50, 50)).Op())
20 }, func(r result) {
21 r.expect(0, 0, transparent)
22 r.expect(59, 30, colornames.Red)
23 r.expect(60, 30, transparent)
24 r.expect(10, 70, transparent)
25 })
26 }
27
28 func TestPaintRotate(t *testing.T) {
29 run(t, func(o *op.Ops) {
30 a := f32.Affine2D{}.Rotate(f32.Pt(40, 40), -math.Pi/8)
31 op.Affine(a).Add(o)
32 paint.FillShape(o, red, clip.Rect(image.Rect(20, 20, 60, 60)).Op())
33 }, func(r result) {
34 r.expect(40, 40, colornames.Red)
35 r.expect(50, 19, colornames.Red)
36 r.expect(59, 19, transparent)
37 r.expect(21, 21, transparent)
38 })
39 }
40
41 func TestPaintShear(t *testing.T) {
42 run(t, func(o *op.Ops) {
43 a := f32.Affine2D{}.Shear(f32.Point{}, math.Pi/4, 0)
44 op.Affine(a).Add(o)
45 paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 40, 40)).Op())
46 }, func(r result) {
47 r.expect(10, 30, transparent)
48 })
49 }
50
51 func TestClipPaintOffset(t *testing.T) {
52 run(t, func(o *op.Ops) {
53 clip.RRect{Rect: f32.Rect(10, 10, 30, 30)}.Add(o)
54 op.Offset(f32.Pt(20, 20)).Add(o)
55 paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 100, 100)).Op())
56 }, func(r result) {
57 r.expect(0, 0, transparent)
58 r.expect(19, 19, transparent)
59 r.expect(20, 20, colornames.Red)
60 r.expect(30, 30, transparent)
61 })
62 }
63
64 func TestClipOffset(t *testing.T) {
65 run(t, func(o *op.Ops) {
66 op.Offset(f32.Pt(20, 20)).Add(o)
67 clip.RRect{Rect: f32.Rect(10, 10, 30, 30)}.Add(o)
68 paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 100, 100)).Op())
69 }, func(r result) {
70 r.expect(0, 0, transparent)
71 r.expect(29, 29, transparent)
72 r.expect(30, 30, colornames.Red)
73 r.expect(49, 49, colornames.Red)
74 r.expect(50, 50, transparent)
75 })
76 }
77
78 func TestClipScale(t *testing.T) {
79 run(t, func(o *op.Ops) {
80 a := f32.Affine2D{}.Scale(f32.Point{}, f32.Pt(2, 2)).Offset(f32.Pt(10, 10))
81 op.Affine(a).Add(o)
82 clip.RRect{Rect: f32.Rect(10, 10, 20, 20)}.Add(o)
83 paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 1000, 1000)).Op())
84 }, func(r result) {
85 r.expect(19+10, 19+10, transparent)
86 r.expect(20+10, 20+10, colornames.Red)
87 r.expect(39+10, 39+10, colornames.Red)
88 r.expect(40+10, 40+10, transparent)
89 })
90 }
91
92 func TestClipRotate(t *testing.T) {
93 run(t, func(o *op.Ops) {
94 op.Affine(f32.Affine2D{}.Rotate(f32.Pt(40, 40), -math.Pi/4)).Add(o)
95 clip.RRect{Rect: f32.Rect(30, 30, 50, 50)}.Add(o)
96 paint.FillShape(o, red, clip.Rect(image.Rect(0, 40, 100, 100)).Op())
97 }, func(r result) {
98 r.expect(39, 39, transparent)
99 r.expect(41, 41, colornames.Red)
100 r.expect(50, 50, transparent)
101 })
102 }
103
104 func TestOffsetTexture(t *testing.T) {
105 run(t, func(o *op.Ops) {
106 op.Offset(f32.Pt(15, 15)).Add(o)
107 squares.Add(o)
108 scale(50.0/512, 50.0/512).Add(o)
109 paint.PaintOp{}.Add(o)
110 }, func(r result) {
111 r.expect(14, 20, transparent)
112 r.expect(66, 20, transparent)
113 r.expect(16, 64, colornames.Green)
114 r.expect(64, 16, colornames.Green)
115 })
116 }
117
118 func TestOffsetScaleTexture(t *testing.T) {
119 run(t, func(o *op.Ops) {
120 op.Offset(f32.Pt(15, 15)).Add(o)
121 squares.Add(o)
122 op.Affine(f32.Affine2D{}.Scale(f32.Point{}, f32.Pt(2, 1))).Add(o)
123 scale(50.0/512, 50.0/512).Add(o)
124 paint.PaintOp{}.Add(o)
125 }, func(r result) {
126 r.expect(114, 64, colornames.Blue)
127 r.expect(116, 64, transparent)
128 })
129 }
130
131 func TestRotateTexture(t *testing.T) {
132 run(t, func(o *op.Ops) {
133 defer op.Save(o).Load()
134 squares.Add(o)
135 a := f32.Affine2D{}.Offset(f32.Pt(30, 30)).Rotate(f32.Pt(40, 40), math.Pi/4)
136 op.Affine(a).Add(o)
137 scale(20.0/512, 20.0/512).Add(o)
138 paint.PaintOp{}.Add(o)
139 }, func(r result) {
140 r.expect(40, 40-12, colornames.Blue)
141 r.expect(40+12, 40, colornames.Green)
142 })
143 }
144
145 func TestRotateClipTexture(t *testing.T) {
146 run(t, func(o *op.Ops) {
147 squares.Add(o)
148 a := f32.Affine2D{}.Rotate(f32.Pt(40, 40), math.Pi/8)
149 op.Affine(a).Add(o)
150 clip.RRect{Rect: f32.Rect(30, 30, 50, 50)}.Add(o)
151 op.Affine(f32.Affine2D{}.Offset(f32.Pt(10, 10))).Add(o)
152 scale(60.0/512, 60.0/512).Add(o)
153 paint.PaintOp{}.Add(o)
154 }, func(r result) {
155 r.expect(0, 0, transparent)
156 r.expect(37, 39, colornames.Green)
157 r.expect(36, 39, colornames.Green)
158 r.expect(35, 39, colornames.Green)
159 r.expect(34, 39, colornames.Green)
160 r.expect(33, 39, colornames.Green)
161 })
162 }
163
164 func TestComplicatedTransform(t *testing.T) {
165 run(t, func(o *op.Ops) {
166 squares.Add(o)
167
168 clip.RRect{Rect: f32.Rect(0, 0, 100, 100), SE: 50, SW: 50, NW: 50, NE: 50}.Add(o)
169
170 a := f32.Affine2D{}.Shear(f32.Point{}, math.Pi/4, 0)
171 op.Affine(a).Add(o)
172 clip.RRect{Rect: f32.Rect(0, 0, 50, 40)}.Add(o)
173
174 scale(50.0/512, 50.0/512).Add(o)
175 paint.PaintOp{}.Add(o)
176 }, func(r result) {
177 r.expect(20, 5, transparent)
178 })
179 }
180
181 func TestTransformOrder(t *testing.T) {
182 // check the ordering of operations bot in affine and in gpu stack.
183 run(t, func(o *op.Ops) {
184 a := f32.Affine2D{}.Offset(f32.Pt(64, 64))
185 op.Affine(a).Add(o)
186
187 b := f32.Affine2D{}.Scale(f32.Point{}, f32.Pt(8, 8))
188 op.Affine(b).Add(o)
189
190 c := f32.Affine2D{}.Offset(f32.Pt(-10, -10)).Scale(f32.Point{}, f32.Pt(0.5, 0.5))
191 op.Affine(c).Add(o)
192 paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 20, 20)).Op())
193 }, func(r result) {
194 // centered and with radius 40
195 r.expect(64-41, 64, transparent)
196 r.expect(64-39, 64, colornames.Red)
197 r.expect(64+39, 64, colornames.Red)
198 r.expect(64+41, 64, transparent)
199 })
200 }
201