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/patterns/texture.go

55 lines
1.5 KiB
Go
Raw Normal View History

2023-02-25 23:41:16 +00:00
package patterns
2023-01-09 06:03:19 +00:00
import "image"
2023-02-25 23:41:16 +00:00
import "git.tebibyte.media/sashakoshka/tomo/canvas"
2023-02-25 23:41:16 +00:00
// Texture is a pattern that tiles the content of a canvas both horizontally and
// vertically.
type Texture struct {
2023-02-25 23:41:16 +00:00
canvas.Canvas
}
2023-02-25 23:41:16 +00:00
// Draw tiles the pattern's canvas within the clipping bounds. The minimum
// points of the pattern's canvas and the destination canvas will be lined up.
func (pattern Texture) Draw (destination canvas.Canvas, clip image.Rectangle) {
2023-02-27 17:48:44 +00:00
realBounds := destination.Bounds()
bounds := clip.Canon().Intersect(realBounds)
2023-02-25 23:41:16 +00:00
if bounds.Empty() { return }
dstData, dstStride := destination.Buffer()
srcData, srcStride := pattern.Buffer()
srcBounds := pattern.Bounds()
2023-02-27 21:38:33 +00:00
2023-03-07 02:34:14 +00:00
dstPoint := image.Point { }
srcPoint := bounds.Min.Sub(realBounds.Min).Add(srcBounds.Min)
srcPoint.X = wrap(srcPoint.X, srcBounds.Min.X, srcBounds.Max.X)
srcPoint.Y = wrap(srcPoint.Y, srcBounds.Min.Y, srcBounds.Max.Y)
for dstPoint.Y = bounds.Min.Y; dstPoint.Y < bounds.Max.Y; dstPoint.Y ++ {
for dstPoint.X = bounds.Min.X; dstPoint.X < bounds.Max.X; dstPoint.X ++ {
dstIndex := dstPoint.X + dstPoint.Y * dstStride
srcIndex :=
srcPoint.X +
srcPoint.Y * srcStride
dstData[dstIndex] = srcData[srcIndex]
srcPoint.X ++
if srcPoint.X >= srcBounds.Max.X {
srcPoint.X = srcBounds.Min.X
}
}
srcPoint.Y ++
if srcPoint.Y >= srcBounds.Max.Y {
srcPoint.Y = srcBounds.Min.Y
}
}
}
2023-02-25 23:41:16 +00:00
func wrap (value, min, max int) int {
difference := max - min
value = (value - min) % difference
if value < 0 { value += difference }
return value + min
}