draw: make op a mandatory argument, not optional.
Change-Id: Ic08ce587cf458444b098b752f0fa7ab16d43c914 Reviewed-on: https://go-review.googlesource.com/9468 Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
6af46c2009
commit
70cb8023e6
|
@ -30,7 +30,7 @@ func ExampleDraw() {
|
|||
|
||||
dst := image.NewRGBA(image.Rect(0, 0, 400, 300))
|
||||
green := image.NewUniform(color.RGBA{0x00, 0x1f, 0x00, 0xff})
|
||||
draw.Copy(dst, image.Point{}, green, dst.Bounds(), nil)
|
||||
draw.Copy(dst, image.Point{}, green, dst.Bounds(), draw.Src, nil)
|
||||
qs := []draw.Interpolator{
|
||||
draw.NearestNeighbor,
|
||||
draw.ApproxBiLinear,
|
||||
|
@ -42,11 +42,11 @@ func ExampleDraw() {
|
|||
+2 * sin60, +2 * cos60, 100,
|
||||
}
|
||||
|
||||
draw.Copy(dst, image.Point{20, 30}, src, src.Bounds(), nil)
|
||||
draw.Copy(dst, image.Point{20, 30}, src, src.Bounds(), draw.Over, nil)
|
||||
for i, q := range qs {
|
||||
q.Scale(dst, image.Rect(200+10*i, 100*i, 600+10*i, 150+100*i), src, src.Bounds(), nil)
|
||||
q.Scale(dst, image.Rect(200+10*i, 100*i, 600+10*i, 150+100*i), src, src.Bounds(), draw.Over, nil)
|
||||
}
|
||||
draw.NearestNeighbor.Transform(dst, t, src, src.Bounds(), nil)
|
||||
draw.NearestNeighbor.Transform(dst, t, src, src.Bounds(), draw.Over, nil)
|
||||
|
||||
red := image.NewNRGBA(image.Rect(0, 0, 16, 16))
|
||||
for y := 0; y < 16; y++ {
|
||||
|
@ -65,14 +65,13 @@ func ExampleDraw() {
|
|||
draw.Src,
|
||||
}
|
||||
for i, op := range ops {
|
||||
q, opts := draw.NearestNeighbor, &draw.Options{Op: op}
|
||||
dr := image.Rect(120+10*i, 150+60*i, 170+10*i, 200+60*i)
|
||||
q.Scale(dst, dr, red, red.Bounds(), opts)
|
||||
draw.NearestNeighbor.Scale(dst, dr, red, red.Bounds(), op, nil)
|
||||
t := &f64.Aff3{
|
||||
+cos60, -sin60, float64(190 + 10*i),
|
||||
+sin60, +cos60, float64(140 + 50*i),
|
||||
}
|
||||
q.Transform(dst, t, red, red.Bounds(), opts)
|
||||
draw.NearestNeighbor.Transform(dst, t, red, red.Bounds(), op, nil)
|
||||
}
|
||||
|
||||
dr := image.Rect(0, 0, 128, 128)
|
||||
|
@ -95,7 +94,7 @@ func ExampleDraw() {
|
|||
}
|
||||
}
|
||||
cyan := image.NewUniform(color.RGBA{0x00, 0xff, 0xff, 0xff})
|
||||
draw.NearestNeighbor.Scale(dst, dr, cyan, sr, &draw.Options{
|
||||
draw.NearestNeighbor.Scale(dst, dr, cyan, sr, draw.Over, &draw.Options{
|
||||
DstMask: checkerboard,
|
||||
SrcMask: circle,
|
||||
})
|
||||
|
|
44
draw/gen.go
44
draw/gen.go
|
@ -703,7 +703,7 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
|
|||
|
||||
func expnSwitch(op, dType string, expandBoth bool, template string) string {
|
||||
if op == "" && dType != "anyDType" {
|
||||
lines := []string{"switch o.Op {"}
|
||||
lines := []string{"switch op {"}
|
||||
for _, op = range ops {
|
||||
lines = append(lines,
|
||||
fmt.Sprintf("case %s:", op),
|
||||
|
@ -876,7 +876,7 @@ func relName(s string) string {
|
|||
|
||||
const (
|
||||
codeRoot = `
|
||||
func (z $receiver) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
func (z $receiver) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
var o Options
|
||||
if opts != nil {
|
||||
o = *opts
|
||||
|
@ -890,8 +890,8 @@ const (
|
|||
}
|
||||
// Make adr relative to dr.Min.
|
||||
adr = adr.Sub(dr.Min)
|
||||
if o.Op == Over && o.SrcMask == nil && opaque(src) {
|
||||
o.Op = Src
|
||||
if op == Over && o.SrcMask == nil && opaque(src) {
|
||||
op = Src
|
||||
}
|
||||
|
||||
// sr is the source pixels. If it extends beyond the src bounds,
|
||||
|
@ -900,20 +900,20 @@ const (
|
|||
//
|
||||
// Similarly, the fast paths assume that the masks are nil.
|
||||
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
z.scale_Image_Image_Over(dst, dr, adr, src, sr, &o)
|
||||
case Src:
|
||||
z.scale_Image_Image_Src(dst, dr, adr, src, sr, &o)
|
||||
}
|
||||
} else if _, ok := src.(*image.Uniform); ok {
|
||||
Draw(dst, dr, src, src.Bounds().Min, o.Op)
|
||||
Draw(dst, dr, src, src.Bounds().Min, op)
|
||||
} else {
|
||||
$switch z.scale_$dTypeRN_$sTypeRN$sratio_$op(dst, dr, adr, src, sr, &o)
|
||||
}
|
||||
}
|
||||
|
||||
func (z $receiver) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
func (z $receiver) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
var o Options
|
||||
if opts != nil {
|
||||
o = *opts
|
||||
|
@ -926,8 +926,8 @@ const (
|
|||
if adr.Empty() || sr.Empty() {
|
||||
return
|
||||
}
|
||||
if o.Op == Over && o.SrcMask == nil && opaque(src) {
|
||||
o.Op = Src
|
||||
if op == Over && o.SrcMask == nil && opaque(src) {
|
||||
op = Src
|
||||
}
|
||||
|
||||
d2s := invert(s2d)
|
||||
|
@ -951,14 +951,14 @@ const (
|
|||
//
|
||||
// Similarly, the fast paths assume that the masks are nil.
|
||||
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
|
||||
case Src:
|
||||
z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
|
||||
}
|
||||
} else if u, ok := src.(*image.Uniform); ok {
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, o.Op)
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
|
||||
} else {
|
||||
$switch z.transform_$dTypeRN_$sTypeRN$sratio_$op(dst, dr, adr, &d2s, src, sr, bias, &o)
|
||||
}
|
||||
|
@ -1116,9 +1116,9 @@ const (
|
|||
`
|
||||
|
||||
codeKernelRoot = `
|
||||
func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
if z.dw != int32(dr.Dx()) || z.dh != int32(dr.Dy()) || z.sw != int32(sr.Dx()) || z.sh != int32(sr.Dy()) {
|
||||
z.kernel.Scale(dst, dr, src, sr, opts)
|
||||
z.kernel.Scale(dst, dr, src, sr, op, opts)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1135,12 +1135,12 @@ const (
|
|||
}
|
||||
// Make adr relative to dr.Min.
|
||||
adr = adr.Sub(dr.Min)
|
||||
if o.Op == Over && o.SrcMask == nil && opaque(src) {
|
||||
o.Op = Src
|
||||
if op == Over && o.SrcMask == nil && opaque(src) {
|
||||
op = Src
|
||||
}
|
||||
|
||||
if _, ok := src.(*image.Uniform); ok && o.DstMask == nil && o.SrcMask == nil && sr.In(src.Bounds()) {
|
||||
Draw(dst, dr, src, src.Bounds().Min, o.Op)
|
||||
Draw(dst, dr, src, src.Bounds().Min, op)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1168,7 +1168,7 @@ const (
|
|||
}
|
||||
|
||||
if o.DstMask != nil {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
z.scaleY_Image_Over(dst, dr, adr, tmp, &o)
|
||||
case Src:
|
||||
|
@ -1179,7 +1179,7 @@ const (
|
|||
}
|
||||
}
|
||||
|
||||
func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
var o Options
|
||||
if opts != nil {
|
||||
o = *opts
|
||||
|
@ -1192,8 +1192,8 @@ const (
|
|||
if adr.Empty() || sr.Empty() {
|
||||
return
|
||||
}
|
||||
if o.Op == Over && o.SrcMask == nil && opaque(src) {
|
||||
o.Op = Src
|
||||
if op == Over && o.SrcMask == nil && opaque(src) {
|
||||
op = Src
|
||||
}
|
||||
d2s := invert(s2d)
|
||||
// bias is a translation of the mapping from dst coordinates to src
|
||||
|
@ -1212,7 +1212,7 @@ const (
|
|||
adr = adr.Sub(dr.Min)
|
||||
|
||||
if u, ok := src.(*image.Uniform); ok && o.DstMask != nil && o.SrcMask != nil && sr.In(src.Bounds()) {
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, o.Op)
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1231,7 +1231,7 @@ const (
|
|||
//
|
||||
// Similarly, the fast paths assume that the masks are nil.
|
||||
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
q.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
|
||||
case Src:
|
||||
|
|
74
draw/impl.go
74
draw/impl.go
|
@ -10,7 +10,7 @@ import (
|
|||
"golang.org/x/image/math/f64"
|
||||
)
|
||||
|
||||
func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
var o Options
|
||||
if opts != nil {
|
||||
o = *opts
|
||||
|
@ -24,8 +24,8 @@ func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr
|
|||
}
|
||||
// Make adr relative to dr.Min.
|
||||
adr = adr.Sub(dr.Min)
|
||||
if o.Op == Over && o.SrcMask == nil && opaque(src) {
|
||||
o.Op = Src
|
||||
if op == Over && o.SrcMask == nil && opaque(src) {
|
||||
op = Src
|
||||
}
|
||||
|
||||
// sr is the source pixels. If it extends beyond the src bounds,
|
||||
|
@ -34,16 +34,16 @@ func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr
|
|||
//
|
||||
// Similarly, the fast paths assume that the masks are nil.
|
||||
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
z.scale_Image_Image_Over(dst, dr, adr, src, sr, &o)
|
||||
case Src:
|
||||
z.scale_Image_Image_Src(dst, dr, adr, src, sr, &o)
|
||||
}
|
||||
} else if _, ok := src.(*image.Uniform); ok {
|
||||
Draw(dst, dr, src, src.Bounds().Min, o.Op)
|
||||
Draw(dst, dr, src, src.Bounds().Min, op)
|
||||
} else {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
|
@ -97,7 +97,7 @@ func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr
|
|||
}
|
||||
}
|
||||
|
||||
func (z nnInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
func (z nnInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
var o Options
|
||||
if opts != nil {
|
||||
o = *opts
|
||||
|
@ -110,8 +110,8 @@ func (z nnInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
|
|||
if adr.Empty() || sr.Empty() {
|
||||
return
|
||||
}
|
||||
if o.Op == Over && o.SrcMask == nil && opaque(src) {
|
||||
o.Op = Src
|
||||
if op == Over && o.SrcMask == nil && opaque(src) {
|
||||
op = Src
|
||||
}
|
||||
|
||||
d2s := invert(s2d)
|
||||
|
@ -135,16 +135,16 @@ func (z nnInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
|
|||
//
|
||||
// Similarly, the fast paths assume that the masks are nil.
|
||||
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
|
||||
case Src:
|
||||
z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
|
||||
}
|
||||
} else if u, ok := src.(*image.Uniform); ok {
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, o.Op)
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
|
||||
} else {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
|
@ -1031,7 +1031,7 @@ func (nnInterpolator) transform_Image_Image_Src(dst Image, dr, adr image.Rectang
|
|||
}
|
||||
}
|
||||
|
||||
func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
var o Options
|
||||
if opts != nil {
|
||||
o = *opts
|
||||
|
@ -1045,8 +1045,8 @@ func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, s
|
|||
}
|
||||
// Make adr relative to dr.Min.
|
||||
adr = adr.Sub(dr.Min)
|
||||
if o.Op == Over && o.SrcMask == nil && opaque(src) {
|
||||
o.Op = Src
|
||||
if op == Over && o.SrcMask == nil && opaque(src) {
|
||||
op = Src
|
||||
}
|
||||
|
||||
// sr is the source pixels. If it extends beyond the src bounds,
|
||||
|
@ -1055,16 +1055,16 @@ func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, s
|
|||
//
|
||||
// Similarly, the fast paths assume that the masks are nil.
|
||||
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
z.scale_Image_Image_Over(dst, dr, adr, src, sr, &o)
|
||||
case Src:
|
||||
z.scale_Image_Image_Src(dst, dr, adr, src, sr, &o)
|
||||
}
|
||||
} else if _, ok := src.(*image.Uniform); ok {
|
||||
Draw(dst, dr, src, src.Bounds().Min, o.Op)
|
||||
Draw(dst, dr, src, src.Bounds().Min, op)
|
||||
} else {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
|
@ -1118,7 +1118,7 @@ func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, s
|
|||
}
|
||||
}
|
||||
|
||||
func (z ablInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
func (z ablInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
var o Options
|
||||
if opts != nil {
|
||||
o = *opts
|
||||
|
@ -1131,8 +1131,8 @@ func (z ablInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
|
|||
if adr.Empty() || sr.Empty() {
|
||||
return
|
||||
}
|
||||
if o.Op == Over && o.SrcMask == nil && opaque(src) {
|
||||
o.Op = Src
|
||||
if op == Over && o.SrcMask == nil && opaque(src) {
|
||||
op = Src
|
||||
}
|
||||
|
||||
d2s := invert(s2d)
|
||||
|
@ -1156,16 +1156,16 @@ func (z ablInterpolator) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr
|
|||
//
|
||||
// Similarly, the fast paths assume that the masks are nil.
|
||||
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
|
||||
case Src:
|
||||
z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
|
||||
}
|
||||
} else if u, ok := src.(*image.Uniform); ok {
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, o.Op)
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
|
||||
} else {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
|
@ -4398,9 +4398,9 @@ func (ablInterpolator) transform_Image_Image_Src(dst Image, dr, adr image.Rectan
|
|||
}
|
||||
}
|
||||
|
||||
func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
if z.dw != int32(dr.Dx()) || z.dh != int32(dr.Dy()) || z.sw != int32(sr.Dx()) || z.sh != int32(sr.Dy()) {
|
||||
z.kernel.Scale(dst, dr, src, sr, opts)
|
||||
z.kernel.Scale(dst, dr, src, sr, op, opts)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -4417,12 +4417,12 @@ func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr
|
|||
}
|
||||
// Make adr relative to dr.Min.
|
||||
adr = adr.Sub(dr.Min)
|
||||
if o.Op == Over && o.SrcMask == nil && opaque(src) {
|
||||
o.Op = Src
|
||||
if op == Over && o.SrcMask == nil && opaque(src) {
|
||||
op = Src
|
||||
}
|
||||
|
||||
if _, ok := src.(*image.Uniform); ok && o.DstMask == nil && o.SrcMask == nil && sr.In(src.Bounds()) {
|
||||
Draw(dst, dr, src, src.Bounds().Min, o.Op)
|
||||
Draw(dst, dr, src, src.Bounds().Min, op)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -4472,14 +4472,14 @@ func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr
|
|||
}
|
||||
|
||||
if o.DstMask != nil {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
z.scaleY_Image_Over(dst, dr, adr, tmp, &o)
|
||||
case Src:
|
||||
z.scaleY_Image_Src(dst, dr, adr, tmp, &o)
|
||||
}
|
||||
} else {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
|
@ -4498,7 +4498,7 @@ func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr
|
|||
}
|
||||
}
|
||||
|
||||
func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
var o Options
|
||||
if opts != nil {
|
||||
o = *opts
|
||||
|
@ -4511,8 +4511,8 @@ func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.R
|
|||
if adr.Empty() || sr.Empty() {
|
||||
return
|
||||
}
|
||||
if o.Op == Over && o.SrcMask == nil && opaque(src) {
|
||||
o.Op = Src
|
||||
if op == Over && o.SrcMask == nil && opaque(src) {
|
||||
op = Src
|
||||
}
|
||||
d2s := invert(s2d)
|
||||
// bias is a translation of the mapping from dst coordinates to src
|
||||
|
@ -4531,7 +4531,7 @@ func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.R
|
|||
adr = adr.Sub(dr.Min)
|
||||
|
||||
if u, ok := src.(*image.Uniform); ok && o.DstMask != nil && o.SrcMask != nil && sr.In(src.Bounds()) {
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, o.Op)
|
||||
transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -4550,14 +4550,14 @@ func (q *Kernel) Transform(dst Image, s2d *f64.Aff3, src image.Image, sr image.R
|
|||
//
|
||||
// Similarly, the fast paths assume that the masks are nil.
|
||||
if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
q.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
|
||||
case Src:
|
||||
q.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
|
||||
}
|
||||
} else {
|
||||
switch o.Op {
|
||||
switch op {
|
||||
case Over:
|
||||
switch dst := dst.(type) {
|
||||
case *image.RGBA:
|
||||
|
|
|
@ -15,33 +15,34 @@ import (
|
|||
"golang.org/x/image/math/f64"
|
||||
)
|
||||
|
||||
// Copy copies the part of the source image defined by src and sr and writes to
|
||||
// the part of the destination image defined by dst and the translation of sr
|
||||
// so that sr.Min translates to dp.
|
||||
func Copy(dst Image, dp image.Point, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
// Copy copies the part of the source image defined by src and sr and writes
|
||||
// the result of a Porter-Duff composition to the part of the destination image
|
||||
// defined by dst and the translation of sr so that sr.Min translates to dp.
|
||||
func Copy(dst Image, dp image.Point, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
var o Options
|
||||
if opts != nil {
|
||||
o = *opts
|
||||
}
|
||||
dr := sr.Add(dp.Sub(sr.Min))
|
||||
if o.DstMask == nil {
|
||||
DrawMask(dst, dr, src, sr.Min, o.SrcMask, o.SrcMaskP.Add(sr.Min), o.Op)
|
||||
DrawMask(dst, dr, src, sr.Min, o.SrcMask, o.SrcMaskP.Add(sr.Min), op)
|
||||
} else {
|
||||
NearestNeighbor.Scale(dst, dr, src, sr, opts)
|
||||
NearestNeighbor.Scale(dst, dr, src, sr, op, opts)
|
||||
}
|
||||
}
|
||||
|
||||
// Scaler scales the part of the source image defined by src and sr and writes
|
||||
// to the part of the destination image defined by dst and dr.
|
||||
// the result of a Porter-Duff composition to the part of the destination image
|
||||
// defined by dst and dr.
|
||||
//
|
||||
// A Scaler is safe to use concurrently.
|
||||
type Scaler interface {
|
||||
Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options)
|
||||
Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options)
|
||||
}
|
||||
|
||||
// Transformer transforms the part of the source image defined by src and sr
|
||||
// and writes to the part of the destination image defined by dst and the
|
||||
// affine transform m applied to sr.
|
||||
// and writes the result of a Porter-Duff composition to the part of the
|
||||
// destination image defined by dst and the affine transform m applied to sr.
|
||||
//
|
||||
// For example, if m is the matrix
|
||||
//
|
||||
|
@ -53,16 +54,13 @@ type Scaler interface {
|
|||
//
|
||||
// A Transformer is safe to use concurrently.
|
||||
type Transformer interface {
|
||||
Transform(dst Image, m *f64.Aff3, src image.Image, sr image.Rectangle, opts *Options)
|
||||
Transform(dst Image, m *f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options)
|
||||
}
|
||||
|
||||
// Options are optional parameters to Copy, Scale and Transform.
|
||||
//
|
||||
// A nil *Options means to use the default (zero) values of each field.
|
||||
type Options struct {
|
||||
// Op is the compositing operator. The default value is Over.
|
||||
Op Op
|
||||
|
||||
// Masks limit what parts of the dst image are drawn to and what parts of
|
||||
// the src image are drawn from.
|
||||
//
|
||||
|
@ -124,8 +122,8 @@ type Kernel struct {
|
|||
}
|
||||
|
||||
// Scale implements the Scaler interface.
|
||||
func (q *Kernel) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
|
||||
q.newScaler(dr.Dx(), dr.Dy(), sr.Dx(), sr.Dy(), false).Scale(dst, dr, src, sr, opts)
|
||||
func (q *Kernel) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||
q.newScaler(dr.Dx(), dr.Dy(), sr.Dx(), sr.Dy(), false).Scale(dst, dr, src, sr, op, opts)
|
||||
}
|
||||
|
||||
// NewScaler returns a Scaler that is optimized for scaling multiple times with
|
||||
|
|
|
@ -64,9 +64,6 @@ func testInterp(t *testing.T, w int, h int, direction, prefix, suffix string) {
|
|||
if prefix == "tux" {
|
||||
op, scale = Over, 0.125
|
||||
}
|
||||
opts := &Options{
|
||||
Op: op,
|
||||
}
|
||||
green := image.NewUniform(color.RGBA{0x00, 0x22, 0x11, 0xff})
|
||||
|
||||
testCases := map[string]Interpolator{
|
||||
|
@ -79,11 +76,11 @@ func testInterp(t *testing.T, w int, h int, direction, prefix, suffix string) {
|
|||
goldenFilename := fmt.Sprintf("../testdata/%s-%s-%s.png", prefix, direction, name)
|
||||
|
||||
got := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||
Copy(got, image.Point{}, green, got.Bounds(), nil)
|
||||
Copy(got, image.Point{}, green, got.Bounds(), Src, nil)
|
||||
if direction == "rotate" {
|
||||
q.Transform(got, transformMatrix(scale, 40, 10), src, src.Bounds(), opts)
|
||||
q.Transform(got, transformMatrix(scale, 40, 10), src, src.Bounds(), op, nil)
|
||||
} else {
|
||||
q.Scale(got, got.Bounds(), src, src.Bounds(), opts)
|
||||
q.Scale(got, got.Bounds(), src, src.Bounds(), op, nil)
|
||||
}
|
||||
|
||||
if *genGoldenFiles {
|
||||
|
@ -132,12 +129,12 @@ func TestOps(t *testing.T) {
|
|||
}
|
||||
for op, want := range testCases {
|
||||
dst := image.NewRGBA(image.Rect(0, 0, 2, 2))
|
||||
Copy(dst, image.Point{}, blue, dst.Bounds(), nil)
|
||||
Copy(dst, image.Point{}, blue, dst.Bounds(), Src, nil)
|
||||
|
||||
src := image.NewRGBA(image.Rect(0, 0, 1, 1))
|
||||
src.SetRGBA(0, 0, color.RGBA{0x7f, 0x00, 0x00, 0x7f})
|
||||
|
||||
NearestNeighbor.Scale(dst, dst.Bounds(), src, src.Bounds(), &Options{Op: op})
|
||||
NearestNeighbor.Scale(dst, dst.Bounds(), src, src.Bounds(), op, nil)
|
||||
|
||||
if got := dst.RGBAAt(0, 0); got != want {
|
||||
t.Errorf("op=%v: got %v, want %v", op, got, want)
|
||||
|
@ -176,7 +173,7 @@ func TestNegativeWeights(t *testing.T) {
|
|||
}
|
||||
|
||||
dst := image.NewRGBA(image.Rect(0, 0, 32, 32))
|
||||
CatmullRom.Scale(dst, dst.Bounds(), src, src.Bounds(), nil)
|
||||
CatmullRom.Scale(dst, dst.Bounds(), src, src.Bounds(), Over, nil)
|
||||
if err := check(dst); err != nil {
|
||||
t.Fatalf("dst image: %v", err)
|
||||
}
|
||||
|
@ -213,11 +210,11 @@ func TestInterpClipCommute(t *testing.T) {
|
|||
var interp func(dst *image.RGBA)
|
||||
if transform {
|
||||
interp = func(dst *image.RGBA) {
|
||||
q.Transform(dst, transformMatrix(3.75, 2, 1), src, src.Bounds(), nil)
|
||||
q.Transform(dst, transformMatrix(3.75, 2, 1), src, src.Bounds(), Over, nil)
|
||||
}
|
||||
} else {
|
||||
interp = func(dst *image.RGBA) {
|
||||
q.Scale(dst, outer, src, src.Bounds(), nil)
|
||||
q.Scale(dst, outer, src, src.Bounds(), Over, nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,9 +289,9 @@ func TestSrcTranslationInvariance(t *testing.T) {
|
|||
for _, q := range qs {
|
||||
want := image.NewRGBA(image.Rect(0, 0, 20, 20))
|
||||
if transform {
|
||||
q.Transform(want, m00, src, sr, nil)
|
||||
q.Transform(want, m00, src, sr, Over, nil)
|
||||
} else {
|
||||
q.Scale(want, want.Bounds(), src, sr, nil)
|
||||
q.Scale(want, want.Bounds(), src, sr, Over, nil)
|
||||
}
|
||||
for _, delta := range deltas {
|
||||
tsrc := &translatedImage{src, delta}
|
||||
|
@ -304,9 +301,9 @@ func TestSrcTranslationInvariance(t *testing.T) {
|
|||
1, 0, -float64(delta.X),
|
||||
0, 1, -float64(delta.Y),
|
||||
})
|
||||
q.Transform(got, &m, tsrc, sr.Add(delta), nil)
|
||||
q.Transform(got, &m, tsrc, sr.Add(delta), Over, nil)
|
||||
} else {
|
||||
q.Scale(got, got.Bounds(), tsrc, sr.Add(delta), nil)
|
||||
q.Scale(got, got.Bounds(), tsrc, sr.Add(delta), Over, nil)
|
||||
}
|
||||
if !bytes.Equal(got.Pix, want.Pix) {
|
||||
t.Errorf("pix differ for delta=%v, transform=%t, q=%T", delta, transform, q)
|
||||
|
@ -325,8 +322,8 @@ func TestSrcMask(t *testing.T) {
|
|||
red := image.NewUniform(color.RGBA{0xff, 0x00, 0x00, 0xff})
|
||||
blue := image.NewUniform(color.RGBA{0x00, 0x00, 0xff, 0xff})
|
||||
dst := image.NewRGBA(image.Rect(0, 0, 6, 1))
|
||||
Copy(dst, image.Point{}, blue, dst.Bounds(), nil)
|
||||
NearestNeighbor.Scale(dst, dst.Bounds(), red, image.Rect(0, 0, 3, 1), &Options{
|
||||
Copy(dst, image.Point{}, blue, dst.Bounds(), Src, nil)
|
||||
NearestNeighbor.Scale(dst, dst.Bounds(), red, image.Rect(0, 0, 3, 1), Over, &Options{
|
||||
SrcMask: srcMask,
|
||||
SrcMaskP: image.Point{20, 0},
|
||||
})
|
||||
|
@ -367,8 +364,8 @@ func TestDstMask(t *testing.T) {
|
|||
}
|
||||
for _, q := range qs {
|
||||
dst := image.NewRGBA(image.Rect(0, 0, 3, 1))
|
||||
Copy(dst, image.Point{}, blue, dst.Bounds(), nil)
|
||||
q.Scale(dst, dst.Bounds(), red, red.Bounds(), &Options{
|
||||
Copy(dst, image.Point{}, blue, dst.Bounds(), Src, nil)
|
||||
q.Scale(dst, dst.Bounds(), red, red.Bounds(), Over, &Options{
|
||||
DstMask: dstMask,
|
||||
DstMaskP: image.Point{20, 0},
|
||||
})
|
||||
|
@ -410,8 +407,8 @@ func TestRectDstMask(t *testing.T) {
|
|||
|
||||
mk := func(q Transformer, dstMask image.Image, dstMaskP image.Point) *image.RGBA {
|
||||
m := image.NewRGBA(bounds)
|
||||
Copy(m, bounds.Min, dstOutside, bounds, nil)
|
||||
q.Transform(m, m00, src, src.Bounds(), &Options{
|
||||
Copy(m, bounds.Min, dstOutside, bounds, Src, nil)
|
||||
q.Transform(m, m00, src, src.Bounds(), Over, &Options{
|
||||
DstMask: dstMask,
|
||||
DstMaskP: dstMaskP,
|
||||
})
|
||||
|
@ -536,7 +533,6 @@ func TestFastPaths(t *testing.T) {
|
|||
for _, transform := range []bool{false, true} {
|
||||
for _, q := range qs {
|
||||
for _, op := range ops {
|
||||
opts := &Options{Op: op}
|
||||
dst0 := image.NewRGBA(drs[0])
|
||||
dst1 := image.NewRGBA(drs[0])
|
||||
Draw(dst0, dst0.Bounds(), blue, image.Point{}, Src)
|
||||
|
@ -544,11 +540,11 @@ func TestFastPaths(t *testing.T) {
|
|||
|
||||
if transform {
|
||||
m := transformMatrix(3.75, 2, 1)
|
||||
q.Transform(dst0, m, src, sr, opts)
|
||||
q.Transform(dstWrapper{dst1}, m, srcWrapper{src}, sr, opts)
|
||||
q.Transform(dst0, m, src, sr, op, nil)
|
||||
q.Transform(dstWrapper{dst1}, m, srcWrapper{src}, sr, op, nil)
|
||||
} else {
|
||||
q.Scale(dst0, dr, src, sr, opts)
|
||||
q.Scale(dstWrapper{dst1}, dr, srcWrapper{src}, sr, opts)
|
||||
q.Scale(dst0, dr, src, sr, op, nil)
|
||||
q.Scale(dstWrapper{dst1}, dr, srcWrapper{src}, sr, op, nil)
|
||||
}
|
||||
|
||||
if !bytes.Equal(dst0.Pix, dst1.Pix) {
|
||||
|
@ -631,14 +627,11 @@ func benchScale(b *testing.B, w int, h int, op Op, srcf func(image.Rectangle) (i
|
|||
}); ok {
|
||||
scaler = n.NewScaler(dr.Dx(), dr.Dy(), sr.Dx(), sr.Dy())
|
||||
}
|
||||
opts := &Options{
|
||||
Op: op,
|
||||
}
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
scaler.Scale(dst, dr, src, sr, opts)
|
||||
scaler.Scale(dst, dr, src, sr, op, nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -650,14 +643,11 @@ func benchTform(b *testing.B, w int, h int, op Op, srcf func(image.Rectangle) (i
|
|||
}
|
||||
sr := src.Bounds()
|
||||
m := transformMatrix(3.75, 40, 10)
|
||||
opts := &Options{
|
||||
Op: op,
|
||||
}
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
q.Transform(dst, m, src, sr, opts)
|
||||
q.Transform(dst, m, src, sr, op, nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user