xgb-draw: point interpolation
This commit is contained in:
		@@ -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:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user