moduleChunkyPNGclassCanvasmoduleDrawing# Sets a point on the canvas by composing a pixel with its background color.defpoint(x,y,color)self[x,y]=ChunkyPNG::Color.compose(color,self[x,y])end# Draws an anti-aliased line using Xiaolin Wu's algorithm.#defline_xiaolin_wu(x0,y0,x1,y1,color)y0,y1,x0,x1=y1,y0,x1,x0ify0>y1dx=x1-x0sx=dx<0?-1:1dx*=sxdy=y1-y0ifdy==0# vertical lineRange.new(*[x0,x1].sort).eachdo|x|point(x,y0,color)endelsifdx==0# horizontal line(y0..y1).eachdo|y|point(x0,y,color)endelsifdx==dy# diagonalx0.step(x1,sx)do|x|point(x,y0,color)y0+=1endelsifdy>dx# vertical displacementpoint(x0,y0,color)e_acc=0e=((dx<<16)/dy.to_f).round(y0...y1-1).eachdo|i|e_acc_temp,e_acc=e_acc,(e_acc+e)&0xffffx0=x0+sxif(e_acc<=e_acc_temp)w=0xff-(e_acc>>8)point(x0,y0,ChunkyPNG::Color.fade(color,w))ifinclude?(x0,y0)y0=y0+1point(x0+sx,y0,ChunkyPNG::Color.fade(color,0xff-w))ifinclude?(x0+sx,y0)endpoint(x1,y1,color)else# horizontal displacementpoint(x0,y0,color)e_acc=0e=(dy<<16)/dx(dx-1).downto(0)do|i|e_acc_temp,e_acc=e_acc,(e_acc+e)&0xffffy0+=1if(e_acc<=e_acc_temp)w=0xff-(e_acc>>8)point(x0,y0,ChunkyPNG::Color.fade(color,w))ifinclude?(x0,y0)x0+=sxpoint(x0,y0+1,ChunkyPNG::Color.fade(color,0xff-w))ifinclude?(x0,y0+1)endpoint(x1,y1,color)endendalias:line:line_xiaolin_wuendendend