[Info] How to use custom TTF fonts
Posted: Wed Mar 05, 2025 3:52 pm
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
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):
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:
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);
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);
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;