Afficher du texte dans l'environnement graphique
publication: 16 novembre 2024 / mis à jour 18 novembre 2024
Au lancement de eForth Windows, les textes qui s'affichent sont gérés dans une console de terminal Windows. On peut faire beaucoup de choses dans cette console, sauf changer de fonte, positionner du texte au pixel près, encadrer du texte, intégrer des tracés graphiques...
En affichant du texte dans une fenêtre Windows, on va passer dans un univers complexe, mais riche et plein de possibilités.
DrawTextA
Le mot DrawTextA
n'est pas défini dans le vocabulaire graphics. Voici sa définition:
only forth
windows definitions
\ draws formatted text in the specified rectangle.
z" DrawTextA" 5 User32 DrawTextA
Ce nouveau mot requiert cinq paramètres:
- hdc handle de la fenêtre courante;
- lpchText pointeur vers la chaîne à afficher;
- cchText longueur de la chaîne à afficher. Si cette valeur est -1, la chaîne doit se terminer par le code zéro;
- LPRECT lprc pointeur vesr une structure de type
RECT
; - format formatage du texte.
Entrons dans le vif du sujet avec un premier exemple:
only windows also graphics internals : RECT! { left top right bottom addr -- } left addr ->left L! top addr ->top L! right addr ->right L! bottom addr ->bottom L! ; create LPRECT RECT allot : STR01 ( -- addr len ) s" This is my first example." ; : DRAWtext ( -- ) 10 10 300 80 LPRECT RECT! hdc STR01 LPRECT DT_TOP DrawTextA ; : run04 600 400 window 100 ms DRAWtext key drop ;
Résultat:
Ca a l'air touffu, mais cet exemple intègre l'initialisation de divers paramètres.
Définition de la zone de tracé du texte
L'affichage du texte s'effectue dans une zone rectangulaire. Cette zone rectangulaire est définie dans
une structure RECT
. Si vous ne maitrisez pas les structures, lisez l'article:
Structures de données pour eFORTH.
Pour ne pas avoir à gérer les accesseurs de la structure RECT
, on définit le mot RECT!
qui se charge
d'affecter les dimensions du rectangle:
: RECT! { left top right bottom addr -- } left addr ->left L! top addr ->top L! right addr ->right L! bottom addr ->bottom L! ; create LPRECT RECT allot 10 10 300 80 LPRECT RECT!
La séquence 10 10 300 80 LPRECT RECT!
enregistre les paramètres du rectangle dans LPRECT
.
Ici, le rectangle fait 290 pixels de large. Que se passe-t-il si on essaie d'afficher un texte trop long?
: STR01 ( -- addr len ) s" This is my first example.. I try to draw a very long text in this graphic window." ; : DRAWtext ( -- ) 10 10 300 80 LPRECT RECT! hdc STR01 LPRECT DT_TOP DrawTextA ;
Quand le texte dépasse le bord du rectangle, il est tronqué.
Formatage du texte
Le formatage du texte tracé par DrawText
est contrôlé par son dernier paramètre. Dans notre code, c'est défini
via la constante DT_TOP
.
Voici les principaux formats:
DT_TOP
Affichage depuis le haut du rectangleDT_LEFT
Aligne le texte depuis la gauche du rectangleDT_CENTER
Centre le texte horizontalement dans le rectangleDT_RIGHT
Aligne le texte à droite du rectangleDT_VCENTER
Centre le texte verticalementDT_BOTTOM
Justifie le texte depuis le bas du rectangleDT_WORDBREAK
Césure les mots
Il y a encore d'autres formats, mais leur étude sort du cadre de cet article.
Ces formats peuvent se combiner avec l'opérateur OR, sous réserve de ne pas combiner des formats incompatibles.
: STR01 ( -- addr len ) s" This is my first example.. I try to draw a very long text in this graphic window." ; : FORMATTING ( -- n ) DT_TOP \ draw frop top DT_WORDBREAK OR \ break words ; : DRAWtext ( -- ) 10 10 300 80 LPRECT RECT! hdc STR01 LPRECT FORMATTING DrawTextA ;
Résultat:
On notera que la césure de texte s'effectue entre deux mots. Il n'est donc pas nécessaire de s'occuper de la longueur du texte à afficher. Si un mot risque de déborder, il est automatiquement reporté sur la ligne suivante dans le rectangle. Rajoutons le centrage de texte et dans un rectangle plus étroit:
: FORMATTING ( -- n ) DT_TOP \ draw frop top DT_WORDBREAK OR \ break words DT_CENTER OR \ center text ; : DRAWtext ( -- ) 10 10 200 120 LPRECT RECT! hdc STR01 LPRECT FORMATTING DrawTextA ;
Résultat:
A chaque fois, le mot DrawTextA
dépose une valeur au sommet de la pile. Dans le dernier exemple,
il dépose la valeur 48. Cette valeur correspond à la dimension verticale, en pixels, du texte qui a été affiché.
Si vous n'utilisez pas ce paramètre, éliminez-le avec DROP
.
Nous verrons dans un prochain article comment colorer le texte, changer la fonte.
Changer la couleur du texte
Pour changer la couleur du texte, il faut au préalable définir le mot SetTextColor
:
only forth windows also graphics definitions \ Set text color z" SetTextColor" 2 Gdi32 SetTextColor ( hdc color -- fl )
Le mot SetTextColor
a besoin de deux paramètres:
- hdc handle du contexte courant;
- color couleur du texte.
La couleur peut être codée en une seule valeur 32 bits, $00FF00
par exemple.
Sinon, pour être certain de sélectionner une couleur valable, vous pouvez utiliser le mot RGB
:
windows
$FF $00 $00 RGB \ push 32 bits color code on stack
Chaque valeur traitée par RGB
doit être comprise dans l'intervalle [0..255] en
décimal, ou [$00..$FF] en hexadécimal. La première valeur correspond à la composante rouge, la
seconde à la composante verte, la troisième à la composante bleue.
: DRAWtext ( -- )
LPRECT 10 10 200 120 SetRect drop
hdc $FF $00 $00 RGB SetTextColor drop
hdc STR01 LPRECT FORMATTING DrawTextA drop
;
Résultat:
TextOutA
Ce mot est défini comme ceci:
\ write text z" TextOutA" 5 Gdi32 TextOutA ( hdc x y lpString c -- fl )
Liste des paramètres:
- hdc handle de contexte;
- x coordonnée x de la position d'affichage du texte;
- y coordonnée y de la position d'affichage du texte;
- lpString adresse de la chaîne texte à dessiner. La chaîne n’a pas besoin d’être terminée par zéro, car c spécifie la longueur de la chaîne;
- c longueur de la chaîne.
Utilisation:
: String01 s" This is a first test string..." ;
: String02 s" This is a second test string..." ;
: TXTout ( -- )
hdc 10 10 String01 TextOutA drop
hdc 10 30 String02 TextOutA drop ;
Résultat:
Avec eForth Windows, il semble que le mot SetTextColor
n'aie pas d'effet sur la couleur du texte.
Legal: site web personnel sans commerce / personal site without seling