Mega Code Archive

 
Categories / Delphi / Examples
 

Textantialias

If you want to have anti-aliased text independant of the API, you can look into the Graphics32 library at http://www.geocities.com/den_alex. It supports 32-bit bitmaps with alpha blending and also offers varying levels of anti-aliasing on text and lines. **************************************************************************************** Liviu Uba wrote: > When you draw a Text on Canvas using DrawText API or simply Canvas > methods like TextRect(whichis mainly the same), the font is ANTI-ALIASED > with the brush color and it looks fine... > How can one implement this nice drawing on a BITMAP, since the Brush > cannot be invisible.. Here are a group of related functions (which I built up from a variety of sources) that I use to render font characters as anti-aliased bitmaps - I hope it helps: // Draw the font character as a bitmap, setting the size, background and // foreground colours, colour depth and whether or not to anti-alias the // image. // Based on code by Earl F. Glynn and Mike Lischke procedure TfrmTT2Img.CharacterToGraphic(Ht, Wd: cardinal; FontName, ChrStr: string; FontColor, BGColor: TColor; ColDepth: TPixelFormat; AntiAlias: boolean); var bmp: TBitmap; Rect: TRect; out_bmp,big_bmp: TBitmap; begin //Draw the font character as a bitmap image... bmp := TBitmap.Create; try with bmp do begin Width := Wd; Height := Ht; PixelFormat := ColDepth; with Canvas do begin Brush.Color := BGColor; FillRect(bmp.Canvas.ClipRect); Font.Name := FontName; Font.Height := bmp.Height; Font.Color := FontColor; end; Rect := Canvas.ClipRect; ExtTextOutW(Canvas.Handle,0,0,ETO_CLIPPED,@Rect,pWideChar(ChrStr),Length(Chr Str), NIL); end; CenterText(bmp.Canvas, Rect, ChrStr); if AntiAlias then begin // To get accurate, antialiased rendering of the image, // draw it scaled at an enlarged size... big_bmp := TBitmap.Create; try SampleBitmap(Ht,Wd,FontName,ChrStr,FontColor,BGColor,big_bmp); // ...now reduce it to the desired output size, recalculating the // output pixel color. The output color is obtained as an average // of the red, green and blue values of each of the 9 pixels in // the enlarged image that correspond to a single pixel in the //output image out_bmp := TBitmap.Create; try with out_bmp do begin Width := bmp.Width; Height := bmp.Height; PixelFormat := pf24bit; end; AntiAliasPicture(bmp,big_bmp,out_bmp); imgChar.Picture.Graphic := out_bmp; finally out_bmp.Free; end; finally big_bmp.Free; end; end else begin imgChar.Picture.Graphic := bmp; end; finally bmp.Free end; end; procedure SampleBitmap(Ht,Wd: cardinal; FontName, ChrStr: string; FontColor, BGColor: TColor; var big_bmp: TBitmap); var Rect: TRect; begin with big_bmp do begin Width := Wd*3; Height := Ht*3; PixelFormat := pf24Bit; with Canvas do begin Brush.Color := BGColor; FillRect(big_bmp.Canvas.ClipRect); Font.Name := FontName; Font.Height := big_bmp.Height; Font.Color := FontColor; end; Rect := Canvas.ClipRect; ExtTextOutW(Canvas.Handle,0,0,ETO_CLIPPED,@Rect,pWideChar(ChrStr),Length(Chr Str), NIL); end; CenterText(big_bmp.Canvas, Rect, ChrStr); end; //Code by Earl F. Glynn procedure CenterText(const Canvas: TCanvas; const Rect: TRect; const s: string); var X,Y: integer; begin X := (Rect.Left + Rect.Right - Canvas.TextWidth(s)) div 2; Y := (Rect.Top + Rect.Bottom - Canvas.TextHeight(s)) div 2; Canvas.TextRect(Rect,X,Y,s); end; //From code by Nacho Urenda procedure AntiAliasPicture(orig_bmp, big_bmp: TBitmap; var out_bmp: TBitmap); const MaxPixelCount = 32768; type pRGBArray = ^TRGBArray; TRGBArray = array[0..MaxPixelCount-1] of TRGBTriple; var x, y, cx, cy : integer; totr, totg, totb : integer; Row1, Row2, Row3, DestRow: pRGBArray; i: integer; begin // For each row for y := 0 to orig_bmp.Height - 1 do begin // We compute samples of 3 x 3 pixels cy := y*3; // Get pointers to actual, previous and next rows in supersampled bitmap Row1 := big_bmp.ScanLine[cy]; Row2 := big_bmp.ScanLine[cy+1]; Row3 := big_bmp.ScanLine[cy+2]; // Get a pointer to destination row in output bitmap DestRow := out_bmp.ScanLine[y]; // For each column... for x := 0 to orig_bmp.Width - 1 do begin // We compute samples of 3 x 3 pixels cx := 3*x; // Initialize result color totr := 0; totg := 0; totb := 0; // For each pixel in sample for i := 0 to 2 do begin // New red value totr := totr + Row1[cx + i].rgbtRed + Row2[cx + i].rgbtRed + Row3[cx + i].rgbtRed; // New green value totg := totg + Row1[cx + i].rgbtGreen + Row2[cx + i].rgbtGreen + Row3[cx + i].rgbtGreen; // New blue value totb := totb + Row1[cx + i].rgbtBlue + Row2[cx + i].rgbtBlue + Row3[cx + i].rgbtBlue; end; // Set output pixel colors DestRow[x].rgbtRed := totr div 9; DestRow[x].rgbtGreen := totg div 9; DestRow[x].rgbtBlue := totb div 9; end; end; end; Mike Gibbard