I'm trying to implement a custom font family (multiple .otf files for different weights such as heavy, light, regular, ultralight...) for my Firemonkey application, which will be deployed for both Android and iOS.
Implementing the font family on iOS was pretty simple, all I had to do was include them in the info.plist file. When applying font to label, under Font > Family I only need to type "Font name" and it gets applied. Keep in mind that there is no actual "Font name" file, only "Font name Heavy" and other weights.
Extra question here, how do I use font weight in FMX anyway? I didn't find any property for setting font weight.
However, when doing the same thing in Android, it's a completely different outcome. I include the fonts in deployment, and entering "Font name" doesn't apply it at all, but if I enter "Font name Ultralight" for example, then that font with that weight gets applied (while on iOS, adding " Ultralight" has no effect). To make things worse, adding styles to font such as italic and bold do not apply on Android at all, while they do get applied on iOS.
Why are these two acting so differently, and how can one overcome the differences so they both display the same thing?
CodePudding user response:
Support for custom fonts in Android on Delphi FMX has been recently implemented on Sydney 10.4 and its still rudimentary as of Alexandria 11. As you have noted you must enter the "complete" font name to make it work on Android as there is no official support for font weights yet.
However you can still achieve your desired results by editing and recompiling some source code located in the file FMX.FontGlyphs.Android.pas
from your Delphi installation. You can do something like this:
- Locate procedure
LoadResource
from classTAndroidFontGlyphManager
. You can see how FMX looks for fonts taking only the Family name and the file extension. - Check the inner procedure
CreateTypefaceFromFamilyName
and how it determines the weight of the current font. - Following the logic of
CreateTypefaceFromFamilyName
add something like this just before theFontFile
variable is initialized (don't forget to declareFontStyle
):
FontStyle:='';
if not CurrentSettings.Style.Slant.IsRegular and not CurrentSettings.Style.Weight.IsRegular then
FontStyle:=' Bold Italic'
else if not CurrentSettings.Style.Weight.IsRegular then
FontStyle:=' Bold'
else if not CurrentSettings.Style.Slant.IsRegular then
FontStyle:=' Italic';
- Change the assignment to
FontFile
from:
TPath.Combine(TPath.GetDocumentsPath, CurrentSettings.Family '.otf');
to:
TPath.Combine(TPath.GetDocumentsPath, CurrentSettings.Family FontStyle '.otf');
(repeat for .ttf as well)
This should add support for Bold, Italic and Bold Italic for Android. This can be further extended to support more font weights as well, just check the TFontWeight
enum in unit FMX.Graphics.pas
.