How can I override ClearType setting when drawing text using the Win32 API?
Asked Answered
C

2

8

I have written a little application that draws text on in-memory images and writes them to files. The basic Delphi code looks similar to:

var
   Canvas : tCanvas;
   Text : WideString;
   TextRect : tRect;
begin
   Canvas := Bitmap.Canvas;
   Canvas.Brush.Color := clBlack;
   Canvas.Pen.Color := clBlack;
   Canvas.Font.Name := 'Courier New';
   Canvas.Font.Size := 11;
   Canvas.Font.Color := clWhite;

   TextRect := ...;  // calculate text position
   DrawTextW(Canvas.Handle, PWideChar(Text), Length(Text), TextRect, DT_NOCLIP or DT_NOPREFIX or DT_SINGLELINE or DT_CENTER or DT_VCENTER);
end;

Unfortunately the drawn text is different depending on the ClearType setting of the computer running the application. I would like to have a consistent output in my application regardless of the local ClearType setting (output is not displayed to screen directly anyway). Is there some Win32 API option to override the local ClearType settings?

Caesarean answered 25/2, 2013 at 15:49 Comment(0)
P
12

The font smoothing of text is determined by the font that you select into the device. To learn about the options offered by the raw Win32 interface, read the LOGFONT documentation.

In Delphi the underlying Win32 API font API is wrapped up by the TFont class. The property that is pertinent to this question is Quality. The default value is fqDefault which uses the system-wide font smoothing setting. You want to set Quality to either fqAntialiased or fqNonAntialiased.

Older versions of Delphi do not have this property. In which case you will need to call CreateFontIndirect to create an HFONT with the required quality settings. You can call this function immediately before you start drawing text:

procedure SetFontQuality(Font: TFont; Quality: Byte);
var
  LogFont: TLogFont;
begin
  if GetObject(Font.Handle, SizeOf(TLogFont), @LogFont) = 0 then
    RaiseLastOSError;
  LogFont.lfQuality := Quality;
  Font.Handle := CreateFontIndirect(LogFont);
end;

Pass either NONANTIALIASED_QUALITY or ANTIALIASED_QUALITY depending on your needs.

Potto answered 25/2, 2013 at 15:56 Comment(0)
P
6

I believe you can create a new logical font that doesn't use any ClearType. Make sure to pass the NONANTIALIASED_QUALITY flag as the fdwQuality parameter of CreateFont:

Font is never antialiased, that is, font smoothing is not done.

Predate answered 25/2, 2013 at 15:55 Comment(1)
You can also use anti-aliased quality, which renders with old-style antialiasing - ie, without Cleartype. That gives you decent quality text which will look better than text drawn with no font smoothing whatsoever.Namecalling

© 2022 - 2024 — McMap. All rights reserved.