package ui import ( "image" "github.com/nfnt/resize" "opslag.de/schobers/geom" ) func ScaleTexture(render Renderer, texture Texture, scale float32) Texture { w := uint(texture.Width() * scale) if w == 0 { return nil } source, ok := texture.(ImageSource) if !ok { return nil } image, err := source.CreateImage() if err != nil { return nil } scaled := resize.Resize(w, 0, image, resize.Bilinear) res, err := render.CreateTextureGo(scaled, false) 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) createTexture(name string, create func() (Texture, error)) (Texture, error) { texture, err := create() if err != nil { return nil, err } t.AddTexture(name, texture) return texture, nil } func (t *Textures) CreateTexture(name string, source ImageSource) (Texture, error) { return t.createTexture(name, func() (Texture, error) { return t.render.CreateTexture(source) }) } func (t *Textures) CreateTextureGo(name string, im image.Image, source bool) (Texture, error) { return t.createTexture(name, func() (Texture, error) { return t.render.CreateTextureGo(im, source) }) } func (t *Textures) CreateTexturePath(name string, path string, source bool) (Texture, error) { return t.createTexture(name, func() (Texture, error) { return t.render.CreateTexturePath(path, source) }) } func (t *Textures) Destroy() { for _, texture := range t.textures { texture.Destroy() } t.textures = nil for _, texture := range t.scaled { texture.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) if scaled == nil { return nil } textures[scale] = scaled t.scaled[texture] = textures return scaled } func (t *Textures) ScaledHeight(texture Texture, height float32) (Texture, float32) { scale := height / texture.Height() if geom.IsNaN32(scale) { return nil, 0 } return t.Scaled(texture, scale), scale } func (t *Textures) ScaledByName(name string, scale float32) Texture { texture := t.Texture(name) if texture == nil { return nil } return t.Scaled(texture, scale) } type ScaledTextures map[float32]Texture func (t ScaledTextures) Destroy() { for _, texture := range t { texture.Destroy() } }