This repository has been archived on 2024-06-02. You can view files and clone it, but cannot push or open issues or pull requests.
x/canvas/texture.go

81 lines
2.1 KiB
Go
Raw Normal View History

2023-08-22 19:24:38 -06:00
package xcanvas
import "image"
2023-08-24 13:54:22 -06:00
import "git.tebibyte.media/tomo/tomo/canvas"
2023-08-22 19:24:38 -06:00
// Texture is a read-only image texture that can be quickly written to a canvas.
// It must be closed manually after use.
type Texture struct {
pix []uint8
stride int
rect image.Rectangle
transparent bool
}
// NewTextureFrom creates a new texture from a source image.
func NewTextureFrom (source image.Image) *Texture {
bounds := source.Bounds()
texture := &Texture {
pix: make([]uint8, bounds.Dx() * bounds.Dy() * 4),
2023-08-29 13:52:24 -06:00
stride: bounds.Dx() * 4,
2023-08-22 19:24:38 -06:00
rect: bounds.Sub(bounds.Min),
}
index := 0
var point image.Point
for point.Y = bounds.Min.Y; point.Y < bounds.Max.Y; point.Y ++ {
for point.X = bounds.Min.X; point.X < bounds.Max.X; point.X ++ {
r, g, b, a := source.At(point.X, point.Y).RGBA()
texture.pix[index + 0] = uint8(b >> 8)
texture.pix[index + 1] = uint8(g >> 8)
texture.pix[index + 2] = uint8(r >> 8)
texture.pix[index + 3] = uint8(a >> 8)
index += 4
if a != 0xFFFF {
texture.transparent = true
}
}}
2023-08-22 19:24:38 -06:00
return texture
}
2023-09-04 00:33:47 -06:00
// Bounds returns the bounding rectangle of this texture.
func (this *Texture) Bounds () image.Rectangle {
return this.rect
}
2023-08-22 19:24:38 -06:00
// Opaque reports whether or not the texture is fully opaque.
func (this *Texture) Opaque () bool {
return !this.transparent
}
// Close frees the texture from memory.
func (this *Texture) Close () error {
// i lied we dont actually need to close this, but we will once this
// texture resides on the x server or in video memory.
return nil
}
// Clip returns a subset of this texture that points to the same data.
2023-08-24 13:54:22 -06:00
func (this *Texture) Clip (bounds image.Rectangle) canvas.Texture {
2023-08-22 19:24:38 -06:00
clipped := *this
clipped.rect = bounds
return &clipped
}
func (this *Texture) PixOffset (x, y int) int {
x = wrap(x, this.rect.Min.X, this.rect.Max.X)
y = wrap(y, this.rect.Min.Y, this.rect.Max.Y)
return x * 4 + y * this.stride
}
2023-08-29 13:52:24 -06:00
2023-08-24 13:54:22 -06:00
// AssertTexture checks if a given canvas.Texture is a texture from this package.
func AssertTexture (unknown canvas.Texture) *Texture {
2023-08-23 17:21:28 -06:00
if tx, ok := unknown.(*Texture); ok {
return tx
} else {
panic("foregin texture implementation, i did not make this!")
}
}