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() } }