C for Yourself - part 41

Steve Mumford introduces Acorn's outline font manager

Providing our own dedicated window redrawing functions has opened up a whole range of possibilities — the inclusion of custom sprites can provide your desktop application with a distinctive look and allows the creation of some simple games. Although the standard sprite calls aren't fast enough for large-scale window-based arcade games, they're good enough for simple puzzles. Because you can even redirect graphical output to a sprite, it's even possible to write a functional, although basic, sprite editing application with the knowledge we've gained.

However, sprites aren't the end of the road, and there are other goals on which to set our sights. One particular aim that I'll be working towards is the ability to send output to a printer — thanks to Acorn's printer driver system, this is very similar to the process of redrawing a window, and as long as you program carefully, the two processes can share some of the same functions. We've got a few things to cover before we reach that stage — the one I thought I'd turn to next is the process of plotting outline fonts on the screen.

Preparing to plot an outline font is a little like opening a file for read access — you have to locate the font you wish to use and ask RISC OS to give you a unique handle, then select that font and set up certain parameters such as size and resolution before it's possible to print. Once you've finished using a particular font, it's important to tell RISC OS you don't need it any longer — this way it can remove it from the font cache and free up valuable memory.

The SWI calls we'll be using are Font_FindFont and Font_LoseFont to locate and discard individual fonts respectively, Font_Paint to display a string at a given location on screen, and ColourTrans_SetFontColours to choose an appropriate palette to support antialiasing. Here's a code sample to show how you request the initial font handle:

char font_name[] = "Trinity.Medium";
int font_handle = 0;
int font_size = 24 * 16; /* size in l6ths of a point */
int font_res = 0; /* Use the default font resolution /
int font_flags = 1 << 4;

_kernel_swi_regs in, out;

in.r[1] = (int) font_name;
in.r[2] = in.r[3] = font_size;
in.r[4] = in.r[5] = font_res;
_kernel_swi(Font_FindFont, &in, &out);
font_handle = out.r[0];

If you've had a dig around in the !Fonts directory on your machine, you'll recognise the format of the font descriptor — when passing this to Font_FindFont, you should ensure the string is terminated with a control charac- ter. Under normal circumstances this won't be a problem, but it's worth bearing in mind. As we've seen in other examples, the string is passed to the SWI by reference to its address in memory, converted to an integer.

The font size is specified in l6ths of a point, so the font size I'm requesting above is 24 point. Registers 2 and 3 hold the x and y dimensions of the chosen font, so it's possible to select something other than the standard aspect ratio. Registers 4 and 5 hold the x and y resolutions of the font — setting these to zero indicates that you re happy with the standard resolution.

Font_FindFont will then return a font handle in RO — this can be used in a wide range of font-related SWI calls and once each font has been set up in this way, swapping between them is a simple process. It can even be done part-way through painting a line of text to the screen.

Although there's a Font_SetPalette SWI, this can only be used by single-tasking applications and when writing programs to run in the multitasking WIMP environment, more cooperative methods should be used. The ColourTrans module comes into play once more and I have used the ColourTrans_SetFontColours SWI to prepare an appropriate antialiased palette. The call takes four parameters, shown below:

in.r[0] = 0;
in.r[1] = 0xffffff00;
in.r[2] = 0x00000000;
in.r[3] = 14;
_kernel_swi(ColourTrans_SetFontColours, &in, &out);

A zero in RO informs ColourTrans to set the colours of the currently selected font and the next two registers hold the palette entries of the background and foreground colours respectively. Finally, the value in R3 tells ColourTrans how many colour steps are desired between foreground and background — a value of 14 is the maximum, and is a good value to use in order to perform optimum antialiasing.

All that remains is to select the font using the returned font handle, and paint some text on the screen — I'll cover this next month as well as introducing some particularly useful font manipulation tools.

See you then.


Source: Acorn User - 185 - September 1997
Publication: Acorn User
Contributor: Steve Mumford