1 // 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 5 package draw 6 7 import ( 8 "image" 9 "testing" 10 ) 11 12 type 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 21 var 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 { 143 "clip sr and mr", 144 image.Rect(0, 0, 100, 100), 145 image.Rect(0, 0, 100, 100), 146 image.Rect(23, 23, 55, 86), 147 image.Rect(44, 44, 87, 58), 148 image.Pt(10, 10), 149 image.Pt(11, 11), 150 false, 151 image.Rect(33, 33, 45, 47), 152 image.Pt(43, 43), 153 image.Pt(44, 44), 154 }, 155 } 156 157 func TestClip(t *testing.T) { 158 dst0 := image.NewRGBA(image.Rect(0, 0, 100, 100)) 159 src0 := image.NewRGBA(image.Rect(0, 0, 100, 100)) 160 mask0 := image.NewRGBA(image.Rect(0, 0, 100, 100)) 161 for _, c := range clipTests { 162 dst := dst0.SubImage(c.dr).(*image.RGBA) 163 src := src0.SubImage(c.sr).(*image.RGBA) 164 r, sp, mp := c.r, c.sp, c.mp 165 if c.nilMask { 166 clip(dst, &r, src, &sp, nil, nil) 167 } else { 168 clip(dst, &r, src, &sp, mask0.SubImage(c.mr), &mp) 169 } 170 171 // Check that the actual results equal the expected results. 172 if !c.r0.Eq(r) { 173 t.Errorf("%s: clip rectangle want %v got %v", c.desc, c.r0, r) 174 continue 175 } 176 if !c.sp0.Eq(sp) { 177 t.Errorf("%s: sp want %v got %v", c.desc, c.sp0, sp) 178 continue 179 } 180 if !c.nilMask { 181 if !c.mp0.Eq(mp) { 182 t.Errorf("%s: mp want %v got %v", c.desc, c.mp0, mp) 183 continue 184 } 185 } 186 187 // Check that the clipped rectangle is contained by the dst / src / mask 188 // rectangles, in their respective coordinate spaces. 189 if !r.In(c.dr) { 190 t.Errorf("%s: c.dr %v does not contain r %v", c.desc, c.dr, r) 191 } 192 // sr is r translated into src's coordinate space. 193 sr := r.Add(c.sp.Sub(c.dr.Min)) 194 if !sr.In(c.sr) { 195 t.Errorf("%s: c.sr %v does not contain sr %v", c.desc, c.sr, sr) 196 } 197 if !c.nilMask { 198 // mr is r translated into mask's coordinate space. 199 mr := r.Add(c.mp.Sub(c.dr.Min)) 200 if !mr.In(c.mr) { 201 t.Errorf("%s: c.mr %v does not contain mr %v", c.desc, c.mr, mr) 202 } 203 } 204 } 205 } 206