diff options
Diffstat (limited to 'src/pkg/exp/draw/draw.go')
-rw-r--r-- | src/pkg/exp/draw/draw.go | 96 |
1 files changed, 48 insertions, 48 deletions
diff --git a/src/pkg/exp/draw/draw.go b/src/pkg/exp/draw/draw.go index d01cdcc16..59adf1f6a 100644 --- a/src/pkg/exp/draw/draw.go +++ b/src/pkg/exp/draw/draw.go @@ -14,8 +14,8 @@ import "image" // A draw.Image is an image.Image with a Set method to change a single pixel. type Image interface { - image.Image; - Set(x, y int, c image.Color); + image.Image + Set(x, y int, c image.Color) } // Draw aligns r.Min in dst with pt in src and mask @@ -27,7 +27,7 @@ type Image interface { func Draw(dst Image, r Rectangle, src, mask image.Image, pt Point) { // Plenty of room for optimizations here. - dx, dy := src.Width(), src.Height(); + dx, dy := src.Width(), src.Height() if mask != nil { if dx > mask.Width() { dx = mask.Width() @@ -36,8 +36,8 @@ func Draw(dst Image, r Rectangle, src, mask image.Image, pt Point) { dy = mask.Width() } } - dx -= pt.X; - dy -= pt.Y; + dx -= pt.X + dy -= pt.Y if r.Dx() > dx { r.Max.X = r.Min.X + dx } @@ -45,57 +45,57 @@ func Draw(dst Image, r Rectangle, src, mask image.Image, pt Point) { r.Max.Y = r.Min.Y + dy } - x0, x1, dx := r.Min.X, r.Max.X, 1; - y0, y1, dy := r.Min.Y, r.Max.Y, 1; + x0, x1, dx := r.Min.X, r.Max.X, 1 + y0, y1, dy := r.Min.Y, r.Max.Y, 1 if image.Image(dst) == src && r.Overlaps(r.Add(pt.Sub(r.Min))) { // Rectangles overlap: process backward? if pt.Y < r.Min.Y || pt.Y == r.Min.Y && pt.X < r.Min.X { - x0, x1, dx = x1-1, x0-1, -1; - y0, y1, dy = y1-1, y0-1, -1; + x0, x1, dx = x1-1, x0-1, -1 + y0, y1, dy = y1-1, y0-1, -1 } } - var out *image.RGBA64Color; + var out *image.RGBA64Color for y := y0; y != y1; y += dy { for x := x0; x != x1; x += dx { - sx := pt.X + x - r.Min.X; - sy := pt.Y + y - r.Min.Y; + sx := pt.X + x - r.Min.X + sy := pt.Y + y - r.Min.Y if mask == nil { - dst.Set(x, y, src.At(sx, sy)); - continue; + dst.Set(x, y, src.At(sx, sy)) + continue } - _, _, _, ma := mask.At(sx, sy).RGBA(); + _, _, _, ma := mask.At(sx, sy).RGBA() switch ma { case 0: continue case 0xFFFFFFFF: dst.Set(x, y, src.At(sx, sy)) default: - dr, dg, db, da := dst.At(x, y).RGBA(); - dr >>= 16; - dg >>= 16; - db >>= 16; - da >>= 16; - sr, sg, sb, sa := src.At(sx, sy).RGBA(); - sr >>= 16; - sg >>= 16; - sb >>= 16; - sa >>= 16; - ma >>= 16; - const M = 1<<16 - 1; - a := sa * ma / M; - dr = (dr*(M-a) + sr*ma) / M; - dg = (dg*(M-a) + sg*ma) / M; - db = (db*(M-a) + sb*ma) / M; - da = (da*(M-a) + sa*ma) / M; + dr, dg, db, da := dst.At(x, y).RGBA() + dr >>= 16 + dg >>= 16 + db >>= 16 + da >>= 16 + sr, sg, sb, sa := src.At(sx, sy).RGBA() + sr >>= 16 + sg >>= 16 + sb >>= 16 + sa >>= 16 + ma >>= 16 + const M = 1<<16 - 1 + a := sa * ma / M + dr = (dr*(M-a) + sr*ma) / M + dg = (dg*(M-a) + sg*ma) / M + db = (db*(M-a) + sb*ma) / M + da = (da*(M-a) + sa*ma) / M if out == nil { out = new(image.RGBA64Color) } - out.R = uint16(dr); - out.G = uint16(dg); - out.B = uint16(db); - out.A = uint16(da); - dst.Set(x, y, out); + out.R = uint16(dr) + out.G = uint16(dg) + out.B = uint16(db) + out.A = uint16(da) + dst.Set(x, y, out) } } } @@ -106,20 +106,20 @@ func Draw(dst Image, r Rectangle, src, mask image.Image, pt Point) { // operation ``src over dst.'' If w is positive, the border extends w pixels inside r. // If w is negative, the border extends w pixels outside r. func Border(dst Image, r Rectangle, w int, src image.Image, sp Point) { - i := w; + i := w if i > 0 { // inside r - Draw(dst, Rect(r.Min.X, r.Min.Y, r.Max.X, r.Min.Y+i), src, nil, sp); // top - Draw(dst, Rect(r.Min.X, r.Min.Y+i, r.Min.X+i, r.Max.Y-i), src, nil, sp.Add(Pt(0, i))); // left - Draw(dst, Rect(r.Max.X-i, r.Min.Y+i, r.Max.X, r.Max.Y-i), src, nil, sp.Add(Pt(r.Dx()-i, i))); // right - Draw(dst, Rect(r.Min.X, r.Max.Y-i, r.Max.X, r.Max.Y), src, nil, sp.Add(Pt(0, r.Dy()-i))); // bottom - return; + Draw(dst, Rect(r.Min.X, r.Min.Y, r.Max.X, r.Min.Y+i), src, nil, sp) // top + Draw(dst, Rect(r.Min.X, r.Min.Y+i, r.Min.X+i, r.Max.Y-i), src, nil, sp.Add(Pt(0, i))) // left + Draw(dst, Rect(r.Max.X-i, r.Min.Y+i, r.Max.X, r.Max.Y-i), src, nil, sp.Add(Pt(r.Dx()-i, i))) // right + Draw(dst, Rect(r.Min.X, r.Max.Y-i, r.Max.X, r.Max.Y), src, nil, sp.Add(Pt(0, r.Dy()-i))) // bottom + return } // outside r; - i = -i; - Draw(dst, Rect(r.Min.X-i, r.Min.Y-i, r.Max.X+i, r.Min.Y), src, nil, sp.Add(Pt(-i, -i))); // top - Draw(dst, Rect(r.Min.X-i, r.Min.Y, r.Min.X, r.Max.Y), src, nil, sp.Add(Pt(-i, 0))); // left - Draw(dst, Rect(r.Max.X, r.Min.Y, r.Max.X+i, r.Max.Y), src, nil, sp.Add(Pt(r.Dx(), 0))); // right - Draw(dst, Rect(r.Min.X-i, r.Max.Y, r.Max.X+i, r.Max.Y+i), src, nil, sp.Add(Pt(-i, 0))); // bottom + i = -i + Draw(dst, Rect(r.Min.X-i, r.Min.Y-i, r.Max.X+i, r.Min.Y), src, nil, sp.Add(Pt(-i, -i))) // top + Draw(dst, Rect(r.Min.X-i, r.Min.Y, r.Min.X, r.Max.Y), src, nil, sp.Add(Pt(-i, 0))) // left + Draw(dst, Rect(r.Max.X, r.Min.Y, r.Max.X+i, r.Max.Y), src, nil, sp.Add(Pt(r.Dx(), 0))) // right + Draw(dst, Rect(r.Min.X-i, r.Max.Y, r.Max.X+i, r.Max.Y+i), src, nil, sp.Add(Pt(-i, 0))) // bottom } |