Autres articles / Other articles

Afficher du texte dans l'environnement graphique

publication: 16 novembre 2024 / mis à jour 18 novembre 2024

Read this page in english

 


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:

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:

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:

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:

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