stone/image.go

143 lines
2.8 KiB
Go

package stone
import "sync"
import "image"
import "image/color"
type ImageManager struct {
lock sync.RWMutex
images []*ColorImage
}
func (manager *ImageManager) For (callback func (im *ColorImage)) {
manager.lock.RLock()
defer manager.lock.RUnlock()
for _, im := range manager.images {
callback(im)
}
}
func (manager *ImageManager) Add (im *ColorImage) {
manager.lock.Lock()
defer manager.lock.Unlock()
manager.images = append(manager.images, im)
}
func (manager *ImageManager) Size () (size int) {
manager.lock.RLock()
defer manager.lock.RUnlock()
size = len(manager.images)
return
}
func (manager *ImageManager) At (index int) (im *ColorImage) {
manager.lock.RLock()
defer manager.lock.RUnlock()
if index < 0 || index > len(manager.images) { return }
im = manager.images[index]
return
}
func (manager *ImageManager) Remove (im *ColorImage) (removed bool) {
manager.lock.Lock()
defer manager.lock.Unlock()
index := 0
for manager.images[index] != im && index < len(manager.images) {
index ++
}
if index >= len(manager.images) { return }
manager.images = append (
manager.images[:index],
manager.images[index + 1:]...)
removed = true
return
}
type ColorImage struct {
x, y int
width, height int
bufferWidth, bufferHeight int
cellWidth, cellHeight int
buffer []color.RGBA
clean bool
}
func (im *ColorImage) Model () (model color.Model) {
model = color.RGBAModel
return
}
func (im *ColorImage) Bounds () (bounds image.Rectangle) {
bounds.Max.X = im.width
bounds.Max.Y = im.height
return
}
func (im *ColorImage) Size () (width, height int) {
width = im.width
height = im.height
return
}
func (im *ColorImage) SetSize (width, height int) {
im.width = width
im.height = height
im.bufferWidth = im.cellWidth * im.width
im.bufferHeight = im.cellHeight * im.height
im.buffer = make([]color.RGBA, im.bufferWidth * im.bufferHeight)
im.clean = false
}
func (im *ColorImage) At (x, y int) (pixel color.Color) {
if im.outOfBounds(x, y) { return }
pixel = im.buffer[x + y * im.width]
return
}
func (im *ColorImage) AtRGBA (x, y int) (pixel color.RGBA) {
if im.outOfBounds(x, y) { return }
pixel = im.buffer[x + y * im.width]
return
}
func (im *ColorImage) Set (x, y int, pixel color.Color) {
if im.outOfBounds(x, y) { return }
r, g, b, a := pixel.RGBA()
im.buffer[x + y * im.width] = color.RGBA {
R: uint8(r >> 8),
G: uint8(g >> 8),
B: uint8(b >> 8),
A: uint8(a >> 8),
}
im.clean = false
return
}
func (im *ColorImage) SetRGBA (x, y int, pixel color.RGBA) {
if im.outOfBounds(x, y) { return }
im.buffer[x + y * im.width] = pixel
return
}
func (im *ColorImage) MarkClean () {
im.clean = true
}
func (im *ColorImage) outOfBounds (x, y int) (outOfBounds bool) {
outOfBounds =
x >= im.width ||
y >= im.height ||
x < 0 ||
y < 0
return
}