Skip to content

Commit

Permalink
Add atlas support for file loading
Browse files Browse the repository at this point in the history
  • Loading branch information
Allen Ray committed Aug 30, 2024
1 parent 7eae950 commit cf83cb7
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 32 deletions.
8 changes: 5 additions & 3 deletions data.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ func verticalFlip(rgba *image.RGBA) {
}
}

func defaultDecoder(r io.Reader) (image.Image, error) {
type DecoderFunc func(io.Reader) (image.Image, error)

func DefaultDecoderFunc(r io.Reader) (image.Image, error) {
i, _, err := image.Decode(r)
return i, err
}
Expand All @@ -200,15 +202,15 @@ func defaultDecoder(r io.Reader) (image.Image, error) {
// formats you wish to use.
//
// See the example https://github.com/gopxl/pixel-examples/tree/main/core/loadingpictures.
func PictureDataFromFile(path string, decoder func(r io.Reader) (image.Image, error)) (*PictureData, error) {
func PictureDataFromFile(path string, decoder DecoderFunc) (*PictureData, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()

if decoder == nil {
decoder = defaultDecoder
decoder = DefaultDecoderFunc
}

img, err := decoder(f)
Expand Down
20 changes: 10 additions & 10 deletions ext/atlas/atlas.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ func (a *Atlas) AddImage(img image.Image) (id TextureId) {
}

// AddEmbed loads an embed.FS image to the atlas.
func (a *Atlas) AddEmbed(fs embed.FS, path string) (id TextureId) {
return a.DefaultGroup().AddEmbed(fs, path)
func (a *Atlas) AddEmbed(fs embed.FS, path string, decoder pixel.DecoderFunc) (id TextureId) {
return a.DefaultGroup().AddEmbed(fs, path, decoder)
}

// AddFile loads an image file to the atlas.
func (a *Atlas) AddFile(path string) (id TextureId) {
return a.DefaultGroup().AddFile(path)
func (a *Atlas) AddFile(path string, decoder pixel.DecoderFunc) (id TextureId) {
return a.DefaultGroup().AddFile(path, decoder)
}

// SliceImage evenly divides the given image into cells of the given size.
Expand All @@ -114,13 +114,13 @@ func (a *Atlas) SliceImage(img image.Image, cellSize pixel.Vec) (id SliceId) {
}

// Slice loads an image and evenly divides it into cells of the given size.
func (a *Atlas) SliceFile(path string, cellSize pixel.Vec) (id SliceId) {
return a.DefaultGroup().SliceFile(path, cellSize)
func (a *Atlas) SliceFile(path string, cellSize pixel.Vec, decoder pixel.DecoderFunc) (id SliceId) {
return a.DefaultGroup().SliceFile(path, cellSize, decoder)
}

// SliceEmbed loads an embeded image and evenly divides it into cells of the given size.
func (a *Atlas) SliceEmbed(fs embed.FS, path string, cellSize pixel.Vec) (id SliceId) {
return a.DefaultGroup().SliceEmbed(fs, path, cellSize)
func (a *Atlas) SliceEmbed(fs embed.FS, path string, cellSize pixel.Vec, decoder pixel.DecoderFunc) (id SliceId) {
return a.DefaultGroup().SliceEmbed(fs, path, cellSize, decoder)
}

// Pack takes all of the added textures and adds them to the atlas largest to smallest,
Expand Down Expand Up @@ -260,10 +260,10 @@ func (a *Atlas) Pack() {
case iImageEntry:
sprite = add.Data()
case iEmbedEntry:
sprite, err = loadEmbedSprite(add.FS(), add.Path())
sprite, err = loadEmbedSprite(add.FS(), add.Path(), add.DecoderFunc())
err = errors.Wrapf(err, "failed to load embed sprite: %v", add.Path())
case iFileEntry:
sprite, err = loadSprite(add.Path())
sprite, err = loadSprite(add.Path(), add.DecoderFunc())
err = errors.Wrapf(err, "failed to load sprite file: %v", add.Path())
}
if err != nil {
Expand Down
10 changes: 9 additions & 1 deletion ext/atlas/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package atlas
import (
"embed"
"image"

"github.com/gopxl/pixel/v2"
)

type iEntry interface {
Expand Down Expand Up @@ -54,17 +56,23 @@ func (i imageEntry) Data() image.Image {
type iFileEntry interface {
iEntry
Path() string
DecoderFunc() pixel.DecoderFunc
}

type fileEntry struct {
entry
path string
path string
decoderFunc pixel.DecoderFunc
}

func (f fileEntry) Path() string {
return f.path
}

func (f fileEntry) DecoderFunc() pixel.DecoderFunc {
return f.decoderFunc
}

type iSliceEntry interface {
iEntry
Frame() image.Point
Expand Down
28 changes: 16 additions & 12 deletions ext/atlas/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ func (g *Group) AddImage(img image.Image) (id TextureId) {
}

// AddEmbed loads an embed.FS image to the atlas.
func (g *Group) AddEmbed(fs embed.FS, path string) (id TextureId) {
img, err := loadEmbedSprite(fs, path)
func (g *Group) AddEmbed(fs embed.FS, path string, decoder pixel.DecoderFunc) (id TextureId) {
img, err := loadEmbedSprite(fs, path, decoder)
if err != nil {
panic(err)
}
Expand All @@ -95,16 +95,17 @@ func (g *Group) AddEmbed(fs embed.FS, path string) (id TextureId) {
id: g.atlas.id,
bounds: img.Bounds(),
},
path: path,
path: path,
decoderFunc: decoder,
},
fs: fs,
}
return g.addEntry(e)
}

// AddFile loads an image file to the atlas.
func (g *Group) AddFile(path string) (id TextureId) {
img, err := loadSprite(path)
func (g *Group) AddFile(path string, decoder pixel.DecoderFunc) (id TextureId) {
img, err := loadSprite(path, decoder)
if err != nil {
panic(err)
}
Expand All @@ -113,7 +114,8 @@ func (g *Group) AddFile(path string) (id TextureId) {
id: g.atlas.id,
bounds: img.Bounds(),
},
path: path,
path: path,
decoderFunc: decoder,
}
return g.addEntry(e)
}
Expand Down Expand Up @@ -145,9 +147,9 @@ func (g *Group) SliceImage(img image.Image, cellSize pixel.Vec) (id SliceId) {
}

// SliceFile loads an image and evenly divides it into cells of the given size.
func (g *Group) SliceFile(path string, cellSize pixel.Vec) (id SliceId) {
func (g *Group) SliceFile(path string, cellSize pixel.Vec, decoder pixel.DecoderFunc) (id SliceId) {
frame := image.Pt(int(cellSize.X), int(cellSize.Y))
img, err := loadSprite(path)
img, err := loadSprite(path, decoder)
if err != nil {
panic(err)
}
Expand All @@ -162,7 +164,8 @@ func (g *Group) SliceFile(path string, cellSize pixel.Vec) (id SliceId) {
id: g.atlas.id,
bounds: bounds,
},
path: path,
path: path,
decoderFunc: decoder,
},
sliceEntry: sliceEntry{
frame: frame,
Expand All @@ -176,8 +179,8 @@ func (g *Group) SliceFile(path string, cellSize pixel.Vec) (id SliceId) {
}

// SliceEmbed loads an embeded image and evenly divides it into cells of the given size.
func (g *Group) SliceEmbed(fs embed.FS, path string, cellSize pixel.Vec) (id SliceId) {
img, err := loadEmbedSprite(fs, path)
func (g *Group) SliceEmbed(fs embed.FS, path string, cellSize pixel.Vec, decoder pixel.DecoderFunc) (id SliceId) {
img, err := loadEmbedSprite(fs, path, decoder)
if err != nil {
panic(err)
}
Expand All @@ -194,7 +197,8 @@ func (g *Group) SliceEmbed(fs embed.FS, path string, cellSize pixel.Vec) (id Sli
id: g.atlas.id,
bounds: bounds,
},
path: path,
path: path,
decoderFunc: decoder,
},
fs: fs,
},
Expand Down
18 changes: 12 additions & 6 deletions ext/atlas/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,32 @@ func image2PixelRect(r image.Rectangle) pixel.Rect {
return pixelRect(r.Min.X, r.Min.Y, r.Max.X, r.Max.Y)
}

func loadEmbedSprite(fs embed.FS, file string) (i image.Image, err error) {
func loadEmbedSprite(fs embed.FS, file string, decoder pixel.DecoderFunc) (i image.Image, err error) {
f, err := fs.Open(file)
if err != nil {
return
}
defer f.Close()

i, _, err = image.Decode(f)
return
if decoder == nil {
decoder = pixel.DefaultDecoderFunc
}

return decoder(f)
}

func loadSprite(file string) (i image.Image, err error) {
func loadSprite(file string, decoder pixel.DecoderFunc) (i image.Image, err error) {
f, err := os.Open(file)
if err != nil {
return
}
defer f.Close()

i, _, err = image.Decode(f)
return
if decoder == nil {
decoder = pixel.DefaultDecoderFunc
}

return decoder(f)
}

// split is the actual algorithm for splitting a given space (by j in spcs) to fit the given width and height.
Expand Down

0 comments on commit cf83cb7

Please sign in to comment.