Fixed the Texture pattern

This commit is contained in:
Sasha Koshka 2023-04-02 22:37:38 -04:00
parent 6c3230c0f8
commit 46a4858597

View File

@ -10,42 +10,58 @@ type Texture struct {
} }
// Draw tiles the pattern's canvas within the given bounds. The minimum // Draw tiles the pattern's canvas within the given bounds. The minimum
// points of the pattern's canvas and the destination canvas will be lined up. // point of the pattern's canvas will be lined up with the minimum point of the
// bounding rectangle.
func (pattern Texture) Draw (destination canvas.Canvas, bounds image.Rectangle) { func (pattern Texture) Draw (destination canvas.Canvas, bounds image.Rectangle) {
drawBounds := bounds.Canon().Intersect(destination.Bounds()) dstBounds := bounds.Canon().Intersect(destination.Bounds())
if drawBounds.Empty() { return } if dstBounds.Empty() { return }
dstData, dstStride := destination.Buffer() dstData, dstStride := destination.Buffer()
srcData, srcStride := pattern.Buffer() srcData, srcStride := pattern.Buffer()
srcBounds := pattern.Bounds() srcBounds := pattern.Bounds()
dstPoint := image.Point { } // offset is a vector that is added to points in destination space to
srcPoint := drawBounds.Min.Sub(bounds.Min).Add(srcBounds.Min) // convert them to points in source space
offset := srcBounds.Min.Sub(bounds.Min)
// calculate the starting position in source space
srcPoint := dstBounds.Min.Add(offset)
srcPoint.X = wrap(srcPoint.X, srcBounds.Min.X, srcBounds.Max.X) srcPoint.X = wrap(srcPoint.X, srcBounds.Min.X, srcBounds.Max.X)
srcPoint.Y = wrap(srcPoint.Y, srcBounds.Min.Y, srcBounds.Max.Y) srcPoint.Y = wrap(srcPoint.Y, srcBounds.Min.Y, srcBounds.Max.Y)
srcStartPoint := srcPoint
for dstPoint.Y = drawBounds.Min.Y; dstPoint.Y < drawBounds.Max.Y; dstPoint.Y ++ {
srcPoint.X = srcBounds.Min.X // for each row
dstPoint.X = drawBounds.Min.X dstPoint := image.Point { }
for dstPoint.Y = dstBounds.Min.Y; dstPoint.Y < dstBounds.Max.Y; dstPoint.Y ++ {
srcPoint.X = srcStartPoint.X
dstPoint.X = dstBounds.Min.X
dstYComponent := dstPoint.Y * dstStride dstYComponent := dstPoint.Y * dstStride
srcYComponent := srcPoint.Y * srcStride srcYComponent := srcPoint.Y * srcStride
// for each pixel in the row
for { for {
// draw pixel
dstIndex := dstYComponent + dstPoint.X dstIndex := dstYComponent + dstPoint.X
srcIndex := srcYComponent + srcPoint.X srcIndex := srcYComponent + srcPoint.X
dstData[dstIndex] = srcData[srcIndex] dstData[dstIndex] = srcData[srcIndex]
// increment X in source space. wrap to start if out of
// bounds.
srcPoint.X ++ srcPoint.X ++
if srcPoint.X >= srcBounds.Max.X { if srcPoint.X >= srcBounds.Max.X {
srcPoint.X = srcBounds.Min.X srcPoint.X = srcBounds.Min.X
} }
// increment X in destination space. stop drawing this
// row if out of bounds.
dstPoint.X ++ dstPoint.X ++
if dstPoint.X >= drawBounds.Max.X { if dstPoint.X >= dstBounds.Max.X {
break break
} }
} }
// increment row in source space. wrap to start if out of
// bounds.
srcPoint.Y ++ srcPoint.Y ++
if srcPoint.Y >= srcBounds.Max.Y { if srcPoint.Y >= srcBounds.Max.Y {
srcPoint.Y = srcBounds.Min.Y srcPoint.Y = srcBounds.Min.Y