Flex 2 - Externaliser les polices

Illustration d'une police de caractères Cette fois, j'essaye de charger des polices de caractères dynamiquement. Ca peut servir à plein de choses, c'est vous qui voyez :) .

Utiliser une police TrueType

D'après l'aide en ligne, il n'est possible d'inclure que des polices TrueType à l'aide du metadata Embed. Je n'ai rien d'autre sur mon poste, si cette première technique ne marche pas avec d'autres formats de police, essayez la deuxième technique.

Inclure la police dans un SWF

Comme Flash ne peut pas charger un fichier de police dynamiquement et le comprendre tout de suite, je vais utiliser un intermédiaire.

Je crée donc un SWF avec juste la police dedans (dans mon exemple, la police s'appelle GoodDogPlain):

package
{
import flash.display.Sprite;
 
public class GoodDogPlain extends Sprite
{
	[Embed(source="GoodDogPlain.ttf", mimeType="application/x-font-truetype", fontName="truc")]
	public var font:Class;
	public function GoodDogPlain()
	{
		
	}
}
 
}

La police aura comme identifiant truc.

Charger la police

Maintenant, il ne reste plus qu'à la charger dans mon application.

import mx.controls.SWFLoader;
import flash.events.Event;
import flash.text.Font;
 
function init():void
{
	var loader:SWFLoader = new SWFLoader();
	loader.addEventListener(Event.COMPLETE, this._fontLoadComplete);
 
	loader.load("fonts/GoodDogPlain.swf");
}
 
private function _fontLoadComplete(pEvent:Event):void
{
	// On accède à l'instance de "SWFLoader" avec "pEvent.target"
	// "pEvent.target.content" est donc une instance de ma class "GoodDogPlain"
	// Je récupère la valeur de la propriété "font" qui contient la police
	var font_class:Object = pEvent.target.content["font"];
 
	// Il faut répertorier la police dans une liste
	// Et là je fais un cast, sinon ça ne marche pas
	Font.registerFont(Class(font_class));
}

Voilà, la police truc est disponible. Tous les champs de texte peuvent utiliser cette police, même les prochains SWF chargés.

J'ai testé en chargeant ce SWF :

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*">
	<mx:Label text="glou glou" fontFamily="truc"/>
</mx:Application>

Et ça marche :) .

On peut aussi changer la police d'un texte déjà affiché bien sûr.

Utiliser une police FlashType

On peut aussi utiliser une police d'un SWF généré avec Flash IDE. Apparement, Adobe appelle ces polices importées : FlashType.

La technique est la même, sauf que le metadata devient :

// Au lieu d'inclure directement la police, j'inclus le SWF qui contient un symbole Font
[Embed(source="GoodDogPlain.swf", symbol="toto")]

Il faut bien sûr un symbole Font avec un nom de liaison (ici c'est toto).

Par contre, une fois chargé, l'identifiant de la police est GoodDogPlain, pas toto ni truc. Donc j'imagine qu'il prend le nom système qu'avait la police ou un quelque chose comme ça :) .

Conclusion

Je suis assez satisfait. Il y a une liste globale de polices qu'on peut utiliser. Quand on en répertorie une, elle est disponible partout.

Commentaires

1. Le vendredi, octobre 27 2006, 14:37 par Roikku

Me reste plus qu'à tester de mon côté via Flash9, sans flex.

Si j'arrive à pouvoir choisir via une liste dynamiquement sans à avoir à charger un gros swf incluant les fontes voulues, ce serait le top...

Je finis mon taff dans 1/2 heure, le temps de rentrer, je teste et je fais un post aussi.

En tous les cas, merci pour ton billet

4. Le dimanche, octobre 29 2006, 18:02 par neolao

Non, pas de raison particulière. Je faisais mes tests et j'avais ça déjà dans mon code lol

Mais j'ai eu des trucs curieux entre SWFLoader et Loader, j'me suis pas encore penché sur le problème. En plus, la source du framework n'est pas celle compilée dans les swc, j'en suis pratiquement sûr.

Bref, à priori, on peut faire la même chose avec Loader.

5. Le lundi, octobre 30 2006, 09:53 par Roikku

Bah, de toute façon, sous Flash IDE, comme on ne peut pas utiliser SWFLoader, on est de toute façon obligé de passer par Loader.

La seule différence que je vois, c'est que pour Loader, on doit passer un argument URLRequest, alors que SWFLoader, une chaine de caractère suffit.

6. Le lundi, octobre 30 2006, 10:20 par neolao

D'après la source fournie de SWFLoader, il utilise FlexLoader qui hérite de Loader. Il faudrait juste trouver comment accéder à "content", mais c'est vrai que ça a l'air pareil de toute façon.

7. Le mercredi, novembre 1 2006, 11:50 par Roikku

Mmmm, je suis en train de voir un truc, mais ton casting est faux. Je me demande comment j'ai pas pu le voir tout de suite.

en as3, ca devient :
Font.registerFont( font_class as Class );

De mon côté, j'ai plus l'erreur de casting, mais comme j'ai trop trituté ma source, faut que je relise tout mon code. Après, je poste sur MédiaBox

10. Le jeudi, novembre 9 2006, 07:53 par nico-k

Bonjour,
Ca à l'air d'être exactement ce que je cherche (pouvoir charger des fonts dans une animation principale sans avoir besoin de la recompiler à chaque fois).
Malheureusement je n'arrive pas à faire fonctionner le script j'ai des erreur à la compilation et je ne suis pas une bête en actionscript :
Est ce qu'il serait possible pouvoir télécharger un exemple source fonctionnel?
Merci d'avance et bravo pour l'astuce, ça fait 2 jours que je cherche une soluce.

11. Le jeudi, novembre 9 2006, 09:10 par neolao

Au début, je pensais fournir des fichiers mais je me suis rendu compte que c'était pas évident. Je n'utilise pas Flex builder ni Flash IDE, donc pas de fichier de projet ou des choses de ce genre.

Ce que j'pourrai te proposer, c'est de me détailler sur le forum le problème que tu as eu.

Je précise que j'utilise le compilateur mxmlc.exe hein :)

12. Le jeudi, novembre 9 2006, 10:22 par Roikku

>nico-k
Il n'est pas possible de faire marcher des codes ActionScript 3, version de langage utilisable que depuis Flash 9 ou Flex 2, sous Flash 8 et inférieur.

Pour une version sous FLash MX2004, tu peux faire un tour sur mon site qui donne deux tutoriels à ce que tu souhaites obtenir.