imagecache

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 4, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package imagecache loads the images a document shows through an images.Source: an asynchronous cache that fetches and decodes each image once, and decoding of animated GIFs.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Animation

type Animation struct {
	// contains filtered or unexported fields
}

Animation holds every frame of a decoded GIF, already composited to full-canvas, disposal-correct frames (see decodeAnimatedGIF). CurrentFrame is a pure function of now (elapsed time since rendering started) and the animation's own total duration - there's no per-animation "start" to track: now is already "time since start", so a looping animation just always shows whichever frame now % total currently lands in, as if it had been playing since time zero. Deterministic and easy to test without any real waiting, and no clock-skew concerns between decode time and draw time to reason about, since nothing is stamped at decode time. Always loops forever.

func NewAnimation

func NewAnimation(frames []image.Image, delays []time.Duration) *Animation

NewAnimation returns an Animation showing each frame for its delay.

func (*Animation) Bounds

func (a *Animation) Bounds() image.Rectangle

Bounds is every frame's shared size - GIF frames may individually be smaller (see decodeAnimatedGIF), but every composited frame here is full-canvas.

func (*Animation) CurrentFrame

func (a *Animation) CurrentFrame(now time.Duration) image.Image

CurrentFrame returns whichever frame now lands in, looping forever.

type Cache

type Cache struct {
	// contains filtered or unexported fields
}

Cache is the "management of image data" the library owns: an image is fetched and decoded at most once, however many times Load is called for it afterwards - every layout rebuild asks again. A Canvas implementation never fetches its own copy either - ImageBox carries the already-decoded image.Image forward from here, straight into Canvas.DrawImage.

Load never blocks: a cache miss (or a failed entry whose retry delay has elapsed) returns Pending immediately and starts a fetch on a background goroutine, which is why this type is safe for concurrent use (Load from the layout goroutine, the goroutine's own writes as a fetch progresses) - unlike everything else in this codebase, which is only ever touched from ebiten's single game-loop goroutine and has no need to be.

func NewCache

func NewCache(source images.Source) *Cache

NewCache returns a Cache loading the srcs passed to Load through source.

func (*Cache) ChangedSince

func (c *Cache) ChangedSince(mark uint64) (changed []Change, newMark uint64)

ChangedSince returns every change since a previous ChangedSince (or an initial call with mark 0) returned mark, plus a new mark to pass next time. Cheap: each entry just remembers the cache's own version counter at the moment it last changed, so this is a scan of however many distinct images exist, not a growing log.

func (*Cache) Load

func (c *Cache) Load(src string) (resolved string, result Result)

Load resolves src through the Source and returns its current state, starting a fetch in the background on a genuine miss, or on a failed entry old enough to retry - never blocking on the fetch itself. resolved is the AsyncImage's Key, or src itself when the Source failed - InlineImage's fallback text names it in a missing- or broken-image message.

func (*Cache) LoadImage

func (c *Cache) LoadImage(img images.AsyncImage) Result

LoadImage is Load for an image that needs no resolving - e.g. a code block plugin's diagram, whose fetch might be a POST rather than a GET.

type Change

type Change struct {
	Src string
	// BoundsRevealed is true if, since the mark passed to
	// ChangedSince, this src's bounds became known for the first time
	// - the one transition that can change a slot's height
	// unpredictably (everything else - becoming ready, a retry's
	// outcome - happens at an already-known, already-laid-out size).
	BoundsRevealed bool
}

Change is one entry Cache.ChangedSince reports.

type Result

type Result struct {
	Status Status
	// Bounds is the image's native pixel size - known once Status ==
	// Ready, but may already be known earlier, while Status is
	// still Pending (see Cache's header-peek). Zero while
	// genuinely unknown.
	Bounds image.Rectangle
	// Image is the decoded image - valid only when Status == Ready
	// and this isn't an animated GIF (Animation is set instead; exactly
	// one of the two is set on a ready result).
	Image image.Image
	// Animation is set instead of Image when the decoded image is an
	// animated GIF.
	Animation *Animation
	// Err says why the most recent attempt failed - valid only when
	// Status == Failed.
	Err error
}

Result is what Cache.Load returns for one src.

type Status

type Status int

Status is an image's state within a Cache.

const (
	// Pending means a fetch is in flight (or about to start) - not
	// yet ready, not (yet, or any longer) failed. Bounds may already be
	// known even in this state - see Cache's own doc comment.
	Pending Status = iota
	// Ready means Image holds the fully decoded result.
	Ready
	// Failed means the most recent attempt failed - Err says how.
	// Not necessarily permanent: see Cache's retry behavior.
	Failed
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL