Commit 7d3173fc authored by Nigel Tao's avatar Nigel Tao

exp/draw: remove the Color, Point and Rectangle types.

image: introduce Transparent and Opaque.

R=r
CC=golang-dev
https://golang.org/cl/1947042
parent 4368a787
......@@ -10,7 +10,7 @@
package main
import . "exp/draw"
import . "image"
var pieces4 = []Piece{
Piece{0, 0, Point{4, 1}, []Point{Point{0, 0}, Point{1, 0}, Point{1, 0}, Point{1, 0}}, nil, nil},
......
This diff is collapsed.
......@@ -6,8 +6,6 @@ include ../../../Make.$(GOARCH)
TARG=exp/draw
GOFILES=\
arith.go\
color.go\
draw.go\
event.go\
......
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package draw
// A Point is an X, Y coordinate pair.
type Point struct {
X, Y int
}
// ZP is the zero Point.
var ZP Point
// A Rectangle contains the Points with Min.X <= X < Max.X, Min.Y <= Y < Max.Y.
type Rectangle struct {
Min, Max Point
}
// ZR is the zero Rectangle.
var ZR Rectangle
// Pt is shorthand for Point{X, Y}.
func Pt(X, Y int) Point { return Point{X, Y} }
// Rect is shorthand for Rectangle{Pt(x0, y0), Pt(x1, y1)}.
func Rect(x0, y0, x1, y1 int) Rectangle { return Rectangle{Point{x0, y0}, Point{x1, y1}} }
// Rpt is shorthand for Rectangle{min, max}.
func Rpt(min, max Point) Rectangle { return Rectangle{min, max} }
// Add returns the sum of p and q: Pt(p.X+q.X, p.Y+q.Y).
func (p Point) Add(q Point) Point { return Point{p.X + q.X, p.Y + q.Y} }
// Sub returns the difference of p and q: Pt(p.X-q.X, p.Y-q.Y).
func (p Point) Sub(q Point) Point { return Point{p.X - q.X, p.Y - q.Y} }
// Mul returns p scaled by k: Pt(p.X*k p.Y*k).
func (p Point) Mul(k int) Point { return Point{p.X * k, p.Y * k} }
// Div returns p divided by k: Pt(p.X/k, p.Y/k).
func (p Point) Div(k int) Point { return Point{p.X / k, p.Y / k} }
// Eq returns true if p and q are equal.
func (p Point) Eq(q Point) bool { return p.X == q.X && p.Y == q.Y }
// In returns true if p is within r.
func (p Point) In(r Rectangle) bool {
return p.X >= r.Min.X && p.X < r.Max.X &&
p.Y >= r.Min.Y && p.Y < r.Max.Y
}
// Inset returns the rectangle r inset by n: Rect(r.Min.X+n, r.Min.Y+n, r.Max.X-n, r.Max.Y-n).
func (r Rectangle) Inset(n int) Rectangle {
return Rectangle{Point{r.Min.X + n, r.Min.Y + n}, Point{r.Max.X - n, r.Max.Y - n}}
}
// Add returns the rectangle r translated by p: Rpt(r.Min.Add(p), r.Max.Add(p)).
func (r Rectangle) Add(p Point) Rectangle { return Rectangle{r.Min.Add(p), r.Max.Add(p)} }
// Sub returns the rectangle r translated by -p: Rpt(r.Min.Sub(p), r.Max.Sub(p)).
func (r Rectangle) Sub(p Point) Rectangle { return Rectangle{r.Min.Sub(p), r.Max.Sub(p)} }
// Canon returns a canonical version of r: the returned rectangle
// has Min.X <= Max.X and Min.Y <= Max.Y.
func (r Rectangle) Canon() Rectangle {
if r.Max.X < r.Min.X {
r.Min.X, r.Max.X = r.Max.X, r.Min.X
}
if r.Max.Y < r.Min.Y {
r.Min.Y, r.Max.Y = r.Max.Y, r.Min.Y
}
return r
}
// Overlaps returns true if r and r1 cross; that is, it returns true if they share any point.
func (r Rectangle) Overlaps(r1 Rectangle) bool {
return r.Min.X < r1.Max.X && r1.Min.X < r.Max.X &&
r.Min.Y < r1.Max.Y && r1.Min.Y < r.Max.Y
}
// Empty retruns true if r contains no points.
func (r Rectangle) Empty() bool { return r.Max.X <= r.Min.X || r.Max.Y <= r.Min.Y }
// InRect returns true if all the points in r are also in r1.
func (r Rectangle) In(r1 Rectangle) bool {
if r.Empty() {
return true
}
if r1.Empty() {
return false
}
return r1.Min.X <= r.Min.X && r.Max.X <= r1.Max.X &&
r1.Min.Y <= r.Min.Y && r.Max.Y <= r1.Max.Y
}
// Combine returns the smallest rectangle containing all points from r and from r1.
func (r Rectangle) Combine(r1 Rectangle) Rectangle {
if r.Empty() {
return r1
}
if r1.Empty() {
return r
}
if r.Min.X > r1.Min.X {
r.Min.X = r1.Min.X
}
if r.Min.Y > r1.Min.Y {
r.Min.Y = r1.Min.Y
}
if r.Max.X < r1.Max.X {
r.Max.X = r1.Max.X
}
if r.Max.Y < r1.Max.Y {
r.Max.Y = r1.Max.Y
}
return r
}
// Clip returns the largest rectangle containing only points shared by r and r1.
func (r Rectangle) Clip(r1 Rectangle) Rectangle {
if r.Empty() {
return r
}
if r1.Empty() {
return r1
}
if !r.Overlaps(r1) {
return Rectangle{r.Min, r.Min}
}
if r.Min.X < r1.Min.X {
r.Min.X = r1.Min.X
}
if r.Min.Y < r1.Min.Y {
r.Min.Y = r1.Min.Y
}
if r.Max.X > r1.Max.X {
r.Max.X = r1.Max.X
}
if r.Max.Y > r1.Max.Y {
r.Max.Y = r1.Max.Y
}
return r
}
// Dx returns the width of the rectangle r: r.Max.X - r.Min.X.
func (r Rectangle) Dx() int { return r.Max.X - r.Min.X }
// Dy returns the width of the rectangle r: r.Max.Y - r.Min.Y.
func (r Rectangle) Dy() int { return r.Max.Y - r.Min.Y }
// Eq returns true if r and r1 are equal.
func (r Rectangle) Eq(r1 Rectangle) bool {
return r.Min.Eq(r1.Min) && r.Max.Eq(r1.Max)
}
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package draw
import "image"
// A Color represents a color with 8-bit R, G, B, and A values,
// packed into a uint32—0xRRGGBBAA—so that comparison
// is defined on colors.
// Color implements image.Color.
// Color also implements image.Image: it is a
// 10⁹x10⁹-pixel image of uniform color.
type Color uint32
// Check that Color implements image.Color and image.Image
var _ image.Color = Black
var _ image.Image = Black
var (
Opaque Color = 0xFFFFFFFF
Transparent Color = 0x00000000
Black Color = 0x000000FF
White Color = 0xFFFFFFFF
Red Color = 0xFF0000FF
Green Color = 0x00FF00FF
Blue Color = 0x0000FFFF
Cyan Color = 0x00FFFFFF
Magenta Color = 0xFF00FFFF
Yellow Color = 0xFFFF00FF
PaleYellow Color = 0xFFFFAAFF
DarkYellow Color = 0xEEEE9EFF
DarkGreen Color = 0x448844FF
PaleGreen Color = 0xAAFFAAFF
MedGreen Color = 0x88CC88FF
DarkBlue Color = 0x000055FF
PaleBlueGreen Color = 0xAAFFFFFF
PaleBlue Color = 0x0000BBFF
BlueGreen Color = 0x008888FF
GreyGreen Color = 0x55AAAAFF
PaleGreyGreen Color = 0x9EEEEEFF
YellowGreen Color = 0x99994CFF
MedBlue Color = 0x000099FF
GreyBlue Color = 0x005DBBFF
PaleGreyBlue Color = 0x4993DDFF
PurpleBlue Color = 0x8888CCFF
)
func (c Color) RGBA() (r, g, b, a uint32) {
x := uint32(c)
r, g, b, a = x>>24, (x>>16)&0xFF, (x>>8)&0xFF, x&0xFF
r |= r << 8
g |= g << 8
b |= b << 8
a |= a << 8
return
}
// SetAlpha returns the color obtained by changing
// c's alpha value to a and scaling r, g, and b appropriately.
func (c Color) SetAlpha(a uint8) Color {
r, g, b, oa := c>>24, (c>>16)&0xFF, (c>>8)&0xFF, c&0xFF
if oa == 0 {
return 0
}
r = r * Color(a) / oa
if r < 0 {
r = 0
}
if r > 0xFF {
r = 0xFF
}
g = g * Color(a) / oa
if g < 0 {
g = 0
}
if g > 0xFF {
g = 0xFF
}
b = b * Color(a) / oa
if b < 0 {
b = 0
}
if b > 0xFF {
b = 0xFF
}
return r<<24 | g<<16 | b<<8 | Color(a)
}
func (c Color) Bounds() image.Rectangle { return image.Rect(0, 0, 1e9, 1e9) }
func (c Color) At(x, y int) image.Color { return c }
func toColor(color image.Color) image.Color {
if c, ok := color.(Color); ok {
return c
}
r, g, b, a := color.RGBA()
return Color(r>>8<<24 | g>>8<<16 | b>>8<<8 | a>>8)
}
func (c Color) ColorModel() image.ColorModel { return image.ColorModelFunc(toColor) }
......@@ -34,15 +34,15 @@ type Image interface {
}
// Draw calls DrawMask with a nil mask and an Over op.
func Draw(dst Image, r Rectangle, src image.Image, sp Point) {
DrawMask(dst, r, src, sp, nil, ZP, Over)
func Draw(dst Image, r image.Rectangle, src image.Image, sp image.Point) {
DrawMask(dst, r, src, sp, nil, image.ZP, Over)
}
// DrawMask aligns r.Min in dst with sp in src and mp in mask and then replaces the rectangle r
// in dst with the result of a Porter-Duff composition. A nil mask is treated as opaque.
// The implementation is simple and slow.
// TODO(nigeltao): Optimize this.
func DrawMask(dst Image, r Rectangle, src image.Image, sp Point, mask image.Image, mp Point, op Op) {
func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op) {
sb := src.Bounds()
dx, dy := sb.Dx()-sp.X, sb.Dy()-sp.Y
if mask != nil {
......@@ -160,7 +160,7 @@ func DrawMask(dst Image, r Rectangle, src image.Image, sp Point, mask image.Imag
}
}
func drawFillOver(dst *image.RGBA, r Rectangle, src image.ColorImage) {
func drawFillOver(dst *image.RGBA, r image.Rectangle, src image.ColorImage) {
cr, cg, cb, ca := src.RGBA()
// The 0x101 is here for the same reason as in drawRGBA.
a := (m - ca) * 0x101
......@@ -179,7 +179,7 @@ func drawFillOver(dst *image.RGBA, r Rectangle, src image.ColorImage) {
}
}
func drawCopyOver(dst *image.RGBA, r Rectangle, src *image.RGBA, sp Point) {
func drawCopyOver(dst *image.RGBA, r image.Rectangle, src *image.RGBA, sp image.Point) {
x0, x1 := r.Min.X, r.Max.X
y0, y1 := r.Min.Y, r.Max.Y
for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
......@@ -207,7 +207,7 @@ func drawCopyOver(dst *image.RGBA, r Rectangle, src *image.RGBA, sp Point) {
}
}
func drawGlyphOver(dst *image.RGBA, r Rectangle, src image.ColorImage, mask *image.Alpha, mp Point) {
func drawGlyphOver(dst *image.RGBA, r image.Rectangle, src image.ColorImage, mask *image.Alpha, mp image.Point) {
x0, x1 := r.Min.X, r.Max.X
y0, y1 := r.Min.Y, r.Max.Y
cr, cg, cb, ca := src.RGBA()
......@@ -237,7 +237,7 @@ func drawGlyphOver(dst *image.RGBA, r Rectangle, src image.ColorImage, mask *ima
}
}
func drawFillSrc(dst *image.RGBA, r Rectangle, src image.ColorImage) {
func drawFillSrc(dst *image.RGBA, r image.Rectangle, src image.ColorImage) {
if r.Dy() < 1 {
return
}
......@@ -261,7 +261,7 @@ func drawFillSrc(dst *image.RGBA, r Rectangle, src image.ColorImage) {
}
}
func drawCopySrc(dst *image.RGBA, r Rectangle, src *image.RGBA, sp Point) {
func drawCopySrc(dst *image.RGBA, r image.Rectangle, src *image.RGBA, sp image.Point) {
dx0, dx1 := r.Min.X, r.Max.X
dy0, dy1 := r.Min.Y, r.Max.Y
sx0, sx1 := sp.X, sp.X+dx1-dx0
......@@ -278,7 +278,7 @@ func drawCopySrc(dst *image.RGBA, r Rectangle, src *image.RGBA, sp Point) {
}
}
func drawRGBA(dst *image.RGBA, r Rectangle, src image.Image, sp Point, mask image.Image, mp Point, op Op) {
func drawRGBA(dst *image.RGBA, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op) {
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(sp.Sub(r.Min))) {
......@@ -334,21 +334,21 @@ func drawRGBA(dst *image.RGBA, r Rectangle, src image.Image, sp Point, mask imag
// in a w-pixel border around r in dst with the result of the Porter-Duff compositing
// 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) {
func Border(dst Image, r image.Rectangle, w int, src image.Image, sp image.Point) {
i := w
if i > 0 {
// inside r
Draw(dst, Rect(r.Min.X, r.Min.Y, r.Max.X, r.Min.Y+i), src, sp) // top
Draw(dst, Rect(r.Min.X, r.Min.Y+i, r.Min.X+i, r.Max.Y-i), src, 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, 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, sp.Add(Pt(0, r.Dy()-i))) // bottom
Draw(dst, image.Rect(r.Min.X, r.Min.Y, r.Max.X, r.Min.Y+i), src, sp) // top
Draw(dst, image.Rect(r.Min.X, r.Min.Y+i, r.Min.X+i, r.Max.Y-i), src, sp.Add(image.Pt(0, i))) // left
Draw(dst, image.Rect(r.Max.X-i, r.Min.Y+i, r.Max.X, r.Max.Y-i), src, sp.Add(image.Pt(r.Dx()-i, i))) // right
Draw(dst, image.Rect(r.Min.X, r.Max.Y-i, r.Max.X, r.Max.Y), src, sp.Add(image.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, sp.Add(Pt(-i, -i))) // top
Draw(dst, Rect(r.Min.X-i, r.Min.Y, r.Min.X, r.Max.Y), src, sp.Add(Pt(-i, 0))) // left
Draw(dst, Rect(r.Max.X, r.Min.Y, r.Max.X+i, r.Max.Y), src, 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, sp.Add(Pt(-i, 0))) // bottom
Draw(dst, image.Rect(r.Min.X-i, r.Min.Y-i, r.Max.X+i, r.Min.Y), src, sp.Add(image.Pt(-i, -i))) // top
Draw(dst, image.Rect(r.Min.X-i, r.Min.Y, r.Min.X, r.Max.Y), src, sp.Add(image.Pt(-i, 0))) // left
Draw(dst, image.Rect(r.Max.X, r.Min.Y, r.Max.X+i, r.Max.Y), src, sp.Add(image.Pt(r.Dx(), 0))) // right
Draw(dst, image.Rect(r.Min.X-i, r.Max.Y, r.Max.X+i, r.Max.Y+i), src, sp.Add(image.Pt(-i, 0))) // bottom
}
......@@ -4,6 +4,10 @@
package draw
import (
"image"
)
// A Context represents a single graphics window.
type Context interface {
// Screen returns an editable Image of window.
......@@ -40,7 +44,7 @@ type Context interface {
// A Mouse represents the state of the mouse.
type Mouse struct {
Buttons int // bit mask of buttons: 1<<0 is left, 1<<1 middle, 1<<2 right
Point // location of cursor
Nsec int64 // time stamp
Buttons int // bit mask of buttons: 1<<0 is left, 1<<1 middle, 1<<2 right
image.Point // location of cursor
Nsec int64 // time stamp
}
......@@ -6,9 +6,13 @@ package image
var (
// Black is an opaque black ColorImage.
Black = ColorImage{RGBAColor{0x00, 0x00, 0x00, 0xff}}
Black = ColorImage{Gray16Color{0}}
// White is an opaque white ColorImage.
White = ColorImage{RGBAColor{0xff, 0xff, 0xff, 0xff}}
White = ColorImage{Gray16Color{0xffff}}
// Transparent is a fully transparent ColorImage.
Transparent = ColorImage{Alpha16Color{0}}
// Opaque is a fully opaque ColorImage.
Opaque = ColorImage{Alpha16Color{0xffff}}
)
// A ColorImage is a practically infinite-sized Image of uniform Color.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment