Apache Adobe Flex TutorialTutoriaux Adobe Flex & AIR en Français

23mai/087

Flex Embed Fonts – Polices Embarquées à la compilation

Même s'il y a plusieurs cas d'utilisation pour les system fonts et device fonts, les polices le plus fréquemment dans les application Flex sont les polices Embarquées (embedFonts). Les polices de texte embedded sont en fait les contours de police compilés avec le .swf, garantissant que tous les utilisateurs auront le même rendu. L'inconvénient avec les polices embedded est qu'elles peuvent augmenter la taille du fichier .swf. Cependant, puisqu'on considère que les applis Flex sont des RIA (Rich Internet Applications), cette augmentation de taille ne sera pas forcement un problème. Dans certains cas, l'augmentation de la taille peut être réduite en embarquant uniquement le contour des polices dont on à besoin pour l'application en question.

Il y a d'autres raisons pour lesquelles on utilise les embed fonts, les polices embarquées résolvent plusieurs problèmes rencontrés avec les polices système.

Tout d'abord, les System fonts dans des applications Flex ne peuvent pas subir de rotation ou d'ajustement de l'opacité. Si vous essayer de tourner une police système, le texte disparaitra. Si vous tentez de jouer avec l'alpha, cela n'aura aucun effet. Cependant, si vous embarquez la police, vous pouvez effectuer ces deux opérations. De plus, les polices système ne sont pas anti-aliasées, quand vous augmentez la taille de ces polices, le crénelage se voit de plus en plus. Les polices embarquées sont anti-aliasées, ce qui veut dire qu'elles rendront mieux pour un texte de grande taille.

Embarquer une police avec le tag Embed

Il existe de nombreuses manières d'embarquer des fonts. Tout d'abord, nous verrons comment embarquer une police dont vous avez le fichier (.ttf). Vous pouvez embarquer ces polices en utilisant le tag metadata Embed en ActionScript. Pour embarquer une police de cette manière, utilisez l'attribut "source" pour spécifier le chemin vers le fichier .tff et l'attribut "fontName" pour spécifier le nom de la font car vous voudrez la référencer pour votre application. Pour utiliser le metadata tag correctement, vous devez le placer juste avant la déclaration d'un variable de type Class. Vous n'aurez pas besoin d'utiliser cette variable mais le compilateur en a besoin.

Voici un exemple qui embarque une police appelée Century Gothic depuis un fichier .tff et en fontName, "gothicCentury":

[Embed(source="C:\\Windows\\Fonts\\GOTHIC.ttf", fontName="gothicCentury")]
private var _centuryGothic:Class;

Une fois que vous avez embarqué la police, vous pouvez utiliser la valeur de fontName pour la référencer comme vous le feriez pour n'importe quelle police:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
	>
	<mx:Style>
		global {
			fontFamily: gothicCentury;
		}
	</mx:Style>
	<mx:Script>
		<![CDATA[
			[Embed(source="C:\\Windows\\Fonts\\GOTHIC.ttf", fontName="gothicCentury")]
			private var _centuryGothic:Class;
		]]>
	</mx:Script>
	<mx:TextArea text="Texte de démonstration"/>
</mx:Application>

Quand vous embarquez une police, seulement un type de contour est embarqué. Dans l'exemple précédent, seuls les contours standards sont embarqués, pas la bold, ni l'italique.

Vous pouvez facilement voir cet effet en ajoutant un bouton à l'application de l'exemple précédent. Comme les boutons utilisent la version en gras par défaut, vous verrez que c'est la police par défaut qui est utilisée. Pour y remédier, vous devez aussi embarquer la police bold de cette police en utilisant la même valeur de fontName. Cependant, cette fois, nous devons fixer le fontWeight à bold comme dans l'exemple suivant:

 <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
	>
	<mx:Style>
		global {
			fontFamily: gothicCentury;
		}
	</mx:Style>
	<mx:Script>
		<![CDATA[
			[Embed(source="C:\\Windows\\Fonts\\GOTHIC.ttf", fontName="gothicCentury")]
			private var _centuryGothic:Class;

			[Embed(source="C:\\Windows\\Fonts\\GOTHICB.ttf", fontName="gothicCentury", fontWeight="bold")]
			private var _centuryGothicBold:Class;
		]]>
	</mx:Script>
	<mx:TextArea text="Texte de démonstration"/>
	<mx:Button label="Exemple"/>
</mx:Application>

Embed une police en CSS pour Flex

Vous pouvez aussi embed une font en CSS en utilisant la directive @font-face. C'est particulièrement pratique si vous utilisez des feuilles de style externes car vous pouvez les compiler pour les utiliser ensuite comme des thèmes ou comme des CSS chargés à la volée. Cependant, il est aussi bon d'utiliser cette technique pour des définitions de style locales simplement car vous préferrez la syntaxe avec le tag metadata Embed.

La directive @font-face permet d'avoir les mêmes attributs/propriétés que le tag Embed quand on embarque des polices. Les différences se font dans le fait que l'attribut "source" du tag est ici appelé src et que fontName est appelé fontFamily. La valeur de src doit aussi être comprise dans un url() comme dans l'exemple suivant:

@font-face{
	src: url("C:\\Windows\\Fonts\\GOTHIC.ttf");
	fontFamily: gothicCentury;
}

Voici l'exemple précédent (avec les polices en gras), réécrit avec les directives @font-face:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
	>
	<mx:Style>
		@font-face{
			src: url("C:\\Windows\\Fonts\\GOTHIC.ttf");
			fontFamily: gothicCentury;
		}
		@font-face{
			src: url("C:\\Windows\\Fonts\\GOTHICB.ttf");
			fontFamily: gothicCentury;
			fontWeight: bold;
		}
		global {
			fontFamily: gothicCentury;
		}
	</mx:Style>
	<mx:TextArea text="Texte de démonstration"/>
	<mx:Button label="Exemple"/>
</mx:Application>

Embarquer une police par son nom système

Flex propose d'embarquer de polices de multiples manières. Plutôt que d'embarquer la police grâce au nom du fichier .tff, vous pouvez utiliser le nom de la police, s'il est reconnu par l'ordinateur. Quand vous voulez faire ça, vous pouvez utiliser le tag Embed. Plutôt que de préciser un attribut "source", vous devez utiliser "systemFont" et spécifier le nom de la police tel qu'il est connu par le système. De plus, vous devez spécifier un type MIME en utilisant l'attribut mimeType. La valeur peut être soir application/x-font ou application/x-font-truetype.

Le code suivant utilise les noms système pour embarquer les polices:

[Embed(systemFont="Century Gothic", fontName="gothicCentury", mimeType="application/x-font")]
private var _centuryGothic:Class;

[Embed(systemFont="Century Gothic", fontName="gothicCentury", mimeType="application/x-font", fontWeight="bold")]
private var _centuryGothicBold:Class;

Vous pouvez aussi le faire en utilisant les CSS. Utilisez seulement local() au lieu de url():

@font-face{
	src: local("Century Gothic");
	fontFamily: gothicCentury;
}
@font-face{
	src: local("Century Gothic");
	fontFamily: gothicCentury;
	fontWeight: bold;
}

Articles similaires

Commentaires (7) Trackbacks (1)
  1. Bonjour,

    Merci pour ce site bien fait !

    En suivant votre tuto, j'ai réussi sans trop de difficulté a intégrer la Bauer Bodoni dans mon application Flex.
    Seul souci que je n'arrive pas à résoudre est le non affichage des caractères accentués…

    Cette police contient bien des accents.

    Avez vous déjà rencontré ce type de problème ? et si oui avez vous pu le résoudre ?

    merci
    Franck

  2. Salut,
    alors je n'ai pas la solution, mais je peux peut-être te donner des pistes.
    Tout d'abord, tu peux essayer de convertir ton fichier TTF en SWF. Pour cela, tu peux voir la manipulation dans cet article:
    http://www.flex-tutorial.fr/2008/06/19/flash-font-convertir-un-fichier-ttf-en-swf-convert-ttf-to-swf/
    Comme cela, tu peux choisir quel types de caractères intégrer dans ton SWF.

    Sinon, si par exemple tu utilises la police en gras (si tu écrit le label d'un Button, il est en gras automatiquement), regarde si la police contient bien les accents dans sa version Bold et s'ils sont bien intégrés.

    Si tu trouves la solution à ton problème, n'hésite pas à la poster en commentaire de cet article ;)

    Bonne chance
    Fabien

  3. Je tiens aussi à préciser une chose.

    Si vous voulez ajouter une police perso à votre RTE en embed via le css (ou autre), il vous faudra OBLIGATOIREMENT faire en sorte que la police système Verdana soit aussi Embed via le css (ou autre).
    exemple:

    @font-face{
    src: local("Verdana");
    fontFamily: Verdana;
    }

    @font-face {
    src: url("../../polices/Champagne_Limousines.ttf");
    fontFamily: ChampagneLimousines;
    }

    Sans le 1er bloc @font-face qui defini Verdana comme embed notre police n'aurait pas pu s'afficher dans notre RTE !

  4. Bonjour et encore merci pour tous ces tutos...
    Peut être pourriez vous m'aider, j'ai un souci de "flou" sur l'affichage de la police quand je l'embarque. Je m'explique
    Si j'utilise de l'arial (police qui est déja intégrée) de façon classique, l'affichage de mon texte est nickel et sans "bavure".
    Exemple de code :

    Actionscript:
    1. global {
    2.             fontFamily: arial;
    3.             fontSize:12;
    4.         }

    Par contre, si ce coup ci j'embarque ma police arial, le texte affiché est flou et imprécis,

    Actionscript:
    1. @font-face{
    2.             src: url("C:\\Windows\\Fonts\\ARIAL.TTF");
    3.             fontFamily: embarque;
    4.             fontWeight:normal;           
    5.         }
    6.         global {
    7.             fontFamily: embarque;
    8.             fontSize:12;
    9.         }

    J'ai regardé un peu les notion de "antiAlias" , mais j'ai beau changer des valeurs, rien ne change.
    Vous auriez une piste ?
    Merci

  5. Salut,
    Effectivement, dans la doc:
    http://livedocs.adobe.com/flex/3/html/help.html?content=Working_with_Text_17.html#153173
    Il est dit:
    "Embedded font characters are anti-aliased, making their edges appear smoother, especially for larger text"
    Je ne vois pas de solution pour l'instant

    Fabien

  6. Salut.
    On est effectivement bien coincé. la seule solution qui va pas trop mal est de jouer avec les paramètres css :
    exemple :

    Actionscript:
    1. fontFamily: "calibri";
    2.     fontSize: 12;
    3.     advancedAntiAliasing: true ;
    4.     fontAntiAliasType: "advanced";
    5.     fontThickness: 50;
    6.     fontGridFitType: "pixel";
    7.     fontSharpness: 100;

    ceci dit, c'est moyennement marrant de tester les valeurs pour voir ce qui va le mieux !

    Merci

  7. un complement au post fait précédemment, vu que je viens de m'arracher les cheveux :
    si le texte est affiché avec une propriété textAlign =right, l'affichage de la police embarquée n'est pas du tout le même (encore plus flou) que si on a un align à left.
    Plus la police est petite, plus cela est flagrant.

    J'ai récupéré un mxml sur le net (cf debut du code) et je l'ai un peu adapté pour pouvoir faire mumuse avec les alignements, et c'est flagrant

    MXML:
    1. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    2.  
    3.         backgroundColor="white">
    4.  
    5.     <mx:Style>
    6.         @font-face {
    7.             src: local("calibri");
    8.             fontFamily: "calibriE";
    9.         }
    10.        
    11.         @font-face {
    12.             src: local("arial");
    13.             fontFamily: "arialE";
    14.         }
    15.        
    16.         @font-face {
    17.             src: local("tahoma");
    18.             fontFamily: "tahomaE";
    19.         }
    20.     </mx:Style>
    21.  
    22.     <mx:Array id="antiAliasTypes">
    23.         <mx:Object label="normal" />
    24.         <mx:Object label="advanced" />
    25.     </mx:Array>
    26.    
    27.     <mx:Array id="fontTypes">
    28.         <mx:Object label="calibriE" />
    29.         <mx:Object label="arialE" />
    30.         <mx:Object label="arial" />
    31.         <mx:Object label="tahomaE" />
    32.     </mx:Array>
    33.    
    34.     <mx:Array id="alignTypes">
    35.         <mx:Object label="left" />
    36.         <mx:Object label="right" />
    37.     </mx:Array>
    38.    
    39.    
    40.  
    41.     <mx:Array id="gridFitTypes">
    42.         <mx:Object label="none" />
    43.         <mx:Object label="pixel" />
    44.         <mx:Object label="subpixel" />
    45.     </mx:Array>
    46.  
    47.     <mx:Boolean id="isAdvanced">
    48.         {antiAliasTypeComboBox.selectedIndex == 1}
    49.     </mx:Boolean>
    50.  
    51.     <mx:ApplicationControlBar dock="true">
    52.         <mx:Form>
    53.             <mx:FormItem label="{sizeSlider.value} fontSize:">
    54.                 <mx:HSlider id="sizeSlider"
    55.                         minimum="6"
    56.                         maximum="24"
    57.                         value="12"
    58.                         liveDragging="true"
    59.                         snapInterval="1"
    60.                         tickInterval="1" />
    61.             </mx:FormItem>
    62.             <mx:FormItem label="rotation:">
    63.                 <mx:HSlider id="rotationSlider"
    64.                         minimum="-3"
    65.                         maximum="3"
    66.                         value="0"
    67.                         liveDragging="true"
    68.                         snapInterval="0.1"
    69.                         tickInterval="1" />
    70.             </mx:FormItem>
    71.             <mx:FormItem label="fontAntiAliasType:">
    72.                 <mx:ComboBox id="antiAliasTypeComboBox"
    73.                         dataProvider="{antiAliasTypes}" selectedIndex="1" />
    74.             </mx:FormItem>
    75.             <mx:FormItem label="{sharpnessSlider.value} : fontSharpness:"
    76.                     enabled="{isAdvanced}">
    77.                 <mx:HSlider id="sharpnessSlider"
    78.                         minimum="-400"
    79.                         maximum="400"
    80.                         value="0"
    81.                         liveDragging="true"
    82.                         snapInterval="1"
    83.                         tickInterval="20" />
    84.             </mx:FormItem>
    85.             <mx:FormItem label="{thicknessSlider.value} :fontThickness:"
    86.                     enabled="{isAdvanced}">
    87.                 <mx:HSlider id="thicknessSlider"
    88.                         minimum="-200"
    89.                         maximum="200"
    90.                         value="0"
    91.                         liveDragging="true"
    92.                         snapInterval="1"
    93.                         tickInterval="10" />
    94.             </mx:FormItem>
    95.             <mx:FormItem label="fontGridFitType:"
    96.                     enabled="{isAdvanced}">
    97.                 <mx:ComboBox id="gridFitTypeComboBox"
    98.                         dataProvider="{gridFitTypes}" selectedIndex="1"/>
    99.             </mx:FormItem>
    100.             <mx:FormItem label="font:">
    101.                 <mx:ComboBox id="fontTypeChoix"
    102.                         dataProvider="{fontTypes}" selectedIndex="0"/>
    103.             </mx:FormItem>
    104.             <mx:FormItem label="alignement:">
    105.                 <mx:ComboBox id="fontAlignChoix"
    106.                         dataProvider="{alignTypes}" selectedIndex="0"/>
    107.             </mx:FormItem>
    108.         </mx:Form>
    109.     </mx:ApplicationControlBar>
    110.    
    111. <mx:Canvas>
    112.  
    113. <mx:FormItem label="Saisir un texte : " x="10" y="80">
    114.     <mx:TextInput id="choix" text="Type de mouvement"
    115.         fontFamily="{fontTypeChoix.selectedItem.label}"
    116.             fontSize="{sizeSlider.value}"
    117.             fontAntiAliasType="{antiAliasTypeComboBox.selectedItem.label}"
    118.             fontSharpness="{sharpnessSlider.value}"
    119.             fontThickness="{thicknessSlider.value}"
    120.             fontGridFitType="{gridFitTypeComboBox.selectedItem.label}"
    121.             rotation="{rotationSlider.value}">
    122.        
    123.     </mx:TextInput>
    124.     </mx:FormItem>
    125.     <mx:Label id="lbl" x="125" y="150" 
    126.         textAlign="{fontAlignChoix.selectedItem.label}"
    127.             text="{choix.text}"
    128.             color="0x000000"
    129.             fontFamily="{fontTypeChoix.selectedItem.label}"
    130.             fontSize="{sizeSlider.value}"
    131.             fontAntiAliasType="{antiAliasTypeComboBox.selectedItem.label}"
    132.             fontSharpness="{sharpnessSlider.value}"
    133.             fontThickness="{thicknessSlider.value}"
    134.             fontGridFitType="{gridFitTypeComboBox.selectedItem.label}"
    135.             rotation="{rotationSlider.value}"
    136.             truncateToFit="false" />
    137. <!-- <mx:FormItem label='image "témoin" : ' x="10" y="170">           
    138.             <mx:Image source="@Embed('police.png')" >
    139.                
    140.             </mx:Image>
    141.             </mx:FormItem> -->
    142.    
    143. </mx:Canvas>               
    144.  
    145. </mx:Application>

    par contre, je n'ai pas de solution pour éviter ce souci. si je trouve qque chose, je posterais...

    bonne blague de flex !


Leave a comment

(required)