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