zntg/ui/images.go

124 lines
2.1 KiB
Go

package ui
import (
"image"
"github.com/nfnt/resize"
"opslag.de/schobers/geom"
)
type CreateImageFn func() (image.Image, error)
func ScaleImage(render Renderer, im Image, scale float32) Image {
w := uint(im.Width() * scale)
if w == 0 {
return nil
}
scaled := resize.Resize(w, 0, im.Image(), resize.Bilinear)
res, err := render.CreateImage(scaled)
if err != nil {
return nil
}
return res
}
type Images struct {
render Renderer
ims map[string]Image
scaled map[Image]ScaledImages
}
func NewImages(render Renderer) *Images {
return &Images{render, map[string]Image{}, map[Image]ScaledImages{}}
}
func (i *Images) AddImage(name string, im Image) {
curr := i.ims[name]
if curr != nil {
curr.Destroy()
}
i.ims[name] = im
}
func (i *Images) AddImageFn(name string, create CreateImageFn) error {
im, err := create()
if err != nil {
return err
}
return i.AddImageNative(name, im)
}
func (i *Images) AddImageNative(name string, im image.Image) error {
m, err := i.render.CreateImage(im)
if err != nil {
return err
}
i.AddImage(name, m)
return nil
}
func (i *Images) Destroy() {
for _, im := range i.ims {
im.Destroy()
}
i.ims = nil
for _, ims := range i.scaled {
ims.Destroy()
}
i.scaled = nil
}
func (i *Images) Image(name string) Image {
im, ok := i.ims[name]
if ok {
return im
}
return nil
}
func (i *Images) Scaled(im Image, scale float32) Image {
if scale <= 0 {
return nil
}
if scale == 1 {
return im
}
ims := i.scaled[im]
if ims == nil {
ims = make(ScaledImages)
} else {
scaled := ims[scale]
if scaled != nil {
return scaled
}
}
scaled := ScaleImage(i.render, im, scale)
ims[scale] = scaled
i.scaled[im] = ims
return scaled
}
func (i *Images) ScaledHeight(im Image, height float32) (Image, float32) {
scale := height / im.Height()
if geom.IsNaN32(scale) {
return nil, 0
}
return i.Scaled(im, scale), scale
}
func (i *Images) ScaledByName(name string, scale float32) Image {
im := i.Image(name)
if im == nil {
return nil
}
return i.Scaled(im, scale)
}
type ScaledImages map[float32]Image
func (i ScaledImages) Destroy() {
for _, im := range i {
im.Destroy()
}
}