Mega Code Archive

 
Categories / Delphi / Graphic
 

Antialiased line drawer using scanline

Title: Antialiased line drawer using scanline Question: How to draw antialiased lines using a TBitmap's scanlines Answer: procedure AALine(x1,y1,x2,y2 : single; color : tcolor; bitmap : tbitmap); function CrossFadeColor(FromColor,ToColor : TColor; Rate : Single) : TColor; var r,g,b : byte; begin r:=Round(GetRValue(FromColor)*Rate+GetRValue(ToColor)*(1-Rate)); g:=Round(GetGValue(FromColor)*Rate+GetGValue(ToColor)*(1-Rate)); b:=Round(GetBValue(FromColor)*Rate+GetBValue(ToColor)*(1-Rate)); Result:=RGB(b,g,r); end; type intarray = array[0..1] of integer; pintarray = ^intarray; procedure hpixel(x : single; y : integer); var FadeRate : single; begin FadeRate:=x-trunc(x); with bitmap do begin if (x=0) and (y=0) and (heighty) and (widthx) then pintarray(bitmap.ScanLine[y])[trunc(x)]:=CrossFadeColor(Color,pintarray(bitmap.ScanLine[y])[trunc(x)],1-FadeRate); if (trunc(x)+1=0) and (y=0) and (heighty) and (widthtrunc(x)+1) then pintarray(bitmap.ScanLine[y])[trunc(x)+1]:=CrossFadeColor(Color,pintarray(bitmap.ScanLine[y])[trunc(x)+1],FadeRate); end; end; procedure vpixel(x : integer; y : single); var FadeRate : single; begin FadeRate:=y-trunc(y); with bitmap do begin if (x=0) and (trunc(y)=0) and (heighttrunc(y)) and (widthx) then pintarray(bitmap.ScanLine[trunc(y)])[x]:=CrossFadeColor(Color,pintarray(bitmap.ScanLine[trunc(y)])[x],1-FadeRate); if (x=0) and (trunc(y)+1=0) and (heighttrunc(y)+1) and (widthx) then pintarray(bitmap.ScanLine[trunc(y)+1])[x]:=CrossFadeColor(Color,pintarray(bitmap.ScanLine[trunc(y)+1])[x],FadeRate); end; end; var i : integer; ly,lx,currentx,currenty,deltax,deltay,l,skipl : single; begin if (x1x2) or (y1y2) then begin bitmap.PixelFormat:=pf32Bit; currentx:=x1; currenty:=y1; lx:=abs(x2-x1); ly:=abs(y2-y1); if lxly then begin l:=trunc(lx); deltay:=(y2-y1)/l; if x1x2 then begin deltax:=-1; skipl:=(currentx-trunc(currentx)); end else begin deltax:=1; skipl:=1-(currentx-trunc(currentx)); end; end else begin l:=trunc(ly); deltax:=(x2-x1)/l; if y1y2 then begin deltay:=-1; skipl:=(currenty-trunc(currenty)); end else begin deltay:=1; skipl:=1-(currenty-trunc(currenty)); end; end; currentx:=currentx+deltax*skipl; currenty:=currenty+deltay*skipl;{} for i:=1 to trunc(l) do begin if lxly then vpixel(trunc(currentx),currenty) else hpixel(currentx,trunc(currenty)); currentx:=currentx+deltax; currenty:=currenty+deltay; end; end; end;