xgb-draw: point interpolation

This commit is contained in:
Přemysl Eric Janouch 2018-09-05 12:03:05 +02:00
parent 254ceb810c
commit e8381d86ce
Signed by: p
GPG Key ID: A0420B94F92B9493
1 changed files with 54 additions and 4 deletions

View File

@ -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: