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