Autres articles / Other articles

Display text in the graphical environment

published: 16 November 2024 / updated 18 November 2024

Lire cette page en français

 


When launching eForth Windows, the texts that are displayed are managed in a Windows terminal console. We can do many things in this console, except change font, position text to the nearest pixel, frame text, integrate graphical paths...

By displaying text in a Windows window, we will enter a complex universe, but rich and full of possibilities.

DrawTextA

The word DrawTextA is not defined in the graphics vocabulary. Here is its definition:

only forth  
windows definitions 
 
\ draws formatted text in the specified rectangle. 
z" DrawTextA"   5 User32 DrawTextA 

This new word requires five parameters:

Let's get to the heart of the matter with a first example:

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 
  ; 

Result:

It looks dense, but this example includes the initialization of various parameters.

Definition of the text plot area

The text is displayed in a rectangular area. This rectangular area is defined in a RECT structure. If you are not familiar with structures, read the article:
  Data structures for eFORTH.

To avoid having to manage the accessors of the RECT structure, we define the word RECT! which is responsible for assigning the dimensions of the 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! 

The sequence 10 10 300 80 LPRECT RECT! stores the rectangle parameters in LPRECT.

Here, the rectangle is 290 pixels wide. What happens if we try to display text that is too 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 
  ; 

When the text goes beyond the edge of the rectangle, it is truncated.

Text Formatting

The formatting of the text drawn by DrawText is controlled by its last parameter. In our code, it is defined via the constant DT_TOP.

Here are the main formats:

There are still other formats, but studying them is beyond the scope of this article.

These formats can be combined with the OR operator, provided that incompatible formats are not combined.

: 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 
  ; 

Result:

It should be noted that the text hyphenation is done between two words. It is therefore not necessary to worry about the length of the text to be displayed. If a word risks overflowing, it is automatically carried over to the next line in the rectangle. Let's add the text centering and in a narrower rectangle:

: 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 
  ; 

Result:

Each time, the word DrawTextA drops a value at the top of the stack. In the last example, it drops the value 48. This value corresponds to the vertical dimension, in pixels, of the text that was displayed.

If you do not use this parameter, eliminate it with DROP.

We will see in a future article how to color the text, change the font.

Change text color

To change the text color, you must first define the word SetTextColor:

only forth  
windows also  
graphics definitions 
 
\ Set text color   
z" SetTextColor"        2 Gdi32 SetTextColor  ( hdc color -- fl ) 

The SetTextColor word needs two parameters:

The color can be encoded as a single 32-bit value, $00FF00 for example.

Alternatively, to be sure to select a valid color, you can use the RGB word:

windows 
$FF $00 $00 RGB   \ push 32 bits color code on stack 

Each value processed by RGB must be in the range [0..255] in decimal, or [$00..$FF] in hexadecimal. The first value corresponds to the red component, the second to the green component, the third to the blue component.

: DRAWtext  ( -- ) 
    LPRECT 10 10 200 120 SetRect drop 
    hdc $FF $00 $00 RGB SetTextColor drop 
    hdc STR01 LPRECT FORMATTING DrawTextA drop 
  ; 

Result:

TextOutA

This word is defined like this:

\ write text    
z" TextOutA"    5 Gdi32 TextOutA  ( hdc x y lpString c -- fl ) 

List of parameters:

Usage:

: 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  ; 

Result:

With eForth Windows, it seems that the SetTextColor word has no effect on the text color.


Legal: site web personnel sans commerce / personal site without seling