package ui import ( "image" "github.com/nfnt/resize" "opslag.de/schobers/geom" ) type CreateImageFn func() (image.Image, error) func ScaleTexture(render Renderer, texture Texture, scale float32) Texture { w := uint(texture.Width() * scale) if w == 0 { return nil } scaled := resize.Resize(w, 0, texture.Texture(), resize.Bilinear) res, err := render.CreateTexture(scaled) if err != nil { return nil } return res } type Textures struct { render Renderer textures map[string]Texture scaled map[Texture]ScaledTextures } func NewTextures(render Renderer) *Textures { return &Textures{render, map[string]Texture{}, map[Texture]ScaledTextures{}} } func (t *Textures) AddTexture(name string, texture Texture) { curr := t.textures[name] if curr != nil { curr.Destroy() } t.textures[name] = texture } func (t *Textures) AddTextureFn(name string, create CreateImageFn) error { im, err := create() if err != nil { return err } return t.AddTextureNative(name, im) } func (t *Textures) AddTextureNative(name string, im image.Image) error { texture, err := t.render.CreateTexture(im) if err != nil { return err } t.AddTexture(name, texture) return nil } func (t *Textures) Destroy() { for _, texture := range t.textures { texture.Destroy() } t.textures = nil for _, textures := range t.scaled { textures.Destroy() } t.scaled = nil } func (t *Textures) Texture(name string) Texture { texture, ok := t.textures[name] if ok { return texture } return nil } func (t *Textures) Scaled(texture Texture, scale float32) Texture { if scale <= 0 { return nil } if scale == 1 { return texture } textures := t.scaled[texture] if textures == nil { textures = make(ScaledTextures) } else { scaled := textures[scale] if scaled != nil { return scaled } } scaled := ScaleTexture(t.render, texture, scale) textures[scale] = scaled t.scaled[texture] = textures return scaled } func (t *Textures) ScaledHeight(textures Texture, height float32) (Texture, float32) { scale := height / textures.Height() if geom.IsNaN32(scale) { return nil, 0 } return t.Scaled(textures, scale), scale } func (t *Textures) ScaledByName(name string, scale float32) Texture { textures := t.Texture(name) if textures == nil { return nil } return t.Scaled(textures, scale) } type ScaledTextures map[float32]Texture func (t ScaledTextures) Destroy() { for _, textures := range t { textures.Destroy() } }