Display text in the graphical environment
published: 16 November 2024 / updated 18 November 2024
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:
- hdc handle of the current window;
- lpchText pointer to the string to display;
- cchText length of the string to display. If this value is -1, the string must end with the code zero;
- LPRECT lprc pointer to a structure of type
RECT; - format formatting of the text.
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:
DT_TOPDisplay from the top of the rectangleDT_LEFTAligns the text from the left of the rectangleDT_CENTERCenters the text horizontally in the rectangleDT_RIGHTAligns the text to the right of the rectangleDT_VCENTERCenters the text verticallyDT_BOTTOMJustifies the text from the bottom of the rectangleDT_WORDBREAKHyphenates words
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:
- hdc handle of the current context;
- color color of the text.
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:
- hdc context handle;
- x x coordinate of the text display position;
- y y coordinate of the text display position;
- lpString address of the text string to draw. The string does not need to be zero-terminated, because c specifies the length of the string;
- c length of the string.
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
