Mesdames, messieurs, j'ai l'honneur de vous présenter le premier chapitre où nous allons pouvoir afficher quelque chose sur notre fenêtre désespérément vide !
Et il s'agit rien de moins que du texte, grâce à une classe que nous allons retourner dans tous les sens : TextField
.
Que le spectacle commence !
- Une histoire de TextField
- Centrer le champ de texte
- La mise en forme
- En HTML dans le texte
- Les polices de caractères embarquées
Une histoire de TextField
La classe
Comme vous l'aurez sûrement compris, nous allons utiliser dans ce chapitre la classe TextField
. Pour se situer, reprenons le diagramme des classes des objets d'affichage :
Comme vous pouvez le voir, la classe TextField
est une sous-classe de InteractiveObject
, elle hérite donc de toutes les fonctionnalités qui permettent à l'utilisateur d'interagir avec les objets TextField
(clic, sélection de texte, frappe au clavier, etc.). Mais c'est aussi un objet d'affichage comme les autres, car la classe InteractiveObject
est fille de la classe DisplayObject
: nous pouvons donc bouger, redimensionner ou tourner nos champs de texte comme bon nous semble, voir les rendre semi-transparents !
Comme d'habitude, je vous conseille de lire la documentation sur la classe TextField
, disponible ici.
Utilisation de base
Créer un champ de texte
Comme toutes les classes des objets d'affichage, la classe TextField
dispose d'un constructeur sans paramètre. Nous allons donc l'utiliser pour créer des champs de texte comme suit :
1 | var monSuperTexte:TextField = new TextField(); |
Du texte brut
L'attribut text
contient le texte brut (c'est-à-dire non formaté) qui est affiché dans le champ de texte. Par défaut, le texte est vide, c'est-à-dire que l'attribut contient une chaîne de caractères vide : ""
.
Il s'utilise comme n'importe quel autre attribut :
1 2 3 4 5 6 7 8 9 | // Affectation d'un texte brut monSuperTexte.text = 'Hello World!'; // Avec une variable : var maSuperChaine:String = 'Je m\'apelle Zozor !'; monSuperTexte.text = maSuperChaine; // Lecture du contenu brut du champ de texte : trace('Zozor a dit : "' + monSuperTexte.text + '"'); // Affiche: Zozor a dit : "Je m'appelle Zozor !" |
À ne pas oublier !
Pour que notre champ de texte soit affiché, il ne faut surtout pas oublier de l'ajouter sur la liste d'affichage, c'est-à-dire qu'il faut l'ajouter parmi les enfants d'un conteneur ! Ainsi, dans notre classe Main
, écrivons ceci :
1 2 | // Ajoutons le champ de texte sur la scène principale : addChild(monSuperTexte); |
Rappel : la classe Main
est une sous-classe de la classe Sprite
, elle-même une sous-classe de la classe DisplayObjectContainer
! Nous pouvons donc y ajouter des objets d'affichage (nous serions bien embêtés sinon).
Le résultat
Par défaut, la couleur du texte est le noir et sans décoration (bordure ou fond), la police utilisée est une police par défaut de votre système (Times New Roman sur Windows/Linux et Times sur Mac), la taille est de 12 points et le texte n'est pas éditable. Mais ne vous inquiétez pas, tout ceci est entièrement paramétrable, comme certains ont pu le remarquer en lisant la documentation.
Pour que vous puissiez vérifier votre code, voici l'ensemble de la classe Main
permettant d'afficher du texte à l'écran :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package { import flash.display.Sprite; import flash.events.Event; import flash.text.TextField; /** * Cette application sait afficher du texte ! */ [SWF(width="800",height="600",backgroundColor="#ffffff")] public class Main extends Sprite { public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point // Mon premier champ de texte ! \o/ var monSuperTexte:TextField = new TextField(); monSuperTexte.text = 'Hello World!'; addChild(monSuperTexte); } } } |
Pour que vous puissiez voir quelque chose, vérifiez que la couleur de fond de votre animation est en blanc : [SWF(width="800",height="600",backgroundColor="#ffffff")]
. Du texte noir sur fond noir par exemple, ce n'est pas ce qu'il y a de plus lisible.
La figure suivante vous montre ce que cela donne à l'écran.
Bon, j'avoue que ce n'est pas très joli, mais nous allons améliorer cela dans peu de temps.
La taille par défaut d'un champ de texte est 100 pixels de largeur et 100 pixels de hauteur. Il est bien entendu possible de la modifier.
Pour le vérifier visuellement, nous pouvons afficher une bordure autour du champ de texte :
1 | monSuperTexte.border = true; |
Ce qui donne à l'écran la figure suivante.
Ce n'est pas ce qu'il y a de plus esthétique, alors enlevons la bordure en commentant la ligne que nous venons d'ajouter :
1 | // monSuperTexte.border = true;
|
Exerçons-nous maintenant à utiliser les propriétés des objets d'affichage, maintenant que nous en avons un vrai sous la main !
Commençons par déplacer notre champ de texte à la position (200, 100) :
1 2 | monSuperTexte.x = 200; monSuperTexte.y = 100; |
Vous devriez maintenant avoir quelque chose ressemblant à la figure suivante.
Je le trouve un peu trop petit, pas vous ? Allez, triplons sa taille :
1 2 3 | // Taille x3 ! monSuperTexte.scaleX = 3; monSuperTexte.scaleY = 3; |
Ce qui donne à l'écran la figure suivante.
Désormais, la taille de notre champ de texte est 300 pixels de largeur et 300 pixels de hauteur. Pour mieux le voir, nous pouvons remettre la bordure à notre champ de texte en décommentant cette ligne :
1 | monSuperTexte.border = true; |
Ce qui donne à l'écran la figure suivante.
Pour récapituler (voir figure suivante), nous avons :
- créé une instance de la classe
TextField
; - défini le texte du champ de texte ;
- ajouté le champ de texte à l'affichage ;
- modifié sa position ;
- modifié son échelle de taille.
Il est impossible de faire tourner du texte ou de changer son opacité dans l'état actuel, car nous utilisons le système pour rendre les caractères, ce qui implique ces limitations. Si vous changez tout de même la rotation ou l'opacité du champ de texte, les caractères ne seront plus affichés. Pour contourner ce problème, il faut utiliser des polices de caractères embarquées, afin que les caractères soient rendus directement par le lecteur Flash. Nous apprendrons comment faire à la fin de ce chapitre.
Sélection du texte
Curseur d'insertion
Tous les champs de texte disposent d'un curseur d'insertion, représenté par une barre verticale. Lorsque le champ de texte n'est pas éditable, on dit qu'il est statique. Dans ce cas, le curseur d'insertion est toujours invisible. Jusqu'ici, notre champ de texte est statique.
Définir une sélection
Il est possible de sélectionner une portion de texte directement à l'aide de la méthode setSelection()
de la classe TextField
, qui prend en paramètre la position du premier caractère à sélectionner et la position du caractère après le dernier caractère de la sélection. Par exemple, pour sélectionner les deux premières lettres, on écrira ceci :
1 | monSuperTexte.setSelection(0, 2); |
Nous mettons 2 en deuxième paramètre, car il faut passer la position du caractère après le dernier caractère à sélectionner, c'est-à-dire la position du dernier caractère à sélectionner (le numéro 1) plus une.
Si vous testez le programme maintenant, vous ne verrez pas le texte sélectionné : c'est normal, car par défaut les champs de texte qui n'ont pas le focus, c'est-à-dire qui ne sont pas actifs, n'affichent pas la sélection du texte. Pour rendre un champ de texte actif, la manière la plus simple est de cliquer dessus.
Il existe cependant un moyen d'afficher tout de même la sélection, même si le champ de texte n'a pas le focus : on met l'attribut alwaysShowSelection
à true
:
1 | monSuperTexte.alwaysShowSelection = true; |
Ce qui nous donne à l'écran la figure suivante.
Accéder à la sélection
Il est possible de savoir à quelles positions le texte sélectionné débute et se termine. Nous disposons pour cela des attributs selectionBeginIndex
, position du premier caractère sélectionné, et selectionEndIndex
, position du dernier caractère sélectionné :
1 | trace("Sélection : " + monSuperTexte.selectionBeginIndex + " -> " + monSuperTexte.selectionEndIndex); // Affiche 0 -> 2 |
Pour avoir le texte sélectionné, nous utiliserons la méthode substring
de l'attribut text:String
du champ de texte :
1 | trace("Texte sélectionné : " + monSuperTexte.text.substring(monSuperTexte.selectionBeginIndex, monSuperTexte.selectionEndIndex)); // Affiche : He |
La valeur renvoyée par selectionEndIndex
correspond à la position du caractère après le dernier caractère sélectionné (autrement dit, la position du dernier caractère sélectionné + 1). Mais cela tombe bien, car la méthode substring
prend les caractères jusqu'à la deuxième position passée en paramètre moins une. Nous obtenons donc le bon texte.
Empêcher la sélection du texte
Par défaut, le texte contenu par un champ de texte peut être sélectionné par l'utilisateur, puis éventuellement copié. Le curseur se change alors en curseur de texte.
Ce comportement peut être gênant, par exemple, si vous utilisez un champ de texte pour créer un bouton. Pour le désactiver, il suffit de mettre l'attribut selectable
de la classe TextField
à false
:
1 | monSuperTexte.selectable = false; |
Centrer le champ de texte
Comme nous l'avons placé jusqu'ici, le texte c'est pas exactement au centre de la fenêtre. Pour remédier à cela, il nous faut connaître la taille exacte de la scène !
Un mot sur la scène principale
La classe Stage
Comme nous l'avoir vu précédemment, une instance de la classe Stage
est automatiquement créée au lancement de notre programme : il s'agit de la scène principale. La scène est un objet d'affichage comme on peut le voir sur le schéma des classes d'affichage à la figure suivante.
La classe Stage
est donc une sous-classe de la classe DisplayObjectContainer
: elle hérite donc de toutes ses propriétés, et s'apparente à un conteneur comme nous en avons vu au chapitre précédent. Mais il y a tout de même quelques différences :
- on ne peut pas créer de scène principale nous-même, car la classe
Stage
est abstraite, - la plupart des propriétés de la classe
DisplayObjectContainer
ne fonctionnent pas, - la classe
Stage
dispose de nouvelles propriétés spécifiques.
Voici une liste des propriétés que nous avons déjà abordées et qui sont sans effet pour la classe Stage
:
- alpha
- rotation
- scaleX
- scaleY
- visible
- x
- y
Inutile donc d'essayer de modifier ces attributs, cela n'aura aucun impact sur la scène principale.
Par contre, il est toujours possible d'utiliser les attributs de l'instance de notre classe Main
, afin d'impacter l'ensemble de notre arbre d'affichage. Par exemple, si l'on veut rendre la scène invisible, nous pouvons mettre ce code dans notre classe Main
:
1 2 3 4 | // Dans la classe Main this.visible = false; // Toute la scène est invisible ! visible = false; // On peut omettre le mot-clé this |
Il est possible d'accéder à la scène principale grâce à l'attribut stage
disponible sur n'importe quel objet d'affichage dérivé de la classe DisplayObject
, à condition que cet objet soit présent dans l'arbre d'affichage.
1 2 3 4 5 | // On ne peut accéder à la scène depuis notre objet voiture seulement s'il est présent dans l'arbre d'affichage : var voiture:Sprite = new Sprite(); trace(voiture.stage); // Affiche null addChild(voiture); trace(voiture.stage); // Affiche [object Stage] |
Cela signifie que l'on peut accéder à la scène principale depuis notre classe Main comme ceci :
1 2 3 4 5 | // Dans la classe Main, dans la méthode init() trace(this.stage); // Affiche [object Stage] // Comme d'habitude, il est possible d'omettre le mot-clé this : trace(stage); // Affiche [object Stage] |
Le code par défaut proposé par FlashDevelop
Il est temps de vous expliquer pourquoi le code par défaut de notre classe Main contient plus de choses que pour les autres classes que nous avons faites, lorsque nous utilisons FlashDevelop. Comme nous l'avons vu précédemment, on ne peut accéder à la scène d'affichage que si notre objet est présent dans l'arbre d'affichage. Ainsi, le code par défaut de notre classe Main
permet de vérifier si notre objet de la classe est bien présent dans l'arbre avant d'appeler la méthode init()
. Si jamais ce n'était pas encore le cas (par exemple, si le lecteur Flash met un peut de temps à lancer le programme), nous aurions des problèmes pour utiliser les propriétés de la scène principale : en effet, l'attribut stage
serait à null
!
Reprenons le code par défaut de la classe Main
et commentons un peu pour mieux comprendre :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package { // Classes nécessaires import flash.display.Sprite; import flash.events.Event; /** * La classe de base sans modification. */ [SWF(width="640",height="480",backgroundColor="#ffffff")] public class Main extends Sprite { // Constructeur public function Main():void { if (stage) // Si l'attribut stage est défini (c'est-à-dire, si il est différent de null) init(); // Alors, on appelle la méthode init() tout de suite else // Sinon addEventListener(Event.ADDED_TO_STAGE, init); // On attend que notre instance de la classe Main soit ajoutée à l'arbre de l'affichage } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // On arrête d'attendre // Nous pouvons commencer à coder ici en tout sérénité :) } } } |
Le code qui permet d'attendre que l'objet soit ajouté à l'arbre d'affichage utilise la notion d'événement, notion que nous aborderons dans la partie suivante.
La taille de la scène
Revenons à nos moutons et intéressons-nous à la taille de la fenêtre de notre programme. On peut y accéder grâce à deux attributs de la classe Stage
(voir figure suivante) :
stageWidth
pour connaître la largeur de la scène,stageHeight
pour la hauteur.
Par exemple, nous pouvons écrire ceci dans notre classe Main pour afficher la taille de la scène principale :
1 | trace("La scène principale a pour dimensions " + stage.stageWidth + "x" + stage.stageHeight); |
La console affichera alors :
1 | La scène principale a pour dimensions 640x480
|
Cela correspond à la configuration de notre programme qui se trouve à cette ligne :
1 | [SWF(width="640",height="480",backgroundColor="#ffffff")] |
Il ne faut pas confondre les attributs stageWidth
et stageHeight
qui donnent les dimensions de la scène principale, avec les attributs width
et height
qui donnent la taille du contenu de la scène !
En effet, nous n'obtenons pas le même résultat dans les deux cas. Pour le vérifiez, ajoutons ce code :
1 | trace("Le contenu de la scène principale a pour taille " + stage.width + "x" + stage.height); |
Ensuite, la console affiche ceci :
1 2 | La scène principale a pour dimensions 640x480 Le contenu de la scène principale a pour taille 300x300 |
Comme le montre la figure suivante, la taille du contenu de la scène est souvent différente des dimensions de la scène :
Adapter la taille du champ de texte au texte
Pour centrer le champ de texte, il serait intéressant que celui-ci fasse la même taille que celle du texte à l'intérieur. Pour l'instant, notre champ de texte fait 300 pixels de largeur et 300 pixels de hauteur, ce qui est beaucoup trop. Nous pouvons dire au champ de texte d'adapter sa taille grâce à son attribut autoSize
:
1 | monSuperTexte.autoSize = TextFieldAutoSize.LEFT; |
Sans oublier d'importer la classe TextFieldAutoSize (qui contient les valeurs autorisées pour l'attribut autoSize
) :
1 | import flash.text.TextFieldAutoSize; |
Petite astuce si vous programmez avec FlashDevelop
: tapez new Text
et l'auto-complétion vous proposera la classe. Sélectionnez-la et elle sera automatiquement importée. Ensuite, n'oubliez pas de supprimer le mot-clé new
dont nous n'avons pas besoin.
Désormais, nous avons à l'écran la figure suivante.
Nous pouvons afficher la taille du champ de texte pour être sûr de nous :
1 | trace("Taille : " + monSuperTexte.width + "x" + monSuperTexte.height); // Affiche 199.95x52.95 |
Modifier la position du champ de texte
Il est temps de centrer notre notre champ de texte ! Nous allons procéder en trois étapes pour bien détailler l'opération.
Etape 1
Commençons par placer l'origine de notre champ de texte au centre de l'écran. Pour cela, il suffit d'utiliser les attributs stageWidth
et stageHeight
que nous venons de voir :
1 2 | monSuperTexte.x = stage.stageWidth / 2; monSuperTexte.y = stage.stageHeight / 2; |
Ce qui nous donne à l'écran la figure suivante.
Notre champ de texte n'est pas encore entièrement centré, mais nous y sommes presque !
Etape 2
Nous allons maintenant retrancher la moitié de la largeur de notre champ de texte à sa position x
pour centrer notre champ de texte horizontalement :
1 | monSuperTexte.x -= monSuperTexte.width / 2; |
Ce qui nous donne à l'écran la figure suivante.
Etape 3
Et pour finir, nous répétons la même chose, mais verticalement : nous retranchons la moitié de la hauteur de notre champ de texte à sa position y
:
1 | monSuperTexte.y -= monSuperTexte.height / 2; |
Ce qui nous donne la figure suivante.
En résumé
L'opération s'est donc déroulée en trois étapes :
- on centre l'origine de l'objet en utilisant
stage.stageWidth
etstage.stageHeight
, - on retranche la moitié de sa largeur à sa position horizontale
x
, - on retranche la moitié de sa hauteur à sa position verticale
y
.
Et voici le code complet concernant notre champ de texte :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // Créons notre champ de texte var monSuperTexte:TextField = new TextField(); monSuperTexte.text = 'Hello World!'; addChild(monSuperTexte); //Multiplions sa taille par quatre monSuperTexte.scaleX = 4; monSuperTexte.scaleY = 4; // Activons la bordure monSuperTexte.border = true; // Adaptons la taille du champ de texte au texte monSuperTexte.autoSize = TextFieldAutoSize.LEFT; // Centrons l'origine monSuperTexte.x = stage.stageWidth / 2; monSuperTexte.y = stage.stageHeight / 2; // Retranchons la moitié de sa taille à sa position monSuperTexte.x -= monSuperTexte.width / 2; monSuperTexte.y -= monSuperTexte.height / 2; |
Nous pouvons compacter la dernière partie de notre code, qui permet de centrer le champ de texte :
1 2 3 | // Centrons le champ de texte monSuperTexte.x = stage.stageWidth / 2 - monSuperTexte.width / 2; monSuperTexte.y = stage.stageHeight / 2 - monSuperTexte.height / 2; |
Nous pouvons encore simplifier en factorisant :
1 2 3 | // Centrons le champ de texte monSuperTexte.x = (stage.stageWidth - monSuperTexte.width) / 2; monSuperTexte.y = (stage.stageHeight - monSuperTexte.height) / 2; |
Cette méthode pour aligner au centre de la scène fonctionne bien évidement avec tous les objets d'affichage, pas seulement les champs de texte.
Pour l'instant, il nous est impossible de faire tourner notre champ de texte, car il utilise une police de votre système pour le rendu. Pour contourner ce problème, il nous faut embarquer notre propre police de caractère, comme nous le verrons dans un prochain chapitre.
La mise en forme
Formatons notre champ de texte
Mise en forme par défaut
Formater du texte est possible grâce à la classe TextFormat
(dont la documentation est disponible ici). Tout objet de classe TextField
dispose d'un attribut defaultTextFormat
de type TextFormat
. Cet attribut permet de modifier la mise en forme par défaut du texte contenu dans le champ de texte, cela signifie qu'un texte qui n'a pas de mise en forme spécifique recevra automatiquement cette mise en forme par défaut.
La mise en forme par défaut doit être appliquée avant de définir le texte.
Pour modifier la mise en forme par défaut de notre champ de texte, nous procéderons ainsi :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // Création de l'instance du champ de texte var monSuperTexte:TextField = new TextField(); // Création de l'instance de la classe TextFormat var format:TextFormat = new TextFormat(); // Modifications du format ici // Application du format au champ de texte monSuperTexte.defaultTextFormat = format; // Texte à afficher - après la mise en forme par défaut monSuperTexte.text = "Hello World!"; // Ajout du champ de texte à l'affichage addChild(monSuperTexte); |
La mise en forme par défaut n'est mise à jour que si nous affectons un objet de classe TextFormat
à l'attribut defaultTextFormat
. Si nous modifions directement les attributs de defaultTextFormat
, il ne se passera rien. Ne pas boulier qu'il faut que le texte soit défini après avoir mis à jour la mise en forme par défaut.
L'heure du changement est arrivée
Nous allons dans un premier temps modifier la taille, la police de caractère et la couleur de notre texte. En se renseignant dans la documentation, nous pouvons noter les différents attributs correspondants :
size:Object
(entier) pour la taille du texte en pixels,font:String
(chaîne de caractère) pour le nom de la police de caractère à utiliser,color:Object
(entier positif) pour la couleur du texte.
Avant de commencer, rendons sa taille normale à notre champ de texte en supprimant (ou commentant) les lignes qui modifient son échelle :
1 2 | // monSuperTexte.scaleX = 3; // monSuperTexte.scaleY = 3; |
Exerçons-nous à modifier la mise en forme de notre champ de texte : notre texte doit être de taille 42
, utilisant la police de caractère Arial
et colorié en bleu (dont le code hexadécimal est 0x0000ff
).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // Création de l'instance du champ de texte var monSuperTexte:TextField = new TextField(); // Création de l'instance de la classe TextFormat var format:TextFormat = new TextFormat(); // Mise en forme format.size = 42; format.font = "Arial"; format.color = 0x0000ff; // Application du format au champ de texte monSuperTexte.defaultTextFormat = format; // Texte monSuperTexte.text = "Hello World!"; // Bordure monSuperTexte.border = true; // Taille adaptative monSuperTexte.autoSize = TextFieldAutoSize.LEFT; // Centrons le champ de texte monSuperTexte.x = (stage.stageWidth - monSuperTexte.width) / 2; monSuperTexte.y = (stage.stageHeight - monSuperTexte.height) / 2; // Ajout du champ de texte à l'affichage addChild(monSuperTexte); |
Ce qui nous donne la figure suivante.
Vous remarquerez qu'il est possible de positionner l'objet d'affichage avant qu'il ne soit ajouté à l'arbre d'affichage.
Si vous vous trompez en écrivant le nom de la police, ou que celle-ci n'est pas installée sur le système de l'utilisateur, la police par défaut sera utilisée à la place.
Pourquoi certains de ces attributs ont pour type Object
au lieu de int
ou uint
?
C'est très simple : les attributs de la classe TextFormat
ont pour valeur par défaut null
, pour signifier qu'il faut utiliser les valeurs par défaut de mise en forme (que l'on peut trouver dans la documentation, en haut de la page). Or, les attributs de type int
ou uint
ne peuvent pas valoir null
, donc on est obligé d'utiliser le type Object
(type indéfini, dont les variables peuvent valoir null
). On aurait aussi pu utiliser le type *
, équivalent au type Object
.
Le constructeur de la classe TextFormat
permet de définir directement certains attributs. Ainsi, nous pourrions simplifier notre code en utilisant le constructeur de la classe TextFormat
ainsi que nous l'indique la documentation :
1 2 | TextFormat(font:String = null, size:Object = null, color:Object = null, bold:Object = null, italic:Object = null, underline:Object = null, url:String = null, target:String = null, align:String = null, leftMargin:Object = null, rightMargin:Object = null, indent:Object = null, leading:Object = null) |
Nous pouvons donc écrire :
1 2 3 4 5 | // Création de l'instance de la classe TextFormat var format:TextFormat = new TextFormat("Arial", 42, 0x0000ff); // Application du format au champ de texte monSuperTexte.defaultTextFormat = format; |
Nous pouvons également mettre le texte en gras, italique, ou souligné, grâce à ces attributs de la classe TextFormat
:
bold:Object
(booléen) pour mettre le texte en gras,italic:Object
(booléen) pour le mettre en italique,underline:Object
(booléen) pour le souligner.
Notre code pour la mise en forme ressemble maintenant à ceci :
1 2 3 4 5 6 7 | // Mise en forme format.size = 42; format.font = "Arial"; format.color = 0x0000ff; format.bold = true; format.italic = true; format.underline = true; |
Nous pouvons également utiliser le constructeur :
1 2 3 4 5 | // Création de l'instance de la classe TextFormat var format:TextFormat = new TextFormat("Arial", 42, 0x0000ff, true, true, true); // Application du format au champ de texte monSuperTexte.defaultTextFormat = format; |
Ce qui nous donne la figure suivante.
Nous avons seulement vu les principaux attributs, mais rien ne vous empêche de jeter un coup d’œil à la documentation pour voir tout ce qu'il est possible de faire.
Modifier la mise en forme par défaut
Une fois la mise en forme par défaut définie, le texte que nous ajoutons à notre champ de texte prend par défaut cette mise en forme. Mais ensuite, vous aurez sûrement envie de modifier cette mise en forme par défaut. Avec un peu d'astuce, c'est possible ! Il suffit d'affecter de nouveau notre objet de classe TextFormat
à l'attribut defaultTextFormat
de notre champ de texte, puis réaffecter son texte :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | // Création de l'instance du champ de texte var monSuperTexte:TextField = new TextField(); // Création de l'instance de la classe TextFormat var format:TextFormat = new TextFormat(); // Mise en forme format.size = 42; format.font = "Arial"; format.color = 0x0000ff; format.bold = true; format.italic = true; format.underline = true; // Application du format au champ de texte monSuperTexte.defaultTextFormat = format; // Texte monSuperTexte.text = "Hello World!"; // Bordure monSuperTexte.border = true; // Taille adaptative monSuperTexte.autoSize = TextFieldAutoSize.LEFT; // Centrons le champ de texte monSuperTexte.x = (stage.stageWidth - monSuperTexte.width) / 2; monSuperTexte.y = (stage.stageHeight - monSuperTexte.height) / 2; // Ajout du champ de texte à l'affichage addChild(monSuperTexte); // ... // Changeons en cours de route pour du rouge format.color = 0xff0000; // Mise à jour du format par défaut monSuperTexte.defaultTextFormat = format; // Il faut redéfinir le texte pour appliquer la nouvelle mise en forme par défaut monSuperTexte.text = monSuperTexte.text; |
Ce qui affiche la figure suivante.
Mise en forme spécifique
Il est possible d'écraser la mise en forme par défaut pour tout ou une partie du texte, grâce à la méthode setTextFormat()
de la classe TextField
, qui prend en paramètre un objet de la classe TextFormat
, la position du premier caractère et la position du caractère après le dernier caractère du texte dont on souhaite modifier la mise en forme. Ces deux positions commencent par zéro, comme pour les tableaux.
Rappel : si vous ne souhaitez pas changer des attributs dans la mise en forme spécifique, il faut que ces attributs valent null
. Ainsi ils n'aurons pas d'effet sur le texte.
Ainsi, il est préférable de créer une nouvelle instance de la classe TextFormat
, pour être sûr que tous les attributs sont à null
.
Changeons la taille de la première lettre pour 72
. La première lettre est à la position 0
, et la lettre après elle est à la position 1
:
1 2 3 4 5 6 7 | // Nouvelle instance de la classe TextFormat (on peut réutiliser le même pointeur "format") format = new TextFormat(); format.size = 72; // Application du nouveau format à la première lettre monSuperTexte.setTextFormat(format, 0, 1); |
Ce qui nous donne la figure suivante.
Comme vous pouver le remarquer, notre lettre est coupée en haut à droite ; c'est un effet de bord de l'italique. Nous pouvons remédier à cela grâce à l'attribut letterSpacing
qui spécifie la largeur de l'espace entre les lettres. Mettons-la à 3 pixels :
1 2 3 4 5 6 7 8 | // Nouvelle instance de la classe TextFormat (on peut réutiliser le même pointeur "format") format = new TextFormat(); format.size = 72; format.letterSpacing = 3; // Application du nouveau format à la première lettre monSuperTexte.setTextFormat(format, 0, 1); |
Ainsi, il y aura 3 pixel d'espace entre la première lettre et la deuxième (voir figure suivante).
Essayons de colorier le mot "World" en bleu et de lui enlever l'italique !
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // Je stocke le mot que je veux colorier var motBleu:String = "World"; // Je cherche les positions adéquates pour la méthode setTextFormat // Position de début, grâce à la méthode indexOf de la classe String var positionDebut:int = monSuperTexte.text.indexOf(motBleu); // Position de fin, en ajoutant la longueur du mot var positionFin:int = positionDebut + motBleu.length; // Je créé le format format = new TextFormat(); format.color = 0x0000ff; format.italic = false; // J'applique le format aux positions que nous avons calculées monSuperTexte.setTextFormat(format, positionDebut, positionFin); |
Ce qui nous donne la figure suivante.
Gestion du multi-ligne
Champ de texte à taille fixe
Nous allons maintenant découvrir comment gérer un champ de texte multi-ligne. Tout d'abord, il nous faut un texte plus long que "Hello World!". Voici un Lorem Ipsum (texte latin de remplissage) pour tester :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var monSuperTexte:TextField = new TextField(); var format:TextFormat = new TextFormat("Arial", 14, 0x000000); monSuperTexte.defaultTextFormat = format; // Texte suffisamment long monSuperTexte.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In pharetra magna imperdiet elit pretium a malesuada nisl pellentesque."; monSuperTexte.border = true; addChild(monSuperTexte); // Centre monSuperTexte.x = (stage.stageWidth - monSuperTexte.width) / 2; monSuperTexte.y = (stage.stageHeight - monSuperTexte.height) / 2; |
Pour l'instant, cela donne la figure suivante.
Nous aimerions bien que le texte revienne automatiquement à la ligne. Pour cela, il faut mettre l'attribut multiline
de la classe TextField
à true
pour activer les lignes multiples, et l'attribut wordWrap
à true
également, pour activer le retour à la ligne automatique :
1 2 | monSuperTexte.multiline = true; monSuperTexte.wordWrap = true; |
Ce qui donne à l'écran la figure suivante.
Le texte dépasse désormais en bas du champ de texte. Toutefois, par défaut, on peut défiler dans le champ de texte avec la molette de la souris. Si vous voulez désactiver ce comportement, il faut mettre l'attribut mouseWheelEnabled
de la classe TextField
à false
:
1 | monSuperTexte.mouseWheelEnabled = false; |
Le champ de texte est peut-être un peu trop étroit, augmentons sa largeur (avant le code qui le centre) :
1 2 3 4 5 6 | // Modifions la largeur du champ de texte monSuperTexte.width = 300; // Centre monSuperTexte.x = (stage.stageWidth - monSuperTexte.width) / 2; monSuperTexte.y = (stage.stageHeight - monSuperTexte.height) / 2; |
Ce qui nous donne la figure suivante.
Aligner le texte
Il est possible de changer l'alignement du texte grâce à l'attribut align
de la classe TextFormat
. Cet attribut accepte les valeurs constantes définies dans la classe TextFormatAlign
.
Par exemple, pour que notre texte soit aligné au centre :
1 2 3 | var format:TextFormat = new TextFormat("Arial", 14, 0x000000); format.align = TextFormatAlign.CENTER; // Texte aligné au centre monSuperTexte.defaultTextFormat = format; |
Sans oublier de bien importer la classe TextFormatAlign
au début du package :
1 | import flash.text.TextFormatAlign; |
Cela nous donne la figure suivante.
Nous pouvons également centrer le texte à droite ou le justifier (voir figure suivante) :
1 2 3 4 5 | // Texte aligné à droite format.align = TextFormatAlign.RIGHT; // Texte justifié format.align = TextFormatAlign.JUSTIFY; |
Un texte justifié est un texte dont les mots sont espacés de telle sorte que les lignes de chaque paragraphes remplissent toutes la largeur disponibles, sauf les dernières lignes. Par exemple, cet "alignement" est souvent utilisé dans les journaux.
Champ de texte à hauteur dynamique
Il est possible d'adapter la hauteur du champ de texte à son texte s'il est multi-ligne, de la même manière que nous avions adapté la taille de notre champ de texte contenant le texte
"Hello World!"
au chapitre précédent : avec l'attribut autoSize
de la classe TextField
:
1 | monSuperTexte.autoSize = TextFieldAutoSize.LEFT; |
Ce qui nous donne la figure suivante.
Contrairement à ce que nous avons vu au chapitre précédent, seule la hauteur est adaptée au texte; la largeur est fixe et c'est vous qui la définissez. Ceci est uniquement valable si le champ de texte est multi-ligne, quand l'attribut multiline
du champ de texte est à true
.
Retour à la ligne
Il est possible d'effectuer des retours à la ligne en écrivant \n
dans le texte :
1 | monSuperTexte.text = "Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit.\nIn pharetra magna imperdiet elit pretium a malesuada nisl pellentesque."; |
Ce qui nous donne la figure suivante.
En HTML dans le texte
Introduction
Le langage HTML
Ce langage est utilisé sur les sites web pour structurer le texte, ajouter des paragraphes, des images, des liens hyper-texte… Le langage est un dérivé du langage XML, ce qui signifie que sa syntaxe est basée sur des balises.
Une balise dispose d'un nom, mis entre chevrons, et elle est répétée deux fois :
1 | <nom></nom>
|
La première balise <nom>
est la balise ouvrante, et la dernière balise </nom>
est la balise fermante.
Il ne faut pas oublier le slash /
pour signifier qu'il s'agit d'une balise fermante.
Il est possible d'imbriquer des balises dans d'autres :
1 2 3 4 5 6 | <balise1> <balise2></balise2> <balise3> <balise4></balise4> </balise3> </balise1> |
Ici, la balise 4 est contenue dans la balise 3. Les balises 2 et 3 sont contenues dans la balise 1.
Attention à bien faire correspondre les noms des balises ouvrantes et fermantes !
Chaque balise ouvrante peut disposer d'attributs, ayant chacun un nom et une valeur entre guillemets doubles :
1 | <nom attribut1="valeur" attribut2="valeur"></nom> |
Si une balise ne contient rien, on peut utiliser sa forme raccourcie :
1 | <balise/>
|
Reprenons l'exemple des balises imbriquées pour voir ce que cela donnerait :
1 2 3 4 5 6 | <balise1> <balise2/> <balise3> <balise4/> </balise3> </balise1> |
Enfin, il est possible de mettre du texte brut à l'intérieur d'une balise :
1 | <balise>Quel temps fera-t-il demain ?</balise> |
On peut également mélanger des balises et du texte brut :
1 | <balise1>Salut !<balise2>Comment va la famille ?</balise2></balise1> |
L'HTML est donc du XML avec des balises spéciales que nous allons découvrir un peu plus loin.
Seule une toute petite partie de ces balises est supportée par la classe TextField
! Nous ne verrons que celles-ci, mais sachez qu'il en existe beaucoup d'autre. D'autre part, il peut y avoir quelques différences au niveau des attributs par rapport au "vrai" HTML.
Du HTML dans nos champs de texte
Il est possible d'utiliser une version très simplifiée de l'HTML dans nos champs de texte en utilisant l'attribut htmlText
de la classe TextField
à la place de l'attribut text
que nous avons utilisé jusque là :
1 2 3 4 5 | // Activation du multi-ligne avant de sépicifier le texte HTML monSuperTexte.multiline = true; // Texte HTML monSuperTexte.htmlText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In pharetra magna imperdiet elit pretium a malesuada nisl pellentesque.'; |
Il faut mettre l'attribut multiline
à true
avant de spécifier le texte HTML, sinon les retours à la ligne seront ignorés, même si vous mettez multiline
à true
ensuite.
Balises principales
Retour à la ligne
Pour effectuer un retour à la ligne dans un texte HTML, nous utiliseront la balise <br/>
comme ceci :
1 | monSuperTexte.htmlText = 'Lorem ipsum dolor sit amet,<br/>consectetur adipiscing elit.<br/>In pharetra magna imperdiet elit pretium a malesuada nisl pellentesque.'; |
Ce qui nous donne la figure suivante.
Paragraphe
Un paragraphe est un bloc de texte pouvant être aligné, qui se termine par un retour à la ligne. La balise à utiliser est la balise <p align="alignement">...</p>
.
L'attribut align
peut prendre les valeurs suivantes :
left
pour aligner le texte à gauche,right
pour l'aligner à droite,center
pour le centrer,justify
pour le justifier.
Voici un exemple où notre texte est aligné à droite :
1 | monSuperTexte.htmlText = '<p align="right">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In pharetra magna imperdiet elit pretium a malesuada nisl pellentesque.</p>'; |
Ce qui nous donne la figure suivante.
Voici un autre exemple avec plusieurs paragraphes :
1 2 | monSuperTexte.htmlText = '<p align="right">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In pharetra magna imperdiet elit pretium a malesuada nisl pellentesque.</p>' + '<p align="left">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In pharetra magna imperdiet elit pretium a malesuada nisl pellentesque.</p>'; |
Vous remarquerez que j'ai utilisé la concaténation de chaînes de caractères avec l'opérateur +
pour pouvoir écrire le texte en plusieurs lignes.
Nous avons alors à l'écran la figure suivante.
Lien
Un lien est une balise cliquable qui permet d'effectuer une action, le plus souvent permettant de changer de site web ou d'aller sur une autre page. Nous pouvons créer un lien à l'aide de la balise <a href="adresse" target="cible">nom du lien</a>
.
L'attribut href
contient l'adresse vers laquelle pointe le lien (par exemple, http://zestedesavoir.com/
, l'adresse de Zeste de Savoir).
L'attribut target
permet de spécifier la cible du lien, c'est à dire où l'adresse va s'ouvrir si l'on clique dessus. Il peut prendre les valeurs suivantes :
_self
: ouvre le lien dans la même page,_blank
: ouvre le lien dans une nouvelle fenêtre, ou un nouvel onglet si le navigateur le permet.
Bien sûr, ces valeurs n'ont d'intérêt que si votre animation Flash est incorporée dans un site web. Dans les autres cas (par exemple lorsque l'on teste le programme), cela ouvrira une nouvelle fenêtre (ou un nouvel onglet) dans votre navigateur, même si la valeur de l'attribut target
est _self
.
Voici un exemple de texte HTML disposant d'un lien pointant sur le Site du Zéro :
1 | monSuperTexte.htmlText = 'Voulez-vous apprendre à partir de zéro ? <a href="http://zestedesavoir.com/" target="_blank">Cliquez ici !</a>'; |
Ce qui nous donne la figure suivante.
Pour tester l'attribut target
, vous pouvez ouvrir votre fichier swf
dans votre navigateur favori (à condition qu'il dispose du lecteur Flash). Vous verrez alors la page d'accueil de Zeste de Savoir se charger dans la même page ou s'ouvrir dans une nouvelle fenêtre ou un nouvel onglet
Image
Il est possible de charger une image locale dans un champ de texte grâce à la balise <img src="adresse" width="largeur" height="hauteur" align="alignement" hspace="espacement horizontal" vspace="espacement vertical"/>
.
Essayons d'afficher Zozor dans notre champ de texte. Tout d'abord, téléchargez cette image et placez-là dans le dossier de votre fichier swf
:
Ensuite, renommez l'image en zozor.png
.
Enfin, écrivons ce code pour charger l'image dans notre texte HTML :
1 | monSuperTexte.htmlText = 'Voici Zozor !<br/><img src="zozor.png" width="150" height="150" align="right"/>'; |
Ce qui nous donne la figure suivante.
Il est impossible d'aligner une image au centre. Il s'agit d'une limitation du champ de texte, on ne peut rien y faire.
Si on met un texte plus long à côté de l'image, il sera détouré. Pour illustrer ceci, prenons un texte beaucoup plus long à côté de Zozor, et alignons-le en justifié. :
1 2 3 4 5 6 7 8 9 | monSuperTexte.htmlText = '<img src="zozor.png" width="150" height="150" align="right"/>' + '<p align="justify">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed pharetra semper ullamcorper.' + 'Sed at urna in elit mollis egestas eu id lectus. Integer aliquam urna vitae massa varius sed cursus mauris aliquam.' + 'Curabitur mauris massa, imperdiet a venenatis ac, vehicula eu ipsum. Nulla turpis enim, tincidunt at imperdiet nec,' + 'mollis vitae nunc. Morbi viverra iaculis neque et tincidunt. Nullam ultrices mi mi, eu pellentesque leo.</p>' + '<p align="justify">Pellentesque sed felis nulla. Phasellus laoreet sagittis ante at fringilla.' + 'Duis iaculis, mi sed bibendum posuere, nisi velit cursus elit, vitae tincidunt augue diam quis elit.' + 'Sed et nisi risus. Vestibulum lobortis auctor viverra. Mauris eleifend nisl ut orci ultricies eget egestas' + 'ante lacinia. Pellentesque ut diam turpis.</p>'; |
Ce qui nous donne la figure suivante.
Liste à puce
Il est possible de faire des listes à puce grâce à la balise <li>...</li>
répétée autant de fois qu'il y a de ligne dans la liste :
1 | monSuperTexte.htmlText = 'Voici une lite à puce :<li>Ligne 1</li><li>Ligne 2</li><li>Ligne 3</li>'; |
Ce qui nous donne la figure suivante.
Balises de mise en forme
Gras
Pour mettre du texte en gras, rien de plus simple ! Il suffit de l'encadrer d'une balise <b>...</b>
(b comme bold, signifiant gras en anglais) comme ceci :
1 | monSuperTexte.htmlText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. <b>In pharetra magna imperdiet elit pretium a malesuada nisl pellentesque.</b>'; |
Ce qui nous donne la figure suivante.
Italique
Pour mettre le texte en italique, c'est tout aussi simple : seule la balise change. Cette fois, il s'agit de <i>...</i>
:
1 | monSuperTexte.htmlText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. <i>In pharetra magna imperdiet elit pretium a malesuada nisl pellentesque.</i>'; |
Ce qui nous donne la figure suivante.
Souligné
Il est possible de souligner du texte grâce à la balise <u>...</u>
comme ceci :
1 | monSuperTexte.htmlText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. <u>In pharetra magna imperdiet elit pretium a malesuada nisl pellentesque.</u>'; |
Ce qui nous donne la figure suivante.
Police, couleur et taille
Pour modifier la police de caractère, la couleur ou la taille des caractères du texte, la balise <font face="police" color="couleur" size="taille">...</font>
est tout indiquée.
L'attribut face
peut recevoir comme valeur le nom d'une police de caractère, comme par exemple face="Arial"
.
L'attribut color
permet de définir une couleur en hexadécimal, précédée d'un dièse. Exemple de couleur orange : color="#ff8800"
.
Enfin, l'attribut size
modifie la taille des caractères du texte. On peut définir une taille absolue en pixels, ou une taille relative en ajoutant un +
ou un -
devant. Exemple de taille absolue : size="42"
. Exemple de taille relative : size="-5"
, ce qui signifie la taille actuelle du texte moins cinq pixels.
Par exemple, nous pouvons colorier une partie de notre texte en bleu :
1 | monSuperTexte.htmlText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. <font color="#0000ff">In pharetra magna imperdiet elit pretium a malesuada nisl pellentesque.</font>'; |
Ce qui nous donne la figure suivante.
Nous aurions pu, au lieu de cela, augmenter la taille de notre texte :
1 | monSuperTexte.htmlText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br/><font size="42">In pharetra magna imperdiet elit pretium a malesuada nisl pellentesque.</font>'; |
Ce qui aurait donné la figure suivante.
Les polices de caractères embarquées
Embarquer des polices
Pourquoi ?
Jusqu'à présent, les polices que nous utilisons sont des polices fournies par le système d'exploitation sur lequel notre programme est lancé. Si nous vouons appliquer une police particulière à notre texte, mais qu'elle n'ai pas présente sur le système, la police par défaut sera utilisée. De plus, il nous est impossible de faire tourner notre texte ou de changer son opacité, ce qui est un peu dommage !
Cependant, il existe une solution à ces problèmes : les polices de caractères embarquées ! Il s'agit d'inclure un fichier contenant une police directement dans notre programme : ainsi, le lecteur Flash peut la rendre directement à l'écran, même si le système de dispose pas de cette police en particulier ! De plus, cela permet de lisser les caractères du texte afin de les rendre plus lisibles et plus attractifs.
Bien évidemment, embarquer des fichiers directement dans le programme augmente sa taille. Cela peut éventuellement être gênant, mais embarquer les polices de caractère présente tant d'avantages que l'on passera souvent outre cet unique inconvénient.
Préparation
Tout d'abord, il faut se munir du fichier de la police de caractère à embarquer dans notre programme. Seules les polices de format TrueType sont reconnues, mais c'est le format le plus répandu, donc cela pose rarement problème.
Par exemple, vous pouvez prendre une police installée sur votre système.
Sur Windows, les polices sont situées dans le dossier C:\Windows\Fonts
.
Sur Mac, il peut y en avoir à plusieurs endroits : ~/Library/Fonts/
, /Library/Fonts/
, /Network/Library/Fonts/
, /System/Library/Fonts/
ou /System Folder/Fonts/
.
Enfin, sur Linux, on peut les trouver dans ces dossiers : /usr/share/fonts
, /usr/local/share/fonts
ou ~/.fonts
.
Ou bien vous pouvez vous rendre sur un site proposant gratuitement des polices de caractères, comme FontSquirrel. Prenons par exemple la police Walkway (voir figure suivante). Téléchargez-la sur le site en cliquant sur le bouton DOWNLOAD TTF.
Vous obtenez une archive zip, contenant différents fichiers de police (voir figure suivante).
Nous aurons besoins de quatre de ces fichiers, un par style de notre police, comme le montre le tableau suivant.
Style |
Nom du fichier |
---|---|
Normal |
Walkway_SemiBold.ttf |
Gras |
Walkway_UltraBold.ttf |
Italique |
Walkway_Oblique_SemiBold.ttf |
Gras Italique |
Walkway_Oblique_UltraBold.ttf |
Vous pouvez incorporer une police de caractères dont il manque certains styles, mais vous ne pourrez pas utiliser les styles manquant. Par exemple, si vous n'avez pas le fichier pour l'italique, vous ne pourrez pas mettre de texte en italique avec cette police.
Dans le répertoire du projet, créez un dossier lib
s'il n'est pas déjà présent, puis créez un dossier à l'intérieur nommé fonts
. Enfin, extrayez les quatre fichiers dont nous avons besoin dans ce dossier (voir figure suivante).
Implémentation
Une fois que nos fichiers sont prêts, il faut les incorporer à notre programme, puis les enregistrer sous le nom "walkway"
pour pouvoir utiliser la police de caractère embarquée partout dans notre projet.
Créez une nouvelle classe EmbedFonts
(dans un fichier nommé EmbedFonts.as
) à côté de la classe Main
et collez-y le code complet suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | package { import flash.text.Font; /** * Gestionnaire des polices de caractères embarquées. * Pour ajouter une police, placer ces fichiers dans le dossier lib/fonts (par exemple : lib/fonts/verdana.ttf), incluez-la dans la classe EmbedFonts ainsi : * [Embed(source='../lib/fonts/verdana.ttf',fontName='Fverdana',fontWeight="normal",embedAsCFF=false)] * private static var F_VERDANA:Class; * puis enregistrez-la dans la méthode init() ainsi : * Font.registerFont(F_VERDANA); * @author Guillaume CHAU */ public class EmbedFonts { // Incorporation des polices de caractères ///// Walkway // Normal [Embed(source='../lib/fonts/Walkway_SemiBold.ttf',fontName='walkway',fontWeight="normal",embedAsCFF=false)] private static var F_WALKWAY:Class; // Gras [Embed(source='../lib/fonts/Walkway_UltraBold.ttf',fontName='walkway',fontWeight='bold',embedAsCFF=false)] private static var F_WALKWAY_BOLD:Class; // Italique [Embed(source='../lib/fonts/Walkway_Oblique_SemiBold.ttf',fontName='walkway',fontStyle='italic',embedAsCFF=false)] private static var F_WALKWAY_ITALIC:Class; // Gras Italique [Embed(source='../lib/fonts/Walkway_Oblique_UltraBold.ttf',fontName='walkway',fontStyle='italic',fontWeight='bold',embedAsCFF=false)] private static var F_WALKWAY_BOLD_ITALIC:Class; /** * Initialisation des polices de caractères. A appeler une fois au lancement de l'application, afin que les polices soient prises en compte. */ public static function init():void { // Enregistrement des polices de caractères Font.registerFont(F_WALKWAY); Font.registerFont(F_WALKWAY_BOLD); Font.registerFont(F_WALKWAY_BOLD_ITALIC); Font.registerFont(F_WALKWAY_ITALIC); } } } |
Nous commençons par importer chaque fichier au début de la classe grâce une instruction spéciale, destinée au compilateur :
1 | [Embed(source='../lib/fonts/Walkway_SemiBold.ttf',fontName='walkway',fontWeight="normal",embedAsCFF=false)] |
J'ai l'impression d'avoir déjà vu quelque chose de similaire…
Très juste ! Nous avons déjà écrit une instruction spéciale dans notre classe Main
pour régler la taille et la couleur de fond de notre fenêtre :
1 | [SWF(width="640",height="480",backgroundColor="#ffffff")] |
Ici, le mot-clé SWF
signifie que nous allons modifier des propriétés de notre programme.
Cette-fois, le mot-clé Embed
signifie que nous allons inclure un fichier dans notre programme. Les fichiers inclus sont directement contenus dans le programme : il sont donc utilisables à tout moment, étant chargés en même temps.
1 | source='../lib/fonts/Walkway_SemiBold.ttf' |
L'attribut source
indique le chemin du fichier à inclure, ici ../lib/fonts/Walkway_SemiBold.ttf
.
1 | fontName='walkway' |
L'attribut fontName
spécifie le nom de la police de caractère, nom qui nous servira à l'utiliser ensuite.
1 | fontWeight="normal" |
Les attributs fontStyle
(style) et fontWeight
(épaisseur) permettent de préciser de quel style il s'agit. En combinant les deux, il est possible de créer un style gras italique :
1 | fontStyle='italic',fontWeight='bold' |
Enfin, le dernier attribut embedAsCFF
est obligatoire et doit être mis à false
. Cela permet d'éviter tout problème lors de l'utilisation de polices embarquées, à cause d'un changement entre Flex SDK 3 et Flex SDK 4.
Sur la ligne suivante, nous déclarons un attribut privé de type Class
qui contiendra le fichier de police embarqué :
1 | private static var F_WALKWAY:Class; |
Ce qui nous donne pour nos quatre fichiers :
1 2 3 4 5 6 7 8 9 10 11 12 13 | ///// Walkway // Normal [Embed(source='../lib/fonts/Walkway_SemiBold.ttf',fontName='walkway',fontWeight="normal",embedAsCFF=false)] private static var F_WALKWAY:Class; // Gras [Embed(source='../lib/fonts/Walkway_UltraBold.ttf',fontName='walkway',fontWeight='bold',embedAsCFF=false)] private static var F_WALKWAY_BOLD:Class; // Italique [Embed(source='../lib/fonts/Walkway_Oblique_SemiBold.ttf',fontName='walkway',fontStyle='italic',embedAsCFF=false)] private static var F_WALKWAY_ITALIC:Class; // Gras Italique [Embed(source='../lib/fonts/Walkway_Oblique_UltraBold.ttf',fontName='walkway',fontStyle='italic',fontWeight='bold',embedAsCFF=false)] private static var F_WALKWAY_BOLD_ITALIC:Class; |
Une fois que tous les fichiers sont incorporés, nous déclarons une méthode publique statique init():void
qui nous permet d'enregistrer la police de caractère, qui sera appelée au tout début de notre programme :
1 2 3 4 5 6 7 | /** * Initialisation des polices de caractères. A appeler une fois au lancement de l'application, afin que les polices soient prises en compte. */ public static function init():void { // Enregistrement des polices de caractères } |
Dans cette méthode, nous enregistrons les classes contenant les fichiers des polices de caractères grâce à la méthode statique registerFont
de la classe Font
:
1 | Font.registerFont(F_WALKWAY); |
Ce qui donne :
1 2 3 4 5 6 7 8 9 10 11 12 | /** * Initialisation des polices de caractères. A appeler une fois au lancement de l'application, afin que les polices soient prises en compte. */ public static function init():void { // Enregistrement des polices de caractères Font.registerFont(F_WALKWAY); Font.registerFont(F_WALKWAY_BOLD); Font.registerFont(F_WALKWAY_BOLD_ITALIC); Font.registerFont(F_WALKWAY_ITALIC); } |
Enfin, dans notre classe Main
, nous appelons la méthode statique init
de notre classe EmbedFonts
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; /** * Notre application embarque des polices de caractères embarquées ! :) */ [SWF(width="640",height="480",backgroundColor="#ffffff")] public class Main extends Sprite { public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; // Polices embarquées EmbedFonts.init(); } } } |
Vous remarquerez qu'il n'est pas nécessaire d'importer la classe EmbedFonts
car elle est dans le package principal (elle est placée dans le dossier racine de la source, ici src/
).
Utilisation
Et voilà ! Notre police de caractère embarquée est prête à l'emploi !
Pour que notre champ de texte utilise les polices de caractères embarquées au lieu des polices du système d'exploitation, il faut mettre l'attribut embedFonts
de la classe TextField
à true
, sans oublier de changer le nom de la police utilisée :
1 2 3 4 5 6 | // Police utilisée : walkway var format:TextFormat = new TextFormat("walkway", 42, 0x000000); monSuperTexte.defaultTextFormat = format; // On utilise les polices embarquées monSuperTexte.embedFonts = true; |
Voici le code complet pour afficher un champ de texte avec une police de caractères embarquée :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // Enregistrement des polices embarquées EmbedFonts.init(); // Création de l'instance du champ de texte var monSuperTexte:TextField = new TextField(); // Police utilisée : walkway var format:TextFormat = new TextFormat("walkway", 42, 0x000000); monSuperTexte.defaultTextFormat = format; // On utilise les polices embarquées monSuperTexte.embedFonts = true; // Taille automatique monSuperTexte.autoSize = TextFieldAutoSize.LEFT; // Texte HTML monSuperTexte.htmlText = "Normal <b>Gras</b> <i>Italique</i> <b><i>Gras Italique</i></b>"; // Ajout à la scène addChild(monSuperTexte); // Alignement au centre monSuperTexte.x = (stage.stageWidth - monSuperTexte.width) / 2; monSuperTexte.y = (stage.stageHeight - monSuperTexte.height) / 2; |
Ce qui nous donne à l'écran la figure suivante.
Désormais, notre texte s'affichera avec cette police même si l'utilisateur ne l'a pas installée ; de plus, il est possible de rendre le texte transparent et de lui appliquer une rotation !
Rotation sur soi-même
Et si nous décidions de tourner notre champ de texte sur lui-même ? Disons 50° dans le sens anti-horaire ? C'est désormais possible, tant donné que nous utilisons notre propre police embarquée. Commençons par écrire le code pour créer un champ de texte utilisant une police de caractères embarquée :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // Polices embarquées EmbedFonts.init(); // Création du champ de texte var monSuperTexte:TextField = new TextField(); var format:TextFormat = new TextFormat("walkway", 50, 0x000000); monSuperTexte.defaultTextFormat = format; monSuperTexte.embedFonts = true; monSuperTexte.autoSize = TextFieldAutoSize.LEFT; monSuperTexte.text = "Tournez-moi !"; addChild(monSuperTexte); // Alignement au centre monSuperTexte.x = (stage.stageWidth - monSuperTexte.width) / 2; monSuperTexte.y = (stage.stageHeight - monSuperTexte.height) / 2; |
Ce qui nous donne la figure suivante.
Essayons d'effectuer une rotation à notre champ de texte :
1 2 | // Rotation de 50° dans le sens anti-horaire monSuperTexte.rotation = - 50; |
Ce qui nous donne la figure suivante.
Ce n'est pas exactement ce que nous voulons accomplir ! En effet, l'objet tourne toujours par rapport à son origine, en haut à gauche : cela explique que le champ de texte soit tourné par rapport à la lettre "T". Malheureusement, nous ne pouvons pas modifier directement l'origine d'un objet d'affichage.
Il est néanmoins possible de changer artificiellement l'origine de l'objet en question, comme nous l'avons vu dans le chapitre précédent, en l'ajoutant dans un conteneur intermédiaire de classe Sprite
que j'appellerai "la boîte" :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // Conteneur intermédiaire var boite:Sprite = new Sprite(); addChild(boite); // Création du champ de texte var monSuperTexte:TextField = new TextField(); var format:TextFormat = new TextFormat("walkway", 50, 0x000000); monSuperTexte.defaultTextFormat = format; monSuperTexte.embedFonts = true; monSuperTexte.autoSize = TextFieldAutoSize.LEFT; monSuperTexte.text = "Tournez-moi !"; // On ajoute le champ de texte dans le conteneur boite.addChild(monSuperTexte); |
Une fois que le champ de texte est dans la boîte, on déplace le champ de texte de la moitié de sa taille, à la fois vers le haut et vers la gauche, ainsi l'origine de la boite se trouvera au centre du champ de texte (voir figure suivante).
Ainsi, l'origine de la boite se retrouve au centre du champ de texte. Si on fait abstraction de la boîte, l'origine de notre objet est le centre du champ de texte, donc il tournera par rapport à son centre ! Voici le code de cette opération :
1 2 3 | // On modifie artificiellement l'origine en la plaçant au centre du champ de texte : monSuperTexte.x = -monSuperTexte.width / 2; monSuperTexte.y = -monSuperTexte.height / 2; |
Enfin, on applique toutes les transformations à la boîte à la place de les appliquer au champ de texte, comme si la boîte était le champ de texte lui-même :
1 2 3 4 5 6 7 8 | // Alignement au centre // On aligne le conteneur au lieu du champ de texte boite.x = stage.stageWidth / 2; boite.y = stage.stageHeight / 2; // Rotation de 50° dans le sens anti-horaire // On tourne le conteneur au lieu du champ de texte boite.rotation = - 50; |
Ce qui nous donne ce que nous voulons (voir figure suivante).
Enfin ! Notre champ de texte a enfin consenti à tourner sur lui-même par rapport à son centre ! Vous serez souvent amené à utiliser cette méthode, par exemple si vous voulez animer une image en la faisant tourner sur elle-même, tout en la déplaçant…
Vous auriez peut-être pensé à recentrer le champ de texte après chaque rotation, mais croyez-moi, il est beaucoup plus simple de passer par un conteneur intermédiaire.
En résumé
- La classe
TextField
permet d'afficher du texte à l'écran. Il est possible de manipuler la sélection du texte. - On peut centrer un objet grâce aux propriétés de la scène principale de classe
Stage
. - La classe
TextFormat
permet de mettre en forme tout ou des portions du texte, c'est-à-dire change la police, la taille, la couleur… - Il est possible d'afficher du texte structuré en HTML simplifié avec l'attribut
htmlText
. - Il est très souvent intéressant d'embarquer les polices de caractères dans l'application, sans oublier de mettre l'attribut
embedFonts
àtrue
. - Utiliser un conteneur intermédiaire permet d'effectuer la rotation d'un objet autour de son centre (ou d'un autre point que son origine initiale).