blob: 65381f72f658e756d7ca0f46b33b67816417b53c [file] [log] [blame]
Colin Cross7bb052a2015-02-03 12:59:37 -08001// Copyright 2011 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package draw
6
7import (
8 "image"
9 "testing"
10)
11
12type clipTest struct {
13 desc string
14 r, dr, sr, mr image.Rectangle
15 sp, mp image.Point
16 nilMask bool
17 r0 image.Rectangle
18 sp0, mp0 image.Point
19}
20
21var clipTests = []clipTest{
22 // The following tests all have a nil mask.
23 {
24 "basic",
25 image.Rect(0, 0, 100, 100),
26 image.Rect(0, 0, 100, 100),
27 image.Rect(0, 0, 100, 100),
28 image.ZR,
29 image.ZP,
30 image.ZP,
31 true,
32 image.Rect(0, 0, 100, 100),
33 image.ZP,
34 image.ZP,
35 },
36 {
37 "clip dr",
38 image.Rect(0, 0, 100, 100),
39 image.Rect(40, 40, 60, 60),
40 image.Rect(0, 0, 100, 100),
41 image.ZR,
42 image.ZP,
43 image.ZP,
44 true,
45 image.Rect(40, 40, 60, 60),
46 image.Pt(40, 40),
47 image.ZP,
48 },
49 {
50 "clip sr",
51 image.Rect(0, 0, 100, 100),
52 image.Rect(0, 0, 100, 100),
53 image.Rect(20, 20, 80, 80),
54 image.ZR,
55 image.ZP,
56 image.ZP,
57 true,
58 image.Rect(20, 20, 80, 80),
59 image.Pt(20, 20),
60 image.ZP,
61 },
62 {
63 "clip dr and sr",
64 image.Rect(0, 0, 100, 100),
65 image.Rect(0, 0, 50, 100),
66 image.Rect(20, 20, 80, 80),
67 image.ZR,
68 image.ZP,
69 image.ZP,
70 true,
71 image.Rect(20, 20, 50, 80),
72 image.Pt(20, 20),
73 image.ZP,
74 },
75 {
76 "clip dr and sr, sp outside sr (top-left)",
77 image.Rect(0, 0, 100, 100),
78 image.Rect(0, 0, 50, 100),
79 image.Rect(20, 20, 80, 80),
80 image.ZR,
81 image.Pt(15, 8),
82 image.ZP,
83 true,
84 image.Rect(5, 12, 50, 72),
85 image.Pt(20, 20),
86 image.ZP,
87 },
88 {
89 "clip dr and sr, sp outside sr (middle-left)",
90 image.Rect(0, 0, 100, 100),
91 image.Rect(0, 0, 50, 100),
92 image.Rect(20, 20, 80, 80),
93 image.ZR,
94 image.Pt(15, 66),
95 image.ZP,
96 true,
97 image.Rect(5, 0, 50, 14),
98 image.Pt(20, 66),
99 image.ZP,
100 },
101 {
102 "clip dr and sr, sp outside sr (bottom-left)",
103 image.Rect(0, 0, 100, 100),
104 image.Rect(0, 0, 50, 100),
105 image.Rect(20, 20, 80, 80),
106 image.ZR,
107 image.Pt(15, 91),
108 image.ZP,
109 true,
110 image.ZR,
111 image.Pt(15, 91),
112 image.ZP,
113 },
114 {
115 "clip dr and sr, sp inside sr",
116 image.Rect(0, 0, 100, 100),
117 image.Rect(0, 0, 50, 100),
118 image.Rect(20, 20, 80, 80),
119 image.ZR,
120 image.Pt(44, 33),
121 image.ZP,
122 true,
123 image.Rect(0, 0, 36, 47),
124 image.Pt(44, 33),
125 image.ZP,
126 },
127
128 // The following tests all have a non-nil mask.
129 {
130 "basic mask",
131 image.Rect(0, 0, 80, 80),
132 image.Rect(20, 0, 100, 80),
133 image.Rect(0, 0, 50, 49),
134 image.Rect(0, 0, 46, 47),
135 image.ZP,
136 image.ZP,
137 false,
138 image.Rect(20, 0, 46, 47),
139 image.Pt(20, 0),
140 image.Pt(20, 0),
141 },
142 // TODO(nigeltao): write more tests.
143}
144
145func TestClip(t *testing.T) {
146 dst0 := image.NewRGBA(image.Rect(0, 0, 100, 100))
147 src0 := image.NewRGBA(image.Rect(0, 0, 100, 100))
148 mask0 := image.NewRGBA(image.Rect(0, 0, 100, 100))
149 for _, c := range clipTests {
150 dst := dst0.SubImage(c.dr).(*image.RGBA)
151 src := src0.SubImage(c.sr).(*image.RGBA)
152 var mask image.Image
153 if !c.nilMask {
154 mask = mask0.SubImage(c.mr)
155 }
156 r, sp, mp := c.r, c.sp, c.mp
157 clip(dst, &r, src, &sp, mask, &mp)
158
159 // Check that the actual results equal the expected results.
160 if !c.r0.Eq(r) {
161 t.Errorf("%s: clip rectangle want %v got %v", c.desc, c.r0, r)
162 continue
163 }
164 if !c.sp0.Eq(sp) {
165 t.Errorf("%s: sp want %v got %v", c.desc, c.sp0, sp)
166 continue
167 }
168 if !c.nilMask {
169 if !c.mp0.Eq(mp) {
170 t.Errorf("%s: mp want %v got %v", c.desc, c.mp0, mp)
171 continue
172 }
173 }
174
175 // Check that the clipped rectangle is contained by the dst / src / mask
176 // rectangles, in their respective co-ordinate spaces.
177 if !r.In(c.dr) {
178 t.Errorf("%s: c.dr %v does not contain r %v", c.desc, c.dr, r)
179 }
180 // sr is r translated into src's co-ordinate space.
181 sr := r.Add(c.sp.Sub(c.dr.Min))
182 if !sr.In(c.sr) {
183 t.Errorf("%s: c.sr %v does not contain sr %v", c.desc, c.sr, sr)
184 }
185 if !c.nilMask {
186 // mr is r translated into mask's co-ordinate space.
187 mr := r.Add(c.mp.Sub(c.dr.Min))
188 if !mr.In(c.mr) {
189 t.Errorf("%s: c.mr %v does not contain mr %v", c.desc, c.mr, mr)
190 }
191 }
192 }
193}