headless: clear background to transparent, not white

The clear background is the most useful, and the old behaviour can
be achieved by filling the entire viewport with a white paint.ColorOp.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-05-03 10:15:19 +02:00
parent 23a839a29d
commit 2c07b2dc0e
52 changed files with 106 additions and 85 deletions
+31 -31
View File
@@ -19,8 +19,8 @@ func TestPaintRect(t *testing.T) {
}, func(r result) {
r.expect(0, 0, colornames.Red)
r.expect(49, 0, colornames.Red)
r.expect(50, 0, colornames.White)
r.expect(10, 50, colornames.White)
r.expect(50, 0, transparent)
r.expect(10, 50, transparent)
})
}
@@ -29,11 +29,11 @@ func TestPaintClippedRect(t *testing.T) {
clip.RRect{Rect: f32.Rect(25, 25, 60, 60)}.Add(o)
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 50, 50)).Op())
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(24, 35, colornames.White)
r.expect(0, 0, transparent)
r.expect(24, 35, transparent)
r.expect(25, 35, colornames.Red)
r.expect(50, 0, colornames.White)
r.expect(10, 50, colornames.White)
r.expect(50, 0, transparent)
r.expect(10, 50, transparent)
})
}
@@ -44,9 +44,9 @@ func TestPaintClippedCircle(t *testing.T) {
clip.Rect(image.Rect(0, 0, 30, 50)).Add(o)
paint.Fill(o, red)
}, func(r result) {
r.expect(21, 21, colornames.White)
r.expect(21, 21, transparent)
r.expect(25, 30, colornames.Red)
r.expect(31, 30, colornames.White)
r.expect(31, 30, transparent)
})
}
@@ -76,9 +76,9 @@ func TestPaintArc(t *testing.T) {
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 128, 128)).Op())
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(0, 25, colornames.Red)
r.expect(0, 15, colornames.White)
r.expect(0, 15, transparent)
})
}
@@ -98,10 +98,10 @@ func TestPaintAbsolute(t *testing.T) {
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 128, 128)).Op())
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(30, 30, colornames.Red)
r.expect(79, 79, colornames.White)
r.expect(90, 90, colornames.White)
r.expect(79, 79, transparent)
r.expect(90, 90, transparent)
})
}
@@ -113,8 +113,8 @@ func TestPaintTexture(t *testing.T) {
}, func(r result) {
r.expect(0, 0, colornames.Blue)
r.expect(79, 10, colornames.Green)
r.expect(80, 0, colornames.White)
r.expect(10, 80, colornames.White)
r.expect(80, 0, transparent)
r.expect(10, 80, transparent)
})
}
@@ -158,7 +158,7 @@ func TestPaintClippedTexture(t *testing.T) {
scale(80.0/512, 80.0/512).Add(o)
paint.PaintOp{}.Add(o)
}, func(r result) {
r.expect(40, 40, colornames.White)
r.expect(40, 40, transparent)
r.expect(25, 35, colornames.Blue)
})
}
@@ -177,7 +177,7 @@ func TestStrokedPathBevelFlat(t *testing.T) {
paint.Fill(o, red)
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(10, 50, colornames.Red)
})
}
@@ -196,7 +196,7 @@ func TestStrokedPathBevelRound(t *testing.T) {
paint.Fill(o, red)
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(10, 50, colornames.Red)
})
}
@@ -215,7 +215,7 @@ func TestStrokedPathBevelSquare(t *testing.T) {
paint.Fill(o, red)
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(10, 50, colornames.Red)
})
}
@@ -234,7 +234,7 @@ func TestStrokedPathRoundRound(t *testing.T) {
paint.Fill(o, red)
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(10, 50, colornames.Red)
})
}
@@ -272,7 +272,7 @@ func TestStrokedPathFlatMiter(t *testing.T) {
}
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(40, 10, colornames.Black)
r.expect(40, 12, colornames.Red)
})
@@ -311,7 +311,7 @@ func TestStrokedPathFlatMiterInf(t *testing.T) {
}
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(40, 10, colornames.Black)
r.expect(40, 12, colornames.Red)
})
@@ -353,10 +353,10 @@ func TestStrokedPathZeroWidth(t *testing.T) {
}
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(10, 50, colornames.Black)
r.expect(30, 50, colornames.Black)
r.expect(65, 50, colornames.White)
r.expect(65, 50, transparent)
})
}
@@ -406,7 +406,7 @@ func TestDashedPathFlatCapEllipse(t *testing.T) {
}
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(0, 62, colornames.Red)
r.expect(0, 65, colornames.Black)
})
@@ -451,10 +451,10 @@ func TestDashedPathFlatCapZ(t *testing.T) {
stk.Load()
}
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(40, 10, colornames.Black)
r.expect(40, 12, colornames.Red)
r.expect(46, 12, colornames.White)
r.expect(46, 12, transparent)
})
}
@@ -494,7 +494,7 @@ func TestDashedPathFlatCapZNoDash(t *testing.T) {
stk.Load()
}
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(40, 10, colornames.Black)
r.expect(40, 12, colornames.Red)
r.expect(46, 12, colornames.Red)
@@ -536,10 +536,10 @@ func TestDashedPathFlatCapZNoPath(t *testing.T) {
stk.Load()
}
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(40, 10, colornames.Black)
r.expect(40, 12, colornames.White)
r.expect(46, 12, colornames.White)
r.expect(40, 12, transparent)
r.expect(46, 12, transparent)
})
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 929 B

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 546 B

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 765 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 375 B

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 B

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 463 B

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 920 B

After

Width:  |  Height:  |  Size: 651 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 571 B

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 B

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 B

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 511 B

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 B

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 B

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 864 B

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 732 B

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 732 B

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 375 B

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 B

After

Width:  |  Height:  |  Size: 252 B

+11 -11
View File
@@ -56,7 +56,7 @@ func TestTransformMacro(t *testing.T) {
}, func(r result) {
r.expect(5, 15, colornames.Red)
r.expect(15, 15, colornames.Black)
r.expect(11, 51, colornames.White)
r.expect(11, 51, transparent)
})
}
@@ -80,7 +80,7 @@ func TestRepeatedPaintsZ(t *testing.T) {
}, func(r result) {
r.expect(5, 5, colornames.Red)
r.expect(11, 15, colornames.Black)
r.expect(11, 51, colornames.White)
r.expect(11, 51, transparent)
})
}
@@ -99,7 +99,7 @@ func TestNoClipFromPaint(t *testing.T) {
r.expect(1, 1, colornames.Black)
r.expect(20, 20, colornames.Black)
r.expect(49, 49, colornames.Black)
r.expect(51, 51, colornames.White)
r.expect(51, 51, transparent)
})
}
@@ -197,16 +197,16 @@ func TestBuildOffscreen(t *testing.T) {
func(ops *op.Ops) {
draw(-100, ops)
}, func(r result) {
r.expect(5, 5, colornames.White)
r.expect(20, 20, colornames.White)
r.expect(5, 5, transparent)
r.expect(20, 20, transparent)
}),
frame(
func(ops *op.Ops) {
draw(0, ops)
}, func(r result) {
r.expect(2, 2, colornames.White)
r.expect(2, 2, transparent)
r.expect(20, 20, colornames.Black)
r.expect(38, 38, colornames.White)
r.expect(38, 38, transparent)
}))
}
@@ -216,10 +216,10 @@ func TestNegativeOverlaps(t *testing.T) {
clip.Rect(image.Rect(0, 120, 100, 122)).Add(ops)
paint.PaintOp{}.Add(ops)
}, func(r result) {
r.expect(60, 60, colornames.White)
r.expect(60, 110, colornames.White)
r.expect(60, 120, colornames.White)
r.expect(60, 122, colornames.White)
r.expect(60, 60, transparent)
r.expect(60, 110, transparent)
r.expect(60, 120, transparent)
r.expect(60, 122, transparent)
})
}
+23 -23
View File
@@ -18,10 +18,10 @@ func TestPaintOffset(t *testing.T) {
op.Offset(f32.Pt(10, 20)).Add(o)
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 50, 50)).Op())
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(59, 30, colornames.Red)
r.expect(60, 30, colornames.White)
r.expect(10, 70, colornames.White)
r.expect(60, 30, transparent)
r.expect(10, 70, transparent)
})
}
@@ -33,8 +33,8 @@ func TestPaintRotate(t *testing.T) {
}, func(r result) {
r.expect(40, 40, colornames.Red)
r.expect(50, 19, colornames.Red)
r.expect(59, 19, colornames.White)
r.expect(21, 21, colornames.White)
r.expect(59, 19, transparent)
r.expect(21, 21, transparent)
})
}
@@ -44,7 +44,7 @@ func TestPaintShear(t *testing.T) {
op.Affine(a).Add(o)
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 40, 40)).Op())
}, func(r result) {
r.expect(10, 30, colornames.White)
r.expect(10, 30, transparent)
})
}
@@ -54,10 +54,10 @@ func TestClipPaintOffset(t *testing.T) {
op.Offset(f32.Pt(20, 20)).Add(o)
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 100, 100)).Op())
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(19, 19, colornames.White)
r.expect(0, 0, transparent)
r.expect(19, 19, transparent)
r.expect(20, 20, colornames.Red)
r.expect(30, 30, colornames.White)
r.expect(30, 30, transparent)
})
}
@@ -67,11 +67,11 @@ func TestClipOffset(t *testing.T) {
clip.RRect{Rect: f32.Rect(10, 10, 30, 30)}.Add(o)
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 100, 100)).Op())
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(29, 29, colornames.White)
r.expect(0, 0, transparent)
r.expect(29, 29, transparent)
r.expect(30, 30, colornames.Red)
r.expect(49, 49, colornames.Red)
r.expect(50, 50, colornames.White)
r.expect(50, 50, transparent)
})
}
@@ -82,10 +82,10 @@ func TestClipScale(t *testing.T) {
clip.RRect{Rect: f32.Rect(10, 10, 20, 20)}.Add(o)
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 1000, 1000)).Op())
}, func(r result) {
r.expect(19+10, 19+10, colornames.White)
r.expect(19+10, 19+10, transparent)
r.expect(20+10, 20+10, colornames.Red)
r.expect(39+10, 39+10, colornames.Red)
r.expect(40+10, 40+10, colornames.White)
r.expect(40+10, 40+10, transparent)
})
}
@@ -95,9 +95,9 @@ func TestClipRotate(t *testing.T) {
clip.RRect{Rect: f32.Rect(30, 30, 50, 50)}.Add(o)
paint.FillShape(o, red, clip.Rect(image.Rect(0, 40, 100, 100)).Op())
}, func(r result) {
r.expect(39, 39, colornames.White)
r.expect(39, 39, transparent)
r.expect(41, 41, colornames.Red)
r.expect(50, 50, colornames.White)
r.expect(50, 50, transparent)
})
}
@@ -108,8 +108,8 @@ func TestOffsetTexture(t *testing.T) {
scale(50.0/512, 50.0/512).Add(o)
paint.PaintOp{}.Add(o)
}, func(r result) {
r.expect(14, 20, colornames.White)
r.expect(66, 20, colornames.White)
r.expect(14, 20, transparent)
r.expect(66, 20, transparent)
r.expect(16, 64, colornames.Green)
r.expect(64, 16, colornames.Green)
})
@@ -124,7 +124,7 @@ func TestOffsetScaleTexture(t *testing.T) {
paint.PaintOp{}.Add(o)
}, func(r result) {
r.expect(114, 64, colornames.Blue)
r.expect(116, 64, colornames.White)
r.expect(116, 64, transparent)
})
}
@@ -152,7 +152,7 @@ func TestRotateClipTexture(t *testing.T) {
scale(60.0/512, 60.0/512).Add(o)
paint.PaintOp{}.Add(o)
}, func(r result) {
r.expect(0, 0, colornames.White)
r.expect(0, 0, transparent)
r.expect(37, 39, colornames.Green)
r.expect(36, 39, colornames.Green)
r.expect(35, 39, colornames.Green)
@@ -174,7 +174,7 @@ func TestComplicatedTransform(t *testing.T) {
scale(50.0/512, 50.0/512).Add(o)
paint.PaintOp{}.Add(o)
}, func(r result) {
r.expect(20, 5, colornames.White)
r.expect(20, 5, transparent)
})
}
@@ -192,9 +192,9 @@ func TestTransformOrder(t *testing.T) {
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 20, 20)).Op())
}, func(r result) {
// centered and with radius 40
r.expect(64-41, 64, colornames.White)
r.expect(64-41, 64, transparent)
r.expect(64-39, 64, colornames.Red)
r.expect(64+39, 64, colornames.Red)
r.expect(64+41, 64, colornames.White)
r.expect(64+41, 64, transparent)
})
}
+39 -18
View File
@@ -31,12 +31,13 @@ var (
)
var (
red = f32color.RGBAToNRGBA(colornames.Red)
green = f32color.RGBAToNRGBA(colornames.Green)
blue = f32color.RGBAToNRGBA(colornames.Blue)
magenta = f32color.RGBAToNRGBA(colornames.Magenta)
black = f32color.RGBAToNRGBA(colornames.Black)
white = f32color.RGBAToNRGBA(colornames.White)
red = f32color.RGBAToNRGBA(colornames.Red)
green = f32color.RGBAToNRGBA(colornames.Green)
blue = f32color.RGBAToNRGBA(colornames.Blue)
magenta = f32color.RGBAToNRGBA(colornames.Magenta)
black = f32color.RGBAToNRGBA(colornames.Black)
white = f32color.RGBAToNRGBA(colornames.White)
transparent = color.RGBA{}
)
func init() {
@@ -163,21 +164,32 @@ func verifyRef(t *testing.T, img *image.RGBA, frame int) (ok bool) {
t.Error("could not decode ref:", err)
return
}
ref, ok := r.(*image.RGBA)
if !ok {
t.Errorf("image is a %T, expected *image.RGBA", r)
return
}
if len(ref.Pix) != len(img.Pix) {
t.Error("not equal to ref (len)")
if img.Bounds() != r.Bounds() {
t.Errorf("reference image is %v, expected %v", r.Bounds(), img.Bounds())
return false
}
var ref *image.RGBA
switch r := r.(type) {
case *image.RGBA:
ref = r
case *image.NRGBA:
ref = image.NewRGBA(r.Bounds())
bnd := r.Bounds()
for x := bnd.Min.X; x < bnd.Max.X; x++ {
for y := bnd.Min.Y; y < bnd.Max.Y; y++ {
ref.SetRGBA(x, y, f32color.NRGBAToRGBA(r.NRGBAAt(x, y)))
}
}
default:
t.Fatalf("reference image is a %T, expected *image.NRGBA or *image.RGBA", r)
}
bnd := img.Bounds()
for x := bnd.Min.X; x < bnd.Max.X; x++ {
for y := bnd.Min.Y; y < bnd.Max.Y; y++ {
c1, c2 := ref.RGBAAt(x, y), img.RGBAAt(x, y)
if !colorsClose(c1, c2) {
t.Error("not equal to ref at", x, y, " ", c1, c2)
exp := ref.RGBAAt(x, y)
got := img.RGBAAt(x, y)
if !colorsClose(exp, got) {
t.Error("not equal to ref at", x, y, " ", got, exp)
return false
}
}
@@ -230,6 +242,7 @@ func yiqEqApprox(c1, c2 color.RGBA, d2 float64) bool {
}
func (r result) expect(x, y int, col color.RGBA) {
r.t.Helper()
if r.img == nil {
return
}
@@ -244,9 +257,17 @@ type result struct {
img *image.RGBA
}
func saveImage(file string, img image.Image) error {
func saveImage(file string, img *image.RGBA) error {
// Only NRGBA images are losslessly encoded by png.Encode.
nrgba := image.NewNRGBA(img.Bounds())
bnd := img.Bounds()
for x := bnd.Min.X; x < bnd.Max.X; x++ {
for y := bnd.Min.Y; y < bnd.Max.Y; y++ {
nrgba.SetNRGBA(x, y, f32color.RGBAToNRGBA(img.RGBAAt(x, y)))
}
}
var buf bytes.Buffer
if err := png.Encode(&buf, img); err != nil {
if err := png.Encode(&buf, nrgba); err != nil {
return err
}
return ioutil.WriteFile(file, buf.Bytes(), 0666)