vector: allow dst and mask to have different strides.
Change-Id: If244dba2c681b11122a7a26b352f9411135f123f Reviewed-on: https://go-review.googlesource.com/29696 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
b077ed42b3
commit
7ea36498ac
|
@ -240,17 +240,45 @@ func (z *Rasterizer) Draw(dst draw.Image, r image.Rectangle, src image.Image, sp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if z.DrawOp == draw.Over {
|
||||||
|
z.rasterizeOpOver(dst, r, src, sp)
|
||||||
|
} else {
|
||||||
|
z.rasterizeOpSrc(dst, r, src, sp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (z *Rasterizer) accumulateMask() {
|
||||||
if n := z.size.X * z.size.Y; n > cap(z.bufU32) {
|
if n := z.size.X * z.size.Y; n > cap(z.bufU32) {
|
||||||
z.bufU32 = make([]uint32, n)
|
z.bufU32 = make([]uint32, n)
|
||||||
} else {
|
} else {
|
||||||
z.bufU32 = z.bufU32[:n]
|
z.bufU32 = z.bufU32[:n]
|
||||||
}
|
}
|
||||||
floatingAccumulateMask(z.bufU32, z.bufF32)
|
floatingAccumulateMask(z.bufU32, z.bufF32)
|
||||||
|
}
|
||||||
|
|
||||||
if z.DrawOp == draw.Over {
|
func (z *Rasterizer) rasterizeDstAlphaSrcOpaqueOpOver(dst *image.Alpha, r image.Rectangle) {
|
||||||
z.rasterizeOpOver(dst, r, src, sp)
|
// TODO: add SIMD implementations.
|
||||||
} else {
|
// TODO: add a fixed point math implementation.
|
||||||
z.rasterizeOpSrc(dst, r, src, sp)
|
// TODO: non-zero vs even-odd winding?
|
||||||
|
if r == dst.Bounds() && r == z.Bounds() {
|
||||||
|
// We bypass the z.accumulateMask step and convert straight from
|
||||||
|
// z.bufF32 to dst.Pix.
|
||||||
|
floatingAccumulateOpOver(dst.Pix, z.bufF32)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
z.accumulateMask()
|
||||||
|
pix := dst.Pix[dst.PixOffset(r.Min.X, r.Min.Y):]
|
||||||
|
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
|
||||||
|
for x, x1 := 0, r.Max.X-r.Min.X; x < x1; x++ {
|
||||||
|
ma := z.bufU32[y*z.size.X+x]
|
||||||
|
i := y*dst.Stride + x
|
||||||
|
|
||||||
|
// This formula is like rasterizeOpOver's, simplified for the
|
||||||
|
// concrete dst type and opaque src assumption.
|
||||||
|
a := 0xffff - ma
|
||||||
|
pix[i] = uint8((uint32(pix[i])*0x101*a/0xffff + ma) >> 8)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,24 +287,27 @@ func (z *Rasterizer) rasterizeDstAlphaSrcOpaqueOpSrc(dst *image.Alpha, r image.R
|
||||||
// TODO: add a fixed point math implementation.
|
// TODO: add a fixed point math implementation.
|
||||||
// TODO: non-zero vs even-odd winding?
|
// TODO: non-zero vs even-odd winding?
|
||||||
if r == dst.Bounds() && r == z.Bounds() {
|
if r == dst.Bounds() && r == z.Bounds() {
|
||||||
|
// We bypass the z.accumulateMask step and convert straight from
|
||||||
|
// z.bufF32 to dst.Pix.
|
||||||
floatingAccumulateOpSrc(dst.Pix, z.bufF32)
|
floatingAccumulateOpSrc(dst.Pix, z.bufF32)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
println("TODO: the general case")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (z *Rasterizer) rasterizeDstAlphaSrcOpaqueOpOver(dst *image.Alpha, r image.Rectangle) {
|
z.accumulateMask()
|
||||||
// TODO: add SIMD implementations.
|
pix := dst.Pix[dst.PixOffset(r.Min.X, r.Min.Y):]
|
||||||
// TODO: add a fixed point math implementation.
|
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
|
||||||
// TODO: non-zero vs even-odd winding?
|
for x, x1 := 0, r.Max.X-r.Min.X; x < x1; x++ {
|
||||||
if r == dst.Bounds() && r == z.Bounds() {
|
ma := z.bufU32[y*z.size.X+x]
|
||||||
floatingAccumulateOpOver(dst.Pix, z.bufF32)
|
|
||||||
return
|
// This formula is like rasterizeOpSrc's, simplified for the
|
||||||
|
// concrete dst type and opaque src assumption.
|
||||||
|
pix[y*dst.Stride+x] = uint8(ma >> 8)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
println("TODO: the general case")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (z *Rasterizer) rasterizeOpOver(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
|
func (z *Rasterizer) rasterizeOpOver(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
|
||||||
|
z.accumulateMask()
|
||||||
out := color.RGBA64{}
|
out := color.RGBA64{}
|
||||||
outc := color.Color(&out)
|
outc := color.Color(&out)
|
||||||
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
|
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
|
||||||
|
@ -299,6 +330,7 @@ func (z *Rasterizer) rasterizeOpOver(dst draw.Image, r image.Rectangle, src imag
|
||||||
}
|
}
|
||||||
|
|
||||||
func (z *Rasterizer) rasterizeOpSrc(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
|
func (z *Rasterizer) rasterizeOpSrc(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
|
||||||
|
z.accumulateMask()
|
||||||
out := color.RGBA64{}
|
out := color.RGBA64{}
|
||||||
outc := color.Color(&out)
|
outc := color.Color(&out)
|
||||||
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
|
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
|
||||||
|
|
|
@ -7,6 +7,7 @@ package vector
|
||||||
// TODO: add tests for NaN and Inf coordinates.
|
// TODO: add tests for NaN and Inf coordinates.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"image/draw"
|
"image/draw"
|
||||||
|
@ -51,111 +52,127 @@ var basicMask = []byte{
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
||||||
func basicRasterizer() *Rasterizer {
|
func testBasicPath(t *testing.T, prefix string, dst draw.Image, src image.Image, op draw.Op, want []byte) {
|
||||||
z := NewRasterizer(16, 16)
|
z := NewRasterizer(16, 16)
|
||||||
z.MoveTo(f32.Vec2{2, 2})
|
z.MoveTo(f32.Vec2{2, 2})
|
||||||
z.LineTo(f32.Vec2{8, 2})
|
z.LineTo(f32.Vec2{8, 2})
|
||||||
z.QuadTo(f32.Vec2{14, 2}, f32.Vec2{14, 14})
|
z.QuadTo(f32.Vec2{14, 2}, f32.Vec2{14, 14})
|
||||||
z.CubeTo(f32.Vec2{8, 2}, f32.Vec2{5, 20}, f32.Vec2{2, 8})
|
z.CubeTo(f32.Vec2{8, 2}, f32.Vec2{5, 20}, f32.Vec2{2, 8})
|
||||||
z.ClosePath()
|
z.ClosePath()
|
||||||
return z
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBasicPathDstAlpha(t *testing.T) {
|
|
||||||
for _, background := range []uint8{0x00, 0x80} {
|
|
||||||
for _, op := range []draw.Op{draw.Over, draw.Src} {
|
|
||||||
z := basicRasterizer()
|
|
||||||
dst := image.NewAlpha(z.Bounds())
|
|
||||||
for i := range dst.Pix {
|
|
||||||
dst.Pix[i] = background
|
|
||||||
}
|
|
||||||
z.DrawOp = op
|
z.DrawOp = op
|
||||||
z.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
|
z.Draw(dst, z.Bounds(), src, image.Point{})
|
||||||
got := dst.Pix
|
|
||||||
|
|
||||||
want := make([]byte, len(basicMask))
|
var got []byte
|
||||||
if op == draw.Over && background == 0x80 {
|
switch dst := dst.(type) {
|
||||||
for i, ma := range basicMask {
|
case *image.Alpha:
|
||||||
want[i] = 0xff - (0xff-ma)/2
|
got = dst.Pix
|
||||||
}
|
case *image.RGBA:
|
||||||
} else {
|
got = dst.Pix
|
||||||
copy(want, basicMask)
|
default:
|
||||||
|
t.Errorf("%s: unrecognized dst image type %T", prefix, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(got) != len(want) {
|
if len(got) != len(want) {
|
||||||
t.Errorf("background=%#02x, op=%v: len(got)=%d and len(want)=%d differ",
|
t.Errorf("%s: len(got)=%d and len(want)=%d differ", prefix, len(got), len(want))
|
||||||
background, op, len(got), len(want))
|
return
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
for i := range got {
|
for i := range got {
|
||||||
delta := int(got[i]) - int(want[i])
|
delta := int(got[i]) - int(want[i])
|
||||||
// The +/- 2 allows different implementations to give different
|
// The +/- 2 allows different implementations to give different
|
||||||
// rounding errors.
|
// rounding errors.
|
||||||
if delta < -2 || +2 < delta {
|
if delta < -2 || +2 < delta {
|
||||||
t.Errorf("background=%#02x, op=%v: i=%d: got %#02x, want %#02x",
|
t.Errorf("%s: i=%d: got %#02x, want %#02x", prefix, i, got[i], want[i])
|
||||||
background, op, i, got[i], want[i])
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBasicPathDstAlpha(t *testing.T) {
|
||||||
|
for _, background := range []uint8{0x00, 0x80} {
|
||||||
|
for _, op := range []draw.Op{draw.Over, draw.Src} {
|
||||||
|
for _, xPadding := range []int{0, 7} {
|
||||||
|
bounds := image.Rect(0, 0, 16+xPadding, 16)
|
||||||
|
dst := image.NewAlpha(bounds)
|
||||||
|
for i := range dst.Pix {
|
||||||
|
dst.Pix[i] = background
|
||||||
|
}
|
||||||
|
|
||||||
|
want := make([]byte, len(dst.Pix))
|
||||||
|
copy(want, dst.Pix)
|
||||||
|
|
||||||
|
if op == draw.Over && background == 0x80 {
|
||||||
|
for y := 0; y < 16; y++ {
|
||||||
|
for x := 0; x < 16; x++ {
|
||||||
|
ma := basicMask[16*y+x]
|
||||||
|
i := dst.PixOffset(x, y)
|
||||||
|
want[i] = 0xff - (0xff-ma)/2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for y := 0; y < 16; y++ {
|
||||||
|
for x := 0; x < 16; x++ {
|
||||||
|
ma := basicMask[16*y+x]
|
||||||
|
i := dst.PixOffset(x, y)
|
||||||
|
want[i] = ma
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix := fmt.Sprintf("background=%#02x, op=%v, xPadding=%d", background, op, xPadding)
|
||||||
|
testBasicPath(t, prefix, dst, image.Opaque, op, want)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBasicPathDstRGBA(t *testing.T) {
|
func TestBasicPathDstRGBA(t *testing.T) {
|
||||||
blue := color.RGBA{0x00, 0x00, 0xff, 0xff}
|
blue := image.NewUniform(color.RGBA{0x00, 0x00, 0xff, 0xff})
|
||||||
|
|
||||||
for _, op := range []draw.Op{draw.Over, draw.Src} {
|
for _, op := range []draw.Op{draw.Over, draw.Src} {
|
||||||
z := basicRasterizer()
|
for _, xPadding := range []int{0, 7} {
|
||||||
dst := image.NewRGBA(z.Bounds())
|
bounds := image.Rect(0, 0, 16+xPadding, 16)
|
||||||
for y := 0; y < 16; y++ {
|
dst := image.NewRGBA(bounds)
|
||||||
for x := 0; x < 16; x++ {
|
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
|
||||||
|
for x := bounds.Min.X; x < bounds.Max.X; x++ {
|
||||||
dst.SetRGBA(x, y, color.RGBA{
|
dst.SetRGBA(x, y, color.RGBA{
|
||||||
R: uint8(y*0x11) / 2,
|
R: uint8(y * 0x07),
|
||||||
G: uint8(x*0x11) / 2,
|
G: uint8(x * 0x05),
|
||||||
B: 0x00,
|
B: 0x00,
|
||||||
A: 0x80,
|
A: 0x80,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
z.DrawOp = op
|
|
||||||
z.Draw(dst, dst.Bounds(), image.NewUniform(blue), image.Point{})
|
|
||||||
got := dst.Pix
|
|
||||||
|
|
||||||
want := make([]byte, len(basicMask)*4)
|
want := make([]byte, len(dst.Pix))
|
||||||
|
copy(want, dst.Pix)
|
||||||
|
|
||||||
if op == draw.Over {
|
if op == draw.Over {
|
||||||
for y := 0; y < 16; y++ {
|
for y := 0; y < 16; y++ {
|
||||||
for x := 0; x < 16; x++ {
|
for x := 0; x < 16; x++ {
|
||||||
i := 16*y + x
|
ma := basicMask[16*y+x]
|
||||||
ma := basicMask[i]
|
i := dst.PixOffset(x, y)
|
||||||
want[4*i+0] = uint8((uint32(0xff-ma) * uint32(y*0x11/2)) / 0xff)
|
want[i+0] = uint8((uint32(0xff-ma) * uint32(y*0x07)) / 0xff)
|
||||||
want[4*i+1] = uint8((uint32(0xff-ma) * uint32(x*0x11/2)) / 0xff)
|
want[i+1] = uint8((uint32(0xff-ma) * uint32(x*0x05)) / 0xff)
|
||||||
want[4*i+2] = ma
|
want[i+2] = ma
|
||||||
want[4*i+3] = ma/2 + 0x80
|
want[i+3] = ma/2 + 0x80
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for y := 0; y < 16; y++ {
|
for y := 0; y < 16; y++ {
|
||||||
for x := 0; x < 16; x++ {
|
for x := 0; x < 16; x++ {
|
||||||
i := 16*y + x
|
ma := basicMask[16*y+x]
|
||||||
ma := basicMask[i]
|
i := dst.PixOffset(x, y)
|
||||||
want[4*i+0] = 0x00
|
want[i+0] = 0x00
|
||||||
want[4*i+1] = 0x00
|
want[i+1] = 0x00
|
||||||
want[4*i+2] = ma
|
want[i+2] = ma
|
||||||
want[4*i+3] = ma
|
want[i+3] = ma
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(got) != len(want) {
|
prefix := fmt.Sprintf("op=%v, xPadding=%d", op, xPadding)
|
||||||
t.Errorf("op=%v: len(got)=%d and len(want)=%d differ", op, len(got), len(want))
|
testBasicPath(t, prefix, dst, blue, op, want)
|
||||||
continue
|
|
||||||
}
|
|
||||||
for i := range got {
|
|
||||||
delta := int(got[i]) - int(want[i])
|
|
||||||
// The +/- 2 allows different implementations to give different
|
|
||||||
// rounding errors.
|
|
||||||
if delta < -2 || +2 < delta {
|
|
||||||
t.Errorf("op=%v: i=%d: got %#02x, want %#02x", op, i, got[i], want[i])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,7 +228,7 @@ var benchmarkGlyphData = []struct {
|
||||||
// Note that, compared to the github.com/google/font-go prototype, the height
|
// Note that, compared to the github.com/google/font-go prototype, the height
|
||||||
// here is the height of the bounding box, not the pixels per em used to scale
|
// here is the height of the bounding box, not the pixels per em used to scale
|
||||||
// a glyph's vectors. A height of 64 corresponds to a ppem greater than 64.
|
// a glyph's vectors. A height of 64 corresponds to a ppem greater than 64.
|
||||||
func benchGlyph(b *testing.B, cm color.Model, height int, op draw.Op) {
|
func benchGlyph(b *testing.B, colorModel byte, loose bool, height int, op draw.Op) {
|
||||||
scale := float32(height) / benchmarkGlyphHeight
|
scale := float32(height) / benchmarkGlyphHeight
|
||||||
|
|
||||||
// Clone the benchmarkGlyphData slice and scale its coordinates.
|
// Clone the benchmarkGlyphData slice and scale its coordinates.
|
||||||
|
@ -226,20 +243,25 @@ func benchGlyph(b *testing.B, cm color.Model, height int, op draw.Op) {
|
||||||
width := int(math.Ceil(float64(benchmarkGlyphWidth * scale)))
|
width := int(math.Ceil(float64(benchmarkGlyphWidth * scale)))
|
||||||
z := NewRasterizer(width, height)
|
z := NewRasterizer(width, height)
|
||||||
|
|
||||||
|
bounds := z.Bounds()
|
||||||
|
if loose {
|
||||||
|
bounds.Max.X++
|
||||||
|
}
|
||||||
dst, src := draw.Image(nil), image.Image(nil)
|
dst, src := draw.Image(nil), image.Image(nil)
|
||||||
switch cm {
|
switch colorModel {
|
||||||
case color.AlphaModel:
|
case 'A':
|
||||||
dst = image.NewAlpha(z.Bounds())
|
dst = image.NewAlpha(bounds)
|
||||||
src = image.Opaque
|
src = image.Opaque
|
||||||
case color.NRGBAModel:
|
case 'N':
|
||||||
dst = image.NewNRGBA(z.Bounds())
|
dst = image.NewNRGBA(bounds)
|
||||||
src = image.NewUniform(color.NRGBA{0x40, 0x80, 0xc0, 0xff})
|
src = image.NewUniform(color.NRGBA{0x40, 0x80, 0xc0, 0xff})
|
||||||
case color.RGBAModel:
|
case 'R':
|
||||||
dst = image.NewRGBA(z.Bounds())
|
dst = image.NewRGBA(bounds)
|
||||||
src = image.NewUniform(color.RGBA{0x40, 0x80, 0xc0, 0xff})
|
src = image.NewUniform(color.RGBA{0x40, 0x80, 0xc0, 0xff})
|
||||||
default:
|
default:
|
||||||
b.Fatal("unsupported color model")
|
b.Fatal("unsupported color model")
|
||||||
}
|
}
|
||||||
|
bounds = z.Bounds()
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
|
@ -255,39 +277,50 @@ func benchGlyph(b *testing.B, cm color.Model, height int, op draw.Op) {
|
||||||
z.QuadTo(d.p, d.q)
|
z.QuadTo(d.p, d.q)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
z.Draw(dst, dst.Bounds(), src, image.Point{})
|
z.Draw(dst, bounds, src, image.Point{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkGlyphAlpha16Over(b *testing.B) { benchGlyph(b, color.AlphaModel, 16, draw.Over) }
|
func BenchmarkGlyphAlpha16Over(b *testing.B) { benchGlyph(b, 'A', false, 16, draw.Over) }
|
||||||
func BenchmarkGlyphAlpha16Src(b *testing.B) { benchGlyph(b, color.AlphaModel, 16, draw.Src) }
|
func BenchmarkGlyphAlpha16Src(b *testing.B) { benchGlyph(b, 'A', false, 16, draw.Src) }
|
||||||
func BenchmarkGlyphAlpha32Over(b *testing.B) { benchGlyph(b, color.AlphaModel, 32, draw.Over) }
|
func BenchmarkGlyphAlpha32Over(b *testing.B) { benchGlyph(b, 'A', false, 32, draw.Over) }
|
||||||
func BenchmarkGlyphAlpha32Src(b *testing.B) { benchGlyph(b, color.AlphaModel, 32, draw.Src) }
|
func BenchmarkGlyphAlpha32Src(b *testing.B) { benchGlyph(b, 'A', false, 32, draw.Src) }
|
||||||
func BenchmarkGlyphAlpha64Over(b *testing.B) { benchGlyph(b, color.AlphaModel, 64, draw.Over) }
|
func BenchmarkGlyphAlpha64Over(b *testing.B) { benchGlyph(b, 'A', false, 64, draw.Over) }
|
||||||
func BenchmarkGlyphAlpha64Src(b *testing.B) { benchGlyph(b, color.AlphaModel, 64, draw.Src) }
|
func BenchmarkGlyphAlpha64Src(b *testing.B) { benchGlyph(b, 'A', false, 64, draw.Src) }
|
||||||
func BenchmarkGlyphAlpha128Over(b *testing.B) { benchGlyph(b, color.AlphaModel, 128, draw.Over) }
|
func BenchmarkGlyphAlpha128Over(b *testing.B) { benchGlyph(b, 'A', false, 128, draw.Over) }
|
||||||
func BenchmarkGlyphAlpha128Src(b *testing.B) { benchGlyph(b, color.AlphaModel, 128, draw.Src) }
|
func BenchmarkGlyphAlpha128Src(b *testing.B) { benchGlyph(b, 'A', false, 128, draw.Src) }
|
||||||
func BenchmarkGlyphAlpha256Over(b *testing.B) { benchGlyph(b, color.AlphaModel, 256, draw.Over) }
|
func BenchmarkGlyphAlpha256Over(b *testing.B) { benchGlyph(b, 'A', false, 256, draw.Over) }
|
||||||
func BenchmarkGlyphAlpha256Src(b *testing.B) { benchGlyph(b, color.AlphaModel, 256, draw.Src) }
|
func BenchmarkGlyphAlpha256Src(b *testing.B) { benchGlyph(b, 'A', false, 256, draw.Src) }
|
||||||
|
|
||||||
func BenchmarkGlyphNRGBA16Over(b *testing.B) { benchGlyph(b, color.NRGBAModel, 16, draw.Over) }
|
func BenchmarkGlyphAlphaLoose16Over(b *testing.B) { benchGlyph(b, 'A', true, 16, draw.Over) }
|
||||||
func BenchmarkGlyphNRGBA16Src(b *testing.B) { benchGlyph(b, color.NRGBAModel, 16, draw.Src) }
|
func BenchmarkGlyphAlphaLoose16Src(b *testing.B) { benchGlyph(b, 'A', true, 16, draw.Src) }
|
||||||
func BenchmarkGlyphNRGBA32Over(b *testing.B) { benchGlyph(b, color.NRGBAModel, 32, draw.Over) }
|
func BenchmarkGlyphAlphaLoose32Over(b *testing.B) { benchGlyph(b, 'A', true, 32, draw.Over) }
|
||||||
func BenchmarkGlyphNRGBA32Src(b *testing.B) { benchGlyph(b, color.NRGBAModel, 32, draw.Src) }
|
func BenchmarkGlyphAlphaLoose32Src(b *testing.B) { benchGlyph(b, 'A', true, 32, draw.Src) }
|
||||||
func BenchmarkGlyphNRGBA64Over(b *testing.B) { benchGlyph(b, color.NRGBAModel, 64, draw.Over) }
|
func BenchmarkGlyphAlphaLoose64Over(b *testing.B) { benchGlyph(b, 'A', true, 64, draw.Over) }
|
||||||
func BenchmarkGlyphNRGBA64Src(b *testing.B) { benchGlyph(b, color.NRGBAModel, 64, draw.Src) }
|
func BenchmarkGlyphAlphaLoose64Src(b *testing.B) { benchGlyph(b, 'A', true, 64, draw.Src) }
|
||||||
func BenchmarkGlyphNRGBA128Over(b *testing.B) { benchGlyph(b, color.NRGBAModel, 128, draw.Over) }
|
func BenchmarkGlyphAlphaLoose128Over(b *testing.B) { benchGlyph(b, 'A', true, 128, draw.Over) }
|
||||||
func BenchmarkGlyphNRGBA128Src(b *testing.B) { benchGlyph(b, color.NRGBAModel, 128, draw.Src) }
|
func BenchmarkGlyphAlphaLoose128Src(b *testing.B) { benchGlyph(b, 'A', true, 128, draw.Src) }
|
||||||
func BenchmarkGlyphNRGBA256Over(b *testing.B) { benchGlyph(b, color.NRGBAModel, 256, draw.Over) }
|
func BenchmarkGlyphAlphaLoose256Over(b *testing.B) { benchGlyph(b, 'A', true, 256, draw.Over) }
|
||||||
func BenchmarkGlyphNRGBA256Src(b *testing.B) { benchGlyph(b, color.NRGBAModel, 256, draw.Src) }
|
func BenchmarkGlyphAlphaLoose256Src(b *testing.B) { benchGlyph(b, 'A', true, 256, draw.Src) }
|
||||||
|
|
||||||
func BenchmarkGlyphRGBA16Over(b *testing.B) { benchGlyph(b, color.RGBAModel, 16, draw.Over) }
|
func BenchmarkGlyphNRGBA16Over(b *testing.B) { benchGlyph(b, 'N', false, 16, draw.Over) }
|
||||||
func BenchmarkGlyphRGBA16Src(b *testing.B) { benchGlyph(b, color.RGBAModel, 16, draw.Src) }
|
func BenchmarkGlyphNRGBA16Src(b *testing.B) { benchGlyph(b, 'N', false, 16, draw.Src) }
|
||||||
func BenchmarkGlyphRGBA32Over(b *testing.B) { benchGlyph(b, color.RGBAModel, 32, draw.Over) }
|
func BenchmarkGlyphNRGBA32Over(b *testing.B) { benchGlyph(b, 'N', false, 32, draw.Over) }
|
||||||
func BenchmarkGlyphRGBA32Src(b *testing.B) { benchGlyph(b, color.RGBAModel, 32, draw.Src) }
|
func BenchmarkGlyphNRGBA32Src(b *testing.B) { benchGlyph(b, 'N', false, 32, draw.Src) }
|
||||||
func BenchmarkGlyphRGBA64Over(b *testing.B) { benchGlyph(b, color.RGBAModel, 64, draw.Over) }
|
func BenchmarkGlyphNRGBA64Over(b *testing.B) { benchGlyph(b, 'N', false, 64, draw.Over) }
|
||||||
func BenchmarkGlyphRGBA64Src(b *testing.B) { benchGlyph(b, color.RGBAModel, 64, draw.Src) }
|
func BenchmarkGlyphNRGBA64Src(b *testing.B) { benchGlyph(b, 'N', false, 64, draw.Src) }
|
||||||
func BenchmarkGlyphRGBA128Over(b *testing.B) { benchGlyph(b, color.RGBAModel, 128, draw.Over) }
|
func BenchmarkGlyphNRGBA128Over(b *testing.B) { benchGlyph(b, 'N', false, 128, draw.Over) }
|
||||||
func BenchmarkGlyphRGBA128Src(b *testing.B) { benchGlyph(b, color.RGBAModel, 128, draw.Src) }
|
func BenchmarkGlyphNRGBA128Src(b *testing.B) { benchGlyph(b, 'N', false, 128, draw.Src) }
|
||||||
func BenchmarkGlyphRGBA256Over(b *testing.B) { benchGlyph(b, color.RGBAModel, 256, draw.Over) }
|
func BenchmarkGlyphNRGBA256Over(b *testing.B) { benchGlyph(b, 'N', false, 256, draw.Over) }
|
||||||
func BenchmarkGlyphRGBA256Src(b *testing.B) { benchGlyph(b, color.RGBAModel, 256, draw.Src) }
|
func BenchmarkGlyphNRGBA256Src(b *testing.B) { benchGlyph(b, 'N', false, 256, draw.Src) }
|
||||||
|
|
||||||
|
func BenchmarkGlyphRGBA16Over(b *testing.B) { benchGlyph(b, 'R', false, 16, draw.Over) }
|
||||||
|
func BenchmarkGlyphRGBA16Src(b *testing.B) { benchGlyph(b, 'R', false, 16, draw.Src) }
|
||||||
|
func BenchmarkGlyphRGBA32Over(b *testing.B) { benchGlyph(b, 'R', false, 32, draw.Over) }
|
||||||
|
func BenchmarkGlyphRGBA32Src(b *testing.B) { benchGlyph(b, 'R', false, 32, draw.Src) }
|
||||||
|
func BenchmarkGlyphRGBA64Over(b *testing.B) { benchGlyph(b, 'R', false, 64, draw.Over) }
|
||||||
|
func BenchmarkGlyphRGBA64Src(b *testing.B) { benchGlyph(b, 'R', false, 64, draw.Src) }
|
||||||
|
func BenchmarkGlyphRGBA128Over(b *testing.B) { benchGlyph(b, 'R', false, 128, draw.Over) }
|
||||||
|
func BenchmarkGlyphRGBA128Src(b *testing.B) { benchGlyph(b, 'R', false, 128, draw.Src) }
|
||||||
|
func BenchmarkGlyphRGBA256Over(b *testing.B) { benchGlyph(b, 'R', false, 256, draw.Over) }
|
||||||
|
func BenchmarkGlyphRGBA256Src(b *testing.B) { benchGlyph(b, 'R', false, 256, draw.Src) }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user