Title: How to use all the capabilities of windows fonts ?
Question: TFont doesn't give you all the capabilities of Windows fonts when you need to draw some text.
This is because the mechanism TFont uses differs from the one Windows have.
Answer:
TFont is a descent of TGraphicsObject. This is the abstract base class for objects which encapsulate a system graphics object: TBrush, TFont, and TPen.
Internally TFont uses the TFontData record to keep track of all changes to our font.
While TFontData structure is like this:
TFontData = record
Handle: HFont;
Height: Integer;
Pitch: TFontPitch;
Style: TFontStylesBase;
Charset: TFontCharset;
Name: TFontDataName;
end;
windows LogFont structure defines the following attributes of a font:
tagLOGFONTA = packed record
lfHeight: Longint;
lfWidth: Longint;
lfEscapement: Longint;
lfOrientation: Longint;
lfWeight: Longint;
lfItalic: Byte;
lfUnderline: Byte;
lfStrikeOut: Byte;
lfCharSet: Byte;
lfOutPrecision: Byte;
lfClipPrecision: Byte;
lfQuality: Byte;
lfPitchAndFamily: Byte;
lfFaceName: array[0..LF_FACESIZE - 1] of AnsiChar;
end;
TLogFontA = tagLOGFONTA;
TLogFont = TLogFontA;
you can already see the difference between both. Anyway, while trying to simplify
the process Delphi team forgot to add to TFontData : lfEscapment, lfOrientation
(with the two we can rotate a font) and lfQuality (this one give us the possibility
of drawing an antialised font).
When you call TextOut, internally when the draw text routine gets the handle
for the font to be used with the windows API ExtTextOut, TFont maps the TFont
structure to windows logfont structure (much like the way I did the DrawText
routine forward).
In TFont.GetHandle we see the following:
(...split...)
lfEscapement := 0; { only straight fonts }
lfOrientation := 0; { no rotation }
(...split...)
lfQuality := DEFAULT_QUALITY;
(...split...)
so... they didn't want to code just a little more :)
I thougth about changing (or even extending) TFont class to have these two properties available, anyway (if someone is interested I could do that) I'll just present here a routine that can draw some text (rotated and with more quality).
procedure DrawText(ACanvas: TCanvas; AAngle: Integer; AQuality: byte; X, Y: Integer;
AText: string);
var
lf: TLogFont;
begin
with ACanvas do
begin
GetObject(Font.Handle, SizeOf(lf), @lf);
with lf do
begin
lfQuality := AQuality;
lfOrientation := AAngle * 10;
lfEscapement := lfOrientation;
end;
Font.Handle := CreateFontIndirect(lf);
TextOut(X, Y, AText);
end;
end;
AQuality can be :
* DEFAULT_QUALITY
Appearance of the font does not matter.
* DRAFT_QUALITY
Appearance of the font is less important than when PROOF_QUALITY is used. For
GDI raster fonts, scaling is enabled, which means that more font sizes are
available, but the quality may be lower. Bold, italic, underline, and strikeout fonts are synthesized if necessary.
* PROOF_QUALITY
Character quality of the font is more important than exact matching of the
logical-font attributes. For GDI raster fonts, scaling is disabled and the font
closest in size is chosen. Although the chosen font size may not be mapped
exactly when PROOF_QUALITY is used, the quality of the font is high and there
is no distortion of appearance. Bold, italic, underline, and strikeout fonts
are synthesized if necessary.
* NONANTIALIASED_QUALITY
* ANTIALIASED_QUALITY
Note: Remember that the 3 attributes just work with True Type Fonts.