Home | History | Annotate | Download | only in draw
      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