Functions

For a list of all the functions which are part of PROforma, including the prototype, exact behaviour and possible errors, you should have a look at the PROforma_ddf DATAdesign file.

Two kinds of PROforma access functions

There are two kinds of PROforma access functions. Most of them use coordinates which are passed as fixpoint values in user space. These functions all start with PF (for PROforma).

However, there are also commands which need parameters which are given directly in device space or pixels. These functions always start with the PFP prefix (for PROforma Pixels). Some commands are only available in one of the two flavours, and some in both. The PFP commands are mostly provided for efficient access from a window manager (like ProWesS). The functions which work in pixels, usually require you to pass the coordinates as integers. However, for accuracy, the drawing operators will always work in fixpoint representation.

Parameters

PROforma is a c (c68) programming library. However, it can also be called from other languages (e.g. assembler). The calling and register saving conventions for c68 are valid. This means that parameters are actually passed on the stack. All parameters are four bytes long and contain either an integer (int), a pointer to a string, or a fixpoint number.

Strings

Contrary to the approach which is usually taken by the operating system, we use null terminated strings (instead of preceding them by the length).

Another problem is that we use two kinds of strings. We have the C standard null terminated strings which contain character codes using the local character set (one byte per character), and we have unicode strings, in which each character is represented by a word (2 bytes). The use of unicode allows us to have character sets which contain more than 256 characters, and have all characters at a fixed spot. Most general characters (about codes 32 to 126) are at about the same position as in the ASCII character set.

fixpoint - pt

This is actually just a representation of a decimal character which can be processed faster than standard floating points. This is done by dividing the actual representation in two parts: an integer part and a fractional part. Each part occupies two bytes in a long word. The most significant bytes are the integer part, and the least significant bytes are the fractional part, expressed as multiples of 1/65536. In binary representation, this means that there is an imaginary dot between the two words in a long word.

Fixpoint numbers can be added and subtracted just as normal integers. A special routine (fixmul) has to be used when you want to multiply them. Some macros are available in "PROforma_h" to manipulate fixpoint values more easily.

/*
    most parameters which are passed to PROforma are fixpoints,
    as they give more accuracy than integers, and more speed
    than floats or doubles. A fixpoint number is actually a long,
    with an imaginary dot between the two words. This convention
    allows for fast adding and multiplication, without loosing
    too much accuracy.
*/

#include "err_h"

typedef long pt;
#define pt_one 0x10000
#define pt_half 0x8000
#define pt_quarter 0x4000
#define pt_hundred 0x640000
#define ptmin 0xc0000000
#define ptmax 0x3fffffff
#define ptmagic 36045           /* .55 in fixpoint */
#define ptcigam 29491           /* .45 in fixpoint */

/*
    Most operations can be done directly on fixed-points :
    addition, subtraction, shifting, multiplication or
    division by integer constants; assignment, assignment
    with zero;  comparison, comparison against zero.
    Multiplication and division by floats is OK if the result
    is explicitly cast back to fixed.
    Conversion to and from int and float types must be done
    explicitly.  Note that if we are casting a fixed to a
    float in a context where only ratios and not actual values
    are involved, we don't need to take the scale factor into
    account: we can simply cast to float directly.
*/

#define long2pt(x) ((pt)((x)<<16))
#define short2pt(x) ((pt)(x)<<16)
#define pt2short(x) ((short)((x)/65536))
#define pt2rshort(x) pt2short((x)+pt_half)
#define pt2long(x) ((long)((x)/65536))
#define pt2rlong(x) pt2long((x)+pt_half)
#define double2pt(x) ((pt)((x)*(double)65536.0))
#define pt2double(x) ((double)((x)/(65536.0)))

/* Rounding and truncation on fixeds */
#define pt_trunc(x) ((x)&(0xffff0000))
#define pt_round(x) pt_trunc(x+pt_half)
#define pt_ceiling(x) pt_trunc(x+pt_one)
#define pt_fraction(x) ((x)&0xffff)
#define pt_center(x) (pt_trunc(x)+pt_half)

/* special multiplication routine for fixpoint coordinates */
pt fixmul(pt x, pt y);  /* returns x*y  */

PROGS, Professional & Graphical Software
last edited June 28, 1996