Font smoothing in Delphi

Brian Frost picture Brian Frost · May 28, 2009 · Viewed 7.9k times · Source

I had cause to need a label with a large font on a Delphi form and noticed that its curves were still slightly jagged. I compared this with the same size and font in MSWord which was much smoother. After research I found code that allowed me to smooth my fonts but it's messy and I was wondering if there was a better way? Looking in the VCL source, TFont seems wedded to NONANTIALIASED_QUALITY which is rather frustrating...

Thanks Bri

procedure TForm1.SetFontSmoothing(AFont: TFont);
var
  tagLOGFONT: TLogFont;
begin
  GetObject(
    AFont.Handle,
    SizeOf(TLogFont),
    @tagLOGFONT);
  tagLOGFONT.lfQuality  := ANTIALIASED_QUALITY;
  AFont.Handle := CreateFontIndirect(tagLOGFONT);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  I : integer;
begin
  For I :=0 to ComponentCount-1 do
    If Components[I] is TLabel then
      SetFontSmoothing( TLabel( Components[I] ).Font );
end;

Answer

mghie picture mghie · May 28, 2009

You can trick the VCL into creating your own class that inherits from TLabel. This is proof-of-concept code, tested with Delphi 4, which should get you started.

Create a new unit for your own TLabel class:

unit AntiAliasedLabel;

interface

uses
  Windows, Messages, SysUtils, Controls, StdCtrls, Graphics;

type
  TLabel = class(StdCtrls.TLabel)
  private
    fFontChanged: boolean;
  public
    procedure Paint; override;
  end;

implementation

procedure TLabel.Paint;
var
  LF: TLogFont;
begin
  if not fFontChanged then begin
    Win32Check(GetObject(Font.Handle, SizeOf(TLogFont), @LF) <> 0);
    LF.lfQuality := ANTIALIASED_QUALITY;
    Font.Handle := CreateFontIndirect(LF);
    fFontChanged := TRUE;
  end;
  inherited;
end;

end.

Now modify your form unit that contains the label, adding the AntiAliasedLabel unit after StdCtrls. This results in your own class AntiAliasedLabel.TLabel being created where normally StdCtrls.TLabel would be created.