Page 1 of 1

[Info] How to use custom TTF fonts

Posted: Wed Mar 05, 2025 3:52 pm
by Sergey Tkachenko
This article explains how to make custom TTF fonts available to your application (without installing fonts in the system and making available to other applications).

VCL

If you want to use a custom TTF font, load it using AddFontResourceEx(PChar(FontFileName), FR_PRIVATE, nil) when your application starts. This font will be available to your application.
When your application exists, call RemoveFontResourceEx(PChar(FontFileName), FR_PRIVATE, nil).

FireMonkey

AddFontResourceEx is available only on Windows, but it does not work. It makes the font available for GDI drawing, but not for FMX drawing that uses advanced renderers (DirectDraw + GDI+, or Skia). So other methods are needed, specific to renderers. I will not discuss them here, because there is a simpler solution.

Skia

If your application is Skia-enabled, you can use cross-platform methods to add custom fonts in your application.
Call

Code: Select all

  TSkTypefaceManager.RegisterTypeface(FontFileName);
TSkTypefaceManager is defined in FMX.Skia.pas. It allows adding custom fonts from a file or a stream.

Delphi 12 warns that TSkTypefaceManager.RegisterTypeface is deprecated, and recommends using TSkDefaultProviders.RegisterTypeface instead.

Fonts added in this way will not be returned by RVFillFontFamilies procedure from fmxRVFontListFM unit. You need to add them to the returned list of font families yourself.

Delphi 12

But the recommended way of adding custom fonts in Delphi 12 is IFMXFontManagerService (defined in FMX.FontManager.pas):

Code: Select all

  var LFontManager: IFMXFontManagerService;
  if TPlatformServices.Current.SupportsPlatformService(IFMXFontManagerService, LFontManager) then
    LFontManager.AddCustomFontFromFile(FontFileName);
As I can see, IFMXFontManagerService is implemented for Skia, and also without Skia (for Windows, macOS, and Linux).
This service allows adding custom fonts and enumerating font families of custom fonts.

Fonts added in this way will not be returned by RVFillFontFamilies procedure from fmxRVFontListFM. You need to add them to the returned list of font families yourself.
Here is how:

Code: Select all

uses
  fmxRVFontListFM,  FMX.FontManager, FMX.Platform;

// adding a list of font families to ComboEdit1.Items.

var
  i: Integer;
  FontList: TStringList;
  LFontManager: IFMXFontManagerService;
begin
  FontList := TStringList.Create;
  RVFillFontFamilies(FontList);
  if TPlatformServices.Current.SupportsPlatformService(IFMXFontManagerService, LFontManager) then
    for i := 0 to LFontManager.GetCustomFontInfoCount - 1 do
      FontList.Add(LFontManager.GetCustomFontInfo(i).FamilyName);
  FontList.Sort;
  ComboEdit1.Items.Assign(FontList);
  FontList.Free;
end;