Freetype-Go: move the pixel offset from the painter to the rasterizer.

R=rsc, r
CC=rog, golang-dev
http://codereview.appspot.com/1332041
This commit is contained in:
Nigel Tao 2010-05-26 13:23:24 -07:00
parent aaeb64cef7
commit 0c4b93bdc3
3 changed files with 23 additions and 29 deletions

View File

@ -145,7 +145,7 @@ func (c *RGBAContext) DrawText(pt raster.Point, s string) (err os.Error) {
advance, x0 := 0, pt.X advance, x0 := 0, pt.X
dx := raster.Fixed(-c.xmin << 8) dx := raster.Fixed(-c.xmin << 8)
dy := raster.Fixed(-c.ymin << 8) dy := raster.Fixed(-c.ymin << 8)
c.rp.Dy, y = c.ymin+int(pt.Y>>8), pt.Y&0xff c.r.Dy, y = c.ymin+int(pt.Y>>8), pt.Y&0xff
y += dy y += dy
prev, hasPrev := truetype.Index(0), false prev, hasPrev := truetype.Index(0), false
for _, ch := range s { for _, ch := range s {
@ -170,7 +170,7 @@ func (c *RGBAContext) DrawText(pt raster.Point, s string) (err os.Error) {
x = x0 + c.FUnitToFixed(advance) x = x0 + c.FUnitToFixed(advance)
// Break the co-ordinate down into an integer pixel part and a // Break the co-ordinate down into an integer pixel part and a
// sub-pixel part, making sure that the latter is non-negative. // sub-pixel part, making sure that the latter is non-negative.
c.rp.Dx, x = c.xmin+int(x>>8), x&0xff c.r.Dx, x = c.xmin+int(x>>8), x&0xff
x += dx x += dx
// Draw the contours. // Draw the contours.
c.r.Clear() c.r.Clear()

View File

@ -39,38 +39,34 @@ type AlphaPainter struct {
Image *image.Alpha Image *image.Alpha
// The Porter-Duff composition operator. // The Porter-Duff composition operator.
Op draw.Op Op draw.Op
// An offset (in pixels) to the painted spans.
Dx, Dy int
} }
// Paint satisfies the Painter interface by painting ss onto an image.Alpha. // Paint satisfies the Painter interface by painting ss onto an image.Alpha.
func (r *AlphaPainter) Paint(ss []Span, done bool) { func (r *AlphaPainter) Paint(ss []Span, done bool) {
for _, s := range ss { for _, s := range ss {
y := r.Dy + s.Y if s.Y < 0 {
if y < 0 {
continue continue
} }
if y >= len(r.Image.Pixel) { if s.Y >= len(r.Image.Pixel) {
return return
} }
p := r.Image.Pixel[y] p := r.Image.Pixel[s.Y]
x0, x1 := r.Dx+s.X0, r.Dx+s.X1 if s.X0 < 0 {
if x0 < 0 { s.X0 = 0
x0 = 0
} }
if x1 > len(p) { if s.X1 > len(p) {
x1 = len(p) s.X1 = len(p)
} }
if r.Op == draw.Over { if r.Op == draw.Over {
a := int(s.A >> 24) a := int(s.A >> 24)
for x := x0; x < x1; x++ { for x := s.X0; x < s.X1; x++ {
ax := int(p[x].A) ax := int(p[x].A)
ax = (ax*255 + (255-ax)*a) / 255 ax = (ax*255 + (255-ax)*a) / 255
p[x] = image.AlphaColor{uint8(ax)} p[x] = image.AlphaColor{uint8(ax)}
} }
} else { } else {
color := image.AlphaColor{uint8(s.A >> 24)} color := image.AlphaColor{uint8(s.A >> 24)}
for x := x0; x < x1; x++ { for x := s.X0; x < s.X1; x++ {
p[x] = color p[x] = color
} }
} }
@ -87,8 +83,6 @@ type RGBAPainter struct {
Image *image.RGBA Image *image.RGBA
// The Porter-Duff composition operator. // The Porter-Duff composition operator.
Op draw.Op Op draw.Op
// An offset (in pixels) to the painted spans.
Dx, Dy int
// The 16-bit color to paint the spans. // The 16-bit color to paint the spans.
cr, cg, cb, ca uint32 cr, cg, cb, ca uint32
} }
@ -96,22 +90,20 @@ type RGBAPainter struct {
// Paint satisfies the Painter interface by painting ss onto an image.RGBA. // Paint satisfies the Painter interface by painting ss onto an image.RGBA.
func (r *RGBAPainter) Paint(ss []Span, done bool) { func (r *RGBAPainter) Paint(ss []Span, done bool) {
for _, s := range ss { for _, s := range ss {
y := r.Dy + s.Y if s.Y < 0 {
if y < 0 {
continue continue
} }
if y >= len(r.Image.Pixel) { if s.Y >= len(r.Image.Pixel) {
return return
} }
p := r.Image.Pixel[y] p := r.Image.Pixel[s.Y]
x0, x1 := r.Dx+s.X0, r.Dx+s.X1 if s.X0 < 0 {
if x0 < 0 { s.X0 = 0
x0 = 0
} }
if x1 > len(p) { if s.X1 > len(p) {
x1 = len(p) s.X1 = len(p)
} }
for x := x0; x < x1; x++ { for x := s.X0; x < s.X1; x++ {
// This code is duplicated from drawGlyphOver in $GOROOT/src/pkg/exp/draw/draw.go. // This code is duplicated from drawGlyphOver in $GOROOT/src/pkg/exp/draw/draw.go.
// TODO(nigeltao): Factor out common code into a utility function, once the compiler // TODO(nigeltao): Factor out common code into a utility function, once the compiler
// can inline such function calls. // can inline such function calls.

View File

@ -64,6 +64,8 @@ type Rasterizer struct {
// If false, the default behavior is to use the even-odd winding fill // If false, the default behavior is to use the even-odd winding fill
// rule during Rasterize. // rule during Rasterize.
UseNonZeroWinding bool UseNonZeroWinding bool
// An offset (in pixels) to the painted spans.
Dx, Dy int
// The width of the Rasterizer. The height is implicit in len(cellIndex). // The width of the Rasterizer. The height is implicit in len(cellIndex).
width int width int
@ -501,7 +503,7 @@ func (r *Rasterizer) Rasterize(p Painter) {
xi1 = r.width xi1 = r.width
} }
if xi0 < xi1 { if xi0 < xi1 {
r.spanBuf[s] = Span{yi, xi0, xi1, alpha} r.spanBuf[s] = Span{yi + r.Dy, xi0 + r.Dx, xi1 + r.Dx, alpha}
s++ s++
} }
} }
@ -518,7 +520,7 @@ func (r *Rasterizer) Rasterize(p Painter) {
xi1 = r.width xi1 = r.width
} }
if xi0 < xi1 { if xi0 < xi1 {
r.spanBuf[s] = Span{yi, xi0, xi1, alpha} r.spanBuf[s] = Span{yi + r.Dy, xi0 + r.Dx, xi1 + r.Dx, alpha}
s++ s++
} }
} }