// blendCheckered is basically a copy of xgraphics.Blend with no interfaces. // (It's faster.) Also, it is hardcoded to blend into a checkered background. func blendCheckered(dest *xgraphics.Image) { dsrc := dest.Bounds() dmnx, dmxx, dmny, dmxy := dsrc.Min.X, dsrc.Max.X, dsrc.Min.Y, dsrc.Max.Y clr1 := xgraphics.BGRA{B: 0xff, G: 0xff, R: 0xff, A: 0xff} clr2 := xgraphics.BGRA{B: 0xde, G: 0xdc, R: 0xdf, A: 0xff} var dx, dy int var bgra, clr xgraphics.BGRA for dx = dmnx; dx < dmxx; dx++ { for dy = dmny; dy < dmxy; dy++ { if dx%30 >= 15 { if dy%30 >= 15 { clr = clr1 } else { clr = clr2 } } else { if dy%30 >= 15 { clr = clr2 } else { clr = clr1 } } bgra = dest.At(dx, dy).(xgraphics.BGRA) dest.SetBGRA(dx, dy, xgraphics.BlendBGRA(clr, bgra)) } } }
// drawPencil takes an (x, y) position (from a MotionNotify event) and draws // a rectangle of size pencilTip on to canvas. func drawPencil(canvas *xgraphics.Image, win *xwindow.Window, x, y int) { // Create a subimage at (x, y) with pencilTip width and height from canvas. // Creating subimages is very cheap---no pixels are copied. // Moreover, when subimages are drawn to the screen, only the pixels in // the sub-image are sent to X. tipRect := midRect(x, y, pencilTip, pencilTip, width, height) // If the rectangle contains no pixels, don't draw anything. if tipRect.Empty() { return } // Output a little message. log.Printf("Drawing pencil point at (%d, %d)", x, y) // Create the subimage of the canvas to draw to. tip := canvas.SubImage(tipRect) // Now color each pixel in tip with the pencil color. tip.For(func(x, y int) xgraphics.BGRA { return xgraphics.BlendBGRA(canvas.At(x, y).(xgraphics.BGRA), pencil) }) // Now draw the changes to the pixmap. tip.XDraw() // And paint them to the window. tip.XPaint(win.Id) }