C for Yourself - part 44

Steve Mumford details some font-handling additions to AULIb

This month, I've worked on packaging the system calls we've seen over the last couple of columns into easy-to-use procedures within the AULib library file; with any luck they should make the process of font manipulation a little easier to bear. A short, single-tasking chunk of code to paint some text to the screen now looks something like the following; with- out the assorted paraphernalia of SWI registers and font flags, the source looks a lot simpler.

#include "AULib.h"

int main(void)
  int fontsize = 24*16;
  int fontres = 0;
  int font_handle = 0;
  font_handle = au_findfont("Homerton.Medium", fontsize, fontres);
  au_selectfont(font handle);
  au_setfontcolours(COLOUR_WHITE, COLOUR_RED);
  au_fontpaint("Hello World!", 500, 500);
  au_losefont(font handle);

Quickly running through the syntax, an_findfont() takes a pointer to a string followed by two integers - the string is the name of the font to be used, in standard Acorn nomenclature, and the integers are the font size and resolution respectively. The procedure returns a font handle as an integer value; this should be stored away for later use. When using the given arguments to find the font you requested, au_findfont() assumes that the values for font size and resolution are to be used for both x and y dimensions, but in most cases this should be sufficient. Once you're certain you won't be using a font any more - when a mode change has produced a mismatch between screen and font resolutions, for instance - calling au_losefont() with the integer font handle will dispose of it and clean up the font cache for you.

Selecting the font is performed by calling au_selectfont() with the font handle generated above as its only parameter; au_setfontcolours() takes two integer values for the background and foreground colours of the text respectively. I have #defined a few within the AULib header file; the ones used most frequently are likely to be COLOUR_BLACK and COLOUR_WHITE. They take the form of a four-byte hexadecimal number that looks like the one shown below, where the values substituted for BB, GG and RR are the levels of blue, green and red in the final colour.

int colour = OxBBGGRR00;

au_fontpaint() takes a pointer to a string followed by a pair of x and y coordinates - the procedure assumes they're in OS units, and plots the given text to the screen using the currently selected font and colours. Again, care should be taken when handling graphics update within a multitasking program, as there's no guarantee the font settings you last used will persist throughout the Wimp_Poll cycle. It's wise not to make any assumptions and you should re-select the font and colours when your program regains control.

On the subject of multitasking programs, I've included a conversion function to map coordinates relative to a particular window into their absolute positions on screen. Window offsets and scrolibar positions are taken into account, allowing the programmer to maintain objects without having to interrogate the pollblock and perform wodges of maths every screen update. The au_convertwindow_to_screen function takes three parameters; the first is a pointer to the data block containing the coordinates of the window and the scroll bar offsets, and the second and third are pointers to two integer variables. Using pointers in this way allows the function to update the coordinates directly, avoiding having to create special data structures in which to return the two converted values. An example of its use might be as follows:

x_coor = 25;
y_coor = -250;
au_convertwindow_to_screen(datablock, &x_coor, &y_coor);

Assuming datablock points to a block of memory in the format as returned by either Wimp_GetRectangle or Wimp_RedrawWindow, the function will take a note of the addresses of x_coor and y_coor, altering their contents directly so they can be used for plotting immediately after the function call. It would also be possible to write a function to perform the opposite conversion, allowing a program to take the coordinates of a mouse click and translate that to see at what position it occurred relative to the window.

Next time round, we'll move onto capturing output and sending it to an appropriate printer; this is similar to the process of redrawing a window within the WIMP environment. Although not perhaps as stimulating as one might wish, an application such as a label creation utility would allow us to make good use of all the knowledge we've gained to date we'll make a start on that next month.

Source: Acorn User - 188 - December 1997
Publication: Acorn User
Contributor: Steve Mumford