Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Font smoothing in Delphi

Tags:

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;
like image 747
Brian Frost Avatar asked May 28 '09 14:05

Brian Frost


3 Answers

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.

like image 68
mghie Avatar answered Sep 19 '22 01:09

mghie


IMHO, the VCL should be checking the System default font smoothing and applying that as the default at run-time. If not, at least it should default to a more reasonable smoothing. One could argue, in this case, that ClearType would be a better default, considering > 50% of monitors these days are LCD (and greater than 50% of machines are running XP or better).

This is an acknowledged hack (and as Ken White mentions, not the best approach if there are alternatives), but I needed a way to fix this globally for forms containing literally hundreds of 3rd-party component types (making component inheritance unrealistic).

I changed the default Font Quality in Graphics.pas, TFont.GetHandle as follows:

// lfQuality := DEFAULT_QUALITY;

lfQuality := 5; // (HACK) CLEARTYPE_QUALITY, forces cleartype

like image 30
tikinoa Avatar answered Sep 20 '22 01:09

tikinoa


From: http://objectmix.com/delphi/725245-tlabel-antialiasing-possibile-3.html

"simply using a font that supports font smoothing should fix this. Delphi uses (or at least used to use) MS Sans Serif as default, which does not support smoothing (ClearType or otherwise). if you set your font to Tahoma (best for XP) or Segoe UI (best for Vista), you will automatically get font smoothing according to system settings in your Delphi app."

Confirmed, it works beautifully using Delphi XE and Win7. Busy changing all my fonts right now ;-)

like image 39
Maya Avatar answered Sep 20 '22 01:09

Maya