Chapter 7 - Extended Primitives

This chapter describes the functions in the Extended Primitives Library. 
The Core Primitives Library is described in the preceding chapter.

Remember to call the set_config function (a member of the Core 
Primitives Library) to initialize the drawing environment before 
you call any of the other functions in the Core and 
Extended Primitives Libraries.

The table below summarizes the 58 functions in the Extended 
Primitives Library. The remainder of this chapter is an alphabetical, 
detailed description of the syntax, usage, and operation of each function. 
These descriptions are augmented by complete example programs that can 
be compiled and run exactly as written.

Function Name	       Description

bitblt		       Transfer bit-aligned block

decode_rect		Decode rectangular image

delete_font		Delete font

draw_line		Draw line 

draw_oval 		Draw oval

draw_ovalarc		Draw oval arc

draw_piearc		Draw pie arc

draw_point		Draw point

draw_polyline		Draw polyline

draw_rect 		Draw rectangle

encode_rect		Encode rectangular image

fill_convex		Fill convex polygon

fill_oval		Fill oval   

fill_piearc		Fill pie arc

fill_polygon		Fill polygon

fill_rect		Fill rectangle  

frame_oval		Fill oval frame

frame_rect		Fill rectangular frame

get_env 	       Get graphics environment information

get_pixel 		Get pixel

get_textattr		Get text attributes

in_font 		Verify characters in font

install_font		Install font

move_pixel		Move pixel

patnfill_convex 	Fill convex polygon with pattern

patnfill_oval		Fill oval with pattern

patnfill_piearc 	Fill pie arc with pattern

patnfill_polygon	Fill polygon with pattern

patnfill_rect		Fill rectangle with pattern

patnframe_oval		Fill oval frame with pattern

patnframe_rect		Fill rectangular frame with pattern

patnpen_line		Draw line with pen and pattern

patnpen_ovalarc        Draw oval arc with pen and pattern

patnpen_piearc	       Draw pie arc with pen and pattern

patnpen_point	       Draw point with pen and pattern

patnpen_polyline	Draw polyline with pen and pattern

pen_line		Draw line with pen

pen_ovalarc		Draw oval arc with pen

pen_piearc		Draw pie arc with pen

pen_point 		Draw point with pen

pen_polyline		Draw polyline with pen

put_pixel		Put pixel 

seed_fill		Seed fill  

seed_patnfill		Seed fill with pattern

select_font		Select font

set_draw_origin 	Set drawing origin

set_dstbm 		Set destination bit map

set_patn		Set fill pattern

set_pensize		Set pen size

set_srcbm 		Set source bit map

set_textattr		Set text attributes

styled_line		Draw styled line

styled_oval		Draw styled oval

styled_ovalarc		Draw styled oval arc

styled_piearc		Draw styled pie arc

swap_bm 		Swap source and destination bit maps

text_width		Get width of text string

zoom_rect 		Zoom rectangle

void bitblt(w, h, xs, ys, xd, yd)
short w, h;		/* width and height of both bit maps */
short xs, ys;		/* source array coordinates */
short xd, yd;		/* destination array coordinates */

The bitblt  function copies a two-dimensional array of pixels from 
the current source bit map to the current destination bit map. 
The source and destination bit maps are specified by calling the 
set_srcbm and set_dstbm  functions before 
calling the bitblt function. Calling the set_config function 
with the init_draw argument set to true causes both the
source and destination bit maps to be set 
to the default bit map, which is the screen.

The source and destination arrays are assumed to be rectangular, 
two-dimensional arrays of pixels. The two arrays are assumed to be 
of identical width and height. The bitblt function accepts source 
and destination arrays that have the same pixel size. If the pixel 
sizes are not equal, the pixel size for either the source or the destination
must be 1. Other combinations of 
source and destination pixel sizes are not accepted by the function.

Arguments w and h specify the width and height common to the
source and destination arrays. Arguments xs and ys specify the
x-y coordinates of the top left corner (lowest memory address) 
of the source array as a displacement from 
the origin (base address) of the source bit map. Arguments xd 
and yd specify the x-y coordinates of the top left corner of 
the destination array as a displacement from the origin of
the destination bit map.

If the source and destination pixel sizes are equal, then pixels 
in the source array are copied to the destination. During the 
copying process, the pixels may be modified, depending 
on the current pixel-processing operation, transparency 
mode, and plane mask.

If the source bit map's pixel size is 1 and the destination pixel 
size is greater than 1, source pixels are expanded to 
color in the destination array. During the expansion process, 
pixels corresponding to 1s in the source bit map 
are expanded to the current foreground color before being 
drawn to the destination; 0s are expanded to the current 
background color.

If the destination bit map's pixel size is 1 and the source 
pixel size is greater than 1, bitblt  performs a contract function on
the source before writing to the destination. During the contraction 
process, destination pixels are set to 0 if they correspond to source 
pixels that are equal to the background color; all other destination 
pixels are set to 1.

When the source or destination bit map is the screen, the 
specified source or destination coordinates are defined relative 
to the current drawing origin. In the case of a linear bit map 
contained in an off-screen buffer, the bitblt 
function calculates the memory address of a pixel 
from the specified x and y coordinates as follows:

address  =  baseaddr + y*(pitch) + x*(psize) 

where baseaddr, pitch, and psize are the argument values passed 
to the set_dstbm or set_srcbm function.

When the destination bit map is set to the screen, the 
function clips the destination bit map to the current rectangular
clipping window. When the source bit map is set to the screen and 
any portion of the source array lies in negative screen coordinate space, 
the source rectangle is clipped to positive x-y coordinate space; 
in most systems this means that the source is clipped to 
the top and left edges of the screen. The resulting clipped 
source rectangle is copied to the destination rectangle and 
justified to the lower right corner of the specified destination rectangle. 
Portions of the destination array corresponding to clipped portions 
of the source are not modified.

The clipping window for a linear bit map encloses the pixels 
in the x-y coordinate range (0,0) to (xext, yext), where xext 
and yext are arguments passed to set_dstbm or set_srcbm. 
The bitblt function itself performs no clipping in the case of a 
linear bit map; responsibility for clipping is left 
to the calling routine.

If both source and destination bit maps are set to the screen, 
then the function correctly handles the case in which the
rectangular areas containing the source and destination 
bit maps overlap. In other words, the order in which 
the pixels of the source are copied to the destination 
is automatically adjusted to prevent any portion of 
the source from being overwritten before it 
has been copied to the destination.

Use the bitblt function to color-expand an image contained 
in a 1-bit-per-pixel bit map to the screen. The original image 
is 16 pixels wide, 40 pixels high, 
and has a pitch of 16. Use the zoom_rect 
function to zoom the screen image by a factor of 5.

#define  PITCH	16     /* pitch of image bit map */
#define  W	16     /* width of image bit map */
#define  H	40     /* height of image bit map */
#define  IMAGEDEPTH   1      /* pixel depth of image bit map */
#define  SCREENDEPTH  4      /* pixel depth of screen */
#define  ZOOM	5      /* zoom factor */

typedef enum { FIELDWIDTH = 1 } BIT;

static BIT image[] = {
    0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
    0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,
    0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,
    0,0,1,1,0,0,0,1,1,1,1,1,0,0,0,0,
    0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,
    0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,
    0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,
    0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,
    0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,
    0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,
    1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,
    1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,0,
    1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,
    1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
    1,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
    1,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,
    0,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,
    1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,
};

main()
{
    char buf[ZOOM*W*SCREENDEPTH/8]; /* zoom_rect buffer */

    set_config(0, !0);
    clear_screen(0);
    set_srcbm(image, PITCH, W, H, IMAGEDEPTH);
    bitblt(W, H, 0, 0, 10, 10);
    set_srcbm(0);
    zoom_rect(W, H, 10, 10, ZOOM*W, ZOOM*H, 20+W, 10, buf);
}

typedef unsigned long PTR;	/* 32-bit GSP memory address */

short decode_rect(xleft, ytop, buf)
short xleft, ytop;	/* top left corner */
PTR buf;		/* image buffer */

The decode_rect function restores a previously compressed 
image to the screen. The image was previously encoded by 
the encode_rect function. The image is rectangular and is restored at the 
same width, height, and pixel size as the image originally 
encoded by the encode_rect function.

The first two arguments, xleft and ytop, specify the x 
and y coordinates at the top left corner of the destination 
rectangle and are defined relative to the 
drawing origin.

The final argument, buf, is a pointer to a buffer
in the TMS340 graphics processor's memory in which
the compressed image is stored.

The function returns a nonzero value if it has successfully 
decoded the image; otherwise, the return value is 0.

Refer to the description of the encode_rect function for a
discussion of the format in which the compressed
image is saved.

Use the decode_rect function to decompress multiple 
copies of a rectangular image that was previously
captured from the screen by the encode_rect function.

#define  MAXSIZE      4096    /* max picture size in bytes */

static char image[MAXSIZE];

main()
{
    short w, h, x, y, n;
    char *s;

    set_config(0, !0);
    clear_screen(-1);

    /* Create an image on the screen. */
    w = 100;
    h = 80;
    x = 10;
    y = 10;
    frame_rect(w, h, x, y, 4, 3);
    frame_oval(w-8, h-6, x+4, y+3, 4, 3);
    s = "IMAGE";
    n = text_width(s);
    text_out(x+(w-n)/2, y+h/2, s);

    /* Compress image. */
    encode_rect(w, h, x, y, image, sizeof(image), 0);

    /* Now decompress the image several times. */
    for (n = x ; n <= x + w; n += 16)
	decode_rect(n, n, image);
}

short delete_font(id)
short id;		/* font identifier */

The delete_font  function removes from the font table 
the installed font designated by an identifier. The font 
is identified by argument id, which 
contains the value returned from the install_font function 
at the time the font 
was installed.

A nonzero value is returned if the font was successfully 
removed. A value of 0 is returned if argument id is invalid;
that is, if id does not correspond to an installed font.

If the font removed was also the one selected for current 
text drawing operations, the system font is automatically 
selected by the function. A request to delete the system 
font (id = 0) will be ignored by the function, and 
a value of 0 will be returned.

Use the delete_font function to delete a font that was 
previously installed. First, install and select three fonts. 
The first and third fonts installed by the example program
are proportionally spaced fonts. The second font is a  
block font. The three fonts are used to write three lines
of text to the screen. At this point, the block font is 
deleted with the delete_font function, 
and another proportionally spaced font is installed
in its place. An additional three lines of text are written 
to the screen using the three installed fonts. 
This example includes the C header file gsptypes.h, 
which defines the FONT and 
FONTINFO structures. The TI Roman font 
sizes 11, 14, and 16 must be linked with 
the program.

#include <gsptypes.h>	/* defines FONT and FONTINFO structures */

#define NFONTS	3	/* number of fonts installed */
#define NLINES	2	/* number of lines of text per font */

extern FONT sys16, ti_rom11, ti_rom14, ti_rom16;/* 4 font names */

main()
{
    FONTINFO fontinfo;
    short index[NFONTS];
    int i, j, x, y;

    set_config(0, !0);
    clear_screen(0);
    index[0] = install_font(&ti_rom11);
    index[1] = install_font(&sys16);	/* install block font */
    index[2] = install_font(&ti_rom16);
    x = y = 10;
    for (i = 0; i < 2; i++) {
       for (j = 0; j < NFONTS; j++) {
           select_font(index[j]);
           get_fontinfo(index[j], &fontinfo);
           text_out(x, y, "Output text in new font.");
           y += fontinfo.charhigh;
       }
       y += fontinfo.charhigh;
       delete_font(index[1]); /* delete block font */
       index[1] = install_font(&ti_rom14);
    }
}

void draw_line(x1, y1, x2, y2)
short x1, y1;		/* start coordinates */
short x2, y2;		/* end coordinates */

The draw_line function uses Bresenham's algorithm to 
draw a straight line from the starting point to the ending point. 
The line is one pixel thick and is 
drawn in the current foreground color.

Arguments x1 and y1 specify the starting x and y coordinates 
of the line, and arguments x2 and y2 specify the ending coordinates.

In the case of a line that is more horizontal than vertical, the 
number of pixels used to render the line is 1 + |x2 - x1|. The 
number of pixels for a line that is more vertical than 
horizontal is 1 + |y2 -y1|.

Use the draw_line function to draw a line 
from (10, 20) to (120, 80).

main()
{
    short x1, y1, x2, y2;

    set_config(0, !0);
    clear_screen(0);
    x1 = 10;
    y1 = 20;
    x2 = 120;
    y2 = 80;
    draw_line(x1, y1, x2, y2);
}

void draw_oval(w, h, xleft, ytop)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */

The draw_oval function draws the outline of an ellipse, given the 
enclosing rectangle in which the ellipse is inscribed. The ellipse 
is in standard position, with its major and minor axes parallel to the 
coordinate axes. The outline of the ellipse is one pixel thick 
and is drawn in the current foreground color.

The four arguments specify the rectangle enclosing the ellipse:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top left corner 
	of the rectangle and are defined relative to the drawing origin.

Use the draw_oval function to draw an ellipse. The ellipse is 130 pixels wide 
and 90 pixels high. Also, draw a rectangle that circumscribes the ellipse.

main()
{
    short w, h, x, y;

    set_config(0, !0);
    clear_screen(0);
    w = 130;
    h = 90;
    x = 10;
    y = 10;
    draw_oval(w, h, x, y);
    draw_rect(w, h, x, y);
}

void draw_ovalarc(w, h, xleft, ytop, theta, arc)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */
short theta;		/* starting angle (degrees) */
short arc;		/* angle extent (degrees) */

The draw_ovalarc function draws an arc taken from an ellipse. The ellipse is in 

standard position, with the major and minor axes parallel to the coordinate 
axes. The ellipse from which the arc is taken is specified in terms of the 
enclosing rectangle in which it is inscribed. The arc is one pixel thick and is 
drawn in the current foreground color.

The first four arguments specify the rectangle enclosing the ellipse from which 
the arc is taken:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top left 
	corner of the rectangle and are defined relative to the drawing origin.

The last two arguments define the limits of the arc and are specified in 
integer degrees:

	Argument theta specifies the starting angle and is measured  from 
	the center of the right side of the enclosing rectangle.

	Argument arc specifies the arc's extent - that is, the number of 
	degrees (positive or negative) spanned by the angle. 

Both arguments are expressed in degrees of elliptical arc, with 360 degrees 
representing one full rotation around the ellipse. For both arguments, positive 

angles are in the clockwise direction, and negative angles are 
counterclockwise. Argument theta is treated as modulus 360. If the value of 
argument arc is outside the range [-359,+359], the entire ellipse is drawn.

Use the draw_ovalarc function to draw an arc that extends from 21 
degrees to 300 degrees. The ellipse from which the arc is taken
is 130 pixels wide and 90 pixels high. Also, draw a rectangle 
enclosing the arc and draw two rays from the center of the ellipse
through the start and end points of the arc.

#define  PI  3.141592654
#define  K   (PI/180.0)       /* convert degrees to radians */

main()
{
    extern double cos(), sin();
    double a, b;
    short w, h, x, y;

    set_config(0, !0);
    clear_screen(0);
    w = 130;
    h = 90;
    x = 40;
    y = 50;
    draw_rect(w, h, x, y);
    draw_ovalarc(w, h, x, y, 21, 300-21);

    /* Now draw the two rays. */
    set_draw_origin(x+w/2, y+h/2);
    a = w;
    b = h;
    x = a*cos(21.0*K) + 0.5;
    y = b*sin(21.0*K) + 0.5;
    draw_line(0, 0, x, y);
    text_out(x, y, " 21");     /* label ray at 21 degrees */
    x = a*cos(300.0*K) + 0.5;
    y = b*sin(300.0*K) + 0.5;
    draw_line(0, 0, x, y);
    text_out(x, y, " 300");    /* label ray at 300 degrees */
}

void draw_piearc(w, h, xleft, ytop, theta, arc)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */
short theta;		/* starting angle (degrees) */
short arc;		/* angle extent (degrees) */

The draw_piearc function draws an arc taken from an ellipse. Two straight
lines connect the two end points of the arc with the center of the ellipse. 
The ellipse is in the standard position, with the major and 
minor axes parallel to the coordinate axes. The ellipse from 
which the arc is taken is specified in terms of the enclosing rectangle
in which it is inscribed. The arc and the two 
lines are all one pixel thick and are drawn in the 
current foreground color.

The first four arguments specify the rectangle enclosing the ellipse from which 
the arc is taken:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top left corner 
	of the rectangle and are defined relative to the drawing origin.

The last two arguments define the limits of the arc and are specified in 
integer degrees:

	Argument theta specifies the starting angle and is measured from the 
	center of the right side of the enclosing rectangle.

	Argument arc specifies the arc's extent - that is, the number of 
	degrees (positive or negative) spanned by the angle. 

Both arguments are expressed in degrees of elliptical arc, with 360 degrees 
representing one full rotation around the ellipse. For both arguments, 
positive angles are in the clockwise direction, and negative angles are 
counterclockwise. Argument theta is treated as modulus 360. If the value
of argument arc is outside the range [-359,+359], the entire ellipse is drawn.

Use the draw_piearc function to draw a pie chart corresponding to a slice of an 
ellipse from 21 degrees to 300 degrees. The ellipse is 130 pixels wide and 90 
pixels high. Draw an enclosing rectangle of the same dimensions.

main()
{
    short w, h, x, y;

    set_config(0, !0);
    clear_screen(0);
    w = 130;
    h = 90;
    x = 10;
    y = 10;
    draw_piearc(w, h, x, y, 21, 300-21);
    draw_rect(w, h, x, y);
}

void draw_point(x, y)
short x, y;		/* pixel coordinates */

The draw_point function draws a point represented as a single pixel. Arguments 
x and y specify the x-y coordinates of the designated pixel and are defined 
relative to the drawing origin. The pixel is drawn in the current foreground 
color.

Use the draw_point function to draw a circle of radius 60 in the top left 
corner of the screen. Each point on the circle is separated from its two 
neighbors by angular increments of approximately 1/8 radian.

#define  TWOPI	411775   /* fixed-point 2*PI */
#define  HALF	32768    /* fixed-point 1/2 */
#define  RADIUS   	60       /* radius of circle */
#define  N		3        /* angular increment = 1/2**N 
                                             radians */

typedef long FIX;	/* fixed-pt with 16-bit fraction */

main()
{
    short x, y;
    int i;
    FIX u, v, xc, yc;

    set_config(0, !0);
    clear_screen(0);
    u = 0;
    v = RADIUS << 16;	  /* convert to fixed-pt */
    xc = yc = v + HALF;   /* fixed-pt center coord's */
    for (i = (TWOPI << N) >> 16; i >= 0; i--) {
	x = (u + xc) >> 16;
	y = (v + yc) >> 16;
	draw_point(x, y);
	u - = v >> N;
	v + = u >> N;
    }
}

typedef struct { short x, y; } POINT;

void draw_polyline(n, vert)
short n;		/* vertex count */
POINT *vert;		/* vertex coordinates */

The draw_polyline function draws multiple, connected lines. An array
of integer x-y coordinates representing the polyline vertices is specified
as one of the arguments. A straight line is drawn between each pair of
adjacent vertices in the array. Each line is constructed with Bresenham's
algorithm, is one pixel thick, and is drawn in the current foreground color.

Argument n specifies the number of vertices in the polyline; the
number of lines drawn is n-1.

Argument vert is an array of x-y coordinates representing the 
polyline vertices in the order in which they are to be traversed. 
The x-y coordinate pairs 0 through n-1 of the vert array 
contain the coordinates for the n vertices. The function 
draws a line between each adjacent pair of vertices in the array. 
Each vertex is represented by a 16-bit x-coordinate value followed 
by a 16-bit y-coordinate value. Coordinates are specified relative
to the drawing origin.

Note that for the polyline to form a closed polygon, the calling 
program must ensure that the first and last vertices in the 
vert array are the same.

Use the draw_polyline function to draw a three-segment polyline. 
The four vertices are located at coordinates 
(0, 0), (60, 70), (120, 10), and (120, 80).

#define  NVERTS    4	 /* number of vertices */

typedef struct { short x, y; } POINT;

static POINT xy[NVERTS] =
{
    { 0, 0 }, { 60, 70 }, { 120, 10 }, { 120, 80 }
};

main()
{
    set_config(0, !0);
    clear_screen(0);
    draw_polyline(NVERTS, xy);
}

void draw_rect(w, h, xleft, ytop)
short w, h;		/* rectangle width and height */
short xleft, ytop;	/* top left corner */

The draw_rect  function draws the outline of a rectangle. The 
rectangle consists of two horizontal and two vertical lines. 
Each line is one pixel thick and is drawn in the 
current foreground color.

The four arguments specify the rectangle:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top
	left corner of the rectangle and are defined relative to the 
	drawing origin.

The draw_rect function is equivalent to the following four calls to the  
draw_line function:                  

draw_line(xleft, ytop, xleft+w, ytop); 

draw_line(xleft, ytop+h, xleft+w, ytop+h); 

draw_line(xleft, ytop+1, xleft, ytop+h-2);

draw_line(xleft+w, ytop+1, xleft+w, ytop+h-2);

Use draw_rect function to draw a rectangle that is 130 pixels 
wide and 90 pixels high.

main()
{
    set_config(0, !0);
    clear_screen(0);
    draw_rect(130, 90, 10, 10);
}

typedef unsigned long PTR;	/* 32-bit GSP memory address */

unsigned long encode_rect(w, h, xleft, ytop, buf, bufsize,
	 	scheme)
short w, h;		/* rectangle width and height */
short xleft, ytop;	/* top left corner */
PTR buf;		/* image buffer */
unsigned long bufsize;	/* buffer capacity in bytes */
unsigned short scheme;	/* encoding scheme */

The encode_rect function uses the specified encoding scheme to save
an image in compressed form. The image to be saved is contained 
in a specified rectangular portion of the screen. The function 
compresses the image and saves it in a specified destination buffer.

Once an image has been encoded by the encode_rect function, 
it can be decompressed and restored to a designated area 
of the screen by the decode_rect  function. The image is restored 
at the same width, height, and pixel size as 
the original image saved by the encode_rect  function.

The first four arguments specify the rectangular region 
of the screen containing the original image:

	Arguments w and h specify the width and height (in pixels) of the 
	rectangle containing the image.

	Arguments xleft and ytop specify the x and y coordinates at the top 
	left corner of the rectangle and are defined relative to the drawing 
	origin.

The next two arguments specify the destination array for the compressed image:

	Argument buf  is a pointer to the destination array.

	Argument bufsize is the storage capacity of the buf  array in bytes.

The final argument, scheme, specifies the encoding scheme to be used. 
Currently, only run-length encoding is supported, for which the value of scheme 
 must be specified as 0.

The value returned by the function is the number of 8-bit bytes
required to encode the image, including the header. If the return
value is nonzero and positive, but less than or equal to the size of 
the output buffer (as specified by the bufsize argument), then the 
encoding is complete. If the value returned by the function is greater
than bufsize, the specified buffer was not large enough to contain 
the encoded data. In this case, the encode_rect function 
should be called again with a larger buffer. A value of 0 is 
returned if the function is unable to perform any encoding. 
This can happen if argument bufsize is specified as 0 or if the 
intersection of the rectangle to be encoded and the 
clipping rectangle is empty.

If the original image lies only partially within the current clipping 
window, only the portion of the image lying within the window is 
encoded. When the encoded image is later restored by the 
decode_rect  function, only the encoded portion of the image 
is restored. Relative to the enclosing rectangle, this 
portion of the restored image occupies the same position as in the 
original image. If the original image lies entirely outside the 
clipping window, the encoded image is empty.

Currently, the only encoding scheme supported by the 
function is run-length encoding. This is a simple but effective
image-compression technique that stores each horizontal line 
of the image as a series of color transitions. The 
color for each transition is paired with the number 
of times the color is repeated (the length of the run) 
before the next color transition. To illustrate, a run of 7 yellow 
pixels followed by a run of 5 red pixels could be 
stored as   [ 7 ] [ yellow ] [ 5 ] [ red ]. As expected, the 
greatest amount of compression is achieved in the 
case of images that contain large regions of 
uniform color.

The compressed image format consists of a 20-byte header 
followed by the data representing the image in compressed form. 
The header structure is invariant 
across all encoding schemes and is defined as follows:

typedef struct {
    unsigned short magic;	/* magic number */
    unsigned long length;  	/* length of data in bytes */
    unsigned short scheme; 	/* encoding scheme */
    short width, height;  	/* dimensions of image rectangle */
    short psize;	/* pixel size of image */
    short flags;	/* usage varies with scheme */
    unsigned long clipadj;  	/* x-y clipping adjustments */
} ENCODED_RECT;

The fields of the ENCODED_RECT data structure above are used as follows:

magic	A TIGA data structure identifier. The value for 
	this data structure is 0x8101.

length	The length of the entire compressed image in bytes, including the 
	header. This value is useful for allocating memory for a data 
	structure and for reading it from a disk.

scheme	The type of encoding scheme that was used to encode the rectangle. Only 

	one scheme is currently supported: scheme = 0 - run-length encoding.

width	The width of the rectangle containing the original image.

height	The height of the rectangle containing the original image.

psize	The original pixel size of the encoded image. This value is 1, 2, 4, 8, 
	16, or 32.

flags	Reserved for future enhancements. Bits in this field are currently set 
	to 0.

clipadj  Set to 0 except in the case in which the top left corner of the
	original image rectangle is located above or to the left of the 
	clipping  window. In this case, the clipadj field
	contains the concatenated x and y
	displacements of the top left corner of the clipping window from the 
	top left corner of the image. (The x displacement
	is in the 16 LSBs, and the y displacement in the
	16 MSBs.) If the left edge of the window is to the right of
	the left edge of the image, the x displacement is set to the positive 
	distance between these two edges; otherwise it is 0.
	If the top edge of the window is below the top edge
	of the image, the y displacement is set to the positive
	distance between these two edges; otherwise it is 0. 

The encoded image immediately follows the clipadj field. This data is of 
variable length, and its format depends on the encoding scheme used to compress 
the image.

The run-length encoded image consists of a number of run-length encoded 
horizontal scan lines; the number of lines is given by the height entry in the 
ENCODED_RECT structure. Each line is encoded according to the following format:

    [REPSIZ] [OPSIZ] [OPCODE] [DATA] [OPCODE] [DATA]...

The REPSIZ and OPSIZ fields, which appear at the start of each line, are 
defined as follows:

REPSIZ	Bits 0-2 specify the size of the repeating data. Repeating data can be 
	1, 2, 4, 8, 16, or 32 bits in length. REPSIZ is the log to the base 2 
	of the data size (that is, 1 shifted
	left by the value of REPSIZ will give the size of
	the repeating data).

OPSIZ	Bits 3-7 specify the length in bits of the OPCODE entry. This can be a 
	value between 1 and 32 indicating the signed 
	integer size of OPCODE. For example, if the value of OPSIZ
	is 8, then OPCODES are 8-bit signed integers. If 
	OPSIZ is 3, then OPCODES are 3-bit signed integers. 
	Beginning with bit 8, the remainder of the line consists of a
	variable number of [OPCODE] [DATA] 
	sequences. If the opcode value is positive, it indicates a repeating
	sequence and will be followed by 1, 2, 4, 8, 16, or 32 bits 
	worth of repeating data, as indicated by REPSIZ. If the opcode 
	is negative, then it is followed by n pixels 
	of absolute (unencoded) data, where n is the absolute value 
	of the OPCODE, and the pixel size is specified in the PSIZE
	field of the ENCODED_RECT structure.

Within each line of the image, the absolute value of all the opcodes read 
equals  the  width  of  the  encoded  rectangle. This fact is utilized by the  
decode_rect function during decompression of the image.

Use the encode_rect function to capture a rectangular image from the 
screen. Verify that the image buffer used by the encode_rect function 
is large enough to contain the entire compressed image. Use the 
decode_rect function to decompress the image to a different region 
of the screen to verify that the image was captured correctly 
by the encode_rect function.

#define  MAXSIZE      4096    /* max picture size in bytes */

static char picture[MAXSIZE];

main()
{
    short w, h, x, y, n;
    char *s;

    set_config(0, !0);
    clear_screen(0);

    /* Create an image on the screen. */
    w = 100;
    h = 80;
    x = 10;
    y = 10;
    frame_rect(w, h, x, y, 1, 1);
    frame_oval(w, h, x, y, 4, 3);
    draw_line(x+w/2, y, x, y+h-1);
    draw_line(x+w/2, y, x+w-1, y+h-1);
    s = "IMAGE";
    n = text_width(s);
    text_out(x+(w-n)/2, y+h/2, s);

    /* Compress image, and verify buffer doesn't overflow. */
    n = encode_rect(w, h, x, y, picture, sizeof(picture), 0);
    if (n > MAXSIZE) {
	text_out(x, y+h+20, "Image buffer too small!");
	exit(1);
    }

    /* Now decompress the image. */
    decode_rect(x+w, y+h, picture);
}

typedef struct { short x, y; } POINT;

void fill_convex(n, vert)
short n;			/* vertex count */
POINT *vert;			/* vertex coordinates */

The fill_convex  function fills a convex polygon with a solid color. 
The polygon is specified by a list of points representing the polygon 
vertices in the order in which they are traversed in tracing the 
boundary of the polygon. The polygon is filled with the current 
foreground color.

Argument n specifies the number of vertices in the polygon, which
is the same as the number of sides.

Argument vert is an array of integer x-y coordinates representing
the polygon vertices in the order in which they are to be traversed. 
The x-y coordinate pairs 0 through n-1 of the vert array contain the
coordinates for the n vertices. The function assumes that an edge 
connects each adjacent pair of vertices in the array and also 
assumes that vertex n-1 is connected to vertex 0 
by an edge. Each vertex is represented by a 16-bit x-coordinate 
value followed by a 16-bit y-coordinate value. Coordinates 
are specified relative to the drawing origin.

The fill_convex function is similar to the fill_polygon function 
but is specialized for rapid drawing of convex polygons. It also 
executes more rapidly and supports realtime applications such as 
animation. The function assumes that the polygon contains no 
concavities; if this requirement is violated, the 
polygon may be drawn incorrectly.

In order to conveniently support 3D applications, the fill_convex  
function automatically culls back faces. A polygon is drawn only 
if its front side is visible-that is, if it is facing toward the viewer. 
The direction in which the polygon is facing is determined by 
the order in which the vertices are listed in the vert array. If the 
vertices are specified in clockwise order, the polygon is assumed
to be facing forward. If the vertices are specified in 
counterclockwise order, the polygon is assumed to 
face away from the viewer and is therefore not drawn.

The back-face test is done by first comparing vertices
n-2, n-1, and 0 to determine whether the polygon vertices 
are specified in clockwise (front 
facing) or counterclockwise (back facing) order. This 
test assumes the polygon contains no concavities. If the 
three vertices are collinear, the back-face 
test is performed again using the next three vertices, 
n-1, 0, and 1. The test repeats until three vertices are found 
that are not collinear. If all the vertices are collinear, 
the polygon is invisible.

Use the fill_convex function to fill a triangle. 
The three vertices are at coordinates (10, 10), (130, 10), and (70, 90).

#define  NVERTS    3	 /* number of vertices */

typedef struct { short x, y; } POINT;

static POINT xy[NVERTS] =
{
    { 10, 10 }, { 130, 10 }, { 70, 90 }
};

main()
{
    set_config(0, !0);
    clear_screen(0);
    fill_convex(NVERTS, xy);
}

void fill_oval(w, h, xleft, ytop)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */

The fill_oval function fills an ellipse with a solid color. The 
ellipse is in standard position, with its major and minor 
axes parallel to the coordinate axes. The ellipse is specified in terms 
of the enclosing rectangle in which the ellipse is inscribed. 
The ellipse is filled with the current foreground color.

The four arguments specify the rectangle enclosing the ellipse:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top 
	left corner of the rectangle and are defined relative 
	to the drawing origin.

If the specified width or height is 0, nothing is drawn.

Use the fill_oval function to draw an ellipse that is 130 pixels wide and 90 
pixels high. Also, draw the outline of a rectangle that encloses the ellipse 
without touching it.

main()
{
    set_config(0, !0);
    clear_screen(0);
    fill_oval(130, 90, 10, 10);
    draw_rect(130+3, 90+3, 10-2, 10-2);
}

void fill_piearc(w, h, xleft, ytop, theta, arc)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */
short theta;		/* starting angle (degrees) */
short arc;		/* extent of angle (degrees) */

The fill_piearc function fills a pie-slice-shaped wedge with a solid 
color. The wedge is bounded by an arc and two straight edges. 
The two straight edges connect the end points of the arc with 
the center of the ellipse. The arc is taken from an ellipse in standard
position, with its major and minor axes parallel to the coordinate axes. 
The ellipse is specified by the enclosing rectangle in which it is 
inscribed. The wedge is filled with the current 
foreground color.

The first four arguments specify the rectangle enclosing the ellipse 
from which the arc is taken:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top left corner 
	of the rectangle and are defined relative to the drawing origin.

If the specified width or height is 0, nothing is drawn.

The last two arguments define the limits of the arc and are specified in 
integer degrees:

	Argument theta specifies the starting angle and is measured from the 
	center of the right side of the enclosing rectangle.

	Argument arc specifies the arc's extent - that is, the number of 
	degrees (positive or negative) spanned by the angle. 

Both arguments are expressed in degrees of elliptical arc, with 360 degrees 
representing one full rotation around the ellipse. For both arguments, positive 

angles are in the clockwise direction, and negative angles are 
counterclockwise. Argument theta is treated as modulus 360. If the value of 
argument arc is outside the range [-359,+359], the entire ellipse is filled.

Use the fill_piearc function to draw a pie chart corresponding to a slice of an 

ellipse from 21 degrees to 300 degrees. The ellipse is 130 pixels wide and 90 
pixels high. Also, draw a rectangle that encloses the ellipse without touching 
it.

main()
{
    short w, h, x, y;

    set_config(0, !0);
    clear_screen(0);
    w = 130;
    h = 90;
    x = 10;
    y = 10;
    fill_piearc(w, h, x, y, 21, 300-21);
    draw_rect(w+3, h+3, x-2, y-2);
}

typedef struct { short x, y; } POINT;

void fill_polygon(n, vert)
short n;			/* vertex count */
POINT *vert;		/* vertex coordinates */

The fill_polygon function fills an arbitrarily shaped polygon 
with a solid color. The polygon is specified by a list of 
points representing the polygon vertices in the order in which 
they are traversed in tracing the boundary of the polygon. 
The interior of the polygon is determined according to the parity 
(or odd# even) rule. A pixel is considered to be part of the
filled region representing the polygon if an infinite, arbitrarily
oriented ray emanating from the center of the pixel crosses 
the boundary of the polygon an odd number 
of times. The polygon is filled with the current foreground color.

Argument n specifies the number of vertices in the 
polygon, which is the same as the number of sides.

Argument vert is an array of integer x-y coordinates 
representing the polygon vertices in the order in which 
they are to be traversed. The x-y coordinate 
pairs 0 through n-1 of the vert array contain the 
coordinates for the n vertices. The function assumes that an edge 
connects each adjacent pair of vertices in the array and also 
assumes that vertex n-1 is connected to vertex 0 
by an edge. Each vertex is represented by a 16-bit 
x-coordinate value followed by a 16-bit y-coordinate value. 
Coordinates are specified relative to the drawing origin.

No restrictions are placed on the shape of the 
polygons filled by this function. Edges may cross each other. 
Filled areas can contain holes (this is accomplished by 
connecting a hole to the outside edge of the polygon by an 
infinitely thin region of the polygon). Two or more filled 
regions can be 
disconnected from each other (or more precisely, be 
connected by infinitely thin regions of the polygon).

Use the fill_polygon function to fill a polygon that has a hole, two 
disconnected regions, and two edges that cross each other.

#define  NVERTS    14	     /* number of vertices */

typedef struct { short x, y; } POINT;

static POINT xy[NVERTS] = {
    { 150, 170 }, {  30, 150 }, { 150,30 }, {  30,  50 },
    { 150, 170 }, { 140,  70 }, { 260,70 }, { 200, 160 },
    { 140,  70 }, { 200,  80 }, { 220, 120 }, { 180, 120 },
    { 200,  80 }, { 140,  70 },
};

main()
{
    set_config(0, !0);
    clear_screen(0);
    fill_polygon(NVERTS, xy);
}

void fill_rect(w, h, xleft, ytop)
short w, h;		/* rectangle width and height */
short xleft, ytop	/* top left corner */

The fill_rect function fills a rectangle with a solid color. The 
rectangle is filled with the current foreground color.

The four arguments specify the rectangle:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top left corner 
	of the rectangle and are defined relative to the drawing origin.

If the specified width or height is 0, nothing is drawn.

Use the fill_rect function to fill a rectangle that is 130 pixels wide and 90 
pixels high.

main()
{
    set_config(0, !0);
    clear_screen(0);
    fill_rect(130, 90, 10, 10);
}

void frame_oval(w, h, xleft, ytop, dx, dy)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */
short dx, dy;		/* frame thickness in x, y */

The frame_oval function fills an ellipse-shaped frame with a solid color. The 
frame consists of a filled region between two concentric ellipses. The outer 
ellipse is specified in terms of the enclosing rectangle in which it is 
inscribed. The frame thickness is specified separately for the x and y 
dimensions. The portion of the screen enclosed by the frame is not altered. The 

frame is filled with the current foreground color.

The first four arguments define the rectangle enclosing the outer edge of the 
elliptical frame:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top left corner 
	of the rectangle, and are defined relative to the drawing origin.

If the specified width or height is 0, nothing is drawn.

The last two arguments control the thickness of the frame:

	Arguments dx and dy specify the horizontal and vertical separation 
	between the outer and inner ellipses, respectively.

Use the frame_oval function to draw an elliptical frame. The outer border of 
the frame is an ellipse that is 130 pixels wide and 90 pixels high. The 
thickness of the frame in the x and y dimensions is 16 and 12, respectively. 
Also, outline the outer border of the frame with the draw_rect function.

main()
{
    short w, h, x, y, dx, dy;

    set_config(0, !0);
    clear_screen(0);
    w = 130;
    h = 90;
    x = 10;
    y = 10;
    dx = 16;
    dy = 12;
    frame_oval(w, h, x, y, dx, dy);
    draw_rect(w+1, h+1, x-1, y-1);
}

void frame_rect(w, h, xleft, ytop, dx, dy)
short w, h;		/* rectangle width and height */
short xleft, ytop;	/* top left corner */
short dx, dy		/* frame thickness in x, y */

The frame_rect function fills a rectangular-shaped frame with a solid color. 
The frame consists of a filled region between two concentric rectangles. The 
outer edge of the frame is a rectangle specified in terms of its width, height, 
and position. The frame thickness is specified separately for the x and y 
dimensions. The portion of the screen enclosed by the frame is not altered. The 
frame is filled with the current foreground color.

The first four arguments define the rectangle enclosing the outer edge of the 
elliptical frame:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top left corner 
	of the rectangle and are defined relative to the drawing origin.

If the specified width or height is 0, nothing is drawn.

The last two arguments control the thickness of the frame:

	Arguments dx and dy specify the horizontal and vertical separation 
	between the outer and inner rectangles, respectively.

Use the frame_rect function to draw an rectangular frame. The outer border of 
the frame is a rectangle that is 127 pixels wide and 89 pixels high. The 
thickness of the frame in the x and y dimensions is 15 and 10, respectively. 
Also draw a diamond shape inside the frame with four calls to the draw_line 
function. The vertices of the diamond touch the center of each of the four 
inner edges of the frame.

main()
{
    short w, h, x, y, dx, dy;

    set_config(0, !0);
    clear_screen(0);
    w = 127;
    h = 89;
    x = 10;
    y = 10;
    dx = 15;
    dy = 10;
    frame_rect(w, h, x, y, dx, dy);
    draw_line(x+w/2, y+dy, x+w-dx-1, y+h/2);
    draw_line(x+w-dx-1, y+h/2, x+w/2, y+h-dy-1);
    draw_line(x+w/2, y+h-dy-1, x+dx, y+h/2);
    draw_line(x+dx, y+h/2, x+w/2, y+dy);
}

typedef unsigned long PTR;	/*32-bit address*/
typedef struct
{
    	PTR     	addr;
    	unsigned short pitch
    	unsigned short xext, yext;
     	unsigned short psize;
} BITMAP;
typedef struct
{
    	unsigned long xyorigin;
    	unsigned long pensize;
   ### 	BITMAP *srcbm, *dstbm;
    	unsigned long stylemask;
} ENVIRONMENT;

void get_env(env)
ENVIRONMENT *env;	/* graphics environment pointer */

The get_env function retrieves the current graphics environment information. 
Although the library contains other functions that manipulate individual 
environment parameters, this function retrieves the entire graphics environment 
as a single structure.

Argument env is a pointer to a structure of type ENVIRONMENT. The function 
copies the graphics environment information into the structure pointed to by 
this argument.

The fields of the ENVIRONMENT structure are defined as follows:

xyorigin     	Current drawing origin in y::x format, set by call to  
		set_draw_origin function

pensize     	Current pen size in y::x format, set by call to set_pen_size 
		function

patnaddr   	Address of current pattern, set  by  call  to  set_patnaddr  
		function

srcbm       	Address of current source bit map structure, set by call to 
		set_srcbm function

dstbm       	Address of current destination bit map structure, set by call 
		to set_dstbm function

stylemask 	Line-style mask used by styled_line function.

In y::x format, 16-bit x and y components are concatenated to form a 32-bit 
value. The x component is followed by the y component. Note that the structure 
described above may change in subsequent revisions. To minimize the impact of 
such changes, write application programs to refer to the elements of the 
structure symbolically by their field names, rather than as offsets from the 
start of the structure. The include files provided with the library will be 
updated in future revisions to track any such changes in data structure 
definitions.

Use the get_env function to verify the initial state of the graphics 
environment parameters immediately following a call to the set_config function. 

Use the text_out function to print the parameter values on the screen. This 
example includes the C header file gsptypes.h, which defines the ENVIRONMENT 
and FONTINFO structures.

#include <gsptypes.h>	  /* define ENVIRONMENT and FONTINFO */

main()
{
    ENVIRONMENT env;
    FONTINFO fontinfo;
    char c[80];
    short val;
    int n, h, x, y;

    set_config(0, !0);
    clear_screen(0);
    get_fontinfo(0, &fontinfo);
    h = fontinfo.charhigh;
    x = y = 10;
    get_env(&env);	 /* get graphics environment */

    text_out(x, y, "INITIAL GRAPHICS ENVIRONMENT:");    

    strcpy(c, "x origin = ");
    n = strlen(c);
    ltoa(val = env.xyorigin, &c[n]);
    text_out(x, y += h, c);   

    strcpy(c, "y origin = ");
    n = strlen(c);
    ltoa(env.xyorigin>>16, &c[n]);
    text_out(x, y += h, c);    

    strcpy(c, "pen width = ");
    n = strlen(c);
    ltoa(val = env.pensize, &c[n]);
    text_out(x, y += h, c);    

    strcpy(c, "pen height = ");
    n = strlen(c);
    ltoa(env.pensize>>16, &c[n]);
    text_out(x, y += h, c);    

    strcpy(c, "source bit map = ");
    n = strlen(c);
    ltoa(env.srcbm, &c[n]);
    text_out(x, y += h, c);    

    strcpy(c, "destination bit map = ");
    n = strlen(c);
    ltoa(env.dstbm, &c[n]);
    text_out(x, y += h, c);    

    strcpy(c, "line-style pattern = ");
    n = strlen(c);
    ltoa(env.stylemask, &c[n]);
    text_out(x, y += h, c);
}

unsigned long get_pixel(x, y)
short x, y;		/* pixel coordinates */

The get_pixel function returns the value of the  pixel  at  x-y  coordinates 
(x, y) on the screen. The coordinates are defined relative to the drawing 
origin. Given a pixel size of n bits, the pixel is contained in the n LSBs of 
the return value; the 32-n MSBs are set to 0.

Use the get_pixel function to rotate a text image on the screen by 180 degrees. 

This example includes the C header file gsptypes.h, which defines the FONTINFO 
structure.

#include <gsptypes.h>	   /* defines FONTINFO structure */

main()
{
    FONTINFO fontinfo;
    short xs, ys, xd, yd, w, h;
    long val;
    char *s;

    set_config(0, !0);
    clear_screen(0);
    s = "Rotate text by 180 degrees.";
    get_fontinfo(0, &fontinfo);
    w = text_width(s);
    h = fontinfo.charhigh;
    xs = ys = 0;
    text_out(xs, ys, s);
    for (yd = 2*h+1; ys <= h; ys++, yd--)
        for (xs = 0, xd = w-1; xs <= w; xs++, xd--) {
            val = get_pixel(xs, ys);
            #put_pixel(val, xd, yd);
        }
}

short get_textattr(pcontrol, count, val)
char *pcontrol; 	/* control string */
short count;		/* val array length */
short *val;		/* array of attribute values */

The get_textattr function retrieves the text rendering attributes. The three  
text attributes currently supported are text alignment, additional 
intercharacter spacing, and intercharacter gaps.

Argument pcontrol is a control string specifying the attributes
(one or more) to be retrieved. Argument count is the number of 
attributes designated in the pcontrol string and is also the number 
of attributes stored in the val array. Argument val is the array 
into which the designated attributes are stored. The 
attribute values are stored into the consecutive elements of 
the val array, beginning with val [0], in the order 
in which they appear in the pcontrol string.

The function returns a value indicating the number of 
attributes actually loaded into the val array.

The following attributes are currently supported:

  Symbol 	Attribute Description	Option Value
     %a	alignment	0 = top left, 1 = base line
     %e	additional intercharacter spacing	16-bit signed integer
     %f	intercharacter gaps	0 = leave gaps, 1 = fill gaps

Use the get_textattr function to verify the initial state of the text 
attributes immediately following a call to the set_config function. 
Use the text_out function to print the attribute values on the screen. 
This example includes the C header file gsptypes.h, which 
defines the FONTINFO structure.

#include <gsptypes.h>	  /* define FONTINFO structure */

main()
{
    ENVIRONMENT env;
    FONTINFO fontinfo;
    char c[80];
    short val[3];
    int n, h, x, y;

    set_config(0, !0);
    clear_screen(-1);
    get_fontinfo(0, &fontinfo);
    h = fontinfo.charhigh;
    x = y = 10;
    get_textattr("%a%e%f", 3, val);  /* get text attributes */

    text_out(x, y, "DEFAULT TEXT ATTRIBUTES:");
    y += h;

    strcpy(c, "text alignment = ");
    n = strlen(c);
    ltoa(val[0], &c[n]);
    text_out(x, y, c);
    y += h;

    strcpy(c, "extra interchar spacing = ");
    n = strlen(c);
    ltoa(val[1], &c[n]);
    text_out(x, y, c);
    y += h;

    strcpy(c, "interchar gaps = ");
    n = strlen(c);
    ltoa(val[1], &c[n]);
    text_out(x, y, c);
}

short in_font(start_code, end_code)
short start_code;     	/* starting character code */
short end_code;       	/* ending character code */

The in_font function returns a value indicating whether the current font 
defines all the characters within a specified range of ASCII codes.

The two arguments specify the range of characters:

	Argument start_code specifies the ASCII code at the start of the range. 
	(This is the first character included in the range.)

	Argument end_code specifies the ASCII code at the end of the range. 
	(This is the last character included in the range.)

The value of start_code should be less than or equal to the value of end_code. 
Valid arguments are restricted to the range 1 to 255.

The value returned by the function is 0 if the current font defines all 
characters in the range specified by the arguments. Otherwise, the return value 

is the ASCII code of the first character (lowest ASCII code) in the specified 
range that is undefined in the current font.

Use the in_font  function to determine whether the system font defines all 
characters from ASCII code 32 to ASCII code 126. Use the text_out  function to 
print the result of the test on the screen.

main()
{
    int n;
    unsigned char v, c[80];

    set_config(0, 1);
    clear_screen(-1);
    if (v = in_font(' ', '~')) {
	n = strlen(strcpy(c, "ASCII character code "));
	n += ltoa(v, &c[n]);
	strcpy(&c[n], " is undefined.");
	text_out(10, 10, c);
    } else
	text_out(10, 10, "Characters ' ' to '~' are defined.");
}

short install_font(pfont)
FONT *pfont;	/* font structure pointer */

The install_font  function installs a font in the font table and returns an 
identifier (ID) of type short. The ID can be used to refer to the font in 
subsequent text operations.

Argument pfont  is a pointer to a structure of type FONT.
(The FONT structure is described in Appendix A.) The install_font  
function merely adds the address of the font to the font table. 
It does not select the font.

The ID returned is nonzero if the installation  was successful. If  
unsuccessful, 0 is returned.

The maximum size of the font table is a constant that can vary 
from system to system. In all systems, the font table will be 
large enough to contain at least 16 installed fonts (in addition 
to the permanently installed system font). Once the font table is full, 
an attempt to install an additional font will be 
ignored, and a value of 0 will be returned.

Use the install_font  function to install a proportionally 
spaced font. Use the text_out  function to print a sample 
of the font on the screen. This example program includes the 
gsptypes.h file, which defines the FONT and FONTINFO 
structures. The TI Roman font size 20 must be linked with the program.

#include <gsptypes.h>	 /* defines FONT and FONTINFO structures */

extern FONT ti_rom20;	 /* proportionally-spaced font */

main()
{
    FONTINFO fontinfo;
    short x, y, id;

    set_config(0, !0);
    clear_screen(0);
    id = install_font(&ti_rom20);  /* install the font */
    get_fontinfo(id, &fontinfo);
    select_font(id);
    x = y = 10;
    text_out(x, y, "The quick brown fox jumped");
    y += fontinfo.charhigh;
    text_out(x, y, "over the lazy sleeping dog.");
}

void move_pixel(xs, ys, xd, yd)
short xs, ys;		/* source pixel coordinates */
short xd, yd;		/* destination pixel coordinates */

The move_pixel  function copies a pixel from one screen location to another. 
Arguments xs and ys are the x and y coordinates of the source pixel. Arguments 
xd and yd are the x and y coordinates of the destination pixel. Coordinates are 
defined relative to the drawing origin.

Use the move_pixel function to rotate text image on screen 
by 90 degrees. This example includes the C header file 
gsptypes.h, which defines the FONTINFO structure.

#include <gsptypes.h>	  /* define FONTINFO structure */

main()
{
    FONTINFO fontinfo;
    short xs, ys, xd, yd, w, h;
    char *s;

    set_config(0, !0);
    clear_screen(0);
    s = "Rotate 90 degrees.";
    get_fontinfo(0, &fontinfo);
    w = text_width(s);
    h = fontinfo.charhigh;
    xs = h;
    ys = 0;
    text_out(xs, ys, s);
    for (xd = yd = h; ys < h; ys++, xd = h-ys, yd = h)
        for (xs = h; xs < w+h; xs++, yd++)
            move_pixel(xs, ys, xd, yd);
}

typedef struct { short x, y; } POINT;

void patnfill_convex(n, vert)
short n;			/* vertex count */
POINT *vert;		/* vertex coordinates */

The patnfill_convex function fills a convex polygon with the 
current area-fill pattern. The polygon is specified by a 
list of points representing the polygon vertices in the order
in which they are traversed in tracing the boundary of the polygon.

Argument n specifies the number of vertices in the polygon, 
which is the same as the number of sides.

Argument vert is an array of integer x-y coordinates representing 
the polygon vertices in the order in which they are to be traversed. 
The x-y coordinate pairs 0 through n-1 of the vert  array 
contain the coordinates for the n vertices. The function assumes 
that an edge connects each adjacent pair of vertices in the array
and that an edge connects vertex n-1 to vertex 0. Each 
vertex is represented by a 16-bit x-coordinate value followed 
by a 16-bit y-coordinate value. Coordinates are specified relative 
to the drawing origin.

The patnfill_convex function is similar to the patnfill_polygon 
function but is specialized for rapid drawing of convex polygons. 
It also executes more rapidly and supports realtime applications, 
such as animation. The function assumes that the polygon contains 
no concavities; if this requirement is violated, the 
polygon may be drawn incorrectly.

In order to conveniently support 3D applications, the patnfill_convex 
function automatically culls back faces. A polygon is drawn only 
if its front side is visible-that is, if it is facing toward the viewer. 
The direction in which the polygon is facing is determined by 
the order in which the vertices are listed in the vert array. If the vertices
are specified in clockwise order, the polygon is assumed to be facing 
forward. If the vertices are specified in counterclockwise order, 
the polygon is assumed to face away from the viewer and 
is therefore not drawn.

The back-face test is done by first comparing vertices n-2, n-1, 
and 0 to determine whether the polygon vertices are 
specified in clockwise (front facing) or counterclockwise 
(back facing) order. This test assumes the polygon 
contains no concavities. If the three vertices are collinear, 
the back-face test is made again using the next three 
vertices, n-1, 0, and 1. The test repeats until three vertices 
are found that are not collinear. If all the 
vertices are collinear, the polygon is invisible.

Use the patnfill_convex function to fill a quadrilateral 
with a pattern. The four vertices are located at (96, 16), 
(176, 72), (96, 128), and (16, 72). This 
example includes the C header file gsptypes.h, 
which defines the PATTERN structure.

#include <gsptypes.h>	/* define PATTERN structure */
#define  NVERTS    4	/* number of vertices in quadrilateral */

typedef struct { short x, y; } POINT;

static short snowflake[16] =
{
    0x0000, 0x01C0, 0x19CC, 0x188C, 0x0490, 0x02A0, 0x31C6, 0x3FFE,
    0x31C6, 0x02A0, 0x0490, 0x188C, 0x19CC, 0x01C0, 0x0000, 0x0000,
};
static PATTERN fillpatn = { 16, 16, 1, (PTR)snowflake };
static POINT xy[NVERTS] =
{
    { 96, 16 }, { 176, 72 }, { 96, 128 }, { 16, 72 },
};

main()
{
    set_config(0, !0);
    clear_screen(0);
    set_patn(&fillpatn);
    patnfill_convex(NVERTS, xy);
}

void patnfill_oval(w, h, xleft, ytop)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */

The patnfill_oval function fills an ellipse with the current area-fill pattern. 

The ellipse is in standard position, with its major and minor axes parallel to 
the coordinate axes. The ellipse is specified in terms of the enclosing 
rectangle in which the ellipse is inscribed.

The four arguments specify the rectangle enclosing the ellipse:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top 
	left corner of the rectangle and are defined relative to 
	the drawing origin.

Use the patnfill_oval function to fill an ellipse that is 144 pixels wide by 96 
pixels high with a 16-by-16 area-fill pattern. This example includes the C 
header file gsptypes.h, which defines the PATTERN structure.

#include <gsptypes.h>	  /* define PATTERN structure */

typedef struct { unsigned short row[16]; } PATNBITS;

static PATNBITS patnbits =     /* brick pattern */
{
    0xFFFF, 0xD555, 0x8000, 0xC001, 0x8000, 0xC001, 0x8000, 0xD555,
    0xFFFF, 0x55D5, 0x0080, 0x01C0, 0x0080, 0x01C0, 0x0080, 0x55D5,
};
static PATTERN current_patn = { 16, 16, 1, (PTR)&patnbits };

main()
{
    set_config(0, !0);
    clear_screen(0);
    set_patn(&current_patn);
    patnfill_oval(144, 96, 16, 16);
}

void patnfill_piearc(w, h, xleft, ytop, theta, arc)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */
short theta;		/* starting angle (degrees) */
short arc;		/* extent of angle (degrees) */

The patnfill_piearc function fills a pie-slice-shaped wedge with an area-fill 
pattern. The wedge is bounded by an arc and two straight edges. The two 
straight edges connect the end points of the arc with the center of the 
ellipse. The arc is taken from an ellipse in standard position, with its major 
and minor axes parallel to the coordinate axes. The ellipse is specified by the 

enclosing rectangle in which it is inscribed. The wedge is filled with the 
current area-fill pattern.

The first four arguments specify the rectangle enclosing the ellipse from which 
the arc is taken:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the 
	top left corner of the rectangle and are defined relative
	to the drawing origin.

The last two arguments define the limits of the arc and are specified in 
integer degrees:

	Argument theta specifies the starting angle and is
	measured from the center of the right side of the enclosing 
	rectangle.

	Argument arc specifies the arc's extent - that is, the 
	number of degrees (positive or negative) spanned by the angle. 

Both arguments are expressed in degrees of elliptical arc, with 360 degrees 
representing one full rotation around the ellipse. For both arguments, 
positive angles are in the clockwise direction, and negative angles are 
counterclockwise. Argument theta is treated as modulus 360. If the 
value of argument arc is outside the range [-359,+359], 
the entire ellipse is filled.

Use the patnfill_piearc  function to draw a pie chart 144 pixels wide 
by 96 pixels high with a 16-by-16 area-fill pattern. The pie chart contains
four pie slices. This example includes the C header file gsptypes.h, 
which defines the PATTERN structure.

#include <gsptypes.h>	   /* define PATTERN structure */
#define  W   	130	   /* width of pie chart */
#define  H	 90	   /* height of pie chart */
#define  X	 10	   /* left edge of pie chart */
#define  Y	 10	   /* top edge of pie chart */

typedef struct { unsigned short row[16]; } PATNBITS;

/* Two contrasting area-fill patterns */
static PATNBITS patnbits[2] =
{
 { 0x8888, 0x4444, 0x2222, 0x1111, 0x8888, 0x4444, 0x2222, 0x1111,
   0x8888, 0x4444, 0x2222, 0x1111, 0x8888, 0x4444, 0x2222, 0x1111},
 { 0xFFFF, 0x1111, 0x1111, 0x1111, 0xFFFF, 0x1111, 0x1111, 0x1111,
   0xFFFF, 0x1111, 0x1111, 0x1111, 0xFFFF, 0x1111, 0x1111, 0x1111},
};

main()
{
    static PATTERN piepatn = { 16, 16, 1, (PTR)0 };

    set_config(0, !0);
    clear_screen(0);
    piepatn.data = (PTR)&patnbits[0];
    set_patn(&piepatn);
    patnfill_piearc(W, H, X, Y, 30, 160-30);      /* slice #1 */
    piepatn.data = (PTR)&patnbits[1];
    set_patn(&piepatn);
    patnfill_piearc(W, H, X, Y, 160, 230-160);    /* slice #2 */
    piepatn.data = (PTR)&patnbits[0];
    set_patn((PTR)&piepatn);
    patnfill_piearc(W, H, X, Y, 230, 320-230);    /* slice #3 */
    piepatn.data = (PTR)&patnbits[1];
    set_patn(&piepatn);
    patnfill_piearc(W, H, X+20, Y, 320, 390-320); /* slice #4 */
}

typedef struct { short x, y; } POINT;

void patnfill_polygon(n, vert)
short n;		/* vertex count */
POINT *vert;		/* vertex coordinates */

The patnfill_polygon function fills an arbitrarily shaped polygon 
with the current area-fill pattern. The polygon is specified by a 
list of points representing the polygon vertices in the order 
in which they are traversed in tracing the boundary of the polygon. 
The interior of the polygon is determined according to the parity 
(or odd-even) rule. A pixel is considered to be part of 
the filled region representing the polygon if an infinite, arbitrarily 
oriented ray emanating from the center of the pixel crosses 
the boundary of the polygon an odd number of times.

Argument n specifies the number of vertices in the polygon, 
which is the same as the number of sides.

Argument vert is an array of integer x-y coordinates representing 
the polygon vertices in the order in which they are to be traversed. 
The x-y coordinate pairs 0 through n-1 of the vert array contain
the coordinates for the n vertices. The function assumes that an 
edge connects each adjacent pair of vertices in the array and also 
assumes that an edge connects vertex n-1 to 
vertex 0. Each vertex is represented by a 16-bit x-coordinate 
value followed by a 16-bit y-coordinate value. Coordinates are 
specified relative to the drawing origin.

No restrictions are placed on the shape of the polygons 
filled by this function. Edges may cross each other. Filled areas 
can contain holes (this is accomplished by connecting a hole
to the outside edge of the polygon by an infinitely thin region 
of the polygon). Two or more filled regions can be 
disconnected from each other (or more precisely, be 
connected by infinitely thin regions of the polygon).

Use the patnfill_polygon function to fill a polygon that has a
hole, two disconnected regions, and two edges that cross each other. 
This example includes the C header file gsptypes.h, which 
defines the PATTERN structure.

#include <gsptypes.h>	 /* define PATTERN structure */
#define  NVERTS    14	 /* 14 vertices in polygon */

typedef struct { short x, y; } POINT;

static short patnbits[16] =     /* squares pattern */
{
    0x00FF, 0x0081, 0x1881, 0x3C81, 0x3C81, 0x1881, 0x0081, 0x00FF,
    0xFF00, 0x8100, 0x8118, 0x813C, 0x813C, 0x8118, 0x8100, 0xFF00,
};
static PATTERN current_patn = { 16, 16, 1, (PTR)patnbits };
static POINT xy[NVERTS] = {
    { 150, 170 }, {  30, 150 }, { 150,30 }, {  30,  50 },
    { 150, 170 }, { 140,  70 }, { 260,70 }, { 200, 160 },
    { 140,  70 }, { 200,  80 }, { 220, 120 }, { 180, 120 },
    { 200,  80 }, { 140,  70 },
};

main()
{
    set_config(0, !0);
    clear_screen(0);
    set_patn(&current_patn);
    patnfill_polygon(NVERTS, xy);
}

void patnfill_rect(w, h, xleft, ytop)
short w, h;		/* rectangle width and height */
short xleft, ytop	/* top left corner */

The patnfill_rect function fills a rectangle with the current area-fill 
pattern.

The four arguments specify the rectangle:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top
	left corner of the rectangle and are defined relative to the 
	drawing origin.

If the specified width or height is 0, nothing is drawn.

Use the patnfill_rect function to fill a rectangle that is 144 pixels 
wide by 96 pixels high with a 16-by-16 area-fill pattern. This 
example includes the C header file gsptypes.h, which defines
the PATTERN structure.

#include <gsptypes.h>	 /* define PATTERN structure */

typedef struct { unsigned short row[16]; } PATNBITS;

static PATNBITS patnbits =
{
    0x0000, 0x01C0, 0x19CC, 0x188C, 0x0490, 0x02A0, 0x31C6, 0x3FFE,
    0x31C6, 0x02A0, 0x0490, 0x188C, 0x19CC, 0x01C0, 0x0000, 0x0000,
};
static PATTERN current_patn = { 16, 16, 1, (PTR)&patnbits };

main()
{
    set_config(0, !0);
    clear_screen(0);
    set_patn(&current_patn);
    patnfill_rect(144, 96, 16, 16);
}

void patnframe_oval(w, h, xleft, ytop, dx, dy)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */
short dx, dy;		/* frame thickness in x, y */

The patnframe_oval function fills an ellipse-shaped frame with the current 
area-fill pattern. The frame consists of a filled region between two concentric 
ellipses. The outer ellipse is specified in terms of the enclosing rectangle in 
which it is inscribed. The frame thickness is specified separately for the x 
and y dimensions. The portion of the screen enclosed by the frame is not 
altered.

The first four arguments define the rectangle enclosing the outer edge of the 
elliptical frame:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the 
	top left corner of the rectangle and are defined relative 
	to the drawing origin.

The last two arguments control the thickness of the frame:

	Arguments dx and dy specify the horizontal and 
	vertical separation, respectively, between the outer 
	and inner ellipses.

Use the patnframe_oval function to draw an elliptical frame 
rendered with an area-fill pattern. The elliptical frame is
superimposed upon a filled rectangle. Both the rectangle 
and the outer boundary of the elliptical frame are of width 
130 and height 90. This example includes the C header file 
gsptypes.h, which defines the PATTERN structure.

#include <gsptypes.h>	 /* define PATTERN structure */

static short fillpatn[] = {     /* 16-by-16 area-fill pattern */
    0x8888, 0x4444, 0x2222, 0x1111, 0x8888, 0x4444, 0x2222, 0x1111,
    0x8888, 0x4444, 0x2222, 0x1111, 0x8888, 0x4444, 0x2222, 0x1111
};
static PATTERN framepatn = { 16, 16, 1, (PTR)fillpatn };

main()
{
    short w, h, x, y, dx, dy;

    set_config(0, !0);
    clear_screen(0);
    w = 130;
    h = 90;
    x = 10;
    y = 10;
    dx = w/4;
    dy = h/4;
    set_patn(&framepatn);
    fill_rect(w, h, x, y);
    patnframe_oval(w, h, x, y, dx, dy);
}

void patnframe_rect(w, h, xleft, ytop, dx, dy)
short w, h;		/* rectangle width and height */
short xleft, ytop;	/* top left corner */
short dx, dy		/* frame thickness in x, y */

The patnframe_rect function fills a rectangle-shaped frame 
with the current area-fill pattern. The frame consists of a
filled region between two concentric 
rectangles. The outer edge of the frame is a rectangle specified
in terms of its width, height, and position. The frame 
thickness is specified separately for the x and y dimensions. 
The portion of the screen enclosed by the frame is not altered. 

The first four arguments define the rectangle enclosing the outer edge of the 
elliptical frame:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the 
	top left corner of the rectangle and are defined relative
	to the drawing origin.

The last two arguments control the thickness of the frame:

	Arguments dx and dy specify the horizontal and 
	vertical separation, respectively, between the outer 
	and inner rectangles.

Use the patnframe_rect function to draw a rectangular frame rendered with a 
16-by-16 area-fill pattern. Also, outline the outer and inner borders of the 
frame with the draw_rect function. This example includes the C header file 
gsptypes.h, which defines the PATTERN structure.

#include <gsptypes.h>	 /* define PATTERN structure */

static short fillpatn[] = {     /* 16-by-16 area-fill pattern */
    0x0000, 0x0000, 0x7C7C, 0x4444, 0x4444, 0x4444, 0x7FFC, 0x0440,
    0x0440, 0x0440, 0x7FFC, 0x4444, 0x4444, 0x4444, 0x7C7C, 0x0000,
};

main()
{
    static PATTERN framepatn = { 16, 16, 1, (PTR)fillpatn };
    short w, h, x, y, dx, dy;

    set_config(0, !0);
    clear_screen(0);
    w = 144;
    h = 96;
    x = 16;
    y = 16;
    dx = 32;
    dy = 16;
    set_patn(&framepatn);
    patnframe_rect(w, h, x, y, dx, dy);
    draw_rect(w+2, h+2, x-1, y-1);
    draw_rect(w-2*dx-2, h-2*dy-2, x+dx+1, y+dy+1);
}

void patnpen_line(x1, y1, x2, y2)
short x1, y1;		/* start coordinates */
short x2, y2;		/* end coordinates */

The patnpen_line  function draws a line with a pen and an area-fill 
pattern. The thickness of the line is determined by the width and 
height of the rectangular drawing pen. The area covered by
the pen to represent the line is filled with the current area-fill pattern.

Arguments x1 and y1 specify the starting x and y coordinates of the line. 
Arguments x2 and y2 specify the ending x and y coordinates of the line.

The pen is a rectangle whose width and height can be 
modified by means of the set_pensize function. At 
each point on the line drawn by the patnpen_line 
function, the pen is located with its top left corner touching the 
line. The area covered by the pen as it traverses the line from start
to end is filled with a pattern.

Use the patnpen_line function to draw two lines.  The first line 
goes from  (16, 16) to (144, 112), and the second line goes
from (144, 112) to (144, 16). Use the set_pensize function to set 
the pen dimensions to 24-by-16. This example includes the 
C header file gsptypes.h, which defines the PATTERN structure.

#include <gsptypes.h>	 /* define PATTERN structure */

static short spiral[16] =
{	  /* 16x16 area-fill pattern */
    0x0000, 0x3FFC, 0x7FFE, 0x0006, 0x0006, 0x1FC6, 0x3FE6, 0x3066,
    0x3066, 0x33E6, 0x31C6, 0x3006, 0x3006, 0x3FFE, 0x1FFC, 0x0000,
};
static PATTERN fillpatn = { 16, 16, 1, (PTR)spiral };

main()
{
    set_config(0, !0);
    clear_screen(0);
    set_pensize(24, 16);
    set_patn(&fillpatn);
    patnpen_line(16, 16, 144, 112);
    patnpen_line(144, 112, 144, 16);
}

void patnpen_ovalarc(w, h, xleft, ytop, theta, arc)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */
short theta;		/* starting angle (degrees) */
short arc;		/* angle extent (degrees) */

The patnpen_ovalarc function draws an arc of an ellipse with a 
pen and an area-fill pattern. The ellipse from which the arc is
taken is in standard position, with the major and minor 
axes parallel to the coordinate axes. The 
ellipse is specified in terms of the enclosing rectangle in 
which it is inscribed. The area swept out by the pen as it 
traverses the arc is filled with the current area-fill pattern. 
The thickness of the arc is determined by the 
width and height of the rectangular drawing pen.

The pen is a rectangle whose width and height can be 
modified by means of  the  set_pensize  function.  At  each  point  
on  the  arc  drawn by the  patnpen_ovalarc function, the pen 
is located with its top left corner touching 
the arc. The area covered by the pen as it traverses the arc from 
start to end is filled with a pattern.

The first four arguments specify the rectangle enclosing the ellipse from which 

the arc is taken:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the
	top left corner of the rectangle and are defined relative to the 
	drawing origin.

The last two arguments define the limits of the arc and are specified in 
integer degrees:

	Argument theta specifies the starting angle and is measured
	from the center of the right side of the enclosing rectangle.

	Argument arc specifies the arc's extent - that is, the 
	number of degrees (positive or negative) spanned by the angle. 

Both arguments are expressed in degrees of elliptical arc, with 360 degrees 
representing one full rotation around the ellipse. For both arguments, positive 
angles are in the clockwise direction, and negative angles are 
counterclockwise. Argument theta is treated as modulus 360. If the value of 
argument arc is outside the range [-359,+359], the entire ellipse is drawn.

Use the patnpen_ovalarc function to draw an arc taken from an ellipse. 
Set the pen dimensions to 24-by-16, and set the width and 
height of the ellipse to 144 and 112, respectively. Use the draw_oval function 
to superimpose a thin ellipse having the same width and height on 
the path taken by the pen in tracing the arc. This example includes 
the C header file gsptypes.h, which defines the PATTERN structure.

#include <gsptypes.h>	 /* define PATTERN structure */

static short stripes[16] =
{				  /* 16x16 area-fill pattern */
    0x8888, 0x4444, 0x2222, 0x1111, 0x8888, 0x4444, 0x2222, 0x1111,
    0x8888, 0x4444, 0x2222, 0x1111, 0x8888, 0x4444, 0x2222, 0x1111,
};
static PATTERN fillpatn = { 16, 16, 1, (PTR)stripes };

main()
{
    short w, h, x, y;

    set_config(0, !0);
    clear_screen(0);
    set_pensize(24, 16);
    set_patn(&fillpatn);
    w = 144;
    h = 112;
    x = 16;
    y = 16;
    patnpen_ovalarc(w, h, x, y, 35, 255-45);
    draw_oval(w, h, x, y);
}

void patnpen_piearc(w, h, xleft, ytop, theta, arc)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */
short theta;		/* starting angle (degrees) */
short arc;		/* angle extent (degrees) */

The patnpen_piearc function draws a pie-slice-shaped wedge 
from an ellipse with a pen and an area-fill pattern. The wedge 
is formed by an arc of the ellipse and by two straight lines that 
connect the two end points of the arc with the 
center of the ellipse. The ellipse from which the arc is taken 
is in standard position, with the major and minor axes parallel 
to the coordinate axes. The ellipse is specified in terms of 
the enclosing rectangle in which it is inscribed. The area swept 
out by the pen as it traverses the perimeter of the 
wedge is filled with the current area-fill pattern. The thickness 
of the arc and of two lines drawn to represent the wedge
is determined by the width and height of the rectangular 
drawing pen.

The pen is a rectangle whose width and height can be modified 
by means of the set_pensize function. As the pen traverses 
the arc from start to end, the pen is located with its top left 
corner touching the arc. The two lines connecting 
the arc start and end points with the center of the
ellipse are drawn in similar fashion, with the top left corner
of the pen touching each line as it traverses the line from start to end.

The first four arguments specify the rectangle 
enclosing the ellipse from which the arc is taken:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top left
	corner of the rectangle and are defined relative to the drawing origin.

The last two arguments define the limits of the arc and are specified in 
integer degrees:

	Argument theta specifies the starting angle and is measured 
	from the center of the right side of the enclosing rectangle.

	Argument arc specifies the arc's extent - that is, the number of 
	degrees (positive or negative) spanned by the angle. 

Both arguments are expressed in degrees of elliptical arc, with 360 degrees 
representing one full rotation around the ellipse. For both arguments, positive 

angles are in the clockwise direction, and negative angles are 
counterclockwise. Argument theta is treated as modulus 360. If the 
value of argument arc is outside the range [-359,+359], 
the entire ellipse is drawn.

Use the patnpen_piearc function to draw an arc taken from an ellipse. 
Set the pen dimensions to 16-by-16. Use the pen_piearc 
function to superimpose a "thin" pie slice on the path taken 
by the pen in tracing the "fat" pie slice. Both the 
fat and thin slices are taken from the same ellipse, which has 
width 144 and height 112. The arc extends from 33 degrees to 
295 degrees. This example includes the C header file gsptypes.h, 
which defines the PATTERN structure.

#include <gsptypes.h>	 /* define PATTERN structure */

static short stripes[16] =
{				  /* 16x16 area-fill pattern */
    0x8888, 0x4444, 0x2222, 0x1111, 0x8888, 0x4444, 0x2222, 0x1111,
    0x8888, 0x4444, 0x2222, 0x1111, 0x8888, 0x4444, 0x2222, 0x1111,
};
static PATTERN fillpatn = { 16, 16, 1, (PTR)stripes };

main()
{
    short w, h, x, y;

    set_config(0, !0);
    clear_screen(0);
    set_patn(&fillpatn);
    w = 144;
    h = 112;
    x = 16;
    y = 16;
    set_pensize(16, 16);
    patnpen_piearc(w, h, x, y, 33, 295-33);
    set_pensize(1, 1);
    pen_piearc(w, h, x, y, 33, 295-33);
}

void patnpen_point(x, y)
short x, y;		/* pen coordinates */

The patnpen_point  function draws a point with a pen and 
an area-fill pattern. Arguments x and y specify where the top 
left corner of the rectangular drawing pen is positioned. The 
resulting figure is a rectangle the width and height of 
the pen and filled with the current area-fill pattern.

Use the patnpen_point function to draw a sine wave of amplitude 60. Each 
point on the wave is separated from the next by an angular increment of 
approximately 1/16 radian. This example includes the C header file 
gsptypes.h, which defines the PATTERN structure.

#include <gsptypes.h>	   	/* define PATTERN structure */
#define  FOURPI 	823550 	/* fixed-point 4*PI */
#define  HALF	32768  	/* fixed-point 1/2 */
#define  AMPL	60   	/* sine wave amplitude */
#define  N	4   		/* angular increment = 1/2**N radians */

typedef long FIX;	   	/* fixed-pt with 16-bit fraction */

static short stripes[16] =
{				  /* 16x16 area-fill pattern */
    0x8888, 0x4444, 0x2222, 0x1111, 0x8888, 0x4444, 0x2222, 0x1111,
    0x8888, 0x4444, 0x2222, 0x1111, 0x8888, 0x4444, 0x2222, 0x1111,
};
static PATTERN fillpatn = { 16, 16, 1, (PTR)stripes };

main()
{
    int i;
    short x, y;
    FIX u, v;

    set_config(0, !0);
    clear_screen(0);
    set_patn(&fillpatn);
    set_pensize(1, 32);
    set_draw_origin(10, 10+AMPL);

    u = AMPL << 16;	       /* convert to fixed-pt */
    v = 0;
    for (i = (FOURPI << N) >> 16, x = 0 ; i >= 0; i--, x++) {
	y = (v + HALF) >> 16;
	patnpen_point(x, y);   /* draw next point */
	u += v >> N;
	v -= u >> N;
    }
}

typedef struct { short x, y; } POINT;

void patnpen_polyline(n, vert)
short n;		/* vertex count */
POINT *vert;	/* vertex coordinates */

The patnpen_polyline function draws multiple, connected lines with a 
pen and an area-fill pattern. The thickness of the lines is 
determined by the width and height of the rectangular drawing pen. 
An array of integer x-y coordinates representing the polyline vertices is 
specified as one of the arguments. A line 
is drawn between each pair of adjacent vertices in the array. The 
area covered by the rectangular drawing pen as it traverses 
each line is drawn in the current area-fill pattern.

Argument n specifies the number of vertices in the polyline; the 
number of lines drawn is n-1.

Argument vert is an array of x-y coordinates representing the 
polyline vertices in the order in which they are to be traversed. 
The x-y coordinate pairs 0 through n-1 of the vert array contain 
the coordinates for the n vertices. The function draws a line 
between each adjacent pair of vertices in the array. Each 
vertex is represented by a 16-bit x-coordinate value followed 
by a 16-bit y-coordinate value. Coordinates are specified 
relative to the drawing origin.

For the polyline to form a closed polygon, the calling 
program must ensure that the first and last vertices 
in the vert array are the same.

Use the patnpen_polyline function to draw a polyline with
four vertices. Also use the pen_polyline function to superimpose a
"thin" line on the "fat"  line to mark the position of the pen relative
to the specified polyline. The vertex coordinates given to both polyline 
functions are (16, 16), (64, 128), (128, 48), and (160, 48). 
This example includes the C header file gsptypes.h, which 
defines the PATTERN structure.

#include <gsptypes.h>	 /* define PATTERN structure */
#define  NVERTS    4	 /* number of vertices in polyline */

typedef struct { short x, y; } POINT;

static short amoeba[16] =
{				  /* 16x16 area-fill pattern */
    0x1008, 0x0C30, 0x03C0, 0x8001, 0x4002, 0x4002, 0x2004, 0x2004,
    0x2004, 0x2004, 0x4002, 0x4002, 0x8001, 0x03C0, 0x0C30, 0x1008,
};
static PATTERN fillpatn = { 16, 16, 1, (PTR)amoeba };
static POINT xy[NVERTS] =
{
    { 16, 16 }, { 64, 128 }, { 128, 48 }, { 160, 48 },
};

main()
{
    set_config(0, !0);
    clear_screen(0);
    set_patn(&fillpatn);
    set_pensize(24, 32);
    patnpen_polyline(NVERTS, xy);     /* fat polyline */
    set_pensize(2, 2);
    pen_polyline(NVERTS, xy);         /* thin polyline */
}

void pen_line(x1, y1, x2, y2)
short x1, y1;		/* start coordinates */
short x2, y2;		/* end coordinates */

The pen_line function draws draw a line with a pen and a solid 
color. The thickness of the line is determined by the width and 
height of the rectangular drawing pen. The area covered by 
the pen to represent the line is filled with the current foreground color.

Arguments x1 and y1 specify the starting x and y coordinates of the line. 
Arguments x2 and y2 specify the ending x and y coordinates of the line.

The pen is a rectangle whose width and height can be modified 
by means of the set_pensize function. At each point on the 
line drawn by the pen_line function, the pen is located with its
top left corner touching the line. The area covered by the pen
as it traverses the line from start to end is filled 
with a solid color.

Use the pen_line function to draw a thick line from 
(16, 16) to (128, 80) with a 5-by-3 pen. Use the draw_oval 
function to draw a small circle around the start point of the line.

main()
{
    short x1, y1, x2, y2, r;

    set_config(0, !0);
    clear_screen(0);
    set_pensize(5, 3);
    x1 = 16;
    y1 = 16;
    x2 = 128;
    y2 = 80;
    pen_line(x1, y1, x2, y2);
    r = 7;
    draw_oval(2*r, 2*r, x1-r, y1-r);
}

void pen_ovalarc(w, h, xleft, ytop, theta, arc)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */
short theta;		/* starting angle (degrees) */
short arc;		/* angle extent (degrees) */

The pen_ovalarc function draws an arc of an ellipse with a pen 
and a solid color. The ellipse from which the arc is taken is in
standard position, with the major and minor axes parallel to the 
coordinate axes. The ellipse is specified in terms of the enclosing 
rectangle in which it is inscribed. The area swept out by the 
pen as it traverses the arc is filled with the current 
foreground color. The thickness of the arc is determined by the 
width and height of the rectangular drawing pen.

The pen is a rectangle whose width and height can be modified by 
means of  the  set_pensize  function.  At  each  point  on  the  arc  
drawn  by  the   pen_ovalarc  function, the pen is located with its top 
left corner touching the arc. The area covered by the pen as 
it traverses the arc from start to end is filled with a solid color.

The first four arguments specify the rectangle enclosing the ellipse 
from which the arc is taken:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top 
	left corner of the rectangle and are defined relative to the 
	drawing origin.

The last two arguments define the limits of the arc and are specified in 
integer degrees:

	Argument theta specifies the starting angle and is measured 
	from the center of the right side of the enclosing rectangle.

	Argument arc specifies the arc's extent-that is, the number 
	of degrees (positive or negative) spanned by the angle. 

Both arguments are expressed in degrees of elliptical arc, with 360 degrees 
representing one full rotation around the ellipse. For both arguments, positive 

angles are in the clockwise direction, and negative angles are 
counterclockwise. Argument theta is treated as modulus 360. If the value of 
argument arc is outside the range [-359,+359], the entire ellipse is drawn.

Use the pen_ovalarc function to draw two thick arcs taken from an ellipse of 
width 132 and height 94. Also, draw the ellipse with the draw_oval function.

main()
{
    short w, h, x, y;

    set_config(0, !0);
    clear_screen(0);
    w = 132;
    h = 94;
    x = 10;
    y = 10;
    draw_oval(w, h, x, y);
    set_pensize(9, 9);
    pen_ovalarc(w, h, x, y, 0, 90);
    set_pensize(6, 6);
    pen_ovalarc(w, h, x, y, 135, 210-135);
}

void pen_piearc(w, h, xleft, ytop, theta, arc)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */
short theta;		/* starting angle (degrees) */
short arc;		/* angle extent (degrees) */

The pen_piearc function draws a pie-slice-shaped wedge from an ellipse with a 
pen and a solid color. The wedge is formed by an arc of the ellipse and by two 
straight lines that connect the two end points of the arc with the center of 
the ellipse. The ellipse from which the arc is taken is in standard position, 
with the major and minor axes parallel to the coordinate axes. The ellipse is 
specified in terms of the enclosing rectangle in which it is inscribed. The 
area swept out by the pen as it traverses the perimeter of the wedge is filled 
with the current foreground color. The thickness of the arc and two 
lines drawn to represent the wedge is determined by the 
width and height of the rectangular drawing pen.

The pen is a rectangle whose width and height can be modified by 
means of the set_pensize function. As the pen traverses the arc from 
start to end, the pen is located with its top left corner touching the arc. 
The two lines connecting the arc start and end points with the center 
of the ellipse are drawn in similar fashion, with the top left corner of 
the pen touching each line as it traverses the line from start to end.

The first four arguments specify the rectangle enclosing the ellipse from which 
the arc is taken:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the 
	top left corner of the rectangle and are defined relative 
	to the drawing origin.

The last two arguments define the limits of the arc and are specified in 
integer degrees:

	Argument theta specifies the starting angle and is measured  
	from the center of the right side of the enclosing rectangle.

	Argument arc specifies the arc's extent-that is, the 
	number of degrees (positive or negative) spanned by the angle. 

Both arguments are expressed in degrees of elliptical arc, with 360 degrees 
representing one full rotation around the ellipse. For both arguments, 
positive angles are in the clockwise direction, and negative angles are 
counterclockwise. Argument theta is treated as modulus 360. If the 
value of argument arc is outside the range [-359,+359], the entire 
ellipse is drawn.

Use the pen_piearc function to draw two pie slices taken from an ellipse 
of width 132 and height 94. Also, draw the ellipse with the 
draw_oval function.

main()
{
    short w, h, x, y;

    set_config(0, !0);
    clear_screen(0);
    w = 132;
    h = 94;
    x = 10;
    y = 10;
    draw_oval(w, h, x, y);
    set_pensize(7, 6);
    pen_piearc(w, h, x, y, 0, 90);
    set_pensize(4, 3);
    pen_piearc(w, h, x, y, 155, 250-155);
}

void pen_point(x, y)
short x, y;		/* pen coordinates */

The pen_point function draws a point with a pen and a solid color. 
Arguments x and y specify where the top left corner of the rectangular 
drawing pen is positioned. The resulting figure is a rectangle the 
width and height of the pen and filled with the current foreground color.

Use the pen_point function to draw a series of rectangular pens of 
increasing size.

main()
{
    short w, h, x, y;

    set_config(0, !0);
    clear_screen(0);
    x = y = 10;
    w = h = 1;
    for ( ; x < 140; w += 3, h += 2, x += 2*w, y += h) {
        set_pensize(w, h);
        pen_point(x, y);
    }
}

typedef struct { short x, y; } POINT;

void pen_polyline(n, vert)
short n;			/* vertex count */
POINT *vert;		/* vertex coordinates */

The pen_polyline function draws multiple, connected lines with a pen and a 
solid color. The thickness of the lines is determined by the width and height 
of the rectangular drawing pen. An array of x-y coordinates representing the 
polyline vertices is specified as one of the arguments. A line is drawn between 
each pair of adjacent vertices in the array. The area covered by the 
rectangular drawing pen as it traverses each line is drawn in the current 
foreground color.

Argument n specifies the number of vertices in the polyline; 
the number of lines drawn is n-1.

Argument vert is an array of integer x-y coordinates representing the polyline 
vertices in the order in which they are to be traversed. The x-y coordinate 
pairs 0 through n-1 of the vert  array contain the coordinates for the n 
vertices. The function draws a line between each adjacent pair of vertices in 
the array. Each vertex is represented by a 16-bit x-coordinate value followed 
by a 16-bit y-coordinate value. Coordinates are specified relative to the 
drawing origin.

Note that for the polyline to form a closed polygon, the calling program 
must ensure that the first and last vertices in the vert array are the same.

Use the pen_polyline function to draw a "fat" polyline. The polyline 
vertices are at coordinates (10, 10), (64, 96), (100, 48), and (140, 48).

#define  NVERTS  4    /* number of vertices in polyline */

typedef struct { short x, y; } POINT;

static POINT xy[NVERTS] =
{
    { 10, 10 }, { 64, 96 }, { 100, 48 }, { 140, 48 }
};

main()
{
    set_config(0, !0);
    clear_screen(0);
    set_pensize(5, 4);
    pen_polyline(NVERTS, xy);
}

void put_pixel(val, x, y)
unsigned long val;		/* pixel value */
short x, y;			/* pixel coordinates */

The put_pixel function sets a pixel on the screen to a specified value. 
Argument val is the value written to the pixel. Arguments x and y are the 
coordinates of the pixel, defined relative to the drawing origin. If the screen 
pixel size is n bits, the pixel value is contained in the n LSBs of argument 
val; the higher-order bits of val  are ignored.

Use the put_pixel function to rotate a text image on the screen by 45 
degrees. This example includes the C header file gsptypes.h, which 
defines the FONTINFO structure.

#include <gsptypes.h>	   /* define FONTINFO structure */

main()
{
    FONTINFO fontinfo;
    short xs, ys, xd, yd, w, h;
    unsigned long val;
    char *s;

    set_config(0, !0);
    clear_screen(0);
    s = "45-degree slant";
    get_fontinfo(0, &fontinfo);
    w = text_width(s);
    h = fontinfo.charhigh;
    xs = ys = 0;
    text_out(xs, ys, s);
    for (xd = h, yd = h; ys < h; ys++, xd = h-ys, yd = ys+h)
        for (xs = 0; xs < w; xs++, xd++, yd++) {
            val = get_pixel(xs, ys);
            put_pixel(val, xd, yd);
         }
 }

void seed_fill(x, y, buf, maxbytes)
short x, y;		/* seed pixel coordinates */
char *buf;		/* temporary buffer */
short maxbytes; 	/* buffer capacity in bytes */

The seed_fill function fills a connected region of pixels on the
screen with a solid color, starting at a specified seed pixel. 
All pixels that are part of the connected region that includes
the seed pixel are filled with the current foreground color.

The seed color is the original color of the specified seed pixel. All 
pixels in the connected region match the seed color before 
being filled with the foreground color.

The connected region filled by the function always includes the 
seed pixel. To be considered part of the connected region, a pixel 
must both match the seed color and be horizontally or vertically
adjacent to another pixel that is part of the connected region.
(Having a diagonally adjacent neighbor that is part of 
the region is not sufficient.)

Arguments x and y specify the coordinates of the seed pixel, 
defined relative to the current drawing origin.

The last two arguments specify the temporary buffer used
as a working storage during the seed fill. Argument buf  
is an array large enough to contain the temporary data that the 
function uses. Argument maxbytes is the number of 8-bit 
bytes available in the buf array. Working storage requirements
can be expected to increase with the complexity of 
the connected region being filled.

The seed_fill  function aborts (returns immediately) if any of these
conditions are detected:

	The seed pixel matches the current foreground color.

	The seed pixel lies outside the current clipping window.

	The storage buffer space specified by argument maxbytes is 
	insufficient to continue. 

In the last case, the function may have filled some portion of the connected 
region prior to aborting.

Use the seed_fill function to fill a connected region of pixels on the screen. 
Use the draw_rect function to draw a maze, the interior of which is filled by 
the seed_fill function.

#define  MAXBYTES   2048      /* size of temp buffer in bytes */

static char buf[MAXBYTES];    /* seed-fill temp buffer */

main()
{
    set_config(0, !0);
    clear_screen(0);

    /* Construct a maze consisting of 6 rectangles. */
    draw_rect(120, 80, 10, 10);
    draw_rect(10, 30, 35, 5);
    draw_rect(55, 10, 5, 40);
    draw_rect(10, 55, 65, 5);
    draw_rect(85, 10, 5, 65);
    draw_rect(10, 80, 95, 5);

    /* Now seed fill the interior of the maze. */
    seed_fill(20, 20, buf, MAXBYTES);
}

void seed_patnfill(x, y, buf, maxbytes)
short x, y;		/* seed pixel coordinates */
char *buf;	   	/* temporary buffer */
short maxbytes; 	/* buffer capacity in bytes */

The seed_patnfill function fills a connected region of 
pixels with a pattern, starting at a specified seed pixel. 
All pixels that are part of the connected region that includes 
the seed pixel are filled with the current area-fill pattern.

The seed color is the original color of the specified seed pixel. All 
pixels in the connected region match the seed color before 
being filled with the pattern.

The connected region filled by the function always includes the
seed pixel. To be considered part of the connected region, a 
pixel must both match the seed color and be horizontally or
vertically adjacent to another pixel that is part 
of the connected region. (Having a diagonally 
adjacent neighbor that is part of the region is not sufficient.)

Arguments x and y specify the coordinates of the seed pixel, 
defined relative to the current drawing origin.

The last two arguments specify a buffer used as a working 
storage during the seed fill. Argument buf   is an array 
large enough to contain the temporary data that the
function uses. Argument maxbytes is the number of 8-bit bytes 
available in the buf array. Working storage requirements can be 
expected to increase with the complexity of the 
connected region being filled.

The seed_patnfill  function aborts (returns immediately) if 
any of these conditions are detected:

	The seed pixel matches either the current 
	foreground color or background color. (The area-fill pattern 
	is rendered in these two colors.)

	The seed pixel lies outside the current clipping window.

	The storage buffer space specified by maxbytes
	is insufficient to continue. 

In the last case, the function may have filled some portion of the connected 
region prior to aborting.

Use the seed_patnfill function to fill a connected region of pixels on the 
screen with a pattern. Use the draw_rect function to draw a maze, the interior 
of which is filled by the seed_patnfill function. Note that the two colors in 
the area-fill pattern, white and blue, differ from the original color of the 
connected region, black. If either color in the pattern matches the seed pixel 
color, the seed_patnfill function will return immediately without drawing 
anything. This example includes the C header file gsptypes.h, which defines the 

PATTERN structure, and the header file colors.h, which defines the color BLUE.

#include <gsptypes.h>	 /* define PATTERN structure */
#include "colors.h"      	/* define color "BLUE" */
#define  MAXBYTES   2048      /* size of temp buffer in bytes */

static char buf[MAXBYTES];    /* seed-fill temp buffer */
static short snowflake[16] = {    /* area-fill pattern */
    0x0000, 0x01C0, 0x19CC, 0x188C, 0x0490, 0x02A0, 0x31C6, 0x3FFE,
    0x31C6, 0x02A0, 0x0490, 0x188C, 0x19CC, 0x01C0, 0x0000, 0x0000,
};
static PATTERN fillpatn = { 16, 16, 1, (PTR)snowflake };

main()
{
    short w, h, x, y, n;

    set_config(0, !0);
    clear_screen(0);
    set_patn(&fillpatn);

    /* Construct a maze consisting of 6 rectangles. */
    draw_rect(120, 80, 10, 10);
    draw_rect(10, 30, 35, 5);
    draw_rect(55, 10, 5, 40);
    draw_rect(10, 55, 65, 5);
    draw_rect(85, 10, 5, 65);
    draw_rect(10, 80, 95, 5);

    /* Fill the interior of the maze with a pattern. */
    set_bcolor(BLUE);
    seed_patnfill(20, 20, buf, MAXBYTES);
}

short select_font(id)
short id;		/* font identifier */

The select_font function selects one of the installed fonts 
for use by the text functions. The input argument, id, is valid only
if it identifies a font currently installed in the font table. Argument 
id must either be a valid identifier value returned by a previous 
call to the install_font function, or be 0, indicating selection 
of the system font.

A value of 0 is returned if the argument id is not valid; in this case, 
the function returns without attempting to select a new font. 
A nonzero value is returned if the selection is successful.

Use the select_font function to select a previously installed 
font. Use the install_font function to install three proportionally 
spaced fonts, and for each of the three fonts in turn, select the
font and use it to print a couple of lines of text to the screen. 
This example includes the C header file 
gsptypes.h, which defines the FONT and FONTINFO structures.

#include <gsptypes.h>	  /* define FONT and FONTINFO struct's */
#define  NFONTS     3	  /* number of fonts installed */

extern FONT ti_rom11, ti_rom14, ti_rom16;   /* 3 font names */

main()
{
    FONTINFO fontinfo;
    short i, n, x, y, index[NFONTS];

    set_config(0, !0);
    clear_screen(0);

    /* Install 3 proportionally-spaced fonts. */
    index[0] = install_font(&ti_rom11);
    index[1] = install_font(&ti_rom14);
    index[2] = install_font(&ti_rom16);

    /* Now select each of the three fonts in turn. */
    x = y = 10;
    for (i = 0; i < NFONTS; i++) {
	n = select_font(index[i]);  /* select next font */
	if (!n) {
	    select_font(0);         /* select system font */
	    text_out(x, y, "ERROR-- Font not installed!");
	    exit(1);
	}
	get_fontinfo(index[i], &fontinfo);
	text_out(x, y, "The quick brown fox jumped");
	y += fontinfo.charhigh;
	text_out(x, y, "over the lazy sleeping dog.");
	y += fontinfo.charhigh;
    }
}

void set_draw_origin(x, y)
short x, y;		/* new drawing origin */

The set_draw_origin function sets the position of the
drawing origin for all subsequent drawing operations 
to the screen. The coordinates specified for all 
drawing functions are defined relative to the drawing origin. 
The x and y axes for drawing operations pass through 
the drawing origin, with x increasing to 
the right, and y increasing in the downward direction.

Arguments x and y are the horizontal and vertical coordinates 
of the new drawing origin relative to the screen origin at the 
top left corner of the screen.

Use the set_draw_origin function to move the drawing 
origin to various locations on the screen. In each case, 
verify that subsequent text and graphics 
output are positioned relative to the current origin.

main()
{
    short x, y, w;
    char *s;

    set_config(0, !0);
    clear_screen(0);
    s = "abc";
    w = text_width(s);

    for (y = 10; y < 100; y += 50)
        for (x = 10; x < 100; x += 65) {
            set_draw_origin(x, y);
            draw_line(0, 0, 60-1, 45-1);
            draw_line(0, 45-1, 60-1, 0);
            text_out(30-w/2, 10, "abc");
            frame_rect(60, 45, 0, 0, 1, 1);
            frame_oval(60, 45, 0, 0, 3, 3);
        }
}

typedef long PTR;	/* 32-bit address */

void set_dstbm(baseaddr, pitch, xext, yext, psize)
PTR baseaddr;	/* bit map base address */
short pitch;		/* bit map pitch */
short xext, yext;	/* x and y extents */
short psize;		/* pixel size */

The set_dstbm function sets the destination bit map for 
subsequent drawing functions. Currently, only the bitblt 
function can write to a bit map other than the screen. All
other drawing functions abort (return without drawing 
anything) if the destination bit map is set to a bit map 
other than the screen.

Argument baseaddr  is a pointer to the destination bit map. 
Invoking the function with a baseaddr  value of 0 sets the 
destination bit map to the screen and causes the last four arguments 
to the function to be ignored. A nonzero 
baseaddr is interpreted as a pointer to a linear bit map; in other words, 
the destination bit map is contained in an off-screen buffer. 
The specified bit map should begin on an even pixel boundary 
in memory. For instance, when the pixel size is 32 bits, 
the 5 LSBs of the bit map's base address should be 0s.

Argument pitch is the difference in bit addresses from the 
start of one row of the bit map to the next. The bit map 
pitch must be specified as a multiple of 16.

Arguments xext and yext define the upper limits of the effective 
clipping window for a linear destination  bit map. The 
pixel having the lowest memory address in the window is 
the pixel at (0, 0), whose address is baseaddr. The 
pixel having the highest memory address in the window 
is the pixel at (xext, yext), whose address is calculated as 
   	address  =  baseaddr + yext*(pitch) + xext*(psize)
 In the case of a linear bit map, responsibility for clipping is left 
to the calling program.

Use the set_dstbm function to designate an off-screen buffer 
as the destination bit map. Contract an image from the screen 
to 1 bit per pixel and store the contracted image in the off-screen 
buffer. Next, expand the image from 1 bit per pixel to the screen
pixel size and copy to another area of the screen below 
the original image. This example includes the C header file 
gsptypes.h, which defines the FONT and FONTINFO structures.

#include <gsptypes.h>	      /* define FONT and FONTINFO */
#define  MAXBYTES   4096   /* size of image buffer in bytes */

static char image[MAXBYTES];
static FONTINFO fontinfo;

main()
{
    short w, h, x, y, pitch;
    char *s;

    set_config(0, !0);
    clear_screen(0);

    /* Print one line of text to screen. */
    x = y = 10;
    s = "Capture this text image.";
    text_out(x, y, s);
    w = text_width(s);
    get_fontinfo(0, &fontinfo);
    h = fontinfo.charhigh;

    /* Make sure buffer is big enough to contain image. */
    pitch = ((w + 15)/16)*16;
    if (pitch*h/8 > MAXBYTES) {
        text_out(x, y+h, "Image too big!");
        exit(1);
    }

    /* Capture text image from screen. */
    set_dstbm(image, pitch, w, h, 1);  /* off-screen bit map */
    bitblt(w, h, x, y, 0, 0);       /* contract */

    /* Now copy text image to another area of screen. */
    swap_bm();
    bitblt(w, h, 0, 0, x, y+h);        /* expand */
}

typedef long PTR;	/* 32-bit address */
typedef struct
{
	unsigned short width, height;
	unsigned short depth;
	PTR data;
} PATTERN;

void set_patn(ppatn)
PATTERN *ppatn;

The set_patn function sets the fill pattern for subsequent 
drawing operations. This pattern is used for drawing 
functions such as patnfill_rect and patnfill_oval that fill regions 
with patterns. All pattern-filling functions are easily identified 
by their function names, which include the four-letter 
descriptor patn.

Argument ppatn is a pointer to a PATTERN structure.

The fields of the PATTERN structure are defined as follows:

	Fields width and height specify the dimensions of the pattern.

	Field depth specifies the pixel size of the pattern.

	Field data is a pointer to a bit map containing the actual pattern.

Only two-color 16-by-16 patterns are currently supported by the 
pattern-fill drawing functions. This means that the fields width, 
height, and depth of the PATTERN structure pointed to by argument 
ppatn must be specified as 16, 16, and 1, respectively. The 
data field is assumed to be a pointer to a 16-by-16, 
1-bit-per-pixel bit map. A bit value of 1 in the pattern bit map 
specifies that the foreground color be used to draw the 
corresponding pixel; a bit value of 0 specifies the background color. 
The first pattern bit controls the pixel in the 
top left corner of the pattern; the last pattern bit 
controls the pixel in the bottom right corner.

The tiling of patterns to the screen is currently fixed relative 
to the top left corner of the screen. In other words, 
changing the drawing origin causes no shift in the mapping 
of the pattern to the screen, although the boundaries 
of the geometric primitives themselves (rectangles, ovals, 
and so on) are positioned relative to the drawing origin. The 
pixel at  screen coordinates  (x, y) is controlled by the bit at 
coordinates (x mod 16, y mod 16) in the pattern bit map.

The entire PATTERN structure is saved by the set_patn 
function, and the original structure pointed to by argument
ppatn need not be preserved following 
the call to the function. However, the actual bit map containing the 
pattern is not saved by the function; this bit map must be 
preserved by the calling program as long as the pattern remains in use.

During initialization of the drawing environment by the set_config 
function, the area-fill pattern is set to its default state, which is 
to fill with solid foreground color.

Use set_patn function to change the area-fill pattern. With each 
change in pattern, call the patnfill_rect function to tile the screen 
with alternating star and heart patterns. This example includes 
the C header file gsptypes.h, which defines the PATTERN structure.

#include <gsptypes.h>	   /* define PATTERN structure */

typedef struct { short row[16]; } PATNBITS;

static PATTERN fillpatn = { 16, 16, 1, (PTR)0 };
static PATNBITS patnbits[2] =
{
    {
        0x0000, 0x0000, 0x0E38, 0x1F7C,   /* heart pattern */
        0x3FFE, 0x3FFE, 0x3FFE, 0x3FFE,
        0x1FFC, 0x0FF8, 0x07F0, 0x03E0,
        0x01C0, 0x0080, 0x0000, 0x0000
    },
    {
        0xFFFF, 0xFF7F, 0xFF7F, 0xFF7F,   /* star pattern */
        0xFE3F, 0xFE3F, 0x8000, 0xE003,
        0xF007, 0xFC1F, 0xFC1F, 0xF80F,
        0xF9CF, 0xF3E7, 0xF7F7, 0xFFFF
    }
};

main()
{
    short x, y, index;

    set_config(0, !0);
    clear_screen(0);
    index = 0;
    for (x = 16; x < 160; x += 32)
        for (y = 16; y < 96; y += 32) {
            fillpatn.data = (PTR)&patnbits[index ^= 1];
            set_patn(&fillpatn);
            patnfill_rect(32, 32, x, y);
        }
}

void set_pensize(w, h)
short w, h;		/* pen width and height */

The set_pensize function sets the dimensions of the pen for 
subsequent drawing operations. The pen is a rectangular shape that is 
used by drawing functions such as pen_line and pen_ovalarc to 
sweep out wide lines and arcs. All functions that utilize the pen 
are easily identified by their function names, 
which include the three-letter descriptor pen.

Arguments w and h specify the width and height of the pen. The 
width and height are specified in terms of pixels.

A mathematically ideal line is infinitely thin. Conceptually, a 
function such as pen_line renders a wide line by positioning 
he top left corner of the pen to coincide with the ideal line as the pen is
moved from one end of the line to the other. The area swept out by 
the pen is filled with either a solid color 
(for instance, pen_line) or pattern (for instance, 
patnpen_line). Arcs are rendered in similar fashion.

Use set_pensize function to change dimensions of 
rectangular drawing pen. Draw a point and a line to 
show the effect of the change in pen size.

main()
{
    set_config(0, !0);
    clear_screen(0);

    /* Draw point and line with default pen. */
    pen_point(10, 10);
    pen_line(20, 10, 100, 30);

    /* Set pen dimensions to 8x6. */
    set_pensize(8, 6);

    /* Draw new point and line. */
    pen_point(10, 30);
    pen_line(30, 30, 110, 50);
}

typedef long PTR;	/* 32-bit address */

void set_srcbm(baseaddr, pitch, xext, yext, psize)
PTR baseaddr;		/* bit map base address */
short pitch;		/* bit map pitch */
short xext, yext;	/* x and y extents */
short psize;		/* pixel size */

The set_srcbm function sets the source bit map for  
subsequent drawing functions. Currently, only the bitblt and 
zoom_rect functions can access a 
source bit map other than the screen.

Argument baseaddr  is a pointer to the source bit map. Invoking
the function with a baseaddr value of 0 designates the screen as the
source bit map. In this case, the last four arguments are ignored 
by the function. A nonzero baseaddr is interpreted as a pointer to 
a linear bit map; that is, the source bit map is 
contained in an off-screen buffer. The specified bit map 
should begin on an even pixel boundary in memory. For instance, 
when the pixel size is 32 bits, the 5 LSBs of the bit map's base 
address should all be 0s.

Argument pitch is the difference in bit addresses from the 
start of one row of the linear bit map to the next. The value 
of pitch  must be specified as a multiple of 16.

Arguments xext  and yext  define the upper limits of the effective
clipping window for the linear bit map. The pixel having the 
lowest memory address in the window is the pixel at (0,0), 
whose address is baseaddr. The pixel having 
the highest memory address in the window is the pixel 
at (xext,yext), whose address is calculated as
 	address  =  baseaddr + yext*(pitch) + xext*(psize)
In the case of a linear bit map, responsibility for clipping 
is left to the application program.

Use the set_srcbm function to designate an off-screen 
buffer as the source bit map. Expand the image from 1 bit 
per pixel to the screen pixel size and copy 
the image to the screen.

#define  W	23      /* width of image in pixels */
#define  H	9       /* height of image in pixels */
#define  PITCH	32      /* pitch of image in bits */
#define  DEPTH	4       /* screen pixel size */
#define  MAXBYTES   DEPTH*W/8 /* zoom_rect buffer size in bytes */

static short image[H*PITCH/16] = {
    0xFFFF, 0x007F, 0x0001, 0x0040, 0x45D5, 0x005C,
    0x4455, 0x0054, 0x44DD, 0x0054, 0x4455, 0x0054,
    0xDDD5, 0x005D, 0x0001, 0x0040, 0xFFFF, 0x007F,
};
static char buf[4*W/8];     /* temp buffer for zoom_rect */

main()
{
    short x, y;

    set_config(0, !0);
    clear_screen(0);

    /* Expand image to screen. */
    x = y = 10;
    set_srcbm(image, PITCH, W, H, 1);  /* off-screen bit map */
    bitblt(W, H, 0, 0, x, y);

    /* Blow the image up so it's big enough to see. */
    set_srcbm(0, 0, 0, 0, 0);       /* screen */
    zoom_rect(W, H, x, y, 3*W, 3*H, x, y+2*H, buf);
}

short set_textattr(pcontrol, count, val)
char *pcontrol; 	/* control string */
short count;		/* val array length */
short *val;		/* array of attribute values */

The set_textattr function sets text-rendering attributes. The function 
provides control over text attributes such as alignment, 
additional intercharacter spacing, and intercharacter gaps. 
The attributes specified by the function remain in effect 
during subsequent calls to the install_font, select_font, and 
delete_font functions.

Argument pcontrol is a control string specifying the attributes 
(one or more) to be updated. Argument count is the number of 
elements in the val array and is also the number of asterisks in the
control string. Argument val is the array 
containing the attribute values designated by asterisks 
in the control string. The attribute values are contained in the 
consecutive elements of the val array, beginning with val [0], 
in the order in which they appear in the 
pcontrol string.

The following attributes are currently supported:

Symbol    	Attribute Description	Option Value
    %a	alignment	0 = top left, 1 = base line
    %e	additional intercharacter spacing	16-bit signed integer
    %f	fill gaps	0 = leave gaps, 1 = fill gaps
    %r	reset all options	ignored

Values associated with attributes can be specified either as 
immediate values in the control string or as values in the val array. 
When an attribute value is passed as a string literal, 
it should be placed between the percent (%) 
character and the attribute symbol. When an attribute value is
passed as a val array element, an asterisk (*) is placed between 
the percent character and the attribute symbol. Upon encountering
the asterisk, the function will retrieve the value from the val array
and increment its internal pointer to the next val array element.

The value returned by the function is the number of 
attributes successfully set.

Only the text attributes of proportionally spaced fonts can be 
modified by this function; the attributes of block fonts are fixed. 
Block fonts are characterized by uniform horizontal spacing between 
adjacent characters. Block fonts are always aligned to the top left 
corner of the character cell; that is, the position of a string of 
block text is always specified in terms of the x-y 
coordinates at the top left corner of the first character in the string. 
The intercharacter gaps between block-font characters are 
always filled with the background color.

The system font, font 0, is always a block font. Fonts installed 
by calls to the install_font function (identified by font indices 
1, 2, and so on) may be selected to be either block fonts 
or proportionally spaced fonts.

In the case of a proportionally spaced font, text alignment in 
the y dimension can be set either to the top of the character 
or to the base line of the character. Text alignment in the x 
dimension is fixed at the left edge of the character. Immediately 
following initialization of the drawing environment by 
the set_config function, the alignment is to the top left 
corner of the character, which is the default.

The additional intercharacter spacing attribute specifies 
how many extra pixels of space are to be added 
(or subtracted in the case of a negative value) to the 
default horizontal separation between adjacent characters, 
as specified in the FONT data structure. Immediately 
following initialization of the drawing environment by 
the set_config function, the additional intercharacter 
spacing is 0, which is the default.

The intercharacter gaps attribute controls whether the gaps 
between horizontally adjacent characters are automatically 
filled with the background color. When this attribute is 
enabled, one line of proportionally spaced text 
may be cleanly written directly on top of another without 
first erasing the text underneath. Immediately following 
initialization of the drawing environment by the set_config  
function, the filling of intercharacter gaps is 
disabled, which is the default.

Set the text alignment mode to top-left-corner position. This 
can accomplished by assigning the value 1 to attribute
symbol %a  by means of the literal 
method:

	set_textattr("%1a", 0, 0);

Note that in the example above the third argument is ignored 
by the function.

The same effect can be achieved by passing the attribute value 
in the val array. An asterisk is placed between the "%" and 
the "a" in the control  string, and val [0] contains the attribute 
value, 1:

	short val[1];
	val[0] = 1;
	set_textattr("%*a", 1, val);

The following example sets two attributes in a single call to 
set_textattr. It sets the text alignment mode to base line 
position using a literal value embedded in the control string, 
and sets the additional intercharacter spacing 
to -21 by passing the value through the val array:

	short val[1];
	val[0] = -21;
	set_textattr("%0a%*e", 1, val);

The same effect can be achieved by passing both values through the 
val array:

	short val[1];
	val[0] = 0;
	val[1] = -21;
	set_textattr("%*a%*e", 2, val);

Finally, the following function call resets all text attributes 
to their default values:

	set_textattr("%0r",0,0);

void styled_line(x1, y1, x2, y2, style, mode)
short  x1, y1;		/* start coordinates */
short  x2, y2;		/* end coordinates */
long style;		/* 32-bit line style pattern */
short mode		/* 1 of 4 drawing modes */

The styled_line function uses Bresenham's algorithm 
to draw a styled line from the specified start point to the 
specified end point. The line is a single 
pixel thick and is drawn in the specified line-style pattern.

Arguments x1 and y1 specify the starting coordinates of the
line. Arguments x2 and y2 specify the ending coordinates. 
Coordinates are specified relative to the drawing origin. 
The last two arguments, style and mode, specify the line 
style and drawing mode.

Argument style is a long integer containing a 32-bit 
repeating line-style pattern. Pattern bits are consumed 
in the order 0,1,...,31, where 0 is the rightmost bit (the LSB). 
The pattern is repeated modulo 32 as the line is 
drawn. A bit value of 1 in the pattern specifies that the
foreground color is used to draw the corresponding pixel. 
A bit value of 0 in the pattern means that the corresponding 
pixel is either drawn in the background color (drawing 
modes 1 and 3) or not drawn (modes 0 and 2).

The function supports four drawing modes:

mode 0 - 	Does not draw background pixels (leaves gaps); loads new 
		line-style pattern from style argument.

mode 1 - 	Draws background pixels, and loads new line-style pattern from 
		style argument.

mode 2 - 	Does not draw background pixels (leaves gaps); reuses old 
		line-style pattern (ignores style argument).

mode 3 - 	Draws background pixels and reuses old line-style pattern 
		(ignores style argument).

Drawing modes 2 and 3 support line-style pattern reuse 
in instances in which the pattern must be continuous across
two or more connecting lines. During the course of drawing 
a line of length n (in pixels), the original line-style 
pattern is rotated left (n-1) modulo 32 bits. The 
rotated pattern is always saved by the function before returning. 
The saved pattern is ready to be used 
as the pattern for a new line that continues from the end 
of the line just drawn.

During initialization of the drawing environment by the set_config
function, the line-style pattern is set to its default value, which is all 1s.

The current line-style pattern can be obtained by calling 
the get_env  function. See the get_env function 
description for more  information.

Use the styled_line function to draw four connected lines. 
The line-style pattern is continuous from one line segment to the next.

#define  DOTDASH    0x18FF18FF 	/* dot-dash line-style pattern */
#define  NEW        0	 	/* mode = load new line style */
#define  OLD        2		/* mode = re-use old line style */

main()
{
    set_config(0, !0);
    clear_screen(0);
    styled_line(10, 10, 140, 10, DOTDASH, NEW);
    styled_line(140, 10, 140, 60, 0, OLD);
    styled_line(140, 60, 95, 60, 0, OLD);
    styled_line(95, 60, 55, 100, 0, OLD);
}

void styled_oval(w, h, xleft, ytop, style, mode)
short w, h;		/* ellipse width and height */
short xleft, ytop;	/* top left corner */
long style;		/* 32-bit line-style pattern */
short mode;		/* selects 1 of 4 drawing modes */

The styled_oval function draws the styled outline of an ellipse, 
given the enclosing rectangle in which the ellipse is inscribed. 
The outline of the ellipse is only one pixel in thickness and 
is drawn using a 32-bit line-style pattern. The ellipse is in 
standard position, with its major and minor axes 
parallel to the coordinate axes.

The first four arguments specify the rectangle enclosing the ellipse:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the 
	top left corner of the rectangle and are defined relative to the 
	drawing origin. 

	If either the width or height is 0, the oval is not drawn.

The line-style pattern is specified in argument style, a long integer 
containing a 32-bit repeating line-style pattern. Pattern bits are consumed in 
the order 0,1,...,31, where bit 0 is the LSB. The pattern is repeated modulo 
32, as the ellipse is drawn. A bit value of 1 in the pattern specifies that the 
foreground color is used to draw the corresponding pixel. A bit value of 0 
means that the corresponding pixel is either drawn in the background color 
(modes 1 and 3) or not drawn (modes 0 and 2). The ellipse is drawn in the 
clockwise direction on the screen, beginning  at the rightmost  point of the 
ellipse if  w < h, or at the bottom of the ellipse if w . h.

The function supports four drawing modes:

mode 0 - 	Does not draw background pixels (leaves gaps); loads
		new line-style pattern from style argument.

mode 1 - 	Draws background pixels and loads new 
		line-style pattern from style argument.

mode 2 - 	Does not draw background pixels (leaves gaps); 
		reuses old line-style pattern (ignores style argument).

mode 3 - 	Draws background pixels and reuses old line-style 
		pattern (ignores style argument).

The (rotated) pattern is always saved by the function before returning. 
This pattern is available to draw a subsequent arc or line.

During initialization of the drawing environment by the set_config 
function, the line-style pattern is set to its default value, 
which is all 1s.

Use the styled_oval function to render the outline of an ellipse 
with a 32-bit repeating line-style pattern.

#define  DOTDASH   0x18FF18FF   /* dot-dash line-style pattern */

main()
{
    set_config(0, !0);
    clear_screen(0);
    styled_oval(130, 90, 10, 10, DOTDASH, 0);
}

void styled_ovalarc(w, h, xleft, ytop, theta, arc, style, 
									
							mode)
short w, h;		/* width and height		*/
short xleft, ytop;	/* top left corner		*/
short theta;		/* starting angle (degrees)	*/
short arc;		/* angle extent (degrees)	*/
long style;		/* 32-bit line-style pattern	*/
short mode;		/* selects 1 of 4 drawing modes */

The styled_ovalarc function draws a styled arc taken from an ellipse. The 
ellipse is in standard position, with the major and minor axes parallel to the 
x and y axes. The arc is drawn one pixel in thickness using the specified 
repeating line-style pattern. The ellipse from which the arc is taken is 
specified in terms of the enclosing rectangle in which it is inscribed.

The first four arguments specify the rectangle enclosing the ellipse from which 

the arc is taken:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates at the top 
	left corner of the rectangle and are defined relative to 
	the drawing origin. If either the width or height is 0, 
	the arc is not drawn.

The next two arguments define the limits of the arc and are specified in 
integer degrees:

	Argument theta specifies the starting angle and is measured 
	from the center of the right side of the enclosing rectangle.

	Argument arc specifies the arc's extent - that is, the 
	number of degrees (positive or negative) spanned by the angle. 

Both arguments are expressed in degrees of elliptical arc, with 
360 degrees representing one full rotation around the ellipse. 
For both arguments, positive angles are in the clockwise direction, 
and negative angles are counterclockwise. Argument theta is treated
as modulus 360. If the value of argument arc is outside the range 
[-359,+359], the entire ellipse is drawn.

Argument style is a long integer containing a 32-bit repeating 
line-style pattern. Pattern bits are consumed in the order 
0,1,...,31, where 0 is the rightmost bit (the LSB). The pattern
is repeated modulo 32 as the line is drawn. A bit value of 1 
in the pattern specifies that the foreground color is 
used to draw the corresponding pixel. A bit value of
0 in the pattern  means that the corresponding pixel 
is either drawn in the background color (drawing 
modes 1 and 3) or not drawn (modes 0 and 2).

The function supports four drawing modes:

mode 0 - 	Does not draw background pixels (leaves gaps); 
		loads new line-style pattern from style argument.

mode 1 - 	Draws background pixels and loads new line-style 
		pattern from style argument.

mode 2 - 	Does not draw background pixels (leaves gaps); 
		reuses old line-style pattern (ignores style argument).

mode 3 - 	Draws background pixels and reuses old line-style 
		pattern (ignores style argument).

The (rotated) pattern is always saved by the function before returning.
This pattern is available to draw a subsequent arc or line.

Use the styled_ovalarc function to draw two arcs that are rendered with a 
dot-dot-dash line-style pattern. Use the styled_line 
function to draw a line connecting the two arcs. The line-style 
pattern is continuous at the joints 
between the arcs and the line.

#define  DOTDOTDASH 0x3F333F33	/* ..-..- line-style pattern */
#define  NEW        0	/* mode = load new line style */
#define  OLD        2	/* mode = re-use old line style */

main()
{
    set_config(0, !0);
    clear_screen(0);
    styled_ovalarc(70, 70, 10, 65, 180, 90, DOTDOTDASH, NEW);
    styled_line(45, 65, 85, 65, -1, OLD);
    styled_ovalarc(110, 110, 30, -45, 90, -90, -1, OLD);
}

void styled_piearc(w, h, xleft, ytop, theta, arc, style,                        

                                    mode)
short w, h;		/* width and height */
short xleft, ytop;	/* top left corner */
short theta;		/* starting angle (degrees) */
short arc;		/* angle extent (degrees) */
long style;		/* 32-bit line-style pattern */
short mode;		/* selects 1 of 4 drawing modes */

The styled_piearc function draws a styled arc taken from an ellipse. Two 
straight, styled lines connect the two end points of the arc with the 
center of the ellipse. The ellipse is in standard position, with the
major and minor axes parallel to the x and y axes. The arc and the 
two lines from the center are drawn one pixel in thickness using 
the specified repeating line-style pattern. The ellipse from which 
the arc is taken is specified in terms of the enclosing 
rectangle in which it is inscribed.

The first four arguments specify the rectangle enclosing the 
ellipse from which the arc is taken:

	Arguments w and h specify the width and height of the rectangle.

	Arguments xleft and ytop specify the coordinates 
	at the top left corner of the rectangle and are defined 
	relative to the drawing origin. 

	If either the width or height is 0, the arc is not drawn.

The next two arguments define the limits of the arc and are specified in 
integer degrees:

	Argument theta specifies the starting angle and is 
	measured from the center of the right side of the 
	enclosing rectangle.

	Argument arc specifies the arc's extent - that is, the 
	number of degrees (positive or negative) spanned by the angle. 

Both arguments are expressed in degrees of elliptical arc, with 360 degrees 
representing one full rotation around the ellipse. For both arguments, 
positive angles are in the clockwise direction, and negative angles are 
counterclockwise. Argument theta is treated as modulus 360. If the
value of argument arc is outside the range [-359,+359], the entire 
ellipse is drawn.

Argument style is a long integer containing a 32-bit repeating line-style 
pattern. Pattern bits are consumed in the order 0,1,...,31, where 0 is the 
rightmost bit (the LSB). The pattern is repeated modulo 32 as the line is 
drawn. A bit value of 1 in the pattern specifies that the foreground color is 
used to draw the corresponding pixel. A bit value of 0 in the pattern means 
that the corresponding pixel is either drawn in background color 
(drawing modes 1 and 3) or not drawn (modes 0 and 2).

The function supports four drawing modes:

mode 0 - 	Does not draw background pixels (leaves gaps); loads 
	new line-style pattern from style argument.

mode 1 - 	Draws background pixels and loads new line-style
		pattern from style argument.

mode 2 - 	Does not draw background pixels (leaves gaps); 
		reuses old line-style pattern (ignores style argument).

mode 3 - 	Draws background pixels and reuses old line-style 
		pattern (ignores style argument).

Use the styled_piearc function to draw a pie slice taken from an 
ellipse of width 130 and height 90. The slice traverses a 
237-degree arc of the ellipse extending from -33 degrees to -270 
degrees, drawn in the counterclockwise 
direction around the perimeter of the ellipse.

#define  DOTDOTDASH 0x3F333F33	/* line-style pattern */

main()
{
    set_config(0, !0);
    clear_screen(0);
    styled_piearc(130, 90, 10, 10, -33, -270+33, DOTDOTDASH, 0);
}

void swap_bm()

The swap_bm function swaps the source and destination bit maps. 
To move pixels back and forth between two bit maps, this
function is more convenient than 
calling both the set_srcbm and set_dstbm functions.

Use the swap_bm function to swap the source and destination 
bit maps. Initially, the destination bit map is designated 
as an off-screen buffer, and the source bit map is the screen. 
A line of text is rendered on the screen, and its image is 
contracted from the screen pixel depth to one bit per pixel and 
stored in the off-screen buffer by a call to the bitblt  function. 
Following a call to swap_bm, the destination bit map is 
the screen, and the source bit map is the off-screen buffer. 
The captured image is copied to the screen three times 
by three calls to the bitblt  function. This example includes 
the C header file gsptypes.h, which defines the 
FONT and FONTINFO structures.

#include <gsptypes.h>	    /* define FONT and FONTINFO */
#define  MAXBYTES    2048   /* size of image buffer in bytes */

static char image[MAXBYTES];
static FONTINFO fontinfo;

main()
{
    short w, h, x, y, pitch;
    char *s;

    set_config(0, !0);
    clear_screen(0);

    /* Print one line of text to screen. */
    x = y = 10;
    s = "TEXT IMAGE";
    text_out(x, y, s);
    w = text_width(s);
    get_fontinfo(0, &fontinfo);
    h = fontinfo.charhigh;

    /* Make sure buffer is big enough to contain image. */
    pitch = ((w + 15)/16)*16;
    if (pitch*h/8 > MAXBYTES) {
        text_out(x, y+h, "Image won't fit!");
        exit(1);
    }

    /* Capture text image from screen. */
    set_dstbm(image, pitch, w, h, 1);  	/* off-screen bit map */
    bitblt(w, h, x, y, 0, 0);	/* contract */

    /* Now copy text image to 3 other areas of screen. */
    swap_bm();
    bitblt(w, h, 0, 0, x, y+h); 	/* expand copy #1 */
    bitblt(w, h, 0, 0, x, y+2*h);	/* expand copy #2 */
    bitblt(w, h, 0, 0, x, y+3*h);	/* expand copy #3 */
}

short text_width(s)
unsigned char *s;  	/* character string */

The text_width returns the width of the string in pixels, as if 
it were rendered using the current selected font and the current
set of text-drawing attributes. Argument s is a string of 8-bit 
ASCII character codes terminated by a null (0) character code.

Use the text_width function to enclose a line of text 
in a rectangular frame. This example includes the C header file 
gsptypes.h, which defines the FONTINFO 
structure.

#include <gsptypes.h>	/* define FONTINFO structure */
#define  DX	  5	/* frame thickness in x dimension */
#define  DY	  4	/* frame thickness in y dimension */

main()
{
    FONTINFO fontinfo;
    short w, h, x, y;
    char *s;

    set_config(0, !0);
    clear_screen(0);
    s = "Enclose this text.";
    get_fontinfo(0, &fontinfo);
    w = text_width(s);
    h = fontinfo.charhigh;
    x = y = 10;
    text_out(x+2*DX, y+2*DY, s);
    frame_rect(w+4*DX, h+4*DY, x, y, DX, DY);
}

void zoom_rect(ws, hs, xs, ys, wd, hd, xd, yd, rowbuf)
short ws, hs;		/* source width and height */
short xs, ys;		/* source top left corner */
short wd, hd		/* destination width and height	*/
short xd, yd;		/* destination top left corner	*/
char *rowbuf;	/* temporary row buffer */

The zoom_rect function expands or shrinks a
two-dimensional source array of pixels to fit the 
dimensions of a rectangular destination array on the screen. 
The source array may be either a rectangular area of the 
screen or a pixel array contained in an off-screen buffer. 
The width and height of the source array are specified 
independently from (and in general differ from) those of 
the destination array. Horizontal zooming is accomplished by 
replicating or collapsing (by deleting, for instance) columns of 
pixels from the source array to fit the width of the destination 
array. Vertical zooming is accomplished by 
replicating or collapsing rows of pixels from the source 
array to fit the height of the destination array. This type of
function is sometimes referred to as a stretch blit.

The source and destination arrays are contained within the 
currently selected source and destination bit maps; these bit maps 
are selected by calling the set_srcbm and set_dstbm functions 
before calling zoom_rect. Calling the set_config function with 
the init_draw argument set to a nonzero value causes 
both the source and destination bit maps to be set to the 
default bit map, which is the screen. The zoom_rect function requires 
that the pixel sizes for the source and destination bit maps 
be the same. The destination bit map must be the screen.

The first four arguments define the source array:

	Arguments ws and hs specify the width and height of the 
	source array.

	Arguments xs and ys specify the x and y displacements 
	of the top left corner of the source array from the origin.
	If the source bit map is the screen, the current drawing origin
	is used. If the source bit map is an 
	off-screen buffer, the origin lies at the bit map's base address, 
	as specified to the set_srcbm function.

The next four arguments define the destination array on the screen:

	Arguments wd and hd specify the width and height of the  
	destination array.

	Arguments xd and yd specify the x and y 
	coordinates at the top left corner of the source array, 
	defined relative to the drawing origin.

The final argument, rowbuf, is a buffer large enough to 
contain one complete row of either the destination array 
or the source array, whichever has the greater width. 
(A buffer the width of the screen will always be sufficient.) 
The required storage capacity in 8-bit bytes is calculated by 
multiplying the array width by the pixel size and dividing 
the result by 8.

Each of the following conditions is treated as an error that 
causes the zoom_rect function to abort (return immediately) 
without drawing anything:

	The destination is not the screen.

	The source and destination pixel sizes are not the same.

	The widths and heights specified for the source and 
	destination arrays are not all nonnegative. No value is
	returned by the function in any event.

Only the portion of the destination rectangle lying within the 
current clipping window is modified by this function. 
The source rectangle, however, is permitted to lie partially or 
entirely outside the clipping window, in which case the pixels 
lying within the source rectangle are zoomed to the 
destination, regardless of whether they are inside or outside 
the window. The applications programmer is responsible 
for constraining the size and position 
of the source rectangle to ensure that it encloses valid pixel values.

The only exception to this behavior occurs when the left or top 
edge of the source rectangle lies in negative screen coordinate 
space, in which case the function automatically clips the 
source rectangle to positive x-y coordinate 
space; in most systems, this means that the source is 
clipped to the top and left edges of the screen. The resulting
clipped source rectangle is zoomed to the destination rectangle and 
justified to the lower right corner of the 
specified destination rectangle. Portions of the 
destination rectangle corresponding to clipped portions of the 
source are not modified.

If the desired effect is to zoom a 1-bit-per-pixel bit map 
to the screen and the screen pixel size is greater than 1, 
the zoom operation must be done in two 
stages. First, the bitblt function is called to expand the original 
bit map to a color pixel array contained in an off-screen buffer. 
Second, the zoom_rect function is called to zoom the 
expanded pixel array from the off-screen buffer to the screen.

Shrinking in the horizontal direction causes some number of 
horizontally-adjacent source pixels to be collapsed to a 
single destination pixel. Similarly, shrinking in the 
vertical direction causes some number of 
vertically adjacent rows of source pixels to be collapsed 
to a single row in the destination array. When several 
source pixels are collapsed to a single 
destination pixel, they are combined with each other and 
with the destination background pixel according to 
the selected pixel-processing operation code. For 
example, the replace operation simply selects a
single source pixel to represent all the source pixels in the
region being collapsed. A better result 
can often be obtained by using a Boolean-OR 
operation (at 1 bit per pixel) or a 
max operation (at multiple bits per pixel).

The function internally disables transparency during the zoom 
operation but restores the original transparency state prior to returning.

The zoom_rect  function may yield unexpected results for the following pixel- 
processing operation codes:

PPOP Code	    Operation
7	    ~src AND ~dst
11	    ~src AND dst
13	    ~src OR dst
14	    ~src OR ~dst
15	    ~src

 When used in conjunction with the zoom_rect function, selecting these 
operations causes the source array to be 1s complemented not once, 
as might be expected, but twice.

The buffer specified by the rowbuf  argument is not used if 
all three of the following conditions are satisfied:

1)	The pixel-processing operation code is 0 (replace).

2)	The destination width and height are both greater than or 
	equal to the source width and height.

3)	The top of the destination rectangle does not lie above 
	the top of the screen (in negative-y screen space).

Use the zoom_rect function to blow up an area-fill pattern for closer 
inspection. The image is zoomed by a factor of 3. This example includes the C 
header file gsptypes.h, which defines the PATTERN structure.

#include <gsptypes.h>	   	/* define PATTERN structure */
#define  W	    48	/* width of source rectangle */
#define  H	    32	/* height of source rectangle */
#define  X	    12	/* left edge of source rectangle */
#define  Y	    12	/* top edge of source rectangle */
#define  Z	    3	/* zoom factor */
#define  DEPTH	    4	/* screen pixel size */
#define  MAXBYTES   DEPTH*Z*W/8  /* zoom_rect buffer size in bytes */

static short tinyblobs[16] =
{		/* 16x16 area-fill pattern */
    0x1008, 0x0C30, 0x03C0, 0x8001, 0x4002, 0x4002, 0x2004, 0x2004,
    0x2004, 0x2004, 0x4002, 0x4002, 0x8001, 0x03C0, 0x0C30, 0x1008,
};
static PATTERN fillpatn = { 16, 16, 1, (PTR)tinyblobs };
static char buf[MAXBYTES];

main()
{
    set_config(0, !0);
    clear_screen(0);
    set_patn(&fillpatn);
    patnfill_rect(W, H, X, Y);
    frame_rect(W, H, X, Y, 1, 1);
    zoom_rect(W, H, X, Y, Z*W, Z*H, X+W+10, Y, buf);
}

