xgb-draw: point interpolation
This commit is contained in:
parent
254ceb810c
commit
e8381d86ce
|
@ -1,7 +1,6 @@
|
||||||
// Network-friendly drawing application based on XRender.
|
// Network-friendly drawing application based on XRender.
|
||||||
//
|
//
|
||||||
// TODO
|
// TODO
|
||||||
// - interpolate motion between points
|
|
||||||
// - use double buffering to remove flicker
|
// - use double buffering to remove flicker
|
||||||
// (more pronounced over X11 forwarding)
|
// (more pronounced over X11 forwarding)
|
||||||
// - maybe keep the pixmap as large as the window
|
// - maybe keep the pixmap as large as the window
|
||||||
|
@ -183,7 +182,7 @@ func main() {
|
||||||
// - http://ssp.impulsetrain.com/porterduff.html
|
// - http://ssp.impulsetrain.com/porterduff.html
|
||||||
// - https://keithp.com/~keithp/talks/renderproblems/renderproblems/render-title.html
|
// - https://keithp.com/~keithp/talks/renderproblems/renderproblems/render-title.html
|
||||||
// - https://keithp.com/~keithp/talks/cairo2003.pdf
|
// - https://keithp.com/~keithp/talks/cairo2003.pdf
|
||||||
drawLineTo := func(x, y int16) {
|
drawPointAt := func(x, y int16) {
|
||||||
_ = render.Composite(X, render.PictOpConjointOver,
|
_ = render.Composite(X, render.PictOpConjointOver,
|
||||||
brushid, render.PictureNone, pixmaskpictid,
|
brushid, render.PictureNone, pixmaskpictid,
|
||||||
0, 0, 0, 0, x-brushRadius, y-brushRadius,
|
0, 0, 0, 0, x-brushRadius, y-brushRadius,
|
||||||
|
@ -203,6 +202,55 @@ func main() {
|
||||||
pixWidth, pixHeight)
|
pixWidth, pixHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Integer version of Bresenham's line drawing algorithm
|
||||||
|
drawLine := func(x0, y0, x1, y1 int16) {
|
||||||
|
dx, dy := x1-x0, y1-y0
|
||||||
|
if dx < 0 {
|
||||||
|
dx = -dx
|
||||||
|
}
|
||||||
|
if dy < 0 {
|
||||||
|
dy = -dy
|
||||||
|
}
|
||||||
|
|
||||||
|
steep := dx < dy
|
||||||
|
if steep {
|
||||||
|
// Flip the coordinate system on input
|
||||||
|
x0, y0 = y0, x0
|
||||||
|
x1, y1 = y1, x1
|
||||||
|
dx, dy = dy, dx
|
||||||
|
}
|
||||||
|
|
||||||
|
var stepX, stepY int16 = 1, 1
|
||||||
|
if x0 > x1 {
|
||||||
|
stepX = -1
|
||||||
|
}
|
||||||
|
if y0 > y1 {
|
||||||
|
stepY = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
dpr := dy * 2
|
||||||
|
delta := dpr - dx
|
||||||
|
dpru := delta - dx
|
||||||
|
|
||||||
|
for ; dx > 0; dx-- {
|
||||||
|
// Unflip the coordinate system on output
|
||||||
|
if steep {
|
||||||
|
drawPointAt(y0, x0)
|
||||||
|
} else {
|
||||||
|
drawPointAt(x0, y0)
|
||||||
|
}
|
||||||
|
|
||||||
|
x0 += stepX
|
||||||
|
if delta > 0 {
|
||||||
|
y0 += stepY
|
||||||
|
delta += dpru
|
||||||
|
} else {
|
||||||
|
delta += dpr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var startX, startY int16 = 0, 0
|
||||||
drawing := false
|
drawing := false
|
||||||
for {
|
for {
|
||||||
ev, xerr := X.WaitForEvent()
|
ev, xerr := X.WaitForEvent()
|
||||||
|
@ -242,12 +290,14 @@ func main() {
|
||||||
[]xproto.Rectangle{{Width: pixWidth, Height: pixHeight}})
|
[]xproto.Rectangle{{Width: pixWidth, Height: pixHeight}})
|
||||||
|
|
||||||
drawing = true
|
drawing = true
|
||||||
drawLineTo(e.EventX, e.EventY)
|
drawPointAt(e.EventX, e.EventY)
|
||||||
|
startX, startY = e.EventX, e.EventY
|
||||||
}
|
}
|
||||||
|
|
||||||
case xproto.MotionNotifyEvent:
|
case xproto.MotionNotifyEvent:
|
||||||
if drawing {
|
if drawing {
|
||||||
drawLineTo(e.EventX, e.EventY)
|
drawLine(startX, startY, e.EventX, e.EventY)
|
||||||
|
startX, startY = e.EventX, e.EventY
|
||||||
}
|
}
|
||||||
|
|
||||||
case xproto.ButtonReleaseEvent:
|
case xproto.ButtonReleaseEvent:
|
||||||
|
|
Loading…
Reference in New Issue