Skip to content

Instantly share code, notes, and snippets.

@gyuque
Created November 12, 2009 12:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gyuque/232866 to your computer and use it in GitHub Desktop.
Save gyuque/232866 to your computer and use it in GitHub Desktop.
package canvas
import "image"
func minmax(a, b int) (min, max int, reversed bool) {
if a < b {
min = a;
max = b;
reversed = false;
} else {
max = a;
min = b;
reversed = true;
}
return;
}
type Color32 uint32
func (p Color32) RGBA() (r, g, b, a uint32) {
x := uint32(p);
a = x >> 24;
a |= a << 8;
a |= a << 16;
r = (x >> 16) & 0xFF;
r |= r << 8;
r |= r << 16;
g = (x >> 8) & 0xFF;
g |= g << 8;
g |= g << 16;
b = x & 0xFF;
b |= b << 8;
b |= b << 16;
return;
}
type CanvasImage struct {
Pixel [][]Color32;
}
func (m *CanvasImage) At(x, y int) image.Color {
return m.Pixel[y][x];
}
func (m *CanvasImage) Height() int {
return len(m.Pixel);
}
func (m *CanvasImage) Width() int {
if len(m.Pixel) == 0 {
return 0
}
return len(m.Pixel[0]);
}
func EmptyCanvasImage(dx, dy int, fillColor Color32) *CanvasImage {
pix := make([][]Color32, dy);
linear := make([]Color32, dx*dy);
for i := range pix {
pix[i] = linear[dx*i : dx*(i+1)];
for k := range pix[i] {
pix[i][k] = fillColor;
}
}
return &CanvasImage{pix};
}
func (m *CanvasImage) SetAt(x, y int, c Color32) {
m.Pixel[y][x] = c;
}
func (m *CanvasImage) DrawVerticalLine(x1, y1, length int, c Color32) {
for y := 0;y < length;y++ {
m.SetAt(x1, y1+y, c);
}
}
func (m *CanvasImage) DrawLine(x1, y1, x2, y2 int, c Color32) {
x_min, x_max, xrev := minmax(x1, x2);
y_min, y_max, yrev := minmax(y1, y2);
dx := x_max - x_min;
dy := y_max - y_min;
if dx == 0 {
m.DrawVerticalLine(x_min, y_min, dy, c);
return;
}
e := 0;
if dy < dx {
var ys, y int;
if xrev==yrev {y = y_min; ys = 1;} else {y = y_max; ys = -1;}
for x := x_min;x <= x_max;x++ {
e += dy;
if (e > dx) {
e -= dx;
y += ys;
}
m.SetAt(x, y, c);
}
} else {
var xs, x int;
if yrev==xrev {x = x_min; xs = 1;} else {x = x_max; xs = -1;}
for y := y_min;y <= y_max;y++ {
e += dx;
if (e > dy) {
e -= dy;
x += xs;
}
m.SetAt(x, y, c);
}
}
}
func (m *CanvasImage) ColorModel() image.ColorModel {
return ColorModel
}
func makeColor(r, g, b, a uint32) Color32 {
return Color32(a>>24<<24 | r>>24<<16 | g>>24<<8 | b>>24)
}
func toColor(color image.Color) image.Color {
if c, ok := color.(Color32); ok {
return c
}
return makeColor(color.RGBA());
}
var ColorModel = image.ColorModelFunc(toColor)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment