Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 930
blerontin Avatar asked Feb 25 '13 15:02

blerontin


2 Answers

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.

like image 57
David Heffernan Avatar answered Oct 13 '22 05:10

David Heffernan


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.

like image 28
Andreas Rejbrand Avatar answered Oct 13 '22 05:10

Andreas Rejbrand