This repository has been archived on 2023-08-08. You can view files and clone it, but cannot push or open issues or pull requests.
tomo-old/artist/pattern.go

62 lines
2.0 KiB
Go

package artist
import "image"
import "git.tebibyte.media/sashakoshka/tomo/canvas"
import "git.tebibyte.media/sashakoshka/tomo/shatter"
// Pattern is capable of drawing to a canvas within the bounds of a given
// clipping rectangle.
type Pattern interface {
// Draw draws the pattern onto the destination canvas, using the
// specified bounds. The given bounds can be smaller or larger than the
// bounds of the destination canvas. The destination canvas can be cut
// using canvas.Cut() to draw only a specific subset of a pattern.
Draw (destination canvas.Canvas, bounds image.Rectangle)
}
// Fill fills the destination canvas with the given pattern.
func Fill (destination canvas.Canvas, source Pattern) (updated image.Rectangle) {
source.Draw(destination, destination.Bounds())
return destination.Bounds()
}
// DrawClip lets you draw several subsets of a pattern at once.
func DrawClip (
destination canvas.Canvas,
source Pattern,
bounds image.Rectangle,
subsets ...image.Rectangle,
) (
updatedRegion image.Rectangle,
) {
for _, subset := range subsets {
source.Draw(canvas.Cut(destination, subset), bounds)
updatedRegion = updatedRegion.Union(subset)
}
return
}
// DrawShatter is like an inverse of DrawClip, drawing nothing in the areas
// specified by "rocks".
func DrawShatter (
destination canvas.Canvas,
source Pattern,
bounds image.Rectangle,
rocks ...image.Rectangle,
) (
updatedRegion image.Rectangle,
) {
tiles := shatter.Shatter(bounds, rocks...)
return DrawClip(destination, source, bounds, tiles...)
}
// AllocateSample returns a new canvas containing the result of a pattern. The
// resulting canvas can be sourced from shape drawing functions. I beg of you
// please do not call this every time you need to draw a shape with a pattern on
// it because that is horrible and cruel to the computer.
func AllocateSample (source Pattern, width, height int) canvas.Canvas {
allocated := canvas.NewBasicCanvas(width, height)
Fill(allocated, source)
return allocated
}