xgb-draw: point interpolation
This commit is contained in:
		@@ -1,7 +1,6 @@
 | 
			
		||||
// Network-friendly drawing application based on XRender.
 | 
			
		||||
//
 | 
			
		||||
// TODO
 | 
			
		||||
//  - interpolate motion between points
 | 
			
		||||
//  - use double buffering to remove flicker
 | 
			
		||||
//    (more pronounced over X11 forwarding)
 | 
			
		||||
//  - maybe keep the pixmap as large as the window
 | 
			
		||||
@@ -183,7 +182,7 @@ func main() {
 | 
			
		||||
	//  - http://ssp.impulsetrain.com/porterduff.html
 | 
			
		||||
	//  - https://keithp.com/~keithp/talks/renderproblems/renderproblems/render-title.html
 | 
			
		||||
	//  - https://keithp.com/~keithp/talks/cairo2003.pdf
 | 
			
		||||
	drawLineTo := func(x, y int16) {
 | 
			
		||||
	drawPointAt := func(x, y int16) {
 | 
			
		||||
		_ = render.Composite(X, render.PictOpConjointOver,
 | 
			
		||||
			brushid, render.PictureNone, pixmaskpictid,
 | 
			
		||||
			0, 0, 0, 0, x-brushRadius, y-brushRadius,
 | 
			
		||||
@@ -203,6 +202,55 @@ func main() {
 | 
			
		||||
			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
 | 
			
		||||
	for {
 | 
			
		||||
		ev, xerr := X.WaitForEvent()
 | 
			
		||||
@@ -242,12 +290,14 @@ func main() {
 | 
			
		||||
					[]xproto.Rectangle{{Width: pixWidth, Height: pixHeight}})
 | 
			
		||||
 | 
			
		||||
				drawing = true
 | 
			
		||||
				drawLineTo(e.EventX, e.EventY)
 | 
			
		||||
				drawPointAt(e.EventX, e.EventY)
 | 
			
		||||
				startX, startY = e.EventX, e.EventY
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		case xproto.MotionNotifyEvent:
 | 
			
		||||
			if drawing {
 | 
			
		||||
				drawLineTo(e.EventX, e.EventY)
 | 
			
		||||
				drawLine(startX, startY, e.EventX, e.EventY)
 | 
			
		||||
				startX, startY = e.EventX, e.EventY
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		case xproto.ButtonReleaseEvent:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user