home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / fgl / fglight / manuals.arj / USER07.DOC < prev    next >
Text File  |  1995-02-06  |  55KB  |  1,177 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7. Chapter 7
  8.  
  9.  
  10.  
  11.  
  12.  
  13. Character Display Routines                                                     
  14. 126   Fastgraph User's Guide
  15.  
  16.  
  17. Overview
  18.  
  19.      An important part of any program is the capability to display text or
  20. other characters on the screen. Fastgraph supports two character sets: the
  21. hardware or BIOS character set available with each video mode, and Fastgraph's
  22. own software character set for graphics video modes. Fastgraph/Light does not
  23. support the software character set.
  24.  
  25.      We'll begin this chapter with a review of character space, and then
  26. discuss the specifics about hardware and software characters. At the end of
  27. the chapter, we'll briefly explain how to implement bitmapped characters into
  28. a program. To simplify matters, the example programs presented in this chapter
  29. are mode-specific examples, and no testing is done to check if the video mode
  30. is available on the user's system.
  31.  
  32.  
  33. Character Space
  34.  
  35.      The coordinate system used for displaying hardware characters is called
  36. character space. It is the only coordinate system available in text video
  37. modes, but it is a supplementary coordinate system you can use with either
  38. screen space or world space in graphics video modes. Character space can be
  39. thought of as a grid of rows and columns, with each cell in the grid holding
  40. one character. Each cell is identified by its unique (row,column) integer
  41. coordinates. The rows and columns are numbered starting at zero; the origin is
  42. always the upper left corner of the screen. For example, in the 80-column by
  43. 25-row video modes, the (row,column) coordinates of the screen corners are
  44. shown in the following diagram.
  45.  
  46.  
  47.                             (0,0)           (0,79)
  48.  
  49.  
  50.  
  51.                             (24,0)         (24,79)
  52.  
  53.  
  54. The default number of rows and columns depends on the video mode, as shown in
  55. the following table. For graphics modes, the table also includes the default
  56. width and height in pixels of a character cell.
  57.  
  58.                            Mode   No. of No. of Char. Char.
  59.                           Number  Columns Rows  WidthHeight
  60.  
  61.                              0      40     25
  62.                              1      40     25
  63.                              2      80     25
  64.                              3      80     25
  65.                              4      40     25     8     8
  66.                              5      40     25     8     8
  67.                              6      80     25     8     8
  68.                              7      80     25
  69.                              9      40     25     8     8
  70.                             11      80     25     9    14
  71.                             12      40     25     8     8                      
  72.                                   Chapter 7:  Character Display Routines   127
  73.  
  74.                             13      40     25     8     8
  75.                             14      80     25     8     8
  76.                             15      80     25     8    14
  77.                             16      80     25     8    14
  78.                             17      80     30     8    16
  79.                             18      80     30     8    16
  80.                             19      40     25     8     8
  81.                             20      40     25     8     8
  82.                             21      40     50     8     8
  83.                             22      40     30     8     8
  84.                             23      40     60     8     8
  85.                             24      80     25     8    16
  86.                             25      80     30     8    16
  87.                             26      100    37     8    16
  88.                             27      128    48     8    16
  89.                             28      100    37     8    16
  90.                             29      128    48     8    16
  91.  
  92.  
  93. Hardware Characters
  94.  
  95.      Hardware characters are available in all supported video modes. As
  96. explained in Chapter 5, text mode characters have a display attribute that
  97. defines their foreground color, their background color, and whether or not
  98. they blink. Graphics mode characters appear in a single color, as determined
  99. by the current color index. Chapter 5 also explained how Fastgraph's
  100. fg_setattr and fg_setcolor routines define the attribute or color index in
  101. which subsequent hardware characters appear.
  102.  
  103.      It is obviously important to define the color or attribute for hardware
  104. characters, but it is equally important to define their location on the
  105. screen. Fastgraph draws hardware characters at the position defined by the
  106. text cursor. Like the graphics cursor, the text cursor is not a cursor in the
  107. true sense, but is simply a pair of character space (row,column) coordinates
  108. with a special meaning. The fg_setmode routine sets the text cursor position
  109. to the character space coordinates (0,0), which of course is the upper left
  110. corner of the screen.2
  111.  
  112.      The Fastgraph routine fg_locate changes the text cursor position. It has
  113. two integer arguments that specify the (row,column) character space
  114. coordinates of the new position. The row values must be between 0 and one less
  115. than the number of character rows available. The column values must be between
  116. 0 and one less than the number of character columns available.
  117.  
  118.      The fg_text routine is Fastgraph's basic character display routine. It
  119. displays a string of hardware characters, starting at the text cursor
  120. position, using the current color attribute (for text modes) or color index
  121. (for graphics modes). If the string reaches the last column in a row, fg_text
  122. will wrap the string to the first column of the next row. Additionally,
  123. fg_text leaves the cursor one column to the right of the last character
  124. displayed (or the first column of the next row if the last character appears
  125. ____________________
  126.  
  127.    (2) In reality there are eight text cursors, one for each video page. The
  128. fg_setmode routine initializes each text cursor position to (0,0). The next
  129. chapter describes this in more detail.                                         
  130. 128   Fastgraph User's Guide
  131.  
  132. at the end of a row). This feature makes it possible for successive calls to
  133. fg_text to display adjacent strings. The first argument for the fg_text
  134. routine is a character string of arbitrary length, and the second argument is
  135. an integer value that specifies the number of characters to display from that
  136. string.
  137.  
  138.      Example 7-1 illustrates the use of fg_locate and fg_text in the 80x25
  139. color text mode (mode 3). After establishing the video mode and making the
  140. BIOS cursor invisible, the program displays four strings with different
  141. attributes. The attributes are selected using fg_setattr, and the strings are
  142. displayed by fg_text. The first string appears in yellow (attributes 14,0,0)
  143. in the upper left corner of the screen; fg_locate is not necessary because
  144. (0,0) is the default text cursor position established by fg_setmode. The
  145. second string appears in light green (10,0,0) one space to the right of the
  146. first string. Its position relies on the fact fg_text leaves the text cursor
  147. positioned one space to the right of the last character displayed (following
  148. the "w" of "yellow" in this case). The leading space in " green" leaves a
  149. space between the first and second strings. Similarly, the third string
  150. appears in blinking light red (12,0,1) one space to the right of the second
  151. string.
  152.  
  153.      The program then uses fg_locate to move the text cursor to the lower left
  154. corner of the screen and displays the "Press any key" string. This string is
  155. displayed with a light red foreground against a gray background (12,7,0). The
  156. extra spaces surrounding the string extend the background color one character
  157. position to the left and right and make the string more visually appealing.
  158. Finally, once you press any key, the program restores the original video mode
  159. and screen attributes before returning to DOS.
  160.  
  161.                                  Example 7-1.
  162.  
  163.                       #include <fastgraf.h>
  164.                       void main(void);
  165.  
  166.                       void main()
  167.                       {
  168.                          int old_mode;
  169.  
  170.                          fg_initpm();
  171.                          old_mode = fg_getmode();
  172.                          fg_setmode(3);
  173.                          fg_cursor(0);
  174.  
  175.                          fg_setattr(14,0,0);
  176.                          fg_text("yellow",6);
  177.  
  178.                          fg_setattr(10,0,0);
  179.                          fg_text(" green",6);
  180.  
  181.                          fg_setattr(12,0,1);
  182.                          fg_text(" blinking",9);
  183.  
  184.                          fg_setattr(12,7,0);
  185.                          fg_locate(24,0);
  186.                          fg_text(" Press any key. ",16);
  187.                          fg_waitkey();                                         
  188.                                   Chapter 7:  Character Display Routines   129
  189.  
  190.  
  191.                          fg_setmode(old_mode);
  192.                          fg_reset();
  193.                       }
  194.  
  195.  
  196.      The fg_where routine retrieves the text cursor position in its two
  197. integer arguments. This routine is not used as frequently as fg_locate and
  198. fg_text because more often than not your program will know the text cursor
  199. position implicitly, or you'll know in advance the locations at which text
  200. will be displayed. The fg_where routine takes two integer arguments passed by
  201. reference, and these two arguments respectively receive the text cursor's
  202. current row and column position.
  203.  
  204.      Example 7-2 produces the same results as example 7-1, but it does so a
  205. bit differently. It uses its own routine, put_string, to display a string at a
  206. specified row and column. The put_string routine simply calls fg_locate to
  207. establish the text cursor position and then calls fg_text to display the
  208. string. Note the use of the C library function strlen to determine the string
  209. length passed to fg_text. Example 7-2 also uses fg_where to retrieve the new
  210. text cursor positions, which are then passed to put_string.
  211.  
  212.                                  Example 7-2.
  213.  
  214.                     #include <fastgraf.h>
  215.                     #include <string.h>
  216.                     void main(void);
  217.                     void put_string(char*,int,int);
  218.  
  219.                     void main()
  220.                     {
  221.                        int old_mode;
  222.                        int row, column;
  223.  
  224.                        fg_initpm();
  225.                        old_mode = fg_getmode();
  226.                        fg_setmode(3);
  227.                        fg_cursor(0);
  228.  
  229.                        fg_setattr(14,0,0);
  230.                        put_string("yellow",0,0);
  231.  
  232.                        fg_setattr(10,0,0);
  233.                        fg_where(&row,&column);
  234.                        put_string("green",row,column+1);
  235.  
  236.                        fg_setattr(12,0,1);
  237.                        fg_where(&row,&column);
  238.                        put_string("blinking",row,column+1);
  239.  
  240.                        fg_setattr(12,7,0);
  241.                        put_string(" Press any key. ",24,0);
  242.                        fg_waitkey();
  243.  
  244.                        fg_setmode(old_mode);
  245.                        fg_reset();                                             
  246. 130   Fastgraph User's Guide
  247.  
  248.                     }
  249.  
  250.                     void put_string(string,row,column)
  251.                     char *string;
  252.                     int row, column;
  253.                     {
  254.                        fg_locate(row,column);
  255.                        fg_text(string,strlen(string));
  256.                     }
  257.  
  258.  
  259.      Sometimes you may wish to change the display attribute of existing text,
  260. such as when creating a shadow around the edges of a pop-up window. The
  261. Fastgraph routine fg_chgattr performs this function. It applies the current
  262. text display attribute (as defined in the most recent call to fg_setattr or
  263. fg_setcolor) to a given number of characters, starting at the text cursor
  264. position. It leaves the text cursor one column to the right of the last
  265. character changed (or the first column of the next row if the last character
  266. is at the end of a row). The fg_chgattr routine's argument specifies the
  267. number of characters to change. This routine has no effect in graphics video
  268. modes.
  269.  
  270.      The Fastgraph routine fg_chgtext performs somewhat the opposite function
  271. of fg_chgattr. It displays new text but uses the display attributes already
  272. assigned to the character cells where the text will appear. The fg_chgtext
  273. routine takes the same two arguments as fg_text, displays the characters
  274. starting at the text cursor position, and leaves the cursor one column to the
  275. right of the last character displayed. Like fg_chgattr, fg_chgtext has no
  276. effect in graphics video modes.
  277.  
  278.      Example 7-3 illustrates the fg_chgattr and fg_chgtext routines. It runs
  279. in the 80-column color text mode (mode 3), but if we change the fg_setmode
  280. argument it also would run in the monochrome text mode (mode 7). The program
  281. first displays the word "hello" in the upper left corner of the screen, using
  282. a gray foreground and black background attribute. After waiting for a
  283. keystroke, the program calls fg_chgattr to make the word "hello" appear in
  284. reverse video (that is, a black foreground and gray background attribute).
  285. After a second keystroke, the program uses fg_chgtext to change the "h" of
  286. "hello" to upper case. Following this, the program returns to DOS.
  287.  
  288.                                  Example 7-3.
  289.  
  290.                           #include <fastgraf.h>
  291.                           void main(void);
  292.  
  293.                           void main()
  294.                           {
  295.                              int old_mode;
  296.  
  297.                              fg_initpm();
  298.                              old_mode = fg_getmode();
  299.                              fg_setmode(3);
  300.                              fg_cursor(0);
  301.  
  302.                              fg_setattr(7,0,0);
  303.                              fg_text("hello",5);                               
  304.                                   Chapter 7:  Character Display Routines   131
  305.  
  306.                              fg_waitkey();
  307.  
  308.                              fg_locate(0,0);
  309.                              fg_setattr(0,7,0);
  310.                              fg_chgattr(5);
  311.                              fg_waitkey();
  312.  
  313.                              fg_locate(0,0);
  314.                              fg_chgtext("H",1);
  315.                              fg_waitkey();
  316.  
  317.                              fg_setmode(old_mode);
  318.                              fg_reset();
  319.                           }
  320.  
  321.  
  322.      You also can retrieve the character or attribute stored in a specific
  323. character cell. The Fastgraph routine fg_getchar retrieves character values,
  324. while fg_getattr retrieves character attributes. Both routines have two
  325. integer arguments that specify the (row,column) coordinates for the character
  326. cell of interest. Example 7-4 uses fg_getchar and fg_getattr to read the
  327. character and attribute stored at row 24, column 0. Just before the program
  328. exits, it displays these values.
  329.  
  330.                                  Example 7-4.
  331.  
  332.                       #include <fastgraf.h>
  333.                       #include <stdio.h>
  334.                       void main(void);
  335.  
  336.                       void main()
  337.                       {
  338.                          int attr, value;
  339.                          int old_mode;
  340.  
  341.                          fg_initpm();
  342.                          old_mode = fg_getmode();
  343.                          fg_setmode(3);
  344.                          fg_cursor(0);
  345.  
  346.                          fg_setattr(9,7,0);
  347.                          fg_locate(24,0);
  348.                          fg_text("Test",4);
  349.                          value = fg_getchar(24,0);
  350.                          attr  = fg_getattr(24,0);
  351.                          fg_waitkey();
  352.  
  353.                          fg_setmode(old_mode);
  354.                          fg_reset();
  355.                          printf("%c %2.2X\n",value,attr);
  356.                       }
  357.  
  358.  
  359.      If you need to retrieve characters and attributes from a rectangular
  360. area, it's more efficient to use the fg_getimage routine (described in Chapter
  361. 10) than to call fg_getchar and fg_getattr repeatedly.                         
  362. 132   Fastgraph User's Guide
  363.  
  364.  
  365.      Displaying hardware characters in graphics video modes is different from
  366. doing so in text modes. Like text modes, we can still use fg_text to display
  367. strings in character space, which of course restricts the places where strings
  368. can appear. Graphics modes offer the ability to display strings relative to
  369. any pixel, not just character cells. The fg_print and fg_justify routines are
  370. provided for this purpose. To compare the two methods of displaying strings in
  371. graphics modes, let's begin with an example of doing so with fg_text.
  372.  
  373.      Example 7-5 is similar to example 7-1, but it runs in the EGA enhanced
  374. graphics mode (mode 16) instead of a text mode. In graphics modes, fg_cursor
  375. has no effect, so we have omitted it from the program. Furthermore, characters
  376. cannot be displayed with a blinking attribute, so we have omitted the blinking
  377. characters (we could simulate blinking by repetitively displaying and erasing
  378. them, but that is beyond the scope of this example). Because graphics mode
  379. characters only have a foreground color, we had to simulate the gray
  380. background of the "Press any key" string by first drawing a rectangle where
  381. that string appears. The differences between examples 7-5 and 7-1 hold for any
  382. graphics video mode, not just mode 16.
  383.  
  384.                                  Example 7-5.
  385.  
  386.                       #include <fastgraf.h>
  387.                       void main(void);
  388.  
  389.                       void main()
  390.                       {
  391.                          int old_mode;
  392.  
  393.                          fg_initpm();
  394.                          old_mode = fg_getmode();
  395.                          fg_setmode(16);
  396.  
  397.                          fg_setcolor(14);
  398.                          fg_text("yellow",6);
  399.  
  400.                          fg_setcolor(10);
  401.                          fg_text(" green",6);
  402.  
  403.                          fg_setcolor(7);
  404.                          fg_rect(0,127,336,349);
  405.                          fg_setcolor(12);
  406.                          fg_locate(24,0);
  407.                          fg_text(" Press any key. ",16);
  408.                          fg_waitkey();
  409.  
  410.                          fg_setmode(old_mode);
  411.                          fg_reset();
  412.                       }
  413.  
  414.  
  415.      Now let's show how to display graphics mode strings using the more
  416. flexible screen space coordinate system. The fg_print routine is identical to
  417. fg_text, but it displays a string relative to the graphics cursor position
  418. (that is, in screen space) rather than the character space position
  419. established with fg_locate. By default, fg_print displays strings so their     
  420.                                   Chapter 7:  Character Display Routines   133
  421.  
  422. lower left corner is at the graphics cursor position. The fg_justify routine
  423. lets you change this default justification. Its two parameters, xjust and
  424. yjust, control the string positioning about the current graphics position, as
  425. summarized in the following table:
  426.  
  427.                 value of     value of   horizontal      vertical
  428.                   xjust       yjust    justification  justification
  429.  
  430.                    -1           -1         left           lower
  431.                    -1           0          left          center
  432.                    -1           1          left           upper
  433.                     0           -1        center          lower
  434.                     0           0         center         center
  435.                     0           1         center          upper
  436.                     1           -1         right          lower
  437.                     1           0          right         center
  438.                     1           1          right          upper
  439.  
  440. Any other justification values produce undefined results. In the context of
  441. vertical justification, lower justification means the bottom of each character
  442. will be at the current graphics y position. Upper justification means the top
  443. of each character will be at the graphics y position, while center
  444. justification means characters will be centered about the graphics y position.
  445. The default justification settings (established by fg_setmode) are xjust = -1
  446. and yjust = -1, and you can retrieve the current justification settings with
  447. Fastgraph's fg_getxjust and fg_getyjust functions. Like fg_text, fg_print
  448. leaves the graphics cursor positioned just beyond the bottom right corner of
  449. the last character displayed.
  450.  
  451.      Neither fg_print nor fg_text performs clipping. There may be times,
  452. however, when displaying clipped strings is desirable, such as when displaying
  453. text inside a fixed window. When clipping is needed, use fg_printc or fg_textc
  454. for displaying strings. These two routines are identical in all respects to
  455. fg_print and fg_text, but they do not display characters lying outside the
  456. clipping region established by fg_setclip or fg_setclipw. Further, if part of
  457. a character is outside the clipping region, fg_printc and fg_textc display
  458. only that part of the character that falls within the clipping region. Because
  459. clipping is supported only in graphics video modes, fg_textc is equivalent to
  460. fg_text when used in text video modes.
  461.  
  462.      Example 7-6 illustrates the use of fg_print and fg_justify to display
  463. justified text in the VGA 640x480 16-color graphics mode (mode 18). The first
  464. series of calls to fg_move, fg_justify, and fg_print display the string
  465. "Fastgraph" left justified, centered, and right justified against the top row
  466. of the screen. The second series of such calls also displays the string in
  467. these positions, but each is centered vertically in the middle of the screen.
  468. The final series displays the strings against the bottom row of the screen.
  469. The nine calls to fg_justify in example 7-6 represent all possible
  470. justification settings for strings displayed with fg_print.
  471.  
  472.                                  Example 7-6.
  473.  
  474.                           #include <fastgraf.h>
  475.                           void main(void);
  476.  
  477.                           void main()                                          
  478. 134   Fastgraph User's Guide
  479.  
  480.                           {
  481.                              int old_mode;
  482.  
  483.                              fg_initpm();
  484.                              old_mode = fg_getmode();
  485.                              fg_setmode(18);
  486.                              fg_setcolor(9);
  487.                              fg_fillpage();
  488.                              fg_setcolor(14);
  489.  
  490.                              fg_move(0,0);
  491.                              fg_justify(-1,1);
  492.                              fg_print("Fastgraph",9);
  493.                              fg_move(320,0);
  494.                              fg_justify(0,1);
  495.                              fg_print("Fastgraph",9);
  496.                              fg_move(639,0);
  497.                              fg_justify(1,1);
  498.                              fg_print("Fastgraph",9);
  499.  
  500.                              fg_move(0,240);
  501.                              fg_justify(-1,0);
  502.                              fg_print("Fastgraph",9);
  503.                              fg_move(320,240);
  504.                              fg_justify(0,0);
  505.                              fg_print("Fastgraph",9);
  506.                              fg_move(639,240);
  507.                              fg_justify(1,0);
  508.                              fg_print("Fastgraph",9);
  509.  
  510.                              fg_move(0,479);
  511.                              fg_justify(-1,-1);
  512.                              fg_print("Fastgraph",9);
  513.                              fg_move(320,479);
  514.                              fg_justify(0,-1);
  515.                              fg_print("Fastgraph",9);
  516.                              fg_move(639,479);
  517.                              fg_justify(1,-1);
  518.                              fg_print("Fastgraph",9);
  519.                              fg_waitkey();
  520.  
  521.                              fg_setmode(old_mode);
  522.                              fg_reset();
  523.                           }
  524.  
  525.  
  526.      Example 7-7 demonstrates a side effect that occurs when displaying
  527. characters in graphics modes. This example uses the MCGA graphics mode (mode
  528. 19) and displays two character strings at the same location. If we were to do
  529. this in a text mode, the first string would disappear once we displayed the
  530. second string (assuming the second string isn't shorter than the first). In
  531. graphics modes, however, the portions of the first string not covered by
  532. characters from the second string are still visible. The reason for this may
  533. not be clear at first, but remember when we display characters in graphics
  534. modes, we aren't really displaying characters but merely a pixel
  535. representation of the characters. Fastgraph has no way to distinguish such     
  536.                                   Chapter 7:  Character Display Routines   135
  537.  
  538. pixels from any other pixels, no matter what routine we use for string
  539. display.
  540.  
  541.                                  Example 7-7.
  542.  
  543.                           #include <fastgraf.h>
  544.                           void main(void);
  545.  
  546.                           void main()
  547.                           {
  548.                              int old_mode;
  549.  
  550.                              fg_initpm();
  551.                              old_mode = fg_getmode();
  552.                              fg_setmode(19);
  553.  
  554.                              fg_setcolor(14);
  555.                              fg_text("yellow",6);
  556.                              fg_locate(0,0);
  557.                              fg_setcolor(10);
  558.                              fg_text(" green",6);
  559.                              fg_waitkey();
  560.  
  561.                              fg_setmode(old_mode);
  562.                              fg_reset();
  563.                           }
  564.  
  565.  
  566.      To avoid this problem, the recommended procedure for displaying
  567. characters in graphics modes is to first erase the area where the text will
  568. appear. The easiest way to do this is to use fg_rect to draw a rectangle in
  569. the background color. In example 7-7, we could do this by inserting the
  570. statements
  571.  
  572.  
  573.                               fg_setcolor(0);
  574.                               fg_rect(0,47,0,7);
  575.  
  576.  
  577. immediately before the call to fg_locate. The parameters passed to the fg_rect
  578. routine represent the 48 by 8 pixel region that corresponds to the first six
  579. character cells of row 0 in the 320x200 graphics modes.
  580.  
  581.  
  582. Character Height
  583.  
  584.      In VGA and SVGA graphics modes (modes 17 to 29), it's possible to change
  585. the height of characters displayed with fg_print, fg_printc, fg_text, and
  586. fg_textc. By default, characters are 16 pixels high in the VGA and SVGA
  587. graphics modes (17, 18, 24 to 29) and 8 pixels high in the MCGA and XVGA
  588. graphics modes (19 to 23). The fg_fontsize routine lets you display characters
  589. from the BIOS 8x8, 8x14, or 8x16 fonts in any of these modes. Its only
  590. parameter specifies the character height in pixels; it must be 8, 14, or 16.
  591. If the character height is some other value, or if fg_fontsize is used in a
  592. video mode numbered 16 or less (that is, in a non-VGA mode), nothing happens.  
  593. 136   Fastgraph User's Guide
  594.  
  595.      When we change the character height with fg_fontsize, the number of text
  596. rows on the screen changes accordingly. The following table shows the number
  597. of text rows available in each supported video mode when using the different
  598. character sizes. The values in boldface represent the default character size
  599. and number of rows for that video mode.
  600.  
  601.                                  Mode No. of rows with
  602.                                 Number 8x8  8x14 8x16
  603.  
  604.                                   17    60   34   30
  605.                                   18    60   34   30
  606.                                   19    25   14   12
  607.                                   20    25   14   12
  608.                                   21    50   28   25
  609.                                   22    30   17   15
  610.                                   23    60   34   30
  611.                                   24    50   28   25
  612.                                   25    60   34   30
  613.                                   26    75   42   37
  614.                                   27    96   54   48
  615.                                   28    75   42   37
  616.                                   29    96   54   48
  617.  
  618.      Example 7-8 shows how to use fg_fontsize to activate the 8x8 character
  619. font in the 16-color 640x480 VGA graphics mode (mode 18). In this mode,
  620. characters are normally 16 pixels high, giving 30 character rows per screen.
  621. When we use the 8x8 font, this increases to 60 rows because the characters are
  622. now half as tall as before. The example program uses fg_text to display the
  623. string "8x8 ROM font" 60 times, once in each row.
  624.  
  625.                                  Example 7-8.
  626.  
  627.                       #include <fastgraf.h>
  628.                       void main(void);
  629.  
  630.                       void main()
  631.                       {
  632.                          int old_mode;
  633.                          int row;
  634.  
  635.                          fg_initpm();
  636.                          old_mode = fg_getmode();
  637.                          fg_setmode(18);
  638.  
  639.                          fg_setcolor(9);
  640.                          fg_fillpage();
  641.                          fg_setcolor(15);
  642.                          fg_fontsize(8);
  643.  
  644.                          for (row = 0; row < 60; row++) {
  645.                             fg_locate(row,34);
  646.                             fg_text("8x8 ROM font",12);
  647.                             }
  648.                          fg_waitkey();
  649.  
  650.                          fg_setmode(old_mode);                                 
  651.                                   Chapter 7:  Character Display Routines   137
  652.  
  653.                          fg_reset();
  654.                       }
  655.  
  656.  
  657.  
  658. Conversion Routines
  659.  
  660.      In Chapter 4 we introduced Fastgraph's routines for converting
  661. coordinates between character space and screen space. In this section we'll
  662. review these routines and then present an example that uses some of them.
  663.  
  664.      The fg_xalpha and fg_yalpha routines convert screen space coordinates to
  665. character space. The fg_xalpha routine converts a screen space x coordinate to
  666. the character space column that contains the coordinate. Similarly, fg_yalpha
  667. converts a screen space y coordinate to the character space row that contains
  668. the coordinate.
  669.  
  670.      The fg_xconvert and fg_yconvert routines convert character space
  671. coordinates to screen space. The fg_xconvert routine converts a character
  672. space column to the screen space coordinate of its leftmost pixel. Similarly,
  673. fg_yconvert converts a character space row to the screen space coordinate of
  674. its top (lowest-numbered) pixel.
  675.  
  676.      Example 7-5 demonstrated how to display characters in a graphics mode.
  677. Because characters do not have a background color in graphics modes, that
  678. example used fg_rect to simulate a background color by drawing a gray
  679. rectangle before displaying the text. It was necessary to determine the screen
  680. coordinates of the character cells so we could pass the correct parameters to
  681. fg_rect. By using fg_xconvert and fg_yconvert, we can let Fastgraph calculate
  682. the required screen coordinates. This method has the additional benefit of
  683. working in any graphics mode, while the coordinates passed to fg_rect in
  684. example 7-5 would only work properly in a 640x350 graphics mode. Example 7-9
  685. shows how we could extend example 7-5 using fg_xconvert and fg_yconvert.
  686.  
  687.                                  Example 7-9.
  688.  
  689.                       #include <fastgraf.h>
  690.                       void main(void);
  691.  
  692.                       void main()
  693.                       {
  694.                          int old_mode;
  695.                          int minx, maxx, miny, maxy;
  696.  
  697.                          fg_initpm();
  698.                          fg_old_mode = fg_getmode();
  699.                          fg_setmode(16);
  700.  
  701.                          fg_setcolor(14);
  702.                          fg_text("yellow",6);
  703.  
  704.                          fg_setcolor(10);
  705.                          fg_text(" green",6);
  706.  
  707.                          fg_setcolor(7);
  708.                          minx = fg_xconvert(0);                                
  709. 138   Fastgraph User's Guide
  710.  
  711.                          maxx = fg_xconvert(16) - 1;
  712.                          miny = fg_yconvert(24);
  713.                          maxy = fg_yconvert(25) - 1;
  714.                          fg_rect(minx,maxx,miny,maxy);
  715.                          fg_setcolor(12);
  716.                          fg_locate(24,0);
  717.                          fg_text(" Press any key. ",16);
  718.                          fg_waitkey();
  719.  
  720.                          fg_setmode(old_mode);
  721.                          fg_reset();
  722.                       }
  723.  
  724.  
  725.  
  726. Software Characters
  727.  
  728.      Software characters, also called stroke characters or vector characters
  729. in other literature, are only are available in graphics video modes. Unlike
  730. the fixed-size hardware characters, you can display software characters in any
  731. size, at any angle, and at any position. In addition, software characters are
  732. proportionally spaced. However, software characters take longer to draw than
  733. hardware characters do.
  734.  
  735.      Fastgraph includes two software character fonts, called the primary font
  736. and the alternate font. The primary font contains upper and lower case
  737. letters, numbers, punctuation, and most other printable ASCII characters. The
  738. alternate font contains upper and lower case Greek letters and other
  739. mathematical and scientific symbols.
  740.  
  741.      The Fastgraph routine fg_swchar displays a string of software characters
  742. in the current color index (as defined by the most recent call to
  743. fg_setcolor). The string may contain any characters from the primary font, the
  744. alternate font, or both. You can display the characters left justified,
  745. centered, or right justified relative to the graphics cursor position. Just as
  746. fg_text updates the text cursor position, fg_swchar sets the graphics cursor
  747. position just to the right of the last character drawn. The characters are
  748. clipped according to the current clipping region. In addition to the
  749. characters, the string passed to fg_swchar also may contain operators for
  750. switching fonts, underlining, subscripting, or superscripting characters.
  751. Because fg_swchar internally uses world space coordinates, you must call the
  752. fg_initw routine at some point in your program before the first call to
  753. fg_swchar. You also must establish a world space coordinate system with the
  754. fg_setworld routine.
  755.  
  756.      The fg_swchar routine has three arguments. The first argument is the
  757. character string to display. The second argument is an integer value that
  758. specifies the number of characters in the string, including any characters
  759. used as special operators. The third argument is an integer value that
  760. determines the position of the string relative to the graphics cursor
  761. position. If this value is negative, the lower left corner of the first
  762. character will be at the graphics cursor position. If it is positive, the
  763. lower right corner of the last character will be at the graphics cursor
  764. position. If it is zero, the string will be horizontally centered at the
  765. graphics cursor position.                                                      
  766.                                   Chapter 7:  Character Display Routines   139
  767.  
  768.      The size of software characters is determined by the values passed to
  769. fg_setsize, fg_setsizew, and fg_setratio. The fg_setsize routine has a single
  770. integer argument that defines the height of software characters in screen
  771. space units, while fg_setsizew has a single floating point argument that
  772. defines the height in world space units. If neither of these routines is
  773. called, Fastgraph will use its default character height of one world space
  774. unit. The fg_setratio routine has a single floating point argument that
  775. defines the aspect ratio for software characters. The aspect ratio is the
  776. ratio of character width to character height. For example, an aspect ratio of
  777. 2.0 means characters are twice as wide as they are high. If fg_setratio is not
  778. called, Fastgraph uses its default aspect ratio of 1.
  779.  
  780.      Example 7-10 displays all characters in both software character fonts.
  781. The program uses the enhanced EGA graphics mode (mode 16), but it could run in
  782. any graphics mode by changing the fg_setmode argument. After establishing the
  783. video mode, the program calls fg_initw to initialize Fastgraph's world space
  784. parameters; this is required since the software character drawing routines
  785. internally use world space coordinates. The next statement is a call to
  786. fg_setworld that establishes a world space coordinate system with 0.01 world
  787. space units per pixel. Following this is a call to fg_setsizew that defines
  788. the character height as 0.21 world space units, or 21 pixels. Note we could
  789. have instead used fg_setsize here with an integer argument of 21.
  790.  
  791.      The next part of the program draws the characters in the primary font on
  792. the upper half of the screen. After doing this, the program draws the
  793. alternate font characters on the lower half. In each case it does this with
  794. fg_swchar. By default, the string passed to fg_swchar will produce characters
  795. from the primary font. However, you can insert a back slash character (\) in
  796. the string to toggle between the two fonts. Don't forget C and C++ apply a
  797. special meaning to the back slash character within strings, so you must use
  798. two consecutive back slashes to insert a single back slash in the string.
  799.  
  800.                                  Example 7-10.
  801.  
  802.              #include <fastgraf.h>
  803.              void main(void);
  804.  
  805.              void main()
  806.              {
  807.                 int old_mode;
  808.  
  809.                 fg_initpm();
  810.                 old_mode = fg_getmode();
  811.                 fg_setmode(16);
  812.                 fg_initw();
  813.                 fg_setworld(0.0,6.39,0.0,3.49);
  814.                 fg_setsizew(0.21);
  815.  
  816.                 fg_setcolor(15);
  817.                 fg_locate(0,26);
  818.                 fg_text("Software characters - font 1",28);
  819.  
  820.                 fg_setcolor(10);
  821.                 fg_movew(0.0,3.1);
  822.                 fg_swchar("ABCDEFGHIJKLMNOPQRSTUVWXYZ",26,-1);
  823.                 fg_movew(0.0,2.8);                                             
  824. 140   Fastgraph User's Guide
  825.  
  826.                 fg_swchar("abcdefghijklmnopqrstuvwxyz",26,-1);
  827.                 fg_movew(0.0,2.5);
  828.                 fg_swchar("0123456789",10,-1);
  829.                 fg_movew(0.0,2.2);
  830.                 fg_swchar("!\"#$%&'()*+,-./:;<=>?[]^`{|}~",29,-1);
  831.  
  832.                 fg_setcolor(15);
  833.                 fg_locate(12,26);
  834.                 fg_text("Software characters - font 2",28);
  835.  
  836.                 fg_setcolor(10);
  837.                 fg_movew(0.0,1.4);
  838.                 fg_swchar("\\ABCDEFGHIJKLMNOPRSTUWXYZ",25,-1);
  839.                 fg_movew(0.0,1.1);
  840.                 fg_swchar("\\abcdefghijklmnoprstuwxyz",25,-1);
  841.                 fg_movew(0.0,0.4);
  842.                 fg_swchar("\\012345678#$%&()*+/<=>?[]{}",27,-1);
  843.                 fg_waitkey();
  844.  
  845.                 fg_setmode(old_mode);
  846.                 fg_reset();
  847.              }
  848.  
  849.  
  850. If you compare the primary font strings with the alternate font strings,
  851. you'll see the alternate font contains fewer characters. For example, the
  852. letters Q and V (either upper or lower case) have no corresponding character
  853. in the alternate font. You might have also noticed the primary font does not
  854. support the full printable ASCII character set. Any character in a string
  855. passed to fg_swchar that does not have a corresponding character in the
  856. current font will display a blank character.
  857.  
  858.      In addition to the font change operator (the back slash character),
  859. fg_swchar recognizes three other operators. The superscript operator is a back
  860. slash followed by a caret (\^). It causes the next character to appear as a
  861. superscript. Similarly, the subscript operator is a back slash followed by a
  862. lower case v (\v); it causes the next character to appear as a subscript. The
  863. size of superscripted and subscripted characters is one half the height of the
  864. other characters. The underline operator is the underscore character (_). It
  865. causes all subsequent characters in the string to be underlined until another
  866. underscore character is found, or until the end of the string. When using
  867. these operators, be sure to include them as part of the string length count
  868. passed to fg_swchar.
  869.  
  870.      Example 7-11 illustrates the use of the font selection, superscript,
  871. subscript, and underline operators with fg_swchar. Again, because the back
  872. slash character has a special meaning in C and C++, we must use two
  873. consecutive back slashes to represent a single back slash within the string.
  874. The program displays four strings:
  875.  
  876.                                cos2  + sin2  = 1
  877.                                       H2O
  878.                                      U232
  879.                             One word is underlined.                            
  880.                                   Chapter 7:  Character Display Routines   141
  881.  
  882. The theta symbol in the first string is produced by displaying the character
  883. "h" in the alternate font. Note another font selection operator (\) appears
  884. immediately after the "h" to revert to the primary font. The first string also
  885. includes superscript operators (\^) to display the exponents in the equation.
  886. The second string includes a single subscripted character, while the third
  887. string shows how to display three consecutive subscripted characters. Finally,
  888. the fourth string illustrates how to underline characters.
  889.  
  890.      Note example 7-11 also uses fg_setratio. The first three strings are
  891. drawn with an aspect ratio of 2, making them twice as wide as they are high.
  892. The fourth string is drawn with an aspect ratio of 1 (Fastgraph's default
  893. aspect ratio for software characters), so the character height is the same as
  894. the character width. Also, the strings are centered instead of left justified
  895. as in the previous example.
  896.  
  897.                                  Example 7-11.
  898.  
  899.              #include <fastgraf.h>
  900.              void main(void);
  901.  
  902.              void main()
  903.              {
  904.                 int old_mode;
  905.  
  906.                 fg_initpm();
  907.                 old_mode = fg_getmode();
  908.                 fg_setmode(16);
  909.                 fg_setcolor(10);
  910.                 fg_initw();
  911.                 fg_setworld(0.0,6.39,0.0,3.49);
  912.                 fg_setratio(2.0);
  913.                 fg_setsizew(0.21);
  914.  
  915.                 fg_movew(3.2,3.0);
  916.                 fg_swchar("cos\\^2\\h\\ + sin\\^2\\h\\ = 1",25,0);
  917.  
  918.                 fg_movew(3.2,2.0);
  919.                 fg_swchar("H\\v2O   U\\v2\\v3\\v2",18,0);
  920.  
  921.                 fg_movew(3.2,1.0);
  922.                 fg_setratio(1.0);
  923.                 fg_swchar("One _word_ is underlined.",25,0);
  924.                 fg_waitkey();
  925.  
  926.                 fg_setmode(old_mode);
  927.                 fg_reset();
  928.              }
  929.  
  930.  
  931.      The fg_setangle routine defines the angle of rotation at which software
  932. characters are displayed. Its only argument is a floating point value that
  933. specifies the angle, measured in degrees counterclockwise from the positive x
  934. axis. If a program draws software characters before calling fg_setangle,
  935. Fastgraph will use its default angle of zero degrees (that is, the characters
  936. will be oriented horizontally).                                                
  937. 142   Fastgraph User's Guide
  938.  
  939.      In most programs, the alternate font is not needed. However, if you use
  940. the fg_swchar routine, Fastgraph will include the definitions of these
  941. characters in your program's data segment. To prevent wasting this space,
  942. Fastgraph includes the fg_swtext routine. The fg_swtext routine is same as
  943. fg_swchar, except it does not include the alternate font. Since the font
  944. selection operator does not apply when using fg_swtext, the routine simply
  945. ignores it. You should only use fg_swtext if do not use fg_swchar. If you use
  946. both routines, your program will still work correctly, but its data segment
  947. will contain an extra copy of the primary font definitions.
  948.  
  949.      Example 7-12 demonstrates the use of fg_setangle and fg_swtext. The
  950. program draws a series of strings of the form "nnn degrees", where nnn is a
  951. multiple of 15, radiating from the screen center. Each string appears at the
  952. specified angle. For example, the string "15 degrees" is drawn at an angle of
  953. 15 degrees.
  954.  
  955.                                  Example 7-12.
  956.  
  957.                 #include <fastgraf.h>
  958.                 #include <stdio.h>
  959.                 void main(void);
  960.  
  961.                 void main()
  962.                 {
  963.                    char string[24];
  964.                    int angle;
  965.                    int old_mode;
  966.  
  967.                    fg_initpm();
  968.                    old_mode = fg_getmode();
  969.                    fg_setmode(16);
  970.                    fg_setcolor(10);
  971.                    fg_initw();
  972.                    fg_setworld(0.0,6.39,0.0,3.49);
  973.                    fg_setsizew(0.21);
  974.  
  975.                    for (angle = 0; angle < 360; angle += 15) {
  976.                       fg_movew(3.2,1.75);
  977.                       fg_setangle((double)angle);
  978.                       sprintf(string,"     %3d degrees",angle);
  979.                       fg_swtext(string,16,-1);
  980.                       }
  981.                    fg_waitkey();
  982.  
  983.                    fg_setmode(old_mode);
  984.                    fg_reset();
  985.                 }
  986.  
  987.  
  988.      The final routine pertaining to software characters is fg_swlength, which
  989. returns the length of a specified string of software characters in world space
  990. units. The length is returned as the routine's floating point function value.
  991. The fg_swlength routine has two arguments -- a string of software characters,
  992. and an integer value specifying the number of characters in the string. As
  993. with fg_swchar and fg_swtext, the count includes any of the special operator
  994. characters.                                                                    
  995.                                   Chapter 7:  Character Display Routines   143
  996.  
  997.  
  998.      Example 7-13 demonstrates a typical use of the fg_swlength routine. The
  999. program displays the string "hello there." in light green against a gray
  1000. background in the middle of the screen. As in our previous software character
  1001. examples, the program uses mode 16 and first performs the necessary
  1002. initializations to use software characters. Following this, the program uses
  1003. fg_swlength to compute the length in world space units of the string. Note we
  1004. have added blank characters to each end of the string passed to fg_swlength;
  1005. this increases the length of the actual string and will effectively give the
  1006. gray rectangle an extended border on its left and right sides. The string
  1007. length returned by fg_swlength is multiplied by 0.5, giving the distance from
  1008. the middle of the screen to either side of the rectangle. The program then
  1009. uses this value to compute the minimum and maximum x coordinates passed to
  1010. fg_rectw. After drawing the gray rectangle, the program uses fg_swtext to draw
  1011. the string of software characters in the middle of the screen. It then waits
  1012. for a keystroke before restoring the original video mode and screen attributes
  1013. and returning to DOS.
  1014.  
  1015.                                  Example 7-13.
  1016.  
  1017.                #include <fastgraf.h>
  1018.                void main(void);
  1019.  
  1020.                void main()
  1021.                {
  1022.                   int old_mode;
  1023.                   double half;
  1024.  
  1025.                   fg_initpm();
  1026.                   old_mode = fg_getmode();
  1027.                   fg_setmode(16);
  1028.                   fg_initw();
  1029.                   fg_setworld(0.0,6.39,0.0,3.49);
  1030.                   fg_setsizew(0.21);
  1031.  
  1032.                   fg_setcolor(7);
  1033.                   half = fg_swlength(" Hello there. ",14) * 0.5;
  1034.                   fg_rectw(3.2-half,3.2+half,1.6,1.9);
  1035.  
  1036.                   fg_setcolor(10);
  1037.                   fg_movew(3.2,1.65);
  1038.                   fg_swtext("Hello there.",12,0);
  1039.                   fg_waitkey();
  1040.  
  1041.                   fg_setmode(old_mode);
  1042.                   fg_reset();
  1043.                }
  1044.  
  1045.  
  1046.  
  1047. Bitmapped Characters
  1048.  
  1049.      Bitmapped characters combine the properties of hardware and software
  1050. characters. Like hardware characters, they are a fixed size, but they are
  1051. almost always more visually appealing. Because they are not scalable, they do  
  1052. 144   Fastgraph User's Guide
  1053.  
  1054. not require floating point arithmetic, and therefore they are much faster than
  1055. software characters.
  1056.  
  1057.      Fastgraph makes no special provision for bitmapped characters because it
  1058. treats them as if they were any other bitmapped image. For example, to use a
  1059. five-pixel by five-pixel bitmapped font, you can construct characters as shown
  1060. here and then store these representations in an image array.
  1061.  
  1062.                            *       * * * *       * * * *
  1063.                          *   *     *       *   *
  1064.                        * * * * *   * * * *     *
  1065.                        *       *   *       *   *
  1066.                        *       *   * * * *       * * * *
  1067.  
  1068. The image display routines fg_drawmap and fg_drwimage, discussed in Chapter
  1069. 10, could then be used to display specific characters from the image array.
  1070. Also, the Fastgraph/Fonts add-on product greatly simplifies adding bitmapped
  1071. font support to Fastgraph applications.
  1072.  
  1073.  
  1074. Summary of Character Display Routines
  1075.  
  1076.      This section summarizes the functional descriptions of the Fastgraph
  1077. routines presented in this chapter. More detailed information about these
  1078. routines, including their arguments and return values, may be found in the
  1079. Fastgraph Reference Manual.
  1080.  
  1081.      FG_CHGATTR applies the current text display attribute to a given number
  1082. of characters, starting at the text cursor position. This routine leaves the
  1083. text cursor one column to the right of the last character changed (or the
  1084. first column of the next row if the last character is at the end of a row). It
  1085. has no effect in graphics video modes.
  1086.  
  1087.      FG_CHGTEXT displays a string of hardware characters, starting at the text
  1088. cursor position, using the existing text display attributes. This routine
  1089. leaves the text cursor one column to the right of the last character displayed
  1090. (or the first column of the next row if the last character is at the end of a
  1091. row). It has no effect in graphics video modes.
  1092.  
  1093.      FG_FONTSIZE enables the 8x8, 8x14, or 8x16 ROM BIOS character font for
  1094. strings displayed with fg_print and fg_text. This routine is meaningful only
  1095. in VGA and SVGA graphics video modes.
  1096.  
  1097.      FG_GETATTR returns the character attribute stored at the specified
  1098. position on the active video page. It has no effect in graphics video modes.
  1099.  
  1100.      FG_GETCHAR returns the character value stored at the specified position
  1101. on the active video page. It has no effect in graphics video modes.
  1102.  
  1103.      FG_GETXJUST returns the current horizontal justification setting for
  1104. strings displayed with fg_print or fg_printc.
  1105.  
  1106.      FG_GETYJUST returns the current vertical justification setting for
  1107. strings displayed with fg_print or fg_printc.                                  
  1108.                                   Chapter 7:  Character Display Routines   145
  1109.  
  1110.      FG_JUSTIFY defines the horizontal and vertical justification settings for
  1111. strings displayed with fg_print or fg_printc.
  1112.  
  1113.      FG_LOCATE establishes the text cursor position for the active video page.
  1114.  
  1115.      FG_PRINT displays a string of hardware characters, relative to the
  1116. graphics cursor position, using the current color index. By default, strings
  1117. are displayed such that the bottom row of the first character is at the
  1118. current graphics position. On return, the graphics cursor is positioned just
  1119. to the right of the last character displayed.
  1120.  
  1121.      FG_PRINTC is a version of fg_print that performs clipping.
  1122.  
  1123.      FG_SETANGLE defines the angle or orientation at which software characters
  1124. are displayed. The angle is measured in degrees counterclockwise from the
  1125. positive x axis.
  1126.  
  1127.      FG_SETATTR establishes the current text display attribute in text video
  1128. modes. This routine has no effect in graphics video modes.
  1129.  
  1130.      FG_SETCOLOR establishes the current color index (which may be a virtual
  1131. color index in graphics modes). In text modes, the fg_setcolor routine
  1132. provides an alternate method of establishing the current text display
  1133. attribute.
  1134.  
  1135.      FG_SETRATIO defines the aspect ratio for software characters. The aspect
  1136. ratio is the ratio of character width to character height.
  1137.  
  1138.      FG_SETSIZE defines the height of software characters in screen space
  1139. units.
  1140.  
  1141.      FG_SETSIZEW defines the height of software characters in world space
  1142. units.
  1143.  
  1144.      FG_SWCHAR displays a string of software characters using the current
  1145. color index. The string may be left justified, centered, or right justified
  1146. relative to the graphics cursor position. The string passed to fg_swchar may
  1147. contain special operators that allow switching between fonts, underlining,
  1148. superscripting, or subscripting. This routine has no effect in text video
  1149. modes.
  1150.  
  1151.      FG_SWLENGTH returns the length in world space units of a string of
  1152. software characters.
  1153.  
  1154.      FG_SWTEXT is a scaled down version of the fg_swchar routine. It does not
  1155. include the alternate font character definitions and thus requires less memory
  1156. than fg_swchar.
  1157.  
  1158.      FG_TEXT displays a string of hardware characters, starting at the text
  1159. cursor position, using the current color attribute (for text modes) or color
  1160. index (for graphics modes). This routine leaves the text cursor one column to
  1161. the right of the last character displayed (or the first column of the next row
  1162. if the last character is at the end of a row).
  1163.  
  1164.      FG_TEXTC is a version of fg_text that performs clipping when run in
  1165. graphics video modes. In text modes, fg_textc is equivalent to fg_text.        
  1166. 146   Fastgraph User's Guide
  1167.  
  1168.  
  1169.      FG_WHERE retrieves the row and column numbers of the text cursor
  1170. position.
  1171.  
  1172.      FG_XALPHA and FG_YALPHA convert screen space coordinates to character
  1173. space.
  1174.  
  1175.      FG_XCONVERT and FG_YCONVERT convert character space coordinates to screen
  1176. space.
  1177.