draw: refactor codegen to use argf instead of fmt.Sprintf.

Change-Id: Iee4cb1b605c381b75a688a5e65e9afc4d34df193
Reviewed-on: https://go-review.googlesource.com/8900
Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
Nigel Tao 2015-04-14 10:26:02 +10:00
parent 8ed4ff0a33
commit e83a2376af

View File

@ -260,29 +260,21 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
} }
switch d.sType { switch d.sType {
default: default:
return fmt.Sprintf(""+ return argf(args, ""+
"%sr = %s*%sr + %s*%sr\n"+ "$3r = $0*$1r + $2*$3r\n"+
"%sg = %s*%sg + %s*%sg\n"+ "$3g = $0*$1g + $2*$3g\n"+
"%sb = %s*%sb + %s*%sb\n"+ "$3b = $0*$1b + $2*$3b\n"+
"%sa = %s*%sa + %s*%sa", "$3a = $0*$1a + $2*$3a",
args[3], args[0], args[1], args[2], args[3],
args[3], args[0], args[1], args[2], args[3],
args[3], args[0], args[1], args[2], args[3],
args[3], args[0], args[1], args[2], args[3],
) )
case "*image.Gray": case "*image.Gray":
return fmt.Sprintf(""+ return argf(args, ""+
"%sr = %s*%sr + %s*%sr", "$3r = $0*$1r + $2*$3r",
args[3], args[0], args[1], args[2], args[3],
) )
case "*image.YCbCr": case "*image.YCbCr":
return fmt.Sprintf(""+ return argf(args, ""+
"%sr = %s*%sr + %s*%sr\n"+ "$3r = $0*$1r + $2*$3r\n"+
"%sg = %s*%sg + %s*%sg\n"+ "$3g = $0*$1g + $2*$3g\n"+
"%sb = %s*%sb + %s*%sb", "$3b = $0*$1b + $2*$3b",
args[3], args[0], args[1], args[2], args[3],
args[3], args[0], args[1], args[2], args[3],
args[3], args[0], args[1], args[2], args[3],
) )
} }
@ -316,34 +308,22 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
default: default:
log.Fatalf("bad dType %q", d.dType) log.Fatalf("bad dType %q", d.dType)
case "Image": case "Image":
return fmt.Sprintf(""+ return argf(args, ""+
"qr, qg, qb, qa := dst.At(%s, %s).RGBA()\n"+ "qr, qg, qb, qa := dst.At($0, $1).RGBA()\n"+
"%sa1 := 0xffff - uint32(%sa)\n"+ "$2a1 := 0xffff - uint32($2a)\n"+
"dstColorRGBA64.R = uint16(qr*%sa1/0xffff + uint32(%sr))\n"+ "dstColorRGBA64.R = uint16(qr*$2a1/0xffff + uint32($2r))\n"+
"dstColorRGBA64.G = uint16(qg*%sa1/0xffff + uint32(%sg))\n"+ "dstColorRGBA64.G = uint16(qg*$2a1/0xffff + uint32($2g))\n"+
"dstColorRGBA64.B = uint16(qb*%sa1/0xffff + uint32(%sb))\n"+ "dstColorRGBA64.B = uint16(qb*$2a1/0xffff + uint32($2b))\n"+
"dstColorRGBA64.A = uint16(qa*%sa1/0xffff + uint32(%sa))\n"+ "dstColorRGBA64.A = uint16(qa*$2a1/0xffff + uint32($2a))\n"+
"dst.Set(%s, %s, dstColor)", "dst.Set($0, $1, dstColor)",
args[0], args[1],
args[2], args[2],
args[2], args[2],
args[2], args[2],
args[2], args[2],
args[2], args[2],
args[0], args[1],
) )
case "*image.RGBA": case "*image.RGBA":
return fmt.Sprintf(""+ return argf(args, ""+
"%sa1 := (0xffff - uint32(%sa)) * 0x101\n"+ "$2a1 := (0xffff - uint32($2a)) * 0x101\n"+
"dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*%sa1/0xffff + uint32(%sr)) >> 8)\n"+ "dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*$2a1/0xffff + uint32($2r)) >> 8)\n"+
"dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*%sa1/0xffff + uint32(%sg)) >> 8)\n"+ "dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*$2a1/0xffff + uint32($2g)) >> 8)\n"+
"dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*%sa1/0xffff + uint32(%sb)) >> 8)\n"+ "dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*$2a1/0xffff + uint32($2b)) >> 8)\n"+
"dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*%sa1/0xffff + uint32(%sa)) >> 8)", "dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*$2a1/0xffff + uint32($2a)) >> 8)",
args[2], args[2],
args[2], args[2],
args[2], args[2],
args[2], args[2],
args[2], args[2],
) )
} }
@ -354,63 +334,54 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
case "Image": case "Image":
switch d.sType { switch d.sType {
default: default:
return fmt.Sprintf(""+ return argf(args, ""+
"dstColorRGBA64.R = uint16(%sr)\n"+ "dstColorRGBA64.R = uint16($2r)\n"+
"dstColorRGBA64.G = uint16(%sg)\n"+ "dstColorRGBA64.G = uint16($2g)\n"+
"dstColorRGBA64.B = uint16(%sb)\n"+ "dstColorRGBA64.B = uint16($2b)\n"+
"dstColorRGBA64.A = uint16(%sa)\n"+ "dstColorRGBA64.A = uint16($2a)\n"+
"dst.Set(%s, %s, dstColor)", "dst.Set($0, $1, dstColor)",
args[2], args[2], args[2], args[2],
args[0], args[1],
) )
case "*image.Gray": case "*image.Gray":
return fmt.Sprintf(""+ return argf(args, ""+
"out := uint16(%sr)\n"+ "out := uint16($2r)\n"+
"dstColorRGBA64.R = out\n"+ "dstColorRGBA64.R = out\n"+
"dstColorRGBA64.G = out\n"+ "dstColorRGBA64.G = out\n"+
"dstColorRGBA64.B = out\n"+ "dstColorRGBA64.B = out\n"+
"dstColorRGBA64.A = 0xffff\n"+ "dstColorRGBA64.A = 0xffff\n"+
"dst.Set(%s, %s, dstColor)", "dst.Set($0, $1, dstColor)",
args[2],
args[0], args[1],
) )
case "*image.YCbCr": case "*image.YCbCr":
return fmt.Sprintf(""+ return argf(args, ""+
"dstColorRGBA64.R = uint16(%sr)\n"+ "dstColorRGBA64.R = uint16($2r)\n"+
"dstColorRGBA64.G = uint16(%sg)\n"+ "dstColorRGBA64.G = uint16($2g)\n"+
"dstColorRGBA64.B = uint16(%sb)\n"+ "dstColorRGBA64.B = uint16($2b)\n"+
"dstColorRGBA64.A = 0xffff\n"+ "dstColorRGBA64.A = 0xffff\n"+
"dst.Set(%s, %s, dstColor)", "dst.Set($0, $1, dstColor)",
args[2], args[2], args[2],
args[0], args[1],
) )
} }
case "*image.RGBA": case "*image.RGBA":
switch d.sType { switch d.sType {
default: default:
return fmt.Sprintf(""+ return argf(args, ""+
"dst.Pix[d+0] = uint8(uint32(%sr) >> 8)\n"+ "dst.Pix[d+0] = uint8(uint32($2r) >> 8)\n"+
"dst.Pix[d+1] = uint8(uint32(%sg) >> 8)\n"+ "dst.Pix[d+1] = uint8(uint32($2g) >> 8)\n"+
"dst.Pix[d+2] = uint8(uint32(%sb) >> 8)\n"+ "dst.Pix[d+2] = uint8(uint32($2b) >> 8)\n"+
"dst.Pix[d+3] = uint8(uint32(%sa) >> 8)", "dst.Pix[d+3] = uint8(uint32($2a) >> 8)",
args[2], args[2], args[2], args[2],
) )
case "*image.Gray": case "*image.Gray":
return fmt.Sprintf(""+ return argf(args, ""+
"out := uint8(uint32(%sr) >> 8)\n"+ "out := uint8(uint32($2r) >> 8)\n"+
"dst.Pix[d+0] = out\n"+ "dst.Pix[d+0] = out\n"+
"dst.Pix[d+1] = out\n"+ "dst.Pix[d+1] = out\n"+
"dst.Pix[d+2] = out\n"+ "dst.Pix[d+2] = out\n"+
"dst.Pix[d+3] = 0xff", "dst.Pix[d+3] = 0xff",
args[2],
) )
case "*image.YCbCr": case "*image.YCbCr":
return fmt.Sprintf(""+ return argf(args, ""+
"dst.Pix[d+0] = uint8(uint32(%sr) >> 8)\n"+ "dst.Pix[d+0] = uint8(uint32($2r) >> 8)\n"+
"dst.Pix[d+1] = uint8(uint32(%sg) >> 8)\n"+ "dst.Pix[d+1] = uint8(uint32($2g) >> 8)\n"+
"dst.Pix[d+2] = uint8(uint32(%sb) >> 8)\n"+ "dst.Pix[d+2] = uint8(uint32($2b) >> 8)\n"+
"dst.Pix[d+3] = 0xff", "dst.Pix[d+3] = 0xff",
args[2], args[2], args[2],
) )
} }
} }
@ -429,50 +400,30 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
default: default:
log.Fatalf("bad dType %q", d.dType) log.Fatalf("bad dType %q", d.dType)
case "Image": case "Image":
ret = fmt.Sprintf(""+ ret = argf(args, ""+
"qr, qg, qb, qa := dst.At(%s, %s).RGBA()\n"+ "qr, qg, qb, qa := dst.At($0, $1).RGBA()\n"+
"%sr0 := uint32(%s(%sr * %s))\n"+ "$3r0 := uint32($2($3r * $4))\n"+
"%sg0 := uint32(%s(%sg * %s))\n"+ "$3g0 := uint32($2($3g * $4))\n"+
"%sb0 := uint32(%s(%sb * %s))\n"+ "$3b0 := uint32($2($3b * $4))\n"+
"%sa0 := uint32(%s(%sa * %s))\n"+ "$3a0 := uint32($2($3a * $4))\n"+
"%sa1 := 0xffff - %sa0\n"+ "$3a1 := 0xffff - $3a0\n"+
"dstColorRGBA64.R = uint16(qr*%sa1/0xffff + %sr0)\n"+ "dstColorRGBA64.R = uint16(qr*$3a1/0xffff + $3r0)\n"+
"dstColorRGBA64.G = uint16(qg*%sa1/0xffff + %sg0)\n"+ "dstColorRGBA64.G = uint16(qg*$3a1/0xffff + $3g0)\n"+
"dstColorRGBA64.B = uint16(qb*%sa1/0xffff + %sb0)\n"+ "dstColorRGBA64.B = uint16(qb*$3a1/0xffff + $3b0)\n"+
"dstColorRGBA64.A = uint16(qa*%sa1/0xffff + %sa0)\n"+ "dstColorRGBA64.A = uint16(qa*$3a1/0xffff + $3a0)\n"+
"dst.Set(%s, %s, dstColor)", "dst.Set($0, $1, dstColor)",
args[0], args[1],
args[3], args[2], args[3], args[4],
args[3], args[2], args[3], args[4],
args[3], args[2], args[3], args[4],
args[3], args[2], args[3], args[4],
args[3], args[3],
args[3], args[3],
args[3], args[3],
args[3], args[3],
args[3], args[3],
args[0], args[1],
) )
case "*image.RGBA": case "*image.RGBA":
ret = fmt.Sprintf(""+ ret = argf(args, ""+
"%sr0 := uint32(%s(%sr * %s))\n"+ "$3r0 := uint32($2($3r * $4))\n"+
"%sg0 := uint32(%s(%sg * %s))\n"+ "$3g0 := uint32($2($3g * $4))\n"+
"%sb0 := uint32(%s(%sb * %s))\n"+ "$3b0 := uint32($2($3b * $4))\n"+
"%sa0 := uint32(%s(%sa * %s))\n"+ "$3a0 := uint32($2($3a * $4))\n"+
"%sa1 := (0xffff - uint32(%sa0)) * 0x101\n"+ "$3a1 := (0xffff - uint32($3a0)) * 0x101\n"+
"dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*%sa1/0xffff + %sr0) >> 8)\n"+ "dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*$3a1/0xffff + $3r0) >> 8)\n"+
"dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*%sa1/0xffff + %sg0) >> 8)\n"+ "dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*$3a1/0xffff + $3g0) >> 8)\n"+
"dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*%sa1/0xffff + %sb0) >> 8)\n"+ "dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*$3a1/0xffff + $3b0) >> 8)\n"+
"dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*%sa1/0xffff + %sa0) >> 8)", "dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*$3a1/0xffff + $3a0) >> 8)",
args[3], args[2], args[3], args[4],
args[3], args[2], args[3], args[4],
args[3], args[2], args[3], args[4],
args[3], args[2], args[3], args[4],
args[3], args[3],
args[3], args[3],
args[3], args[3],
args[3], args[3],
args[3], args[3],
) )
} }
@ -483,73 +434,54 @@ func expnDollar(prefix, dollar, suffix string, d *data) string {
case "Image": case "Image":
switch d.sType { switch d.sType {
default: default:
ret = fmt.Sprintf(""+ ret = argf(args, ""+
"dstColorRGBA64.R = %s(%sr * %s)\n"+ "dstColorRGBA64.R = $2($3r * $4)\n"+
"dstColorRGBA64.G = %s(%sg * %s)\n"+ "dstColorRGBA64.G = $2($3g * $4)\n"+
"dstColorRGBA64.B = %s(%sb * %s)\n"+ "dstColorRGBA64.B = $2($3b * $4)\n"+
"dstColorRGBA64.A = %s(%sa * %s)\n"+ "dstColorRGBA64.A = $2($3a * $4)\n"+
"dst.Set(%s, %s, dstColor)", "dst.Set($0, $1, dstColor)",
args[2], args[3], args[4],
args[2], args[3], args[4],
args[2], args[3], args[4],
args[2], args[3], args[4],
args[0], args[1],
) )
case "*image.Gray": case "*image.Gray":
ret = fmt.Sprintf(""+ ret = argf(args, ""+
"out := %s(%sr * %s)\n"+ "out := $2($3r * $4)\n"+
"dstColorRGBA64.R = out\n"+ "dstColorRGBA64.R = out\n"+
"dstColorRGBA64.G = out\n"+ "dstColorRGBA64.G = out\n"+
"dstColorRGBA64.B = out\n"+ "dstColorRGBA64.B = out\n"+
"dstColorRGBA64.A = 0xffff\n"+ "dstColorRGBA64.A = 0xffff\n"+
"dst.Set(%s, %s, dstColor)", "dst.Set($0, $1, dstColor)",
args[2], args[3], args[4],
args[0], args[1],
) )
case "*image.YCbCr": case "*image.YCbCr":
ret = fmt.Sprintf(""+ ret = argf(args, ""+
"dstColorRGBA64.R = %s(%sr * %s)\n"+ "dstColorRGBA64.R = $2($3r * $4)\n"+
"dstColorRGBA64.G = %s(%sg * %s)\n"+ "dstColorRGBA64.G = $2($3g * $4)\n"+
"dstColorRGBA64.B = %s(%sb * %s)\n"+ "dstColorRGBA64.B = $2($3b * $4)\n"+
"dstColorRGBA64.A = 0xffff\n"+ "dstColorRGBA64.A = 0xffff\n"+
"dst.Set(%s, %s, dstColor)", "dst.Set($0, $1, dstColor)",
args[2], args[3], args[4],
args[2], args[3], args[4],
args[2], args[3], args[4],
args[0], args[1],
) )
} }
case "*image.RGBA": case "*image.RGBA":
switch d.sType { switch d.sType {
default: default:
ret = fmt.Sprintf(""+ ret = argf(args, ""+
"dst.Pix[d+0] = uint8(%s(%sr * %s) >> 8)\n"+ "dst.Pix[d+0] = uint8($2($3r * $4) >> 8)\n"+
"dst.Pix[d+1] = uint8(%s(%sg * %s) >> 8)\n"+ "dst.Pix[d+1] = uint8($2($3g * $4) >> 8)\n"+
"dst.Pix[d+2] = uint8(%s(%sb * %s) >> 8)\n"+ "dst.Pix[d+2] = uint8($2($3b * $4) >> 8)\n"+
"dst.Pix[d+3] = uint8(%s(%sa * %s) >> 8)", "dst.Pix[d+3] = uint8($2($3a * $4) >> 8)",
args[2], args[3], args[4],
args[2], args[3], args[4],
args[2], args[3], args[4],
args[2], args[3], args[4],
) )
case "*image.Gray": case "*image.Gray":
ret = fmt.Sprintf(""+ ret = argf(args, ""+
"out := uint8(%s(%sr * %s) >> 8)\n"+ "out := uint8($2($3r * $4) >> 8)\n"+
"dst.Pix[d+0] = out\n"+ "dst.Pix[d+0] = out\n"+
"dst.Pix[d+1] = out\n"+ "dst.Pix[d+1] = out\n"+
"dst.Pix[d+2] = out\n"+ "dst.Pix[d+2] = out\n"+
"dst.Pix[d+3] = 0xff", "dst.Pix[d+3] = 0xff",
args[2], args[3], args[4],
) )
case "*image.YCbCr": case "*image.YCbCr":
ret = fmt.Sprintf(""+ ret = argf(args, ""+
"dst.Pix[d+0] = uint8(%s(%sr * %s) >> 8)\n"+ "dst.Pix[d+0] = uint8($2($3r * $4) >> 8)\n"+
"dst.Pix[d+1] = uint8(%s(%sg * %s) >> 8)\n"+ "dst.Pix[d+1] = uint8($2($3g * $4) >> 8)\n"+
"dst.Pix[d+2] = uint8(%s(%sb * %s) >> 8)\n"+ "dst.Pix[d+2] = uint8($2($3b * $4) >> 8)\n"+
"dst.Pix[d+3] = 0xff", "dst.Pix[d+3] = 0xff",
args[2], args[3], args[4],
args[2], args[3], args[4],
args[2], args[3], args[4],
) )
} }
} }
@ -781,6 +713,17 @@ func expnSwitchYCbCr(op, dType, template string) string {
return strings.Join(lines, "\n") return strings.Join(lines, "\n")
} }
func argf(args []string, s string) string {
if len(args) > 9 {
panic("too many args")
}
for i, a := range args {
old := fmt.Sprintf("$%d", i)
s = strings.Replace(s, old, a, -1)
}
return s
}
func pixOffset(m, x, y, xstride, ystride string) string { func pixOffset(m, x, y, xstride, ystride string) string {
return fmt.Sprintf("(%s-%s.Rect.Min.Y)%s + (%s-%s.Rect.Min.X)%s", y, m, ystride, x, m, xstride) return fmt.Sprintf("(%s-%s.Rect.Min.Y)%s + (%s-%s.Rect.Min.X)%s", y, m, ystride, x, m, xstride)
} }