Textured rectangles are working (if a bit slow)
This commit is contained in:
parent
e2a370259b
commit
ab80658cd9
@ -13,34 +13,53 @@ func (this *pen) textureRectangle (bounds image.Rectangle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *pen) textureRectangleOpaque (bounds image.Rectangle) {
|
func (this *pen) textureRectangleOpaque (bounds image.Rectangle) {
|
||||||
|
|
||||||
dstBounds := bounds.Intersect(this.image.Bounds())
|
dstBounds := bounds.Intersect(this.image.Bounds())
|
||||||
srcBounds := this.texture.rect
|
var pos image.Point
|
||||||
|
|
||||||
offset := dstBounds.Min.Sub(bounds.Min)
|
|
||||||
|
|
||||||
|
|
||||||
dstStep := this.image.Stride - bounds.Dx() * 4
|
dst := this.image.Pix
|
||||||
srcStep := this.texture.stride - srcBounds.Dx() * 4
|
src := this.texture.pix
|
||||||
|
offset := this.texture.rect.Min.Sub(bounds.Min)
|
||||||
|
|
||||||
|
for pos.Y = dstBounds.Min.Y; pos.Y < dstBounds.Max.Y; pos.Y ++ {
|
||||||
|
for pos.X = dstBounds.Min.X; pos.X < dstBounds.Max.X; pos.X ++ {
|
||||||
|
srcPos := pos.Add(offset)
|
||||||
|
dstIndex := this.image.PixOffset(pos.X, pos.Y)
|
||||||
|
srcIndex := this.texture.PixOffset(srcPos.X, srcPos.Y)
|
||||||
|
dst[dstIndex + 0] = src[srcIndex + 0]
|
||||||
|
dst[dstIndex + 1] = src[srcIndex + 1]
|
||||||
|
dst[dstIndex + 2] = src[srcIndex + 2]
|
||||||
|
dst[dstIndex + 3] = src[srcIndex + 3]
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *pen) textureRectangleTransparent (bounds image.Rectangle) {
|
func (this *pen) textureRectangleTransparent (bounds image.Rectangle) {
|
||||||
bounds = bounds.Intersect(this.image.Bounds())
|
dstBounds := bounds.Intersect(this.image.Bounds())
|
||||||
var pos image.Point
|
var pos image.Point
|
||||||
|
|
||||||
for pos.Y = bounds.Min.Y; pos.Y < bounds.Max.Y; pos.Y ++ {
|
dst := this.image.Pix
|
||||||
for pos.X = bounds.Min.X; pos.X < bounds.Max.X; pos.X ++ {
|
src := this.texture.pix
|
||||||
index := this.image.PixOffset(pos.X, pos.Y)
|
offset := this.texture.rect.Min.Sub(bounds.Min)
|
||||||
|
|
||||||
|
for pos.Y = dstBounds.Min.Y; pos.Y < dstBounds.Max.Y; pos.Y ++ {
|
||||||
|
for pos.X = dstBounds.Min.X; pos.X < dstBounds.Max.X; pos.X ++ {
|
||||||
|
srcPos := pos.Add(offset)
|
||||||
|
dstIndex := this.image.PixOffset(pos.X, pos.Y)
|
||||||
|
srcIndex := this.texture.PixOffset(srcPos.X, srcPos.Y)
|
||||||
pixel := xgraphics.BlendBGRA(xgraphics.BGRA {
|
pixel := xgraphics.BlendBGRA(xgraphics.BGRA {
|
||||||
B: this.image.Pix[index + 0],
|
B: dst[dstIndex + 0],
|
||||||
G: this.image.Pix[index + 1],
|
G: dst[dstIndex + 1],
|
||||||
R: this.image.Pix[index + 2],
|
R: dst[dstIndex + 2],
|
||||||
A: this.image.Pix[index + 3],
|
A: dst[dstIndex + 3],
|
||||||
}, c)
|
}, xgraphics.BGRA {
|
||||||
this.image.Pix[index + 0] = pixel.B
|
B: src[srcIndex + 0],
|
||||||
this.image.Pix[index + 1] = pixel.G
|
G: src[srcIndex + 1],
|
||||||
this.image.Pix[index + 2] = pixel.R
|
R: src[srcIndex + 2],
|
||||||
this.image.Pix[index + 3] = pixel.A
|
A: src[srcIndex + 3],
|
||||||
|
})
|
||||||
|
dst[dstIndex + 0] = pixel.B
|
||||||
|
dst[dstIndex + 1] = pixel.G
|
||||||
|
dst[dstIndex + 2] = pixel.R
|
||||||
|
dst[dstIndex + 3] = pixel.A
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +110,7 @@ func (this *pen) strokeRectangle (c xgraphics.BGRA, bounds image.Rectangle) {
|
|||||||
this.fillRectangle(c, bounds)
|
this.fillRectangle(c, bounds)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
top := image.Rect (
|
top := image.Rect (
|
||||||
bounds.Min.X,
|
bounds.Min.X,
|
||||||
bounds.Min.Y,
|
bounds.Min.Y,
|
||||||
@ -122,7 +141,7 @@ func (this *pen) strokeRectangle (c xgraphics.BGRA, bounds image.Rectangle) {
|
|||||||
// the polygon filling algorithm is adapted from:
|
// the polygon filling algorithm is adapted from:
|
||||||
// https://www.alienryderflex.com/polygon_fill/
|
// https://www.alienryderflex.com/polygon_fill/
|
||||||
// (if you write C like that i will disassemble you)
|
// (if you write C like that i will disassemble you)
|
||||||
|
|
||||||
func (this *pen) fillPolygon (c xgraphics.BGRA, points ...image.Point) {
|
func (this *pen) fillPolygon (c xgraphics.BGRA, points ...image.Point) {
|
||||||
if len(points) < 3 { return }
|
if len(points) < 3 { return }
|
||||||
|
|
||||||
@ -183,7 +202,7 @@ func (this *pen) fillPolygon (c xgraphics.BGRA, points ...image.Point) {
|
|||||||
context.fillPolygonHotTransparent()
|
context.fillPolygonHotTransparent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type fillingContext struct {
|
type fillingContext struct {
|
||||||
@ -207,7 +226,7 @@ func (context *fillingContext) fillPolygonHotOpaque () {
|
|||||||
// constrain boundaries to image size
|
// constrain boundaries to image size
|
||||||
if left < context.min { left = context.min }
|
if left < context.min { left = context.min }
|
||||||
if right > context.max { right = context.max }
|
if right > context.max { right = context.max }
|
||||||
|
|
||||||
// fill pixels in between
|
// fill pixels in between
|
||||||
for x := left; x < right; x ++ {
|
for x := left; x < right; x ++ {
|
||||||
index := context.image.PixOffset(x, context.y)
|
index := context.image.PixOffset(x, context.y)
|
||||||
@ -232,7 +251,7 @@ func (context *fillingContext) fillPolygonHotTransparent () {
|
|||||||
// constrain boundaries to image size
|
// constrain boundaries to image size
|
||||||
if left < context.min { left = context.min }
|
if left < context.min { left = context.min }
|
||||||
if right > context.max { right = context.max }
|
if right > context.max { right = context.max }
|
||||||
|
|
||||||
// fill pixels in between
|
// fill pixels in between
|
||||||
for x := left; x < right; x ++ {
|
for x := left; x < right; x ++ {
|
||||||
index := context.image.PixOffset(x, context.y)
|
index := context.image.PixOffset(x, context.y)
|
||||||
|
@ -36,7 +36,7 @@ func NewTextureFrom (source image.Image) *Texture {
|
|||||||
texture.transparent = true
|
texture.transparent = true
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
return texture
|
return texture
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,11 @@ func (this *Texture) Clip (bounds image.Rectangle) canvas.Texture {
|
|||||||
return &clipped
|
return &clipped
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Texture) pixOffset
|
func (this *Texture) PixOffset (x, y int) int {
|
||||||
|
x = wrap(x, this.rect.Min.X, this.rect.Max.X)
|
||||||
|
y = wrap(y, this.rect.Min.Y, this.rect.Max.Y)
|
||||||
|
return x * 4 + y * this.stride
|
||||||
|
}
|
||||||
|
|
||||||
// AssertTexture checks if a given canvas.Texture is a texture from this package.
|
// AssertTexture checks if a given canvas.Texture is a texture from this package.
|
||||||
func AssertTexture (unknown canvas.Texture) *Texture {
|
func AssertTexture (unknown canvas.Texture) *Texture {
|
||||||
|
Reference in New Issue
Block a user