Utiliser une fonte TTF sous Android

Contrairement aux autres plateformes, l'utilisation de fontes personnalisées ne se fait pas en paramétrant un simple fichier. En tout cas pas encore...

Pour utiliser un fichier TTF dans une application mobile sous Android développée avec Delphi il faut déjà joindre le ou les fichiers TTF utiles. Pour cela, comme pour les autres plateformes, le plus simple est de se rendre dans le gestionnaire de déploiements depuis le menu "Projet / Déploiement" de l'EDI.

Une fois fait, rendez-vous dans "Toutes les configurations Android" ou celle(s) qui vous intéresse(nt). Ajoutez les fichiers TTF utiles avec .\assets\internal\ comme dossier de destination. Ce dossier correspondra à TPath.GetDocumentsPath() dans votre programme.

La seconde étape consiste à indiquer à votre programme quelle fonte vous désirez utiliser. Pour cela, deux solutions : soit mettre le nom de la fonte (pour les polices du système), soit mettre le chemin d'accès vers le fichier TTF.

  Label1.TextSettings.Font.Family := TPath.GetDocumentsPath + PathDelim + 'Star_Trek_future.ttf';

Exceptionnellement j'ai utilisé PathDelim dans cet exemple. Je recommande plutôt d'utiliser TPath.combine() qui fait quelques vérifications complémentaires. La classe TPath se trouvant dans System.IOUtils il faut bien entendu ajouter cette unité à vos Uses.

Dans la version actuelle de Firemonkey Delphi ne sait pas interpréter directement un chemin vers un fichier TTF. Il s'attent à ce qu'on lui fournisse le nom d'une fonte de caractères enregistrée dans le système. Il faut donc ruser et c'est là que les choses se corsent.

Pour faire en sorte que Delphi prenne en compte notre fichier TTF, il va falloir modifier une unité du système et l'embarquer dans le projet. Qui dit modification d'une unité système, dit un bidouillage avec chaque version de Delphi tant que cette fonctionnalité n'a pas été intégrée d'une manière ou d'une autre. Ce n'est donc pas génial, mais ça permet aussi de voir la souplesse du logiciel et l'utilité d'avoir à notre disposition les sources des composants et librairies de Firemonkey.

Sur votre ordinateur, dans l'arborescence d'installation de Delphi (ou RAD Studio), vous trouverez le fichier FMX.FontGlyphs.Android.pas

Copiez le fichier d'origine dans un sous-dossier de votre projet. Appelez le par exemple Systeme ou idéalement du nom de la version de Delphi. Dans mon exemple 10_1_Berlin

Faites ensuite la modification dont je vous parlerai un peu plus tard.

Lorsqu'une nouvelle version de Delphi sort, vous devez refaire la même modification dans le même fichier (s'il a changé, n'a pas été déplacé ou rebaptisé entre temps). Copiez donc la nouvelle version du fichier dans un autre dossier de votre projet et faites la modification dessus. Dans mon exemple j'ai donc créé un dossier 10_2_Tokyo

Pourquoi conserver deux versions du fichier ?

Tout simplement parce que pour une raison ou une autre vous serez peut-être amené à compiler votre programme avec l'ancienne ou la nouvelle version de Delphi. Comme vous êtes susceptible de transmettre vos sources à quelqu'un qui ne travaillerait pas forcément avec la même version que vous ça peut aussi être très pratique pour la maintenance, la revue de code ou la transmission à un client ou prestataire.

Notez au passage que la licence de l'environnement de développement ne nous autorise pas à en distribuer les sources.
C'est à titre très exceptionnel et qu'à des utilisateurs ayant aussi une licence que vous pouvez joindre des fichiers "système" à vos projets. Vous ne devez en aucun cas les diffuser librement ou dans le cadre de projets open source sans avoir une autorisation d'Embarcadero.

Revenons en à notre fichier FMX.FontGlyphs.Android.pas et à la modification à lui apporter.

En éditant la version copiée dans le dossier de votre projet, vous devez chercher la méthode TAndroidFontGlyphManager.LoadResource qui est appelée lors de l'affectation d'une chaine à Font.Family Vous y trouverez cette ligne :

Typeface := TJTypeface.JavaClass.Create(FamilyName, TypefaceFlag);

que vous devrez remplacer par celles-ci :

    // begin of changed code
    if CurrentSettings.Family.endsWith('.ttf') and
      FileExists(CurrentSettings.Family) then
      Typeface := TJTypeface.JavaClass.createFromFile(FamilyName)
    else
      Typeface := TJTypeface.JavaClass.Create(FamilyName, TypefaceFlag);
    // Typeface := TJTypeface.JavaClass.create(FamilyName, TypefaceFlag);
    // end of changed code

On remplace ainsi le chargement depuis la mémoire par un chargement depuis la mémoire ou depuis un fichier si le nom de la police de catactères fini par '.ttf' et correspond à un fichier valide.

Il suffit ensuite de faire en sorte que le compilateur prenne en compte ce fichier modifié plutôt que le fichier du système et c'est là que les règles de compilation conditionnelles entrent à nouveau en jeu.

Ouvrez le menu contextuel sur le nom de votre projet dans le gestionnaire de projets et choisissez "Voir le source" ou allez dans le menu "Projets / Voir le source" Puis ajoutez votre fichier à la liste des unités du projet.

uses
  System.StartUpCopy,
{$IFDEF ANDROID}
{$IFDEF VER310}
  FMX.FontGlyphs.Android in '10_1_Berlin\FMX.FontGlyphs.Android.pas',
{$ENDIF }
{$IFDEF VER320}
  FMX.FontGlyphs.Android in '10_2_Tokyo\FMX.FontGlyphs.Android.pas',
{$ENDIF }
{$ENDIF }
  FMX.Forms,

Vous auriez aussi pu vous contenter de l'ajouter au projet comme vous le feriez avec n'importe quelle unité, mais ça peut poser problème lorsque vous voulez joindre plusieurs versions du même fichier alors que la méthode manuelle est plus rapide.

Dans cet exemple, et uniquement si on compile pour la plateforme Android, on joint l'un ou l'autre des fichiers selon la version du compilateur.

Il ne reste plus qu'à compiler, tester et distribuer votre application avec la fonte personnalisée choisie sauf bien entendu si vous désirez faire l'équivalent pour une autre plateforme et ne l'avez pas encore fait.


Si votre application cible des périphériques sous Android 8 ou plus, pouvez utiliser les fontes directement comme ressource à votre APK et demander au système de les précharger. Reportez-vous à la documentation d'Android.


Mug carte postale SydneyMug Pascal case in Alexandrie