WIP texture drawing
This commit is contained in:
parent
b5f67c65b0
commit
e2a370259b
10
box.go
10
box.go
@ -17,6 +17,7 @@ type box struct {
|
|||||||
bounds image.Rectangle
|
bounds image.Rectangle
|
||||||
minSize image.Point
|
minSize image.Point
|
||||||
userMinSize image.Point
|
userMinSize image.Point
|
||||||
|
innerClippingBounds image.Rectangle
|
||||||
|
|
||||||
minSizeQueued bool
|
minSizeQueued bool
|
||||||
focusQueued *bool
|
focusQueued *bool
|
||||||
@ -84,7 +85,7 @@ func (this *box) Bounds () image.Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *box) InnerBounds () image.Rectangle {
|
func (this *box) InnerBounds () image.Rectangle {
|
||||||
return this.padding.Apply(this.innerClippingBounds())
|
return this.padding.Apply(this.innerClippingBounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *box) MinimumSize () image.Point {
|
func (this *box) MinimumSize () image.Point {
|
||||||
@ -102,10 +103,6 @@ func (this *box) borderSum () tomo.Inset {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *box) innerClippingBounds () image.Rectangle {
|
|
||||||
return this.borderSum().Apply(this.bounds)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *box) SetBounds (bounds image.Rectangle) {
|
func (this *box) SetBounds (bounds image.Rectangle) {
|
||||||
if this.bounds == bounds { return }
|
if this.bounds == bounds { return }
|
||||||
this.bounds = bounds
|
this.bounds = bounds
|
||||||
@ -358,11 +355,12 @@ func (this *box) doDraw () {
|
|||||||
if this.canvas == nil { return }
|
if this.canvas == nil { return }
|
||||||
if this.drawer != nil {
|
if this.drawer != nil {
|
||||||
this.drawBorders(this.canvas)
|
this.drawBorders(this.canvas)
|
||||||
this.drawer.Draw(this.canvas.Clip(this.innerClippingBounds()))
|
this.drawer.Draw(this.canvas.Clip(this.innerClippingBounds))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *box) doLayout () {
|
func (this *box) doLayout () {
|
||||||
|
this.innerClippingBounds = this.borderSum().Apply(this.bounds)
|
||||||
if this.parent == nil { this.canvas = nil; return }
|
if this.parent == nil { this.canvas = nil; return }
|
||||||
parentCanvas := this.parent.canvas()
|
parentCanvas := this.parent.canvas()
|
||||||
if parentCanvas == nil { this.canvas = nil; return }
|
if parentCanvas == nil { this.canvas = nil; return }
|
||||||
|
@ -79,9 +79,12 @@ type pen struct {
|
|||||||
func (this *pen) Rectangle (bounds image.Rectangle) {
|
func (this *pen) Rectangle (bounds image.Rectangle) {
|
||||||
bounds = bounds.Canon()
|
bounds = bounds.Canon()
|
||||||
if this.weight == 0 {
|
if this.weight == 0 {
|
||||||
if this.fill.A > 0 {
|
if this.fill.A > 0 && !this.textureObscures() {
|
||||||
this.fillRectangle(this.fill, bounds)
|
this.fillRectangle(this.fill, bounds)
|
||||||
}
|
}
|
||||||
|
if this.texture != nil {
|
||||||
|
this.textureRectangle(bounds)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if this.stroke.A > 0 {
|
if this.stroke.A > 0 {
|
||||||
this.strokeRectangle(this.stroke, bounds)
|
this.strokeRectangle(this.stroke, bounds)
|
||||||
@ -115,6 +118,10 @@ func (this *pen) Stroke (stroke color.Color) { this.stroke = convertColor(
|
|||||||
func (this *pen) Fill (fill color.Color) { this.fill = convertColor(fill) }
|
func (this *pen) Fill (fill color.Color) { this.fill = convertColor(fill) }
|
||||||
func (this *pen) Texture (texture canvas.Texture) { this.texture = AssertTexture(texture) }
|
func (this *pen) Texture (texture canvas.Texture) { this.texture = AssertTexture(texture) }
|
||||||
|
|
||||||
|
func (this *pen) textureObscures () bool {
|
||||||
|
return this.texture != nil && this.texture.Opaque()
|
||||||
|
}
|
||||||
|
|
||||||
func convertColor (c color.Color) xgraphics.BGRA {
|
func convertColor (c color.Color) xgraphics.BGRA {
|
||||||
r, g, b, a := c.RGBA()
|
r, g, b, a := c.RGBA()
|
||||||
return xgraphics.BGRA {
|
return xgraphics.BGRA {
|
||||||
|
@ -4,6 +4,46 @@ import "sort"
|
|||||||
import "image"
|
import "image"
|
||||||
import "github.com/jezek/xgbutil/xgraphics"
|
import "github.com/jezek/xgbutil/xgraphics"
|
||||||
|
|
||||||
|
func (this *pen) textureRectangle (bounds image.Rectangle) {
|
||||||
|
if this.texture.Opaque() {
|
||||||
|
this.textureRectangleOpaque(bounds)
|
||||||
|
} else {
|
||||||
|
this.textureRectangleTransparent(bounds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *pen) textureRectangleOpaque (bounds image.Rectangle) {
|
||||||
|
|
||||||
|
dstBounds := bounds.Intersect(this.image.Bounds())
|
||||||
|
srcBounds := this.texture.rect
|
||||||
|
|
||||||
|
offset := dstBounds.Min.Sub(bounds.Min)
|
||||||
|
|
||||||
|
|
||||||
|
dstStep := this.image.Stride - bounds.Dx() * 4
|
||||||
|
srcStep := this.texture.stride - srcBounds.Dx() * 4
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *pen) textureRectangleTransparent (bounds image.Rectangle) {
|
||||||
|
bounds = bounds.Intersect(this.image.Bounds())
|
||||||
|
var pos image.Point
|
||||||
|
|
||||||
|
for pos.Y = bounds.Min.Y; pos.Y < bounds.Max.Y; pos.Y ++ {
|
||||||
|
for pos.X = bounds.Min.X; pos.X < bounds.Max.X; pos.X ++ {
|
||||||
|
index := this.image.PixOffset(pos.X, pos.Y)
|
||||||
|
pixel := xgraphics.BlendBGRA(xgraphics.BGRA {
|
||||||
|
B: this.image.Pix[index + 0],
|
||||||
|
G: this.image.Pix[index + 1],
|
||||||
|
R: this.image.Pix[index + 2],
|
||||||
|
A: this.image.Pix[index + 3],
|
||||||
|
}, c)
|
||||||
|
this.image.Pix[index + 0] = pixel.B
|
||||||
|
this.image.Pix[index + 1] = pixel.G
|
||||||
|
this.image.Pix[index + 2] = pixel.R
|
||||||
|
this.image.Pix[index + 3] = pixel.A
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
func (this *pen) fillRectangle (c xgraphics.BGRA, bounds image.Rectangle) {
|
func (this *pen) fillRectangle (c xgraphics.BGRA, bounds image.Rectangle) {
|
||||||
if c.A == 255 {
|
if c.A == 255 {
|
||||||
this.fillRectangleOpaque(c, bounds)
|
this.fillRectangleOpaque(c, bounds)
|
||||||
@ -227,3 +267,11 @@ func (this *pen) polyLine (c xgraphics.BGRA, points ...image.Point) {
|
|||||||
prevPoint = point
|
prevPoint = point
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wrap (n, min, max int) int {
|
||||||
|
max -= min
|
||||||
|
n -= min
|
||||||
|
n %= max
|
||||||
|
if n < 0 { n += max }
|
||||||
|
return n + min
|
||||||
|
}
|
||||||
|
@ -17,7 +17,7 @@ func NewTextureFrom (source image.Image) *Texture {
|
|||||||
bounds := source.Bounds()
|
bounds := source.Bounds()
|
||||||
texture := &Texture {
|
texture := &Texture {
|
||||||
pix: make([]uint8, bounds.Dx() * bounds.Dy() * 4),
|
pix: make([]uint8, bounds.Dx() * bounds.Dy() * 4),
|
||||||
stride: bounds.Dx(),
|
stride: bounds.Dx() * 4,
|
||||||
rect: bounds.Sub(bounds.Min),
|
rect: bounds.Sub(bounds.Min),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +59,8 @@ func (this *Texture) Clip (bounds image.Rectangle) canvas.Texture {
|
|||||||
return &clipped
|
return &clipped
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *Texture) pixOffset
|
||||||
|
|
||||||
// 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 {
|
||||||
if tx, ok := unknown.(*Texture); ok {
|
if tx, ok := unknown.(*Texture); ok {
|
||||||
|
@ -132,19 +132,21 @@ func (this *containerBox) SetLayout (layout tomo.Layout) {
|
|||||||
|
|
||||||
func (this *containerBox) Draw (can canvas.Canvas) {
|
func (this *containerBox) Draw (can canvas.Canvas) {
|
||||||
if can == nil { return }
|
if can == nil { return }
|
||||||
pen := can.Pen()
|
|
||||||
pen.Fill(this.color)
|
|
||||||
pen.Texture(this.texture)
|
|
||||||
|
|
||||||
rocks := make([]image.Rectangle, len(this.children))
|
rocks := make([]image.Rectangle, len(this.children))
|
||||||
for index, box := range this.children {
|
for index, box := range this.children {
|
||||||
rocks[index] = box.Bounds()
|
rocks[index] = box.Bounds()
|
||||||
}
|
}
|
||||||
for _, tile := range canvas.Shatter(this.bounds, rocks...) {
|
for _, tile := range canvas.Shatter(this.bounds, rocks...) {
|
||||||
|
clipped := can.Clip(tile)
|
||||||
if this.transparent() && this.parent != nil {
|
if this.transparent() && this.parent != nil {
|
||||||
this.parent.drawBackgroundPart(can.Clip(tile))
|
this.parent.drawBackgroundPart(clipped)
|
||||||
}
|
}
|
||||||
pen.Rectangle(tile)
|
if clipped == nil { continue }
|
||||||
|
pen := clipped.Pen()
|
||||||
|
pen.Fill(this.color)
|
||||||
|
pen.Texture(this.texture)
|
||||||
|
pen.Rectangle(this.innerClippingBounds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +159,7 @@ func (this *containerBox) drawBackgroundPart (can canvas.Canvas) {
|
|||||||
if this.transparent() && this.parent != nil {
|
if this.transparent() && this.parent != nil {
|
||||||
this.parent.drawBackgroundPart(can)
|
this.parent.drawBackgroundPart(can)
|
||||||
}
|
}
|
||||||
pen.Rectangle(can.Bounds())
|
pen.Rectangle(this.innerClippingBounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *containerBox) flushActionQueue () {
|
func (this *containerBox) flushActionQueue () {
|
||||||
|
Reference in New Issue
Block a user