From 43a13e2e02f2b92d912541ae3477b78f7ebd305c Mon Sep 17 00:00:00 2001
From: root <>
Date: Sun, 8 Feb 2009 17:13:33 +0000
Subject: *** empty log message ***

---
 src/cd/Makefile     |   52 ++
 src/cd/cd.announce  |   54 ++
 src/cd/cd.c         | 2372 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/cd/cd.h         |  209 +++++
 src/cd/cd.html      | 1156 +++++++++++++++++++++++++
 src/cd/cd1.2.lsm    |   11 +
 src/cd/cdmulti.c    |   98 +++
 src/cd/cdsimple.c   |  109 +++
 src/cd/cdtest.c     |  425 +++++++++
 src/cd/cdtext.c     |  135 +++
 src/cd/color16.c    |  186 ++++
 src/cd/defines.h    |   55 ++
 src/cd/makefile.bor |   51 ++
 src/cd/readme       |   52 ++
 14 files changed, 4965 insertions(+)
 create mode 100644 src/cd/Makefile
 create mode 100644 src/cd/cd.announce
 create mode 100644 src/cd/cd.c
 create mode 100644 src/cd/cd.h
 create mode 100644 src/cd/cd.html
 create mode 100644 src/cd/cd1.2.lsm
 create mode 100644 src/cd/cdmulti.c
 create mode 100644 src/cd/cdsimple.c
 create mode 100644 src/cd/cdtest.c
 create mode 100644 src/cd/cdtext.c
 create mode 100644 src/cd/color16.c
 create mode 100644 src/cd/defines.h
 create mode 100644 src/cd/makefile.bor
 create mode 100644 src/cd/readme

diff --git a/src/cd/Makefile b/src/cd/Makefile
new file mode 100644
index 0000000..8e77306
--- /dev/null
+++ b/src/cd/Makefile
@@ -0,0 +1,52 @@
+# Makefile for CGM Draw by G. Edward Johnson
+# You may need to modify this makefile
+
+CC=cc 
+AR=ar
+# CFLAGS= 
+#CFLAGS= -O -xF -Wa,-cg92
+CFALGS=-O
+LIBS=-L./ -lcd
+
+all: libcd.a cdtest color16 cdsimple cdtext cdmulti
+
+libcd.a: cd.h defines.h cd.o
+	rm -f libcd.a
+	$(AR) rc libcd.a cd.o
+
+cd.o: cd.c cd.h defines.h
+	$(CC) $(CFLAGS) -c cd.c
+
+testmain.o: testmain.c cd.h defines.h
+	$(CC) $(CFLAGS) -c testmain.c
+
+color16.o: color16.c cd.h defines.h
+	$(CC) $(CFLAGS) -c color16.c
+
+cdsimple.o: cdsimple.c cd.h defines.h
+	$(CC) $(CFLAGS) -c cdsimple.c
+
+cdtext.o: cdtext.c cd.h defines.h
+	$(CC) $(CFLAGS) -c cdtext.c
+
+cdmulti.o: cdmulti.c cd.h defines.h
+	$(CC) $(CFLAGS) -c cdmulti.c
+
+cdsimple: cdsimple.o libcd.a
+	$(CC) -o cdsimple cdsimple.o $(LIBS)
+
+color16: color16.o libcd.a
+	$(CC) -o color16 color16.o $(LIBS)
+
+cdtest: cdtest.o libcd.a
+	$(CC) -o cdtest cdtest.o $(LIBS)
+
+cdtext: cdtext.o libcd.a
+	$(CC) -o cdtext cdtext.o $(LIBS)
+
+cdmulti: cdmulti.o libcd.a
+	$(CC) -o cdmulti cdmulti.o $(LIBS)
+
+
+clean:
+	rm -f *.o *.a cdtest color16 cdsimple cdtext cdmulti
diff --git a/src/cd/cd.announce b/src/cd/cd.announce
new file mode 100644
index 0000000..e19a0ef
--- /dev/null
+++ b/src/cd/cd.announce
@@ -0,0 +1,54 @@
+
+
+Announcing the release of CGM Draw 1.2.
+
+CGM Draw is a freely available library for generating CGM files from a
+C program.  It has been tested on Solaris, Ultrix, Linux, IRIX, and DOS.
+CGM (Computer Graphics Metafile) is a vector graphics format that can be
+read by many popular packages.  With CGM Draw your code can quickly
+draw images complete with lines, arcs, rectangles, polygons, and text.
+CGM Draw is ideal for creating CGM files on the fly when you have
+a rapidly changing data set (such as in response to database queries.)
+
+
+Documentation for cd is included with the package, and is available from
+http://speckle.ncsl.nist.gov/~lorax/cgm/cd.html
+General information about CGM is available many places on the web, including 
+http://speckle.ncsl.nist.gov/~lsr/cgm.htm
+This distribution may be retrieved via ftp from
+zing.ncsl.nist.gov in the directory "cgm"  It will have the
+name cd followed by the version number.
+The current version is 1.2 and is at:
+ftp://zing.ncsl.nist.gov/cgm/cd1.2.tar.gz
+
+
+Whats new in this version:
+- New Text attributes for the direction and rotation of text
+- Multiple pictures can be put in a single cgm file
+- More example programs.
+
+
+What is CGM:
+CGM is a widely used method for representing 2D vector
+pictures.  Many industry users have decided to use CGM as the means of
+representing, storing, and interchanging pictures in all their documentation
+(e.g., Air Transport Association will use CGM to represent illustrations, US
+Petroleum industry has also adopted it).   
+CGM is already and established, open standard.  In 1987
+ISO approved the first version as an international standard, and the
+current version (which extends the original) was approved in 1992 (ISO
+8632.)  Many programs are already capable of creating CGM files.  Major
+illustration packages already can save their files in the CGM format
+(CorelDraw is one example) and many word processing programs (WordPerfect
+and Word) can include CGM files in their documents.
+
+
+What types of pictures is CGM suited for:
+CGM is ideally suited for pictures with geometric shapes, line drawings,
+and text.  Here are some particular applications that CGM would do well
+with:
+    Charts and Graphs--For instance charts of recent stock market data, or
+graphs of web server usage.
+    Technical illustrations--Diagrams for products or engineering drawings.
+CGM pictures can be zoomed in on to show small details.
+    General illustrations--Such as those you see in books or comic strips.
diff --git a/src/cd/cd.c b/src/cd/cd.c
new file mode 100644
index 0000000..97656f9
--- /dev/null
+++ b/src/cd/cd.c
@@ -0,0 +1,2372 @@
+
+/* cd.c main file for cgmdraw module.
+
+        Written by G. Edward Johnson <mailto:lorax@nist.gov>
+        Date: April 1996
+        Copyright: cd software produced by NIST, an agency of the 
+	U.S. government, is by statute not subject to copyright
+	in the United States. Recipients of this software assume all 
+	responsibilities associated with its operation, modification
+	and maintenance.
+ 
+        Portions of this package are from the gd package written by
+	Thomas Boutell and are copyright 1994, 1995, Quest Protein 
+	Database Center, Cold Spring Harbor Labs.  They are marked in the
+	source code.
+
+*/
+
+
+#include <malloc.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include "defines.h"
+#include "cd.h"
+
+
+cdImagePtr cdImageCreate(int sx, int sy)
+{
+	cdImagePtr im;
+	im = (cdImage *) calloc(SIZEOF(cdImage), 1);
+	if (!im) return 0; /* memory allocation failed */
+	/* elemlist is set to some number, when it is full, make it bigger */
+	im->elemlist = (unsigned char *) calloc(CDSTARTLISTSIZE, SIZEOF(unsigned char ) );
+	if (!im->elemlist) return 0; /* memory allocation failed */
+	im->sx = sx;
+	im->sy = sy;
+	im->colorsTotal = 0;
+	/* you can have multiple pictures in a file,  keep track of
+	 * which one you are on */
+	im->picnum = 10;
+	/* set line_width, line_height, line_color to the defaults */
+	/*gej: I should change these when I figure out what the defaults are */
+	im->ltype = CDLTYPE;
+	im->lwidth = CDLWIDTH;
+	im->lcolor = CDLCOLOR;
+	/* interior_style, fill_color, hatch_index */
+	im->shapestyle = CDSHAPESTYLE;
+	im->shapecolor = CDSHAPECOLOR;
+	im->shapehatch = CDSHAPEHATCH;
+	/* edge_type, edge_width, edge_color, edge_visibility */
+	im->edgetype = CDEDGETYPE;
+	im->edgecolor = CDEDGECOLOR;
+	im->edgewidth = CDEDGEWIDTH;
+	im->edgevis = CDEDGEVIS;
+	/* text_color, text_height, text_font */
+	im->textcolor = CDTEXTCOLOR;
+	im->textheight = CDTEXTHEIGHT;
+	im->textfont = CDTEXTFONT;
+	im->textpath = CDTEXTPATH;
+	/* the next three are used for maintaining the element list
+	 * don't change these ever */
+	im->bytestoend = CDSTARTLISTSIZE;
+	im->listlen = CDSTARTLISTSIZE;
+	im->curelemlist = im->elemlist;
+
+	cdCgmHeader(im);
+	return im;
+       
+}
+
+static int cdAppNull(unsigned char *es, int x) {
+/* put x  nulls in the string.
+ * return value is number of octets added (1) */
+	int y;
+
+	for(y=0; y<x; y++) {
+		*es = '\0';
+		es++;
+	}
+	return x;
+
+}
+
+static int cdAppByte(unsigned char *es, short int addme) {
+/* Append an octet to the end of es 
+ * Return value is number of octets added
+ * for internal cd functions only, do not call
+ */
+	*es = addme & 0377;
+	return 1;
+}
+
+static int cdAppShort(unsigned char *es, short int addme) {
+/* Append a short to the end of es 
+ * return value is number of octets added
+ * For internal cd functions only, do not call!
+ */
+	short int temp;
+
+	temp = addme >> 8;
+	*es = (unsigned char) temp & 0377;
+	es++;
+	*es = (unsigned char) addme & 0377;
+	return 2;
+}
+
+/* static int cdAppWord(unsigned char *es, int addme){ */
+/* Append an word to es 
+ * Return value is number of octets added
+ * For internal cd functions only, do not call!
+ */
+/*
+	int temp;
+	temp = addme >> 24;
+	*es = (unsigned char) temp & 0377;
+	es++;
+	temp = addme >> 16;
+	*es = (unsigned char) temp & 0377;
+	es++;
+	temp = addme >> 8;
+	*es = (unsigned char) temp & 0377;
+	es++;
+	*es = (unsigned char) addme & 0377;
+	es++;
+	return 4;
+}
+*/
+
+static int cdcomhead(unsigned char *es, int elemclass, int id, int len) {
+/* sets the command header in the first two bytes of string es 
+ * element class is in bits 15-12
+ * element id is in bits 11-5
+ * parameter list length is in bits 4-0
+ */
+	int temp;
+
+	if (!es) return 0; /* the string must be allocated first */
+
+	/* set the element class */
+	*es = (unsigned char) elemclass << 4;
+	/* set the element id */
+	temp = 0177 & id ;
+	temp = temp >> 3;
+	*es = *es | temp;
+	es++;
+	id = id << 5;
+	*es = (unsigned char) id;
+	*es = *es | (unsigned char) ( 037 & len );
+
+	return 1;
+}
+
+static int cdcomheadlong(unsigned char *es, int elemclass, int id, int len) {
+/* sets the command header for the long form.
+ * first 16 bits:
+ *  element class is in bits 15-12
+ *  element id is in bits 11-5
+ *  parameter list length is in bits 4-0 = 31
+ * second 16 bits:
+ *  bit 15 = 0  (for last partition)
+ *  bit 14-0 param list len
+ */
+
+	/* I'm lazy, call cdcomhead to set the first two bytes */
+	if (!cdcomhead(es, elemclass, id, 31)) return 0;
+	es += 2;
+
+	/* now set the second two bytes */
+	cdAppShort(es, (short int) len);
+	*es = *es & 0177; /* make bit 15 = 0 */
+	es += 2;
+
+	return 1;
+}
+static int cdcomheadlongp(unsigned char *es, int elemclass, int id) {
+/* sets the command header for the long form.
+ * first 16 bits:
+ *  element class is in bits 15-12
+ *  element id is in bits 11-5
+ *  parameter list length is in bits 4-0 = 31
+ * second 16 bits:
+ *  bit 15 = 0  (for last partition)
+ *  bit 14-0 param list len
+ */
+
+	/* I'm lazy, call cdcomhead to set the first two bytes */
+	if (!cdcomhead(es, elemclass, id, 31)) return 0;
+	es += 2;
+
+	return 1;
+}
+static int cdcomheadlongc(unsigned char *es, int part, int len) {
+/* sets the command header for the long form.
+ * second 16 bits:
+ *  bit 15 = 0  (for last partition)
+ *  bit 14-0 param list len
+ */
+
+	cdAppShort(es, (short int) len);
+	*es = *es & 0177; /* make bit 15 = 0 */
+	if (part) *es=(*es) | 128;
+	es += 2;
+
+	return 1;
+}
+
+static int cdAddElem(cdImagePtr im, unsigned char *es, int octet_count)
+/* adds a string, which is a CGM element to the elemlist.
+ * This function is called by other functions in this library and
+ * should NOT be called by users of the library
+ * For internal cd functions only, do not call!
+ */
+{
+	unsigned char *newlist; /* in case memory allocation fails */
+	int x; /* counter */
+
+	while ((octet_count + 1) >= im->bytestoend) {
+	/* not enough space, must grow elemlist */
+		im->listlen = im->listlen + CDGROWLISTSIZE;
+		newlist = (unsigned char *) realloc(im->elemlist, SIZEOF(unsigned char ) * im->listlen);
+		if (newlist) {
+		/* successfully allocated memory */
+			im->elemlist = newlist;
+			im->bytestoend = im->bytestoend + CDGROWLISTSIZE;
+			im->curelemlist = im->elemlist + (im->listlen - im->bytestoend);
+		}
+		else {
+		/* memory allocation failed, save yurself */
+			im->listlen = im->listlen - CDGROWLISTSIZE;
+			return 0;
+		}
+	}
+
+	/* ok, if we get to here, there is enough space, so add it. */
+	for (x=0; x < octet_count; x++) {
+		*im->curelemlist = (unsigned char) *es;
+		im->curelemlist++;
+		es++;
+	}
+	im->bytestoend = im->bytestoend - octet_count;
+	return 1;
+
+}
+
+int cdCgmHeader(cdImagePtr im) {
+/* add the cgm header to the imagepointer's  element list
+ * do it all in a string than call cdAddElem on it
+ * For internal cd functions only, do not call!
+ */
+	unsigned char *headerp;
+	unsigned char *head;
+	unsigned char *buf, *buf2;
+	int octet_count=0;
+	int blen; /* length of buf */
+	int curly;
+
+	headerp = (unsigned char *) calloc(1024, SIZEOF(unsigned char ));
+        if (!headerp) return 0; /* memory allocation failed */
+	head=headerp;
+
+	/*** Attribute: BegMF; Elem Class 0; Elem ID 1 */
+	buf = (unsigned char *) "cd: CgmDraw Library";
+	blen = strlen( (char *) buf);
+	cdcomhead(head, 0, 1, blen+1);
+	head += 2;
+	head += cdAppByte(head, (short int) blen); 
+	buf2 = buf;
+	while (*buf2) {
+		*head++ = *buf2++;
+	}
+	octet_count += (blen + 3);
+	curly = 4 - (octet_count % 4);
+	if (curly % 4) {
+		octet_count += curly;
+		head += cdAppNull(head, curly);
+	}
+
+	/*** Attribute: MFVersion; Elem Class 1; Elem ID 1 */
+	cdcomhead(head, 1, 1, 2);
+	head += 2;
+	head += cdAppShort(head, (short int) 1);
+	octet_count += 4;
+
+	/*** Attribute: MFDesc; Elem Class 1; Elem ID 2 */
+	buf = (unsigned char *) "'ProfileId: Model-Profile''ProfileEd:1''ColourClass:colour''Source:Nist CGMDraw 1.2''Date: 1996-06-28'";
+	blen = strlen( (char *) buf);
+	cdcomheadlong(head, 1, 2, blen+1);
+	head += 4;
+	head += cdAppByte(head, (short int) blen); 
+	buf2 = buf;
+	while (*buf2) {
+		*head++ = *buf2++;
+	}
+	octet_count += (blen + 5);
+	curly = 4 - (octet_count % 4);
+	if (curly % 4) {
+		octet_count += curly;
+		head += cdAppNull(head, curly);
+	}
+
+	/*** Attribute: ColrPrec; Elem Class 1; Elem ID 7 */
+	cdcomhead(head, 1, 7, 2);
+	head += 2;
+	head += cdAppShort(head, (short int) 8);
+	octet_count += 4;
+
+	/*** Attribute: ColrIndexPrec; Elem Class 1; Elem ID 8 */
+	cdcomhead(head, 1, 8, 2);
+	head += 2;
+	head += cdAppShort(head, (short int) 8);
+	octet_count += 4;
+
+	/*** Attribute: MaxColrIndex; Elem Class 1; Elem ID 9 */
+	cdcomhead(head, 1, 9, 1);
+	head += 2;
+	head += cdAppByte(head, (short int) 255);
+	octet_count += 4; head++;
+
+	/*** Attribute: MFElemList; Elem Class 1; Elem ID 11 */
+	/* shorthand here.  1 means 1 element specified, (-1,1)
+	 * means drawing-plus-control set */
+	cdcomhead(head, 1, 11, 6);
+	head += 2;
+	head += cdAppShort(head, (short int) 1);
+	head += cdAppShort(head, (short int) -1);
+	head += cdAppShort(head, (short int) 1);
+	octet_count += 8;
+
+	/*** Attribute: FontList; Elem Class 1; Elem ID 13 */
+	cdcomheadlong(head, 1, 13, 112);
+	head +=4;
+	buf = (unsigned char *) "Times";
+	blen = strlen( (char *) buf);
+	head += cdAppByte(head, (short int) blen); 
+	buf2 = buf;
+	while (*buf2) {
+		*head++ = *buf2++;
+	}
+	buf = (unsigned char *) "Times Bold";
+	blen = strlen( (char *) buf);
+	head += cdAppByte(head, (short int) blen); 
+	buf2 = buf;
+	while (*buf2) {
+		*head++ = *buf2++;
+	}
+	buf = (unsigned char *) "Times Italic";
+	blen = strlen( (char *) buf);
+	head += cdAppByte(head, (short int) blen); 
+	buf2 = buf;
+	while (*buf2) {
+		*head++ = *buf2++;
+	}
+	buf = (unsigned char *) "Times Bold Italic";
+	blen = strlen( (char *) buf);
+	head += cdAppByte(head, (short int) blen); 
+	buf2 = buf;
+	while (*buf2) {
+		*head++ = *buf2++;
+	}
+	buf = (unsigned char *) "Helvetica";
+	blen = strlen( (char *) buf);
+	head += cdAppByte(head, (short int) blen); 
+	buf2 = buf;
+	while (*buf2) {
+		*head++ = *buf2++;
+	}
+	buf = (unsigned char *) "Helvetica Bold";
+	blen = strlen( (char *) buf);
+	head += cdAppByte(head, (short int) blen); 
+	buf2 = buf;
+	while (*buf2) {
+		*head++ = *buf2++;
+	}
+	buf = (unsigned char *) "Helvetica Italic";
+	blen = strlen( (char *) buf);
+	head += cdAppByte(head, (short int) blen); 
+	buf2 = buf;
+	while (*buf2) {
+		*head++ = *buf2++;
+	}
+	buf = (unsigned char *) "Helvetica Bold Italic";
+	blen = strlen( (char *) buf);
+	head += cdAppByte(head, (short int) blen); 
+	buf2 = buf;
+	while (*buf2) {
+		*head++ = *buf2++;
+	}
+	octet_count += (4 + 112);
+	curly = 4 - (octet_count % 4);
+	if (curly % 4) {
+		octet_count += curly;
+		head += cdAppNull(head, curly);
+	}
+
+
+	if (cdAddElem(im, headerp, octet_count)) {
+		free(headerp);
+		headerp = 0;
+	}
+	else {
+		free(headerp);
+		return 0;
+	}
+
+	if (cdCgmPic(im, 0)) {
+		return 1;
+	}
+	else {
+		return 0;
+	}
+}
+
+
+int cdCgmPic(cdImagePtr im, int sticky) {
+/* Start the picture.  if the sticky bit is set, set and use the defaults
+ * of the previous picture.  Otherwise, reset all defaults.
+ * Gej:  Right now, will only work if the sticky bit is not set (is 0)
+ */
+	unsigned char *headerp;
+	unsigned char *head;
+	unsigned char *buf, *buf2;
+	char *tb;
+	int octet_count=0;
+	int blen; /* length of buf */
+
+	/* increment the picture number */
+	im->picnum++;
+	tb = (char *) calloc(4*4, SIZEOF(char) );
+	headerp = (unsigned char *) calloc(1024, SIZEOF(unsigned char ));
+        if (!headerp) return 0; /* memory allocation failed */
+	head=headerp;
+
+
+	/*** Attribute: BegPic; Elem Class 0; Elem ID 3 */
+	sprintf(tb, "picture %d", im->picnum);
+	buf = (unsigned char*) tb;
+	/* buf = (unsigned char *) "picture 1"; */
+	blen = strlen( (char *) buf);
+	cdcomhead(head, 0, 3, blen+1);
+	head += 2;
+	head += cdAppByte(head, (short int) blen); 
+	buf2 = buf;
+	while (*buf2) {
+		*head++ = *buf2++;
+	}
+	octet_count += (blen + 3);
+	if (!(blen % 2)) {
+		octet_count++;
+		head += cdAppNull(head, 1);
+	}
+	if (octet_count % 4) {
+		octet_count +=2;
+		head += cdAppNull(head, 2);
+	}
+
+	/*** Attribute: ColrMode; Elem Class 2; Elem ID 2 */
+	cdcomhead(head, 2, 2, 2);
+	head += 2;
+	head += cdAppShort(head, (short int) 0);
+	octet_count += 4;
+
+	/*** Attribute: VDCExt; Elem Class 2; Elem ID 6 */
+	cdcomhead(head, 2, 6, 8);
+	head += 2;
+	head += cdAppShort(head, (short int) 0);
+	head += cdAppShort(head, (short int) 0);
+	head += cdAppShort(head, (short int) im->sx);
+	head += cdAppShort(head, (short int) im->sy);
+	octet_count += 10;
+
+	/*** Attribute: ColrPrec; Elem Class 0; Elem ID 4 */
+	cdcomhead(head, 0, 4, 0);
+	head += 2;
+	octet_count += 2;
+
+	if (sticky) {
+	/* gej: were screwed. This isn't implemented yet */
+		free(headerp);
+		return 0;
+	}
+	else {
+	/* reset all the defaults */
+		/* set line_width, line_height, line_color to the defaults */
+		im->ltype = CDLTYPE;
+		im->lwidth = CDLWIDTH;
+		im->lcolor = CDLCOLOR;
+		/* interior_style, fill_color, hatch_index */
+		im->shapestyle = CDSHAPESTYLE;
+		im->shapecolor = CDSHAPECOLOR;
+		im->shapehatch = CDSHAPEHATCH;
+		/* edge_type, edge_width, edge_color, edge_visibility */
+		im->edgetype = CDEDGETYPE;
+		im->edgecolor = CDEDGECOLOR;
+		im->edgewidth = CDEDGEWIDTH;
+		im->edgevis = CDEDGEVIS;
+		/* text_color, text_height, text_font */
+		im->textcolor = CDTEXTCOLOR;
+		im->textheight = CDTEXTHEIGHT;
+		im->textfont = CDTEXTFONT;
+		im->textpath = CDTEXTPATH;
+		/* Nuke the color table if there is one */
+		cdImageColorClear(im);
+	}
+
+
+	if (cdAddElem(im, headerp, octet_count)) {
+		free(headerp);
+		return 1;
+	}
+	else {
+		free(headerp);
+		return 0;
+	}
+
+} 
+
+int cdCgmNewPic(cdImagePtr im, int sticky)
+/* The CGM standard allows multiple images in a single file.  This function
+ * will close the current picture, then open a new one.
+ * if sticky is 0 then all attributes will be reset to the defaults
+ * if sticky is 1 then all attributes will be inherited from the prevous
+ * picture.  This is currently not implemented, be sure to set sticky to
+ * 0.
+ */
+{
+	unsigned char *es, *esp;
+	int octet_count=0;
+
+	esp = (unsigned char *) calloc(1024, SIZEOF(unsigned char ));
+        if (!esp) return 0; /* memory allocation failed */
+	es=esp;
+
+	/* Attribute: End Picture; Elem Class 0; Elem ID 5; Length 0  */
+	cdcomhead(es, 0, 5, 0);
+	octet_count += 2;
+
+
+	if (cdAddElem(im, esp, octet_count)) {
+		free(esp);
+	}
+	else {
+		free(esp);
+		return 0;
+	}
+
+	/* now start the new picture */
+	return(cdCgmPic(im, sticky));
+
+
+}
+
+int cdImageCgm(cdImagePtr im, FILE *out)
+/* Gej: Write the image to  file *out, which must be open already
+ * does not close the file */
+{
+	int x; /* counter */
+	int used; /* number of bytes used in the list */
+	unsigned char *efile, *efilep; /* end of file information */
+ 	efile = (unsigned char *) calloc(4*4,SIZEOF(unsigned char ));
+        if (!efile) return 0; /* memory allocation failed */
+        efilep=efile;
+	/* Attribute: End Picture; Elem Class 0; Elem ID 5 */
+	*efilep = '\0';
+	efilep++;
+	*efilep = '\240'; /* set Elem ID */
+	efilep++;
+	/* Attribute: End Metafile; Elem Class 0; Elem ID 2 */
+	*efilep = '\0';
+	efilep++;
+	*efilep = '\100'; /* set Elem ID */
+
+
+        if (cdAddElem(im, efile, 4)) {
+                free(efile);
+		efile = 0;
+		efilep = 0;
+        }
+        else {
+                free(efile);
+                return 0;
+        }
+
+	/* now output the string, one byte at a time */
+	used = im->listlen - im->bytestoend;
+	for (x=0;x < used; x++) {
+		putc((unsigned char) im->elemlist[x], out);
+	}
+
+	return 1;
+
+}
+
+
+int cdSetLineType(cdImagePtr im, int lntype) {
+/* Attribute: Line Type; Elem Class 5; Elem ID 2
+ * Set the line type.  Possible values are:
+ * 1=solid, 2=dash, 3=dot, 4=dash-dot, 5=dash-dot-dot
+ * Even though new ones can be defined, I am limiting lntype to these values
+ * If you really need more, you can make the proper changes.
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (lntype == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (lntype == im->ltype)
+		return 1;
+
+	/* Make sure that lntype is between 1 and 5 */
+	if ((lntype < 1) || (lntype > 5))
+		return 0;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	if (!cdcomhead(es, 5, 2, 2)) return 0;
+	es += 2;
+	/* set Param_List_Len to 2 (signed int at index precision) */
+
+	/* add in the value of lntype */
+	es += cdAppShort(es, (short int) lntype);
+
+	octet_count = 4; /* we just know this */
+
+	/* add it to the buffer */
+	if (cdAddElem(im, esp, octet_count)) {
+		im->ltype = (short int) lntype;
+		free(esp);
+		return 1;
+	}
+	else {
+		free(esp);
+		return 0;
+	}
+
+}
+
+int cdSetLineWidth(cdImagePtr im, int lnwidth) {
+/* Attribute: Line Width; Elem Class 5; Elem ID 3
+ * sets the line width.  with an image of height X with line width 1
+ * the displayed width will be 1/X%.  as an example, if you image is
+ * x=5, y=10, and you set line width = 1, and draw a vertical line, the
+ * resulting line will  cover 20% of horizontal area.
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (lnwidth == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (lnwidth == im->lwidth)
+		return 1;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+
+	octet_count = 2;
+	if (!cdcomhead(es, 5, 3, 4)) return 0;
+	es += 2;
+	/*gej: line width is 32 bit floating point number, 16 bits before the
+	 * decimal, 16 bits after.   */
+
+	es += cdAppShort(es, (short int) lnwidth);
+
+	/* the next two (after decimal point) will always be zero */
+	es += cdAppNull(es, 2);
+
+	octet_count += 4;
+	
+	
+	/* add it to the buffer */
+	if (cdAddElem(im, esp, octet_count)) {
+		im->lwidth = lnwidth;
+		free(esp);
+		return 1;
+	}
+	else {
+		free(esp);
+		return 0;
+	}
+
+
+}
+
+int cdSetLineColor(cdImagePtr im, int lncolor) {
+/* Attribute: Line Colour; Elem Class 5; Elem ID 4
+ * Sets the line color.  lncolor should be an index into the color
+ * table that you have previously allocated.
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (lncolor == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (lncolor == im->lcolor)
+		return 1;
+
+	/* Make sure the color they want to use has been allocated. 
+	 * also, that color must be non-negative */
+	if ((lncolor >= im->colorsTotal ) || (lncolor < 0))
+		return 0;  /* you must allocate a color before you use it */
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+
+	if (!cdcomhead(es, 5, 4, 1)) return 0;
+	es += 2;
+
+	*es =  0377 & lncolor; /* mask off last 8 bits and put in es */
+	es++;
+
+	es += cdAppNull(es, 1);
+
+	octet_count = 4; /* we just know this; 2 octets of header,
+	                  * 1 octet of data, 1 octet of null data */
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+		im->lcolor = (short int) lncolor;
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+
+}
+
+int cdSetFillStyle(cdImagePtr im, int instyle) {
+/* set the style of the interior of filled area elements.
+ * Attribute: Interior Style; Elem Class 5; Elem ID 22
+ * These attributes stay in effect until changed, so you don't have to output
+ * them every time.
+ *     Interior Style: (integers 0-6, corresponding to: hollow, solid,
+ *                      [not pattern], hatch, empty, [not geometric pattern],
+ *                      interpolated.)
+ * attribute is 16 bit signed int
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (instyle == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (instyle == im->shapestyle)
+		return 1;
+
+	/* Make sure that lnhatch is between 0 and 6, but not
+	 * 2, 5, or 6 */
+	if ((instyle < 0) || (instyle > 4) || (instyle == 2))
+		return 0;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	/* set the header to Class 5, ID 22, Length 2 */
+	if (!cdcomhead(es, 5, 22, 2)) return 0;
+	es += 2;
+
+	/* add in the value of inhatch */
+	es += cdAppShort(es, (short int) instyle);
+
+	octet_count = 4; /* we just know this */
+
+	/* add it to the buffer */
+	if (cdAddElem(im, esp, octet_count)) {
+		im->shapestyle = (short int) instyle;
+		free(esp);
+		return 1;
+	}
+	else {
+		free(esp);
+		return 0;
+	}
+
+
+}
+
+int cdSetFillColor(cdImagePtr im, int incolor) {
+/* set the color of the interior of filled area elements
+ * Attribute: Fill Colour; Elem Class 5; Elem ID 23
+ * These attributes stay in effect until changed, so you don't have to output
+ * them every time.
+ *     Fill Colour: (index into the color table)
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (incolor == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (incolor == im->shapecolor)
+		return 1;
+
+	/* Make sure the color they want to use has been allocated. 
+	 * also, that color must be non-negative */
+	if ((incolor >= im->colorsTotal ) || (incolor < 0))
+		return 0;  /* you must allocate a color before you use it */
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	if (!cdcomhead(es, 5, 23, 1)) return 0;
+	es += 2;
+
+	*es =  0377 & incolor; /* mask off last 8 bits and put in es */
+	es++;
+	es += cdAppNull(es, 1);
+
+	octet_count = 4; /* we just know this; 2 octets of header,
+	                  * 1 octet of data, 1 octet of null data */
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+		im->shapecolor = (short int) incolor;
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+
+
+}
+
+int cdSetFillHatch(cdImagePtr im, int inhatch) {
+/* Set the hatch pattern for the interior of filled-area elements
+ * the fill style must be set to hatch for this to have an effect.
+ * Attribute: Hatch Index; Elem Class 5; Elem ID 24
+ * These attributes stay in effect until changed, so you don't have to output
+ * them every time.
+ *     Hatch Index: (integers 1-6, corresponding to: horizontal lines,
+ *                   vertical lines, pos. slope parallel lines,
+ *                   neg. slope parallel lines, horizontal/vertical
+ *                   crosshatch, positive/negative slope crosshatch)
+ */
+
+	unsigned char *es, *esp;
+	int octet_count, temp;
+
+
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (inhatch == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (inhatch == im->shapehatch)
+		return 1;
+
+	/* Make sure that lnhatch is between 1 and 6 */
+	if ((inhatch < 1) || (inhatch > 6))
+		return 0;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	/* set the command header to class 5, id 24, length 2 */
+	if (!cdcomhead (es, 5, 24, 2)) return 0;
+	es += 2;
+
+	/* add in the value of inhatch */
+	temp = inhatch >> 8;
+	*es = *es | (temp & 0377);
+	es++;
+	*es = *es | (inhatch & 0377);
+	es++;
+
+	octet_count = 4; /* we just know this */
+
+	/* add it to the buffer */
+	if (cdAddElem(im, esp, octet_count)) {
+		im->shapehatch = (short int) inhatch;
+		free(esp);
+		return 1;
+	}
+	else {
+		free(esp);
+		return 0;
+	}
+
+}
+
+int cdSetEdgeType(cdImagePtr im, int edtype) {
+/* set the type of the edge of filled-area elements.
+ * Attribute: Edge Type; Elem Class 5; Elem ID 27
+ * These attributes stay in effect until changed, so you don't have to output
+ * them every time.
+ *     Edge Type (integers 1-5, corresponding to: solid, dash, dot,
+ *                dash-dot, dash-dot-dot. These are the same as those used
+ *                for line type.)
+ * In Part 3 of the standard (Binary Encoding) on page 47 it says that
+ * edge type is integer.  This is incorrect.  Edge type is Index, just
+ * like line type.
+ * Even though new ones can be defined, I am limiting lntype to these values
+ * If you really need more, you can make the proper changes.
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (edtype == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (edtype == im->edgetype)
+		return 1;
+
+	/* Make sure that lntype is between 1 and 5 */
+	if ((edtype < 1) || (edtype > 5))
+		return 0;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	if(!cdcomhead(es, 5, 27, 2)) return 0;
+	es += 2;
+
+	/* add in the value of edtype */
+	es += cdAppShort(es, (short int) edtype);
+
+	octet_count = 4; /* we just know this */
+
+	/* add it to the buffer */
+	if (cdAddElem(im, esp, octet_count)) {
+		im->edgetype = (short int) edtype;
+		free(esp);
+		return 1;
+	}
+	else {
+		free(esp);
+		return 0;
+	}
+
+
+}
+
+int cdSetEdgeWidth(cdImagePtr im, int edwidth) {
+/* Set the width of the edge of filled-area elements.
+ * Attribute: Edge Width; Elem Class 5; Elem ID 28
+ * These attributes stay in effect until changed, so you don't have to output
+ * them every time.
+ *     Edge Width (should be the same as line width)
+ */
+	unsigned char *es, *esp;
+	int octet_count, temp;
+
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (edwidth == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (edwidth == im->edgewidth)
+		return 1;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	octet_count = 2;
+	if (!cdcomhead(es, 5, 28, 4)) return 0;
+	es += 2;
+
+	/*gej: edge width is 32 bit floating point number, 16 bits before the
+	 * decimal, 16 bits after.   */
+	es++; octet_count++;
+	temp = edwidth >> 8;
+	*es = *es | (temp & 0377);
+	es++; octet_count++;
+	*es = *es | (edwidth & 0377);
+	/* the next two (after decimal point) will always be zero */
+	es += cdAppNull(es, 2);
+	octet_count+=2;
+	
+	
+	/* add it to the buffer */
+	if (cdAddElem(im, esp, octet_count)) {
+		im->edgewidth = edwidth;
+		free(esp);
+		return 1;
+	}
+	else {
+		free(esp);
+		return 0;
+	}
+
+
+
+}
+
+int cdSetEdgeColor(cdImagePtr im, int edcolor) {
+/* Set the color of the edge of filled-area elements.
+ * Attribute: Edge Color; Elem Class 5; Elem ID 29
+ * These attributes stay in effect until changed, so you don't have to output
+ * them every time.
+ *     Edge Colour (index into the color table)
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (edcolor == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (edcolor == im->edgecolor)
+		return 1;
+
+	/* Make sure the color they want to use has been allocated. 
+	 * also, that color must be non-negative */
+	if ((edcolor >= im->colorsTotal ) || (edcolor < 0))
+		return 0;  /* you must allocate a color before you use it */
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+	if (!cdcomhead(es, 5, 29, 1)) return 0;
+	es += 2;
+
+	*es =  0377 & edcolor; /* mask off last 8 bits and put in es */
+	es++;
+	es += cdAppNull(es, 1);
+
+	octet_count = 4; /* we just know this; 2 octets of header,
+	                  * 1 octet of data, 1 octet of null data */
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+		im->edgecolor = (short int) edcolor;
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+
+
+}
+
+int cdSetEdgeVis(cdImagePtr im, int edvis) {
+/* Set the visibility of the edge of filled-area elements.
+ * Attribute: Edge Visibility; Elem Class 5; Elem ID 30
+ * These attributes stay in effect until changed, so you don't have to output
+ * them every time.
+ *     Edge Visibility (integer 0 or 1, corresponding to: Off, On)
+ * Attribute is 16 bit signed int.
+ */
+	unsigned char *es, *esp;
+	int octet_count, temp;
+
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (edvis == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (edvis == im->edgevis)
+		return 1;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	if (!cdcomhead(es, 5, 30, 2)) return 0;
+	es +=2; octet_count = 2;
+	temp = edvis >> 8;
+	*es = *es | (temp & 0377);
+	es++;
+	*es = *es | (edvis & 0377);
+	es++;
+	octet_count += 2;
+	
+	
+	/* add it to the buffer */
+	if (cdAddElem(im, esp, octet_count)) {
+		im->edgevis = (short int) edvis;
+		free(esp);
+		return 1;
+	}
+	else {
+		free(esp);
+		return 0;
+	}
+
+
+}
+
+int cdSetTextFont(cdImagePtr im, int font) {
+/* Attribute: Text Font Index; Elem Class 5; Elem ID 10
+ * font is an index into the font table.  it can have one of the following
+ * values:
+ * 1 Times
+ * 2 Times Bold
+ * 3 Times Italic
+ * 4 Times Bold Italic
+ * 5 Helvetica
+ * 6 Helvetica Bold
+ * 7 Helvetica Italic
+ * 8 Helvetica Bold Italic
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (font == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (font == im->textfont)
+		return 1;
+
+	/* Make sure that font is between 1 and 8 */
+	if ((font < 1) || (font > 8))
+		return 0;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	if(!cdcomhead(es, 5, 10, 2)) return 0;
+	es += 2;
+
+	es += cdAppShort(es, (short int) font);
+
+	octet_count = 4; /* we just know this */
+
+	/* add it to the buffer */
+	if (cdAddElem(im, esp, octet_count)) {
+		im->textfont = (short int) font;
+		free(esp);
+		return 1;
+	}
+	else {
+		free(esp);
+		return 0;
+	}
+
+}
+
+int cdSetTextColor(cdImagePtr im, int color) {
+/* Attribute: Text Colour ; Elem Class 5; Elem ID 14
+ * set the forground color of text
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (color == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (color == im->textcolor)
+		return 1;
+
+	/* Make sure the color they want to use has been allocated. 
+	 * also, that color must be non-negative */
+	if ((color >= im->colorsTotal ) || (color < 0))
+		return 0;  /* you must allocate a color before you use it */
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	if(!cdcomhead(es, 5, 14, 1)) return 0;
+	es += 2; 
+
+	*es =  0377 & color; /* mask off last 8 bits and put in es */
+	es++;
+
+	octet_count = 4; /* we just know this; 2 octets of header,
+	                  * 1 octet of data, 1 octet of null data */
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+		im->textcolor = (short int) color;
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+}
+
+int cdSetTextHeight(cdImagePtr im, int height) {
+/* Attribute: Character Height; Elem Class 5; Elem ID 15
+ * the height is in the same units as line width
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (height == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (height == im->textheight)
+		return 1;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	if(!cdcomhead(es, 5, 15, 2)) return 0;
+	octet_count = 2; es += 2;
+
+	es += cdAppShort(es, height);
+	octet_count += 2;
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+		im->textheight = height;
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+}
+
+int cdSetTextPath(cdImagePtr im, int tpath) {
+/* Attribute: Text Path; Elem Class 5; Elem ID 17
+ * Is one of:
+ *   0 right -- Means the direction of the character base vector
+ *   1 left  -- means 180 degrees from the character base vector
+ *   2 up    -- means the direction of the character up vector
+ *   3 down  -- means 180 degrees from the character up vector
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+
+	/* First check and see if the user doesn't want any changes,
+	 * if so, just return success */
+	if (tpath == -1)
+		return 1;
+
+	/* Check and see if the value it is being set to is the current
+	 * value, if so, don't make any changes, just return 1 */
+	if (tpath == im->textpath)
+		return 1;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+	octet_count = 0;
+
+	if (!cdcomhead(es, 5, 17, 2)) return 0;
+	es +=2; octet_count = 2;
+
+	es += cdAppShort(es, (short int) tpath);
+	octet_count += 2;
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+		im->textpath = (short int) tpath;
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+}
+
+int cdSetTextOrient(cdImagePtr im, int xup, int yup, int xbase, int ybase) {
+/* Attribute: Character Orientation; Elem Class 5; Elem ID 16
+ * (xbase,ybase) is the run and the rise of the line that the text is
+ * written along.  For regular text at an angle, set xup = -ybase
+ * and yup = xbase.  Setting it to something different will result in
+ * skewed text (which may be what you want.) Text written from bottom to
+ * top at a 90 degree angle would have the following parameters  
+ * xup=-1, yup=0, xbase=0, ybase=1
+ *
+ * This function adds the Orientation to the metafile every time.
+ * It does not follow the normal -1 for no change, although if you
+ * put in the same numbers it won't re-add it to the meta file.
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+	octet_count = 0;
+
+	if (!cdcomhead(es, 5, 16, 8)) return 0;
+	es +=2; octet_count += 2;
+
+	/* In the metafile it is a 16 bit signed integer */
+	/* add xup */
+	es += cdAppShort(es, (short int) xup);
+	octet_count += 2;
+	/* add the rest */
+	es += cdAppShort(es, (short int) yup);
+	octet_count += 2;
+	es += cdAppShort(es, (short int) xbase);
+	octet_count += 2;
+	es += cdAppShort(es, (short int) ybase);
+	octet_count += 2;
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+}
+
+int cdSetLineAttrib(cdImagePtr im, int lntype, int lnwidth, int lncolor) {
+/* Spits out the attributes of lines.  These attributes stay in effect
+ * until changed, so you don't have to output them every time.
+ */
+
+	if (!cdSetLineType(im, lntype)) return 0;
+	if (!cdSetLineWidth(im, lnwidth)) return 0;
+	if (!cdSetLineColor(im, lncolor)) return 0;
+
+	return 1;
+
+}
+
+int cdSetShapeFillAttrib(cdImagePtr im, int instyle, int incolor, int inhatch) {
+/* Spits out the attributes for the interior of filled-area elements.
+ * These attributes stay in effect until changed, so you don't have to output
+ * them every time.
+ * Set the following attributes:
+ *     Interior Style: (integers 0-6, corresponding to: hollow, solid, 
+ *                      [not pattern], hatch, empty, [not geometric pattern], 
+ *                      interpolated.)
+ *     Fill Colour: (index into the color table)
+ *     Hatch Index: (integers 1-6, corresponding to: horizontal lines, 
+ *                   vertical lines, pos. slope parallel lines, 
+ *                   neg. slope parallel lines, horizontal/vertical
+ *                   crosshatch, positive/negative slope crosshatch)
+ */
+	if (!cdSetFillStyle(im, instyle)) return 0;
+	if (!cdSetFillColor(im, incolor)) return 0;
+	if (!cdSetFillHatch(im, inhatch)) return 0;
+
+	return 1;
+}
+
+int cdSetShapeEdgeAttrib(cdImagePtr im, int edtype, int edwidth, int edcolor, int edvis) {
+/* Spits out the attributes for the edges of filled-area elements.  It may
+ * seem logical that these would be the same as the corresponding line 
+ * attributes, but this is not the case.
+ * These attributes stay in effect until changed, so you don't have to output
+ * them every time.
+ * Set the following attributes:
+ *     Edge Type (integers 1-5, corresponding to: solid, dash, dot,
+ *                dash-dot, dash-dot-dot. These are the same as those used
+ *                for line type.)
+ *     Edge Width (should be the same as line width)
+ *     Edge Colour (index into the color table)
+ *     Edge Visibility (integer 0 or 1, corresponding to: Off, On)
+ */
+	if (!cdSetEdgeType(im, edtype)) return 0;
+	if (!cdSetEdgeWidth(im, edwidth)) return 0;
+	if (!cdSetEdgeColor(im, edcolor)) return 0;
+	if (!cdSetEdgeVis(im, edvis)) return 0;
+
+	return 1;
+}
+
+int cdSetTextAttrib(cdImagePtr im, int font, int color, int height) {
+/* Set the attributes of text.  the font is an integer pointer into the
+ * font list where:
+ * 1 Times
+ * 2 Times Bold
+ * 3 Times Italic
+ * 4 Times Bold Italic
+ * 5 Helvetica
+ * 6 Helvetica Bold
+ * 7 Helvetica Italic
+ * 8 Helvetica Bold Italic
+ * color is an index into the colortable which is the color of the text
+ * size is the approximate size you want the text written in.
+ */
+
+	if(!cdSetTextFont(im, font))   return 0;
+	if(!cdSetTextColor(im, color)) return 0;
+	if(!cdSetTextHeight(im, height)) return 0;
+
+	return 1;
+}
+
+
+int cdImageDestroy(cdImagePtr im)
+/* gej: should work, unless I make changes to cdImage Struct */
+{
+	if (im->elemlist) {
+		free(im->elemlist);
+	}
+	free(im);
+
+	return 1;
+}
+
+int cdImageColorClosest(cdImagePtr im, int r, int g, int b)
+/* From gd library, see README file for copyright information */
+/* gej: should work unchanged */
+/* gej: 5/96, changed the colors to use short int */
+{
+	short int i;
+	long rd, gd, bd;
+	int ct = (-1);
+	long mindist = 0;
+	for (i=0; (i<(im->colorsTotal)); i++) {
+		long dist;
+		if (im->open[i]) {
+			continue;
+		}
+		rd = (im->red[i] - r);	
+		gd = (im->green[i] - g);
+		bd = (im->blue[i] - b);
+		dist = rd * rd + gd * gd + bd * bd;
+		if ((i == 0) || (dist < mindist)) {
+			mindist = dist;	
+			ct = i;
+		}
+	}
+	return ct;
+}
+
+int cdImageColorClear(cdImagePtr im) {
+/* mark all entries in the color table as open */
+	short int i;
+	for (i=0; (i<(cdMaxColors)); i++) {
+		im->open[i] = 1;
+	}
+	return 1;
+}
+
+int cdImageColorExact(cdImagePtr im, int r, int g, int b)
+/* From gd library, see README file for copyright information */
+/* gej: should work unchanged */
+/* gej: 5/96, changed colors to work with short ints */
+{
+	short int i;
+	for (i=0; (i<(im->colorsTotal)); i++) {
+		if (im->open[i]) {
+			continue;
+		}
+		if ((im->red[i] == r) && 
+			(im->green[i] == g) &&
+			(im->blue[i] == b)) {
+			return i;
+		}
+	}
+	return -1;
+}
+
+static int cdImageAddColor(cdImagePtr im, int ct, int r, int g, int b)
+/* adds a color to the cgm file.  Does not allocate it in the
+ * cdImagePtr object.  Use cdImageColorAllocate, not this one.
+ */
+{
+	unsigned char *cts, *ctsp; /* GEJ: color table attribute */
+	int octet_count; /* GEJ: octet count */
+	/*
+	 * Attribute: Colour Table; Elem Class 5; Elem ID 34
+	 * two parameters P1: Starting colour table index (1 octet, UI)
+	 * P2: list of direct colour values 3-tuples (3 one-octet values)
+	 */
+ 	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+        cts = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+        if (!cts) return -1; /* memory allocation failed */
+        ctsp=cts;
+	*ctsp = *ctsp | b6 | b4; /* set elem class to 5 */
+	*ctsp = *ctsp | b2; /* set elem id to 34 */
+	ctsp++;
+	*ctsp = *ctsp | b6;
+	*ctsp = *ctsp | b2; /* set param list len to 4 */
+	ctsp++;
+	octet_count = 2; /* so far */
+	/* now fill in the index number */
+	*ctsp =  (unsigned char) 0377 & ct; /* mask off last 8 bits and put in ctsp*/
+	ctsp++;octet_count++;
+	/* now fill in the RGB values */
+	*ctsp =  (unsigned char) 0377 & r; /* mask off last 8 bits and put in ctsp*/
+	ctsp++;octet_count++;
+	*ctsp =  (unsigned char) 0377 & g; /* mask off last 8 bits and put in ctsp*/
+	ctsp++;octet_count++;
+	*ctsp =  (unsigned char) 0377 & b; /* mask off last 8 bits and put in ctsp*/
+	ctsp++;octet_count++;
+        /* add it to the buffer */
+        if (cdAddElem(im, cts, octet_count)) {
+                free(cts);
+                return 1;
+        }
+        else {
+                free(cts);
+                return -1;
+        }
+	
+	
+}
+
+int cdImageColorAllocate(cdImagePtr im, int r, int g, int b)
+/* From gd library, see README file for copyright information
+ * gej: modified to allocate the color in the CGM buffer as well
+ * as the color table */
+/* gej: 5/96, modified to use short ints for colors */
+{
+	short int i;
+	short int ct = (-1);
+	for (i=0; (i<(im->colorsTotal)); i++) {
+		if (im->open[i]) {
+			ct = i;
+			break;
+		}
+	}	
+	if (ct == (-1)) {
+		ct = im->colorsTotal;
+		if (ct == cdMaxColors) {
+			return -1;
+		}
+		im->colorsTotal++;
+	}
+	im->red[ct] = (short int) r;
+	im->green[ct] = (short int) g;
+	im->blue[ct] = (short int) b;
+	im->open[ct] = (short int) 0;
+	/* GEJ: Now we have successfully alocated it in the color table
+	 * so let's put it in the CGM as well. 
+	 */
+	if (!cdImageAddColor(im, ct, r, g, b) ) {
+		return -1;
+	}
+	else {
+		return ct;
+	}
+
+}
+
+int cdImageColor16(cdImagePtr im) {
+/* allocate the 16 basic colors in the windows pallete */
+	if( -1 == cdImageColorAllocate(im, 255, 255, 255)) return 0;
+	if( -1 == cdImageColorAllocate(im, 0, 0, 0)) return 0;
+	if( -1 == cdImageColorAllocate(im, 128, 0, 0)) return 0;
+	if( -1 == cdImageColorAllocate(im, 0, 128, 0)) return 0;
+	if( -1 == cdImageColorAllocate(im, 128, 128, 0)) return 0;
+	if( -1 == cdImageColorAllocate(im, 0, 0, 128)) return 0;
+	if( -1 == cdImageColorAllocate(im, 128, 0, 128)) return 0;
+	if( -1 == cdImageColorAllocate(im, 0, 128, 128)) return 0;
+	if( -1 == cdImageColorAllocate(im, 128, 128, 128)) return 0;
+	if( -1 == cdImageColorAllocate(im, 192, 192, 192)) return 0;
+	if( -1 == cdImageColorAllocate(im, 255, 0, 0)) return 0;
+	if( -1 == cdImageColorAllocate(im, 0, 255, 0)) return 0;
+	if( -1 == cdImageColorAllocate(im, 255, 255, 0)) return 0;
+	if( -1 == cdImageColorAllocate(im, 0, 0, 255)) return 0;
+	if( -1 == cdImageColorAllocate(im, 255, 0, 255)) return 0;
+	if( -1 == cdImageColorAllocate(im, 0, 255, 255)) return 0;
+
+	return 1;
+
+}
+
+int cdImageColorDeallocate(cdImagePtr im, int color)
+/* From gd library, see README file for copyright information */
+/* gej: should work unchanged */
+{
+	/* Mark it open. */
+	/*im->open[color] = 1;*/
+	/* gej: really can't work, we are not allowing redefinition
+	 * of color table entries */
+	return 0;
+}
+
+int cdLine(cdImagePtr im, int x1, int y1, int x2, int y2)
+/* Graphic Primitive: Polyline; Elem Class 4; Elem ID 1
+ * Actually generate the line, if you are writing a program to use this
+ * library, use this function, not cdImageLine or cdImageDashedLine,
+ * those are just in for compatiblilty with gd 
+ *
+ * This function will draw a line using the current line type, width, and color
+ */
+{
+
+	unsigned char *es, *esp;
+	int octet_count;
+	short int sweet;
+	short int sour;
+
+	/* check to make sure the line is withing the scope of the picture
+	 * ie. the values you give for drawing the line are within
+	 * the values you created the picture with */
+	if (!(cdImageBoundsSafe(im, x1,y1)) || !(cdImageBoundsSafe(im, x2,y2)))
+		return 0;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	if (!cdcomhead(es, 4, 1, 8)) return 0;
+	es += 2;
+	octet_count = 2;
+
+	/* now we are ready for the parameter data */
+	sweet = (short int) x1;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) y1;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) x2;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) y2;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	octet_count++;
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+
+
+}
+
+int cdRectangle(cdImagePtr im, int x1, int y1, int x2, int y2) {
+/* Graphic Primitive: rectangle; Elem Class 4; Elem ID 11
+ * Actually generate the rectangle, if you are writing a program to use this
+ * library, use this function, not cdImageRectangle,
+ * those are just in for compatiblilty with gd 
+ *
+ * This function will draw a Rectangle using the current 
+ * edge type, width, color, and visibility, and the current
+ * fill style, color, and hatch
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+	short int sweet;
+	short int sour;
+
+	/* check to make sure the line is withing the scope of the picture
+	 * ie. the values you give for drawing the line are within
+	 * the values you created the picture with */
+	if (!(cdImageBoundsSafe(im, x1,y1)) || !(cdImageBoundsSafe(im, x2,y2)))
+		return 0;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	/* their are four 16 bit signed integers as attributes */
+	if (!cdcomhead(es, 4, 11, 8)) return 0;
+	es +=2; octet_count = 2;
+
+	/* now we are ready for the parameter data */
+	sweet = (short int) x1;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) y1;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) x2;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) y2;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	octet_count++;
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+
+
+}
+
+int cdCircle(cdImagePtr im, int cx, int cy, int r) {
+/* Graphic Primitive: circle; Elem Class 4; Elem ID 12
+ * cx,cy is the center of the circle, r is the radius
+ *
+ * This function will draw a Circle using the current 
+ * edge type, width, color, and visibility, and the current
+ * fill style, color, and hatch
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+	short int sweet;
+	short int sour;
+
+	/* check to make sure the circle is withing the scope of the picture
+	 * ie. the values you give for drawing the circle are within
+	 * the values you created the picture with */
+	if (!(cdImageBoundsSafe(im, cx,cy)))
+		return 0;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	/* their are three 16 bit signed integers as attributes */
+	if (!cdcomhead(es, 4, 12, 6)) return 0;
+	es +=2; octet_count = 2;
+
+	/* now we are ready for the parameter data */
+	sweet = (short int) cx;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) cy;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) r;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	octet_count++;
+
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+
+
+}
+
+int cdArc3Pt(cdImagePtr im, int sx,int sy, int ix,int iy, int ex,int ey) {
+/* Graphic Primitive: Cicular Arc 3 Point; Elem Class 4; Elem ID 13
+ *
+ * This function will draw a Circular Arc using the current 
+ * Line type, width, and color, 
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+	short int sweet;
+	short int sour;
+
+	/* check to make sure the line is withing the scope of the picture
+	 * ie. the values you give for drawing the line are within
+	 * the values you created the picture with */
+	if (!(cdImageBoundsSafe(im, sx,sy)) || !(cdImageBoundsSafe(im, ix,iy)) || !(cdImageBoundsSafe(im, ex, ey)))
+		return 0;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	/* their are six 16 bit signed integers as attributes */
+	if (!cdcomhead(es, 4, 13, 12)) return 0;
+	es +=2; octet_count = 2;
+
+	/* now we are ready for the parameter data */
+	sweet = (short int) sx;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) sy;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) ix;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) iy;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) ex;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	es++; octet_count++;
+	sweet = (short int) ey;
+	sour = sweet >> 8;
+	*es = *es | (sour & 0377);
+	es++; octet_count++;
+	*es = (unsigned char) sweet;
+	octet_count++;
+
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+
+}
+
+int cdArc3PtClose(cdImagePtr im, int sx,int sy, int ix,int iy, int ex,int ey, int cl) {
+/* Graphic Primitive: Cicular Arc 3 Point Close; Elem Class 4; Elem ID 14
+ *
+ * This function will draw a Circle using the current 
+ * edge type, width, color, and visibility, and the current
+ * fill style, color, and hatch
+ *
+ * cd is the closure type.  It can be either 0 for pie closure or
+ * 1 for chord closure.
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+
+	/* check to make sure the line is withing the scope of the picture
+	 * ie. the values you give for drawing the line are within
+	 * the values you created the picture with */
+	if (!(cdImageBoundsSafe(im, sx,sy)) || !(cdImageBoundsSafe(im, ix,iy)) || !(cdImageBoundsSafe(im, ex, ey)))
+		return 0;
+
+	/* make sure that they close the arc either with pie (0) or chord (1) */
+	if ((cl != 0) && (cl != 1))
+		return 0;
+
+	/* allocate sufficent space.  should be 32 bits * 6 to be safe */
+	es = (unsigned char *) calloc(4*6, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	/* their are seven 16 bit signed integers as attributes */
+	if (!cdcomhead(es, 4, 14, 14)) return 0;
+	es +=2; octet_count = 2;
+
+	/* now we are ready for the parameter data */
+	octet_count += cdAppShort(es, (short int) sx);
+	es +=2;
+	octet_count += cdAppShort(es, (short int) sy);
+	es +=2;
+	octet_count += cdAppShort(es, (short int) ix);
+	es +=2;
+	octet_count += cdAppShort(es, (short int) iy);
+	es +=2;
+	octet_count += cdAppShort(es, (short int) ex);
+	es +=2;
+	octet_count += cdAppShort(es, (short int) ey);
+	es +=2;
+	octet_count += cdAppShort(es, (short int) cl);
+	es +=2;
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+
+}
+
+int cdEllipse(cdImagePtr im, int cx,int cy, int d1x,int d1y, int d2x,int d2y ) {
+/* Graphic Primitive: Ellipse; Elem Class 4; Elem ID 17
+ *
+ * This function will draw an Ellipse using the current 
+ * edge type, width, color, and visibility, and the current
+ * fill style, color, and hatch
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+
+	/* check to make sure the line is withing the scope of the picture
+	 * ie. the values you give for drawing the line are within
+	 * the values you created the picture with */
+	if (!(cdImageBoundsSafe(im, cx,cy)) || !(cdImageBoundsSafe(im, d1x,d1y)) || !(cdImageBoundsSafe(im, d2x, d2y)))
+		return 0;
+
+	/* allocate sufficent space.  should be 32 bits * 4 to be safe */
+	es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	/* their are six 16 bit signed integers as attributes */
+	if (!cdcomhead(es, 4, 17, 12)) return 0;
+	es +=2; octet_count = 2;
+
+	/* now we are ready for the parameter data */
+	octet_count += cdAppShort(es, (short int) cx);
+	es +=2;
+	octet_count += cdAppShort(es, (short int) cy);
+	es +=2;
+	octet_count += cdAppShort(es, (short int) d1x);
+	es +=2;
+	octet_count += cdAppShort(es, (short int) d1y);
+	es +=2;
+	octet_count += cdAppShort(es, (short int) d2x);
+	es +=2;
+	octet_count += cdAppShort(es, (short int) d2y);
+	es +=2;
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+                free(esp);
+                return 1;
+        }
+        else {
+                free(esp);
+                return 0;
+        }
+
+
+}
+
+int cdPolygon(cdImagePtr im, cdPointPtr p, int n) {
+/* Graphic Primitive: Polygon; Elem Class 4; Elem ID 7
+ *
+ * cdPointPtr is defined in cd.h, basically, it is two arrays of integers
+ * p[m].x and p[m].y  containing the x and y values respectively.  n
+ * is the number of points in this array (not the index of the last point,
+ * which is n-1).  n must be at least 3 (otherwise
+ * you really don't have much of a polygon, it is closer to a line.)
+ *
+ * This function will draw a Polygon using the current 
+ * edge type, width, color, and visibility, and the current
+ * fill style, color, and hatch
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+	int x; /* counter */
+
+	if (n < 3) return 0; /* it is either a point or a line */
+
+	if (n < 8) {
+	/* It fits in the short form of the command, lets us
+	 * add it right now, shall we? */
+		/* allocate sufficent space. Should be 32 bits*10 to be safe */
+		es = (unsigned char *) calloc(4*10,SIZEOF(unsigned char ));
+		if (!es) return 0; /* memory allocation failed */
+		esp=es;
+
+
+		/* their are n*2 16 bit signed integers as attributes */
+		if (!cdcomhead(es, 4, 7, (n*4))) return 0;
+		es +=2; octet_count = 2;
+
+	}
+	else if (n < 8191) {
+	/* there are more than 7 points in it, that sucks */
+	/* gej, so basically, for this one, I set the header
+	 * to cdcomhead(es, 4, 7, 31) then write a function for the long
+	 * form that takes the first 15 bits of n and tags a 0 in front
+	 * of it and puts it in es, than I do the for loop all over again
+	 * that doesn't seem too hard.  But I will leave that for another
+	 * day.
+
+	 * keep in mind that if CDGROWLISTSIZE is smaller than n*4
+	 * (at most 32769) then things could fail in a most unsavory fashion.
+	 */
+		/* allocate sufficent space.  32 bits*(n+1) to be safe */
+		es = (unsigned char *) calloc(4*(n+1), SIZEOF(unsigned char ));
+		if (!es) return 0; /* memory allocation failed */
+		esp=es;
+
+		if (!cdcomheadlong(es, 4, 7, (n*4))) return 0;
+		es +=4; octet_count = 4;
+	}
+	else {
+	/* there are more than 8191 points in it, I am not going to implement
+	 * that, if you want it that bad, do it yourself. */
+
+		printf("Writing %d points\n",n);
+
+
+	    /* allocate sufficent space.  32 bits*(n+1) to be safe */
+	    esp = (unsigned char *) calloc(4*(n+1), SIZEOF(unsigned char ));
+	    if (!esp) return 0; /* memory allocation failed */
+		es=esp;
+
+		if (!cdcomheadlongp(es, 4, 7)) return 0;
+		es +=2; octet_count = 2;
+
+        	if (!cdAddElem(im, esp, octet_count)) {
+        	       	free(esp);
+         	      	return 0;
+        	}
+
+	    while(n>8191) {
+		es=esp;
+
+		if (!cdcomheadlongc(es, 1,8191*4)) return 0;
+		es +=2; octet_count = 2;
+		
+
+		for (x=0; x<8191; x++) {
+			/* now we are ready for the parameter data */
+			es += cdAppShort(es, (short int) p->x);
+			es += cdAppShort(es, (short int) p->y);
+			octet_count += 4;
+			p++;
+		}
+
+        	/* add it to the buffer */
+        	if (!cdAddElem(im, esp, octet_count)) {
+        	       	free(esp);
+         	      	return 0;
+        	}
+
+		n-=8191;
+		printf("Done 8191 have left %d\n",n);
+	    }
+		printf("doing last %d normally\n",n);
+
+	    es=esp;
+
+	    if (!cdcomheadlongc(es, 0, (n*4))) return 0;
+	    es +=2; octet_count = 2;
+
+
+	}
+	
+
+	for (x=0; x<n; x++) {
+		/* now we are ready for the parameter data */
+		es += cdAppShort(es, (short int) p->x);
+		es += cdAppShort(es, (short int) p->y);
+		octet_count += 4;
+		p++;
+	}
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+               	free(esp);
+               	return 1;
+        }
+        else {
+               	free(esp);
+               	return 0;
+        }
+}
+
+int cdPolyLine(cdImagePtr im, cdPointPtr p, int n) {
+/* Graphic Primitive: Polyline; Elem Class 4; Elem ID 1
+ *
+ * cdPointPtr is defined in cd.h, basically, it is two arrays of integers
+ * p[m].x and p[m].y  containing the x and y values respectively.  n
+ * is the number of points in this array (not the index of the last point,
+ * which is n-1).  if n is 2, it is a regular line, like cdline
+ *
+ * This function will draw a Polyline using the current 
+ * line type, width, color, and visibility, 
+ */
+	unsigned char *es, *esp;
+	int octet_count;
+	int x; /* counter */
+
+	if (n < 2) return 0; /* it is a point */
+
+	if (n < 8) {
+	/* It fits in the short form of the command, lets us
+	 * add it right now, shall we? */
+		/* allocate sufficent space. Should be 32 bits*10 to be safe */
+		es = (unsigned char *) calloc(4*10,SIZEOF(unsigned char ));
+		if (!es) return 0; /* memory allocation failed */
+		esp=es;
+
+
+		/* their are n*2 16 bit signed integers as attributes */
+		if (!cdcomhead(es, 4, 1, (n*4))) return 0;
+		es +=2; octet_count = 2;
+
+	}
+	else if (n < 8191) {
+	/* there are more than 7 points in it, that sucks */
+	/* gej, so basically, for this one, I set the header
+	 * using the long version cdcomheadlong(es, 4, 1, n*4)
+
+	 * keep in mind that if CDGROWLISTSIZE is smaller than n*4
+	 * (at most 32769) then the list may have to grow several times
+	 */
+		/* allocate sufficent space.  32 bits*(n+1) to be safe */
+		es = (unsigned char *) calloc(4*(n+1), SIZEOF(unsigned char ));
+		if (!es) return 0; /* memory allocation failed */
+		esp=es;
+
+		if (!cdcomheadlong(es, 4, 1, (n*4))) return 0;
+		es +=4; octet_count = 4;
+	}
+	else {
+	/* there are more than 8191 points in it, I am not going to implement
+	 * that, if you want it that bad, do it yourself. */
+		return 0;
+	}
+	
+
+	for (x=0; x<n; x++) {
+		/* now we are ready for the parameter data */
+		es += cdAppShort(es, (short int) p->x);
+		es += cdAppShort(es, (short int) p->y);
+		octet_count += 4;
+		p++;
+	}
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+               	free(esp);
+               	return 1;
+        }
+        else {
+               	free(esp);
+               	return 0;
+        }
+}
+
+int cdText(cdImagePtr im, int x, int y, const char *ts) {
+/* Graphic Primitive: Text; Elem Class 4; Elem ID 4
+ * add text to the picture.  Start it at the point (x,y)
+ * this should be the lower left corner of where the text is
+ * the parameters are point, enumerated(set to 1), string
+ *
+ * String encoding in CGM is a little strange.  After you have the other
+ * parameter info, the first octet for the string is either 0..254 which
+ * is the number of octets of string data, or 255 which signifies a long
+ * string.  if it is 255 then the next 16 bits indicate the length of the
+ * string.  the first bit (bit15) is 0 if this is the last part of the
+ * string and 1 if another part follows it.  the next 15 bits  are in the
+ * range 0..32767 and are the number of octets of string info following.
+ * so the length stored in the command header is the whole enchelada.
+ */
+	int tslen, curly;
+	unsigned char *es, *esp;
+	int octet_count;
+
+	/* check to make sure the Text is within the scope of the picture
+	 * actually, I am only checking the start of it
+	 */
+	if (!(cdImageBoundsSafe(im, x, y)))
+		return 0;
+
+	/* allocate sufficent space.  should be tslen+ 32 bits * 4 to be safe */
+	tslen = strlen(ts);
+
+	/* if there are more than 32700 characters fail 
+	 * gej: this could go as high as 32767 I think, but lets 
+	 * cut it off at 32700 */
+	if ((tslen > 32700) || (tslen < 0))return 0;
+
+	es = (unsigned char *) calloc( ((4*4)+tslen), SIZEOF(unsigned char ) );
+	if (!es) return 0; /* memory allocation failed */
+	esp=es;
+
+	if (!cdcomheadlong(es, 4, 4, 9+tslen)) return 0;
+	es +=4; octet_count = 4;
+
+	/* add the x position, the y position, then 1, which signifies
+	 * that this is all the text, there is none appended after it */
+	es += cdAppShort(es, (short int) x);
+	es += cdAppShort(es, (short int) y);
+	es += cdAppShort(es, (short int) 1);
+	octet_count += 6;
+
+	/* now take care of the string information, for strings 254 bytes
+	 * or less, I could use a short one, but why bother, use the long
+	 * form for everything */
+	es += cdAppByte(es, (short int) 255);
+	es += cdAppShort(es, (short int) tslen);
+	octet_count += 3;
+	/* gej: I should set bit 15 to 0 because it is the final part of a 
+	 * string but I am not going to since I already checked that it was
+	 * a 16 number that was non-negative */
+
+	while(*ts) {
+		*es++ = (unsigned char) *ts++;
+	}
+	octet_count +=tslen;
+	/* now if the octet_count is not divisible by 4 add null padding */
+	curly = 4 - (octet_count % 4);
+	if (curly % 4) {
+		octet_count += curly;
+		es += cdAppNull(es, curly);
+	}
+
+        /* add it to the buffer */
+        if (cdAddElem(im, esp, octet_count)) {
+               	free(esp);
+               	return 1;
+        }
+        else {
+               	free(esp);
+               	return 0;
+        }
+
+}
+
+int cdImageLine(cdImagePtr im, int x1, int y1, int x2, int y2, int color)
+/* gej: this should be so much easier to do as a cgm 
+ * This is in for compatibility with gd, if you don't need that, use
+ * cdLine instead */
+{
+	int ltstate;
+
+
+	/* save the linetype state */
+	ltstate = im->ltype;
+	/* set the attributes of the line */
+	if (!cdSetLineAttrib(im, 1, -1, color)) return 0;
+	if (!cdLine(im, x1, y1, x2, y2)) return 0;/* draw the line */
+	/* restore the state If it fails, don't return an error, because
+	 * the line was still drawn */
+	cdSetLineType(im, ltstate);
+
+	return 1;
+}
+
+int cdImageDashedLine(cdImagePtr im, int x1, int y1, int x2, int y2, int color)
+/* gej: this should be so much easier to do as a cgm 
+ * in order to really get a dashed line you must call cdSetLineType first
+ * This is in for compatibility with gd, if you don't need that, use
+ * cdLine instead */
+{
+	/* set the attributes of the line */
+	if (!cdSetLineAttrib(im, -1, -1, color)) return 0;
+	/* generate the line */
+	if (!cdLine(im, x1, y1, x2, y2)) return 0;
+
+	/* everthing is A-OK */
+	return 1;
+}
+
+int cdImageBoundsSafe(cdImagePtr im, int x, int y)
+/* From gd library, see README file for copyright information */
+/* gej: this should work unchanged */
+{
+	return (!(((y < 0) || (y >= im->sy)) ||
+		((x < 0) || (x >= im->sx))));
+}
+
+
+int cdImageRectangle(cdImagePtr im, int x1, int y1, int x2, int y2, int color)
+/* Graphic Primitive: rectangle; Elem Class 4; Elem ID 11
+ */
+
+/* gej: but I think I will use the cgm rectangle */
+{
+	if(!cdImageLine(im, x1, y1, x2, y1, color)) return 0;
+	if(!cdImageLine(im, x1, y2, x2, y2, color)) return 0;	
+	if(!cdImageLine(im, x1, y1, x1, y2, color)) return 0;
+	if(!cdImageLine(im, x2, y1, x2, y2, color)) return 0;
+
+	return 1;
+}
diff --git a/src/cd/cd.h b/src/cd/cd.h
new file mode 100644
index 0000000..3bb303e
--- /dev/null
+++ b/src/cd/cd.h
@@ -0,0 +1,209 @@
+#ifndef CD_H
+#define CD_H 1
+
+/* cd.h: declarations file for the cgmdraw module.
+
+        Written by G. Edward Johnson <mailto:lorax@nist.gov>
+        Date: April 1996
+        Copyright: cd software produced by NIST, an agency of the 
+	U.S. government, is by statute not subject to copyright
+	in the United States. Recipients of this software assume all 
+	responsibilities associated with its operation, modification
+	and maintenance.
+ 
+        Portions of this package are from the gd package written by
+	Thomas Boutell and are copyright 1994, 1995, Quest Protein 
+	Database Center, Cold Spring Harbor Labs.  They are marked in the
+	source code.
+
+*/
+
+/* #include <prof.h> */
+
+/* stdio is needed for file I/O. */
+#include <stdio.h>
+
+/* This can not be changed to a value larger than 256, though smaller
+ * values can be used.
+ */
+
+#define cdMaxColors 256
+
+/* If you know you will be working with large pictures, increase the values
+ * of the next two constants.
+ */
+
+/* The initial size of the element list.  When it fills up, we will just
+ * make it bigger.  Starting  with a larger number reduces the frequency of
+ * the list growing, but increases the memory needed for small pictures 
+ */
+
+#define CDSTARTLISTSIZE 4096
+
+/* How much the element list grows by.  When the list fills up, we allocate
+ * a new larger list.  This number is how much larger.  using a larger number
+ * decreases the frequency of the list growing, but if only a small amount 
+ * more is needed, it could waste memory 
+ */
+
+#define CDGROWLISTSIZE 2048
+
+/* Image type. See functions below; you will not need to change
+	the elements directly. Use the provided macros to
+	access sx, sy, the color table, and colorsTotal for 
+	read-only purposes. */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+typedef struct cdImageStruct {
+	unsigned char * elemlist;
+	int sx;
+	int sy;
+	int colorsTotal;
+	int red[cdMaxColors];
+	int green[cdMaxColors];
+	int blue[cdMaxColors]; 
+	int open[cdMaxColors];
+	/* You can have multiple pictures in the file,  this keeps track
+	 * of which one you are on */
+	int picnum;
+	/* Linetype, line width, line color have a broader scope in CGM */
+	int ltype;
+	int lwidth;
+	int lcolor;
+	/* interior style [of filled objects] (for me) can be empty, hollow, 
+	 * solid, hatch [don't do pattern, geometric pattern, interpolated*/
+	int shapestyle;
+	/* fill color, color used on inside of closed objects, significant
+	 * if interior style is hollow, solid, hatch, or geometric pattern */
+	int shapecolor;
+	/* hatch index, which hatch style to use, 1=horizontal, 2=vertical,
+	 * 3=pos.slope, 4=neg.slope, 5=hor/vert.crosshatch,
+	 * 6=pos/neg.crosshatch*/
+	int shapehatch;
+	/* The edges of filled shapes can have line styles too.  They 
+	 * correspond to the ones for lines.  These next few set them. */
+	int edgetype;
+	int edgewidth;
+	int edgecolor;
+	int edgevis; /* is the edge visible or invisible */
+	/* now for the TEXT related attributes,  Text Color, Text Height,
+	 * and Text font index */
+	int textcolor;
+	int textheight;
+	int textfont;
+	int textpath;
+	/* the next three are used for maintaining the element list */
+        long int bytestoend; /* number of bytes to end of the element list */
+	long int listlen; /* the total length of the element list */
+        unsigned char * curelemlist; /* where we curently are in the list */
+} cdImage;
+
+typedef cdImage * cdImagePtr;
+
+
+/* Point type for use in polygon drawing. */
+
+typedef struct cdPointStruct{
+	int x, y;
+} cdPoint, *cdPointPtr;
+
+
+
+/* Functions to manipulate images. */
+
+cdImagePtr cdImageCreate(int sx, int sy);
+int cdCgmNewPic(cdImagePtr im, int sticky);
+int cdImageCgm(cdImagePtr im, FILE *);
+int cdImageDestroy(cdImagePtr im);
+
+/* Use cdLine, not cdImageLine */
+int cdLine(cdImagePtr im, int x1, int y1, int x2, int y2);
+/* Corners specified (not width and height). Upper left first, lower right
+ 	second. */
+int cdRectangle(cdImagePtr im, int x1, int y1, int x2, int y2);
+/* center x, then center y, then radius of circle */
+int cdCircle(cdImagePtr im, int cx, int cy, int r);
+/* start, middle and end of arc */
+int cdArc3Pt(cdImagePtr im, int sx,int sy, int ix,int iy, int ex,int ey);
+/* cl is 0 for pie closure, 1 for cord closure */
+int cdArc3PtClose(cdImagePtr im, int sx,int sy, int ix,int iy, int ex,int ey, int cl);
+int cdEllipse(cdImagePtr im, int cx,int cy, int d1x,int d1y, int d2x,int d2y );
+/* polyshapes */
+int cdPolygon(cdImagePtr im, cdPointPtr p, int n);
+int cdPolyLine(cdImagePtr im, cdPointPtr p, int n);
+
+/* Functions for Compatibility with gd */
+int cdImageLine(cdImagePtr im, int x1, int y1, int x2, int y2, int color);
+int cdImageRectangle(cdImagePtr im, int x1, int y1, int x2, int y2, int color);
+
+
+int cdImageBoundsSafe(cdImagePtr im, int x, int y);
+/* These put characters in the picture.  CGM can handle fonts*/
+/* (x,y) is the lower left corner of where the text goes */
+int cdText(cdImagePtr im, int x, int y, const char *);
+
+
+/* Functions for allocating colors */
+int cdImageColorAllocate(cdImagePtr im, int r, int g, int b);
+int cdImageColorClosest(cdImagePtr im, int r, int g, int b);
+int cdImageColorExact(cdImagePtr im, int r, int g, int b);
+int cdImageColorDeallocate(cdImagePtr im, int color);
+int cdImageColor16(cdImagePtr im);
+
+/* gej: functions that set style attributes */
+int cdSetLineAttrib(cdImagePtr im, int lntype, int lnwidth, int lncolor);
+int cdSetShapeFillAttrib(cdImagePtr im, int instyle, int incolor, int inhatch);
+int cdSetShapeEdgeAttrib(cdImagePtr im, int edtype, int edwidth, int edcolor, int edvis);
+int cdSetTextAttrib(cdImagePtr im, int font, int color, int height);
+/* gej: or if you prefer, set the attributes individually */
+int cdSetLineType(cdImagePtr im, int lntype);
+int cdSetLineWidth(cdImagePtr im, int lnwidth);
+int cdSetLineColor(cdImagePtr im, int lncolor);
+int cdSetFillStyle(cdImagePtr im, int instyle);
+int cdSetFillColor(cdImagePtr im, int incolor);
+int cdSetFillHatch(cdImagePtr im, int inhatch);
+int cdSetEdgeType(cdImagePtr im, int edtype);
+int cdSetEdgeWidth(cdImagePtr im, int edwidth);
+int cdSetEdgeColor(cdImagePtr im, int edcolor);
+int cdSetEdgeVis(cdImagePtr im, int edvis);
+int cdSetTextFont(cdImagePtr im, int font);
+int cdSetTextColor(cdImagePtr im, int color);
+int cdSetTextHeight(cdImagePtr im, int height);
+/* geJ: these individual attributes can't be set with a group function */
+int cdSetTextPath(cdImagePtr im, int tpath);
+int cdSetTextOrient(cdImagePtr im, int xup, int yup, int xbase, int ybase);
+
+/* Macros to access information about images. READ ONLY. Changing
+	these values will NOT have the desired result. */
+#define cdImageSX(im) ((im)->sx)
+#define cdImageSY(im) ((im)->sy)
+#define cdImageColorsTotal(im) ((im)->colorsTotal)
+#define cdImageRed(im, c) ((im)->red[(c)])
+#define cdImageGreen(im, c) ((im)->green[(c)])
+#define cdImageBlue(im, c) ((im)->blue[(c)])
+
+/* Source: Independent JPEG Group
+ * In ANSI C, and indeed any rational implementation, size_t is also the
+ * type returned by sizeof().  However, it seems there are some irrational
+ * implementations out there, in which sizeof() returns an int even though
+ * size_t is defined as long or unsigned long.  To ensure consistent results
+ * we always use this SIZEOF() macro in place of using sizeof() directly.
+ */
+
+#define SIZEOF(object)  ((size_t) sizeof(object))
+ 
+/* GeJ: these are helper functions I use in cd.  That means DON'T call
+ * them from your program.  Yes, that means you.  */
+int cdCgmHeader(cdImagePtr);
+int cdCgmPic(cdImagePtr, int);
+int cdImageColorClear(cdImagePtr im);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+
+#endif
diff --git a/src/cd/cd.html b/src/cd/cd.html
new file mode 100644
index 0000000..31471b1
--- /dev/null
+++ b/src/cd/cd.html
@@ -0,0 +1,1156 @@
+<HTML><HEAD>
+<META HTTP-EQUIV="author" CONTENT="G. Edward Johnson (lorax@nist.gov)">
+<META HTTP-EQUIV="keywords" CONTENT="CGM, computer graphics metafile, vector graphics, ansi standard, nist, graphics library">
+<META HTTP-EQUIV="abstract" CONTENT="CGM Draw is a freely available library for generating CGM files from a C program. With CGM Draw your code can quickly draw images complete with lines, arcs, rectangles, polygons, and text.">
+<LINK HREF="mailto:lorax@nist.gov">
+<TITLE>CD -- CGM Draw Documentation</TITLE>
+</HEAD>
+<BODY>
+<H1>CD Documentation</H1>
+<H2>A graphics library for fast CGM creation</H2>
+<P>Follow this link for the
+<A HREF="http://speckle.ncsl.nist.gov/~lorax/cgm/cd.html">latest version
+of the CD documentation</A>.</P>
+
+<H3>Table of Contents</H3>
+<UL>
+  <LI><A HREF="#notice">Credits and license terms</A></LI>
+  <LI><A HREF="#whatsnew">What's new</A></LI>
+  <LI><A HREF="#whatis">What is cd?</A></LI>
+  <LI><A HREF="#required">What else do I need to use cd?</A>
+  <LI><A HREF="#get">How do I get cd?</A></LI>
+  <LI><A HREF="#build">How do I build cd?</A></LI>
+  <LI><A HREF="#basics">cd basics: using cd in your program</A></LI>
+  <LI><A HREF="#reference">Function and type reference by category</A></LI>
+  <LI><A HREF="#replacegd">Using cd instead of gd</A></LI>
+  <LI><A HREF="#informing"><strong>Please</strong>
+    tell us you're using cd!</A></LI>
+
+</UL>
+
+<A NAME="notice"><H3>Credits and license terms</H3></A>
+
+<P>cd was written by <A HREF="http://speckle.ncsl.nist.gov/~lorax/">G.
+Edward Johnson</A> at the <A HREF="http://www.nist.gov/">National
+Institute of Standards and Technology</A>.  You may use this code
+for any purpose, but please give us credit.  If find cd useful, please
+<A HREF="mailto:lorax@nist.gov">let us know</A>.
+cd software produced by NIST, an agency of the U.S. government, 
+is by statute not subject to copyright in the United States. 
+Recipients of this software assume all responsibilities associated 
+with its operation, modification and maintenance.
+</P><P>
+Some of this code is from the gd library written by Thomas Boutell.
+Mr. Boutell did not help with this project, so do not send him questions
+about cd.
+Code from gd is clearly marked in the source.  Additionally, this document
+is patterned after the gd documentation, some portions have been copied
+verbatim.  gd is covered by the following license.</P>
+<P>
+gd 1.2 is copyright 1994, 1995, Quest Protein Database Center,
+Cold Spring Harbor Labs. Permission granted to copy and distribute
+this work provided that this notice remains intact. Credit
+for the library must be given to the Quest Protein Database Center,
+Cold Spring Harbor Labs, in all derived works. This does not
+affect your ownership of the derived work itself, and the intent
+is to assure proper credit for Quest, not to interfere with your
+use of gd. If you have questions, ask. ("Derived works"
+includes all programs that utilize the library. Credit must
+be given in user-visible documentation.)</P>
+<P>
+The Quest Protein Database Center is funded under Grant P41-RR02188 by
+the National Institutes of Health.
+</P>
+<A NAME="whatsnew"><H3>What's new?</H3></A>
+<H4>Version 1.2</H4>
+<P>
+<UL>
+  <LI>New Text attributes:
+  <UL>
+    <LI>cdSetTextPath sets the text direction as right, left, up, or down</LI>
+    <LI>cdSetTextOrient sets the angle of the text</LI>
+  </UL></LI>
+  <LI>Multiple pictures in a file.  Now you can put more than one
+    picture in a cgm file, see cdCgmNewPic for details.</LI>
+  <LI>Internal changes like using short int's in some places so it may
+    take less space in memory when using 16 or 64 bit compilers.</LI>
+  <LI>New example programs.
+    <UL>
+      <LI>cdtext to show the new text attributes.</LI>
+      <LI>cdmulti to show the multiple picture capability.</LI>
+    </UL></LI>
+</UL>
+
+<H4>Version 1.1</H4>
+<P>Thanks to Wolfgang Glunz <wogl@weisshorn.zfe.siemens.de> who purified it,
+pointed out some bugs and did the Borland makefile.
+<UL>
+  <LI>Switched from using malloc to calloc most cases, solving an off
+      by one error in a function I then eliminated.</LI>
+  <LI>Added a Makefile for Borland Turbo C++</LI>
+  <LI>Fixed a couple of spelling errors, cleared out some dead code, and
+      some other trivial things.</LI>
+  <LI>Added a new example program cdsimple which walks you through some
+      basics.</LI>
+  <LI>Added a new function <EM>cdPolyLine</EM> for when you want lines
+      with more than two points</LI>
+</UL>
+</P>
+
+<H4>Version 1.0</H4>
+<P>Basically, everything is new, this is the first release.
+</P>
+<A NAME="whatis"><H3>What is cd?</H3></A>
+<P>
+cd is a graphics library.  It allows your code to quickly draw
+images complete with lines, arcs, rectangles, polygons, text,  and multiple 
+colors.  most geometric shapes can be filled or have a hatch pattern as well.
+The output is a CGM file.  If you are unsure of what CGM is, or if
+CGM is appropriate for your project, see the 
+<A HREF="http://speckle.ncsl.nist.gov/~lsr/cgm.htm">NIST CGM Homepage</A>.
+</P><P>
+Every effort has been made to ensure that the generated cgm files
+conform to the standard, however, if you do not use the library
+properly, you could generate invalid metafiles that no one is able
+to read, so be careful.
+</P>
+
+
+<A NAME="required"><H3>What else do I need to use cd?</H3></A>
+<P>
+To use cd, you will need an ANSI C compiler. Any full-ANSI-standard
+C compiler should be adequate, although those with PCs will need to replace
+the Makefile with one of their own. <STRONG>The cc compiler released
+with SunOS 4.1.3 is not an ANSI C compiler. Get gcc, which is freely
+available. See the Sun-related newsgroups for more information.</STRONG>
+</P><P>
+You will also want a CGM viewer, if you do not already have
+one for your system, since you will need a good way to check the
+results of your work.
+</P>
+<A NAME="get"><H3>How do I get cd?</H3></A>
+<P>
+
+You can
+<A HREF="ftp://zing.ncsl.nist.gov/cgm/">
+fetch cd as a gzip'ed tar file</A>, or you can FTP it directly from
+zing.ncsl.nist.gov in the subdirectory cgm.
+</P>
+<A NAME="build"><H3>How do I build cd?</H3></A>
+<P>
+<em>Note:</em> if you have a non-Unix system, you will need
+to acquire versions of "gunzip" and "tar" suitable for
+your system. Both have been ported to PC and Mac
+environments. Consult newsgroups relevant to your
+particular system.
+<PRE>
+gunzip cd1.2.tar.gz
+tar -xf cd1.2.tar
+</PRE>
+This will create the directory "cd1.2" beneath the current
+directory.
+</P><P>
+change to this directory and examine the Makefile, which you may need
+to change slightly depending on your installation (or more than
+slightly for a Windows or Mac environment).
+On UNIX systems the command "make all" will create the cd library
+and three example programs, <EM>cdsimple</EM>, <EM>cdtest</EM>, 
+and <EM>color16</EM>.  If you are using Borland Turbo C++ version 3 
+(or later I hope) try to make it using makefile.bor
+</P><P>
+CGM files are always in Network Byte order,  Big-Endian systems use this
+ordering.  I wrote this on a Big-Endian machine, but it seems to work on
+Little-Endian's as well.  I have Tested cd on Sun's, Ultrix, Linux, 
+IRIX, and DOS (Borland).  
+If you get it to run on other systems, drop me a note.
+</P>
+
+<A NAME="basics"><H3>cd basics: using cd in your program</H3></A>
+<P>
+cd lets you create CGM images on the fly. To use cd in your
+program, include the file cd.h, and link with the libcd.a
+library produced by "make libcd.a", under Unix. You will
+need to adapt the makefile for your needs if you are using
+a non-Unix operating system, but this is very straightforward.
+</P><P>
+Look at the example programs included in this distribution for
+examples of using cd.  The programs are <EM>cdsimple</EM> which is
+a heavily commented program that makes a small cgm. <EM>cdtest</EM> which
+makes a cgm with every different kind of shape you can use.  It
+has lines, circles, arcs, ellipses, rectangles, polygons, and text  as
+well as examples for setting the attributes for them.  So look
+at it closely, it is your friend.  The other example program, 
+<EM>color16</EM> allocates 16 colors using cdImageColor16 (these
+are the 16 standard Windows colors). Than it draws a rectangle
+with each of them.  These programs are created automatically when you
+"make all".
+</P>
+
+
+<H2><A NAME="reference">Function and Type reference</A></H2>
+<UL>
+  <LI><A HREF="#types">Types</A></LI>
+  <UL>
+    <LI><A HREF="#cdImage">Image</A></LI>
+    <LI><A HREF="#cdImagePtr">Image Pointer</A></LI>
+    <LI><A HREF="#cdPoint">Point</A></LI>
+    <LI><A HREF="#cdPointPtr">Point Pointer</A></LI>
+  </UL>
+  <LI><A HREF="#creating">Image creation, destruction, and saving</A></LI>
+  <UL>
+    <LI><A HREF="#cdImageCreate">Creation</A></LI>
+    <LI><A HREF="#cdImageDestroy">Destruction</A></LI>
+    <LI><A HREF="#cdImageCgm">Saving</A></LI>
+  </UL>
+  <LI><A HREF="#drawing">Drawing functions</A>
+  <UL>
+    <LI><A HREF="#cdLine">Lines</A></LI>
+    <LI><A HREF="#cdPolyLine">Polylines</A></LI>
+    <LI><A HREF="#cdRectangle">Rectangles</A></LI>
+    <LI><A HREF="#cdCircle">Circles</A></LI>
+    <LI><A HREF="#cdArc3Pt">Arcs</A></LI>
+    <LI><A HREF="#cdArc3PtClose">Closed Arcs</A></LI>
+    <LI><A HREF="#cdEllipse">Ellipses</A></LI>
+    <LI><A HREF="#cdPolygon">Polygons</A></LI>
+  </UL>
+  </LI>
+  <LI><A HREF="#fonts">Font and text-handling functions</A></LI>
+  <UL>
+    <LI><A HREF="#cdSetTextAttrib">Text Attributes</A>
+    <UL>
+      <LI><A HREF="#cdSetTextFont">The Font of text</A></LI>
+      <LI><A HREF="#cdSetTextColor">The Color of text</A></LI>
+      <LI><A HREF="#cdSetTextHeight">The Height of text</A></LI>
+      <LI><A HREF="#cdSetTextPath">The path text follows</A></LI>
+      <LI><A HREF="#cdSetTextOrient">The angle of text</A></LI>
+    </UL></LI>
+    <LI><A HREF="#cdText">Writing Text</A></LI>
+  </UL>
+  <LI><A HREF="#attrib">Line, Edge, and Fill attributes</A></LI>
+  <UL>
+    <LI><A HREF="#cdSetLineAttrib">Line Attributes</A>
+    <UL>
+      <LI><A HREF="#cdSetLineType">Line Type</A>
+      <LI><A HREF="#cdSetLineWidth">Line Width</A>
+      <LI><A HREF="#cdSetLineColor">Line Color</A>
+    </UL></LI>
+    <LI><A HREF="#cdSetShapeFillAttrib">Filled Area Attributes</A>
+    <UL>
+      <LI><A HREF="#cdSetFillStyle">Interior Style</A>
+      <LI><A HREF="#cdSetFillColor">Fill Color</A>
+      <LI><A HREF="#cdSetFillHatch">Hatch Index</A>
+    </UL></LI>
+    <LI><A HREF="#cdSetShapeEdgeAttrib">Exterior Filled Area Attributes</A>
+    <UL>
+      <LI><A HREF="#cdSetEdgeType">Edge Type</A>
+      <LI><A HREF="#cdSetEdgeWidth">Edge Width</A>
+      <LI><A HREF="#cdSetEdgeColor">Edge Colour</A>
+      <LI><A HREF="#cdSetEdgeVis">Edge Visibility</A>
+    </UL></LI>
+  </UL>
+  <LI><A HREF="#colors">Color handling functions</A></LI>
+  <UL>
+    <LI><A HREF="#cdImageColorAllocate">Allocate a new color</A></LI>
+    <LI><A HREF="#cdImageColorClosest">Find a close match</A></LI>
+    <LI><A HREF="#cdImageColorExact">Find an exact match</A></LI>
+    <LI><A HREF="#cdImageColorsTotal">Number of allocated colors</A></LI>
+    <LI><A HREF="#cdImageColorRed">Red portion of color</A></LI>
+    <LI><A HREF="#cdImageColorGreen">Green portion of color</A></LI>
+    <LI><A HREF="#cdImageColorBlue">Blue portion of color</A></LI>
+  </UL>
+  <LI><A HREF="#constants">Constants</A></LI>
+</UL>
+
+<H3><A NAME="types">Types</A></H3>
+<!-- ***** Types ***** -->
+<DL>
+<DT>
+<A NAME="cdImage">cdImage</A>
+<STRONG>(Type)</STRONG></DT>
+  <DD>The data structure in which cd stores images. 
+  <A HREF="#cdImageCreate">cdImageCreate</A> returns a pointer to this
+  type, and other functions expect to receive a pointer to this type as
+  their first argument.
+  </DD>
+
+<DT>
+<A NAME="cdImagePtr">cdImagePtr</A>
+<STRONG>(Type)</STRONG></DT>
+  <DD>A pointer to an image structure.  
+  <A HREF="#cdImageCreate">cdImageCreate</A> returns this type, and the other
+  functions expect it as the first argument.  you may read the members
+  <EM>sx</EM> (size of x axis), <EM>sy</EM> (size of y axis),
+  <EM>colorsTotal</EM> (total colors allocated), <EM>red</EM> (red component
+  of colors; an array of 256 integers between 0 and 255),
+  <EM>green</EM> (green commponent of colors), and <EM>blue</EM> (blue
+  component of colors).  Please do so using the macros provided. 
+  <STRONG>Do Not</STRONG> set the members directly from your code, use
+  the functions provided.
+  </DD>
+
+<DT>
+<A NAME="cdPoint">cdPoint</A> 
+<STRONG>(Type)</STRONG></DT>
+  <DD>Represents a collection of points in the coordinate space of the image; 
+  used by <A HREF="#cdPolygon">cdPolygon</A> and 
+  by <A HREF="#cdPolyLine">cdPolyLine</A>.
+  </P><P>
+  cdPointPtr is defined in cd.h, basically, it is an array of integer pairs
+  p[m].x and p[m].y  containing the x and y values respectively. pcnt 
+  is the number of points in this array (not the index of the last point,
+  which is pcnt-1).  pcnt must be at least 3 for polygons or 2 for
+  polylines. 
+  </P><P>
+  Declare it with <CODE>cdPoint points[pcnt]</CODE> where <EM>pcnt</EM>
+  is the upper limit of the number of points you wish to have. then fill
+  it in with <CODE>points[0].x = x0; points[0].y = y0;</CODE> and the like.
+  </DD>
+
+<DT>
+<A NAME="cdPointPtr">cdPointPtr</A>
+<STRONG>(Type)</STRONG>
+  <DD>A pointer to a <A HREF="#cdPoint">cdPoint</A> structure; passed
+  as an argument to <A HREF="#cdPolygon">cdPolygon</A>
+  and to <A HREF="#cdPolyLine">cdPolyLine</A>.
+  </DD>
+
+</DL>
+
+
+<H3><A NAME="creating">Image creation, destruction, and saving</A></H3>
+<!-- ***** Image Functions ***** -->
+
+<DL>
+<DT>
+<A NAME="cdImageCreate">cdImageCreate(int sx, int sy)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>cdImageCreate is called to create images.  Invoke cdImageCreate with
+  the x and y dimensions of the desired image.  cdImageCreate returns a
+  <A HREF="#cdImagePtr">cdImagePtr</A> to the new image, or NULL if unable
+  to allocate the image.  The image must eventually be destroyed
+  using <A HREF="#cdImageDestroy">cdImageDestroy</A>
+  </DD>
+
+<DT>
+<A NAME="cdImageDestroy">cdImageDestroy(cdImagePtr im)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>cdImageDestroy is used to free the memory associated with
+  and image.  It is important to invoke cdImageDestroy before exiting
+  your program or assigning a new image to a
+  <A HREF="#cdImagePtr">cdImagePtr</A> variable.
+  </DD>
+
+<DT>
+<A NAME="cdCgmNewPic">cdCgmNewPic(cdImagePtr im, int sticky)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>cdCgmNewPic allows for a single CGM file to contain multiple
+  pictures.  If <EM>sticky</EM> is 0 then all attributes will be reset to
+  their default condition and the color table will be cleared.
+  If <EM>sticky</EM> is 1 then all attributes and the color table will
+  be carried over to the new picture.
+  <STRONG>NOTE:</STRONG> as of now (version 1.2) the only allowable value
+  for <EM>sticky</EM> is 0.  If you set it to 1, the function will fail.
+  </DD>
+
+<DT>
+<A NAME="cdImageCgm">cdImageCgm(cdImagePtr im, FILE *out)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>cdImageCgm outputs the specified image to the specified file
+  in the CGM image format.  The file must be open for
+  writing.  Under MSDOS, it is important to use "wb" as opposed to simply
+  "w" as the mode when opening the file, and under UNIX there is no penalty
+  for doing so.  cdImageCgm does <EM>not</EM> close the file, your code
+  must do that.
+  </DD>
+
+</DL>
+
+
+<H3><A NAME="drawing">Drawing Functions</A></H3>
+<!-- ***** Drawing Functions ***** -->
+
+<DL>
+<DT>
+<A NAME="cdLine">int cdLine(cdImagePtr im, int x1, int y1, int x2, int y2)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Graphic Primitive: Polyline; Elem Class 4; Elem ID 1<BR>
+  Returns 1 for success, 0 for failure.
+  cdLine is used to draw a line between two endpoints (x1,y1) and (x2,y2)
+  This line is drawn using the attributes set by 
+  <A HREF="#cdSetLineAttrib">cdSetLineAttrib</A>  
+  The attributes that may be set are <A HREF="#cdSetLineType">Line Type</A>,
+  <A HREF="#cdSetLineWidth">Line Width</A>, or
+  <A HREF="#cdSetLineColor">Line Color</A>.
+  The endpoints must be within the bounds of the picture.
+  </DD>
+
+<DT>
+<A NAME="cdPolyLine">int cdPolyLine(cdImagePtr im, cdPointPtr p, int n)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Graphic Primitive: Polyline; Elem Class 4; Elem ID 1<BR>
+  Returns 1 for success, 0 for failure.
+  cdPolyLine draws a line connecting all the points specified by
+  <A HREF="#cdPointPtr">cdPointPtr</A>. <em>n</EM> is the number of
+  points in cdPointPtr, (not the index of the last point, which is n-1).
+  This line is drawn using the attributes set by
+  <A HREF="#cdSetLineAttrib">cdSetLineAttrib</A>  
+  The attributes that may be set are <A HREF="#cdSetLineType">Line Type</A>,
+  <A HREF="#cdSetLineWidth">Line Width</A>, or
+  <A HREF="#cdSetLineColor">Line Color</A>.
+  Note that it uses line attributes not edge attributes for drawing the
+  line.
+  The endpoints must be within the bounds of the picture.
+  </P><P>
+  cdPointPtr is defined in cd.h, basically, it is two arrays of integers
+  p[m].x and p[m].y  containing the x and y values respectively.  n
+  is the number of points in this array (not the index of the last point,
+  which is n-1).  n must be at least 2 (otherwise
+  you really don't have much of a line, it is closer to a point.)
+  </P></DD>
+
+<DT>
+<A NAME="cdRectangle">int cdRectangle(cdImagePtr im, int x1, int y1, int x2, int y2)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Graphic Primitive: rectangle; Elem Class 4; Elem ID 11<BR>
+  Returns 1 for success, 0 for failure.
+  cdRectangle draws a line which has (x1,y1) as the upper left corner
+  and (x2,y2) as the lower right corner.
+  This rectangle is drawn using the 
+  attributes set by <A HREF="#cdSetShapeFillAttrib">cdSetShapeFillAttrib</A>
+  and by <A HREF="#cdSetShapeEdgeAttrib">cdSetShapeEdgeAttrib</A>.
+  The fill attributes that may be set are 
+  <A HREF="#cdSetFillStyle">Fill Style</A>,
+  <A HREF="#cdSetFillColor">Fill Color</A>, or
+  <A HREF="#cdSetFillHatch">Fill Hatch</A>.
+  The edge attributes that may be set are 
+  <A HREF="#cdSetEdgeType">Edge Type</A>,
+  <A HREF="#cdSetEdgeWidth">Edge Width</A>,
+  <A HREF="#cdSetEdgeColor">Edge Color</A>, or
+  <A HREF="#cdSetEdgeVis">Edge Visibility</A>.
+  Note that it uses Edge attributes not line attributes for drawing the
+  perimeter of the rectangle.
+  The Rectangle must be within the bounds of the picture.
+  </DD>
+
+
+<DT>
+<A NAME="cdCircle">int cdCircle(cdImagePtr im, int cx, int cy, int r)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Graphic Primitive: circle; Elem Class 4; Elem ID 12<BR>
+  Returns 1 for success, 0 for failure.
+  cdCircle draws a circle which has center (cx, cy) and radius r.
+  This circle is drawn using the attributes set by
+  <A HREF="#cdSetShapeFillAttrib">cdSetShapeFillAttrib</A>
+  and by <A HREF="#cdSetShapeEdgeAttrib">cdSetShapeEdgeAttrib</A>.
+  The fill attributes that may be set are 
+  <A HREF="#cdSetFillStyle">Fill Style</A>,
+  <A HREF="#cdSetFillColor">Fill Color</A>, or
+  <A HREF="#cdSetFillHatch">Fill Hatch</A>.
+  The edge attributes that may be set are 
+  <A HREF="#cdSetEdgeType">Edge Type</A>,
+  <A HREF="#cdSetEdgeWidth">Edge Width</A>,
+  <A HREF="#cdSetEdgeColor">Edge Color</A>, or
+  <A HREF="#cdSetEdgeVis">Edge Visibility</A>.
+  Note that it uses Edge attributes not line attributes for drawing the
+  perimeter of the Circle.
+  The Circle must be within the bounds of the picture.
+  </DD>
+
+<DT>
+<A NAME="cdArc3Pt">int cdArc3Pt(cdImagePtr im, int sx, int sy, int ix, int iy, int ex, int ey)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Graphic Primitive: Cicular Arc 3 Point; Elem Class 4; Elem ID 13<BR>
+  Returns 1 for success, 0 for failure.
+  cdArc3Pt draws an arc specified by the given points. (sx,sy) is the 
+  start of the arc, (ix,iy) is the middle of the arc, and (ex,ey) is the
+  end of the arc.
+  This arc is drawn using the attributes set by 
+  <A HREF="#cdSetLineAttrib">cdSetLineAttrib</A>  
+  The attributes that may be set are <A HREF="#cdSetLineType">Line Type</A>,
+  <A HREF="#cdSetLineWidth">Line Width</A>, or
+  <A HREF="#cdSetLineColor">Line Color</A>.
+  Note that it uses Line attributesfor drawing
+  the perimiter of the arc, not Edge attributes like
+  <A HREF="#cdArc3PtClose">cdArc3PtClose</A>.
+  The Arc must be within the bounds of the picture.
+  </DD>
+
+<DT>
+<A NAME="cdArc3PtClose">int cdArc3PtClose(cdImagePtr im, int sx, int sy, int ix, int iy, int ex, int ey, int cl)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Graphic Primitive: Cicular Arc 3 Point Close; Elem Class 4; Elem ID 14<BR>
+  Returns 1 for success, 0 for failure.
+  cdArc3PtClose draws an arc specified by the given points. (sx,sy) is the 
+  start of the arc, (ix,iy) is the middle of the arc, and (ex,ey) is the
+  end of the arc.  The arc is closed base on <EM>cl</EM>.  If <EM>cl</EM> is
+  0 then pie closure will be used, resulting in a pie shaped slice. if
+  <EM>cl</EM> is 1 then cord closure will be used and a straight line will
+  be drawn from one endpoint to the other.
+  This arc is drawn using the attributes set by
+  <A HREF="#cdSetShapeFillAttrib">cdSetShapeFillAttrib</A>
+  and by <A HREF="#cdSetShapeEdgeAttrib">cdSetShapeEdgeAttrib</A>.
+  The fill attributes that may be set are 
+  <A HREF="#cdSetFillStyle">Fill Style</A>,
+  <A HREF="#cdSetFillColor">Fill Color</A>, or
+  <A HREF="#cdSetFillHatch">Fill Hatch</A>.
+  The edge attributes that may be set are 
+  <A HREF="#cdSetEdgeType">Edge Type</A>,
+  <A HREF="#cdSetEdgeWidth">Edge Width</A>,
+  <A HREF="#cdSetEdgeColor">Edge Color</A>, or
+  <A HREF="#cdSetEdgeVis">Edge Visibility</A>.
+  Note that it uses Edge attributes for drawing the
+  perimeter of the arc, not Line attributes like 
+  <A HREF="#cdArc3Pt">cdArc3Pt</A>.
+  The Arc must be within the bounds of the picture.
+  </DD>
+
+<DT>
+<A NAME="cdEllipse">int cdEllipse(cdImagePtr im, int cx, int cy, int d1x, int d1y, int d2x, int d2y)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Graphic Primitive: Ellipse; Elem Class 4; Elem ID 17<BR>
+  Returns 1 for success, 0 for failure.
+  cdEllipse draws an ellipse specified by the given points. (cx,cy) is
+  the center, (d1x,d1y) is the endpoint of the first conjugate diameter,
+  (d2x, d2y) is the endpoint of the second conjugate diameter.  I can't
+  really explain this one, if you come up with a good description, 
+  <A HREF="mailto:lorax@nist.gov" NAME="Ellipse Description">mail me</A>.
+  This ellipse is drawn using the attributes set by
+  <A HREF="#cdSetShapeFillAttrib">cdSetShapeFillAttrib</A>
+  and by <A HREF="#cdSetShapeEdgeAttrib">cdSetShapeEdgeAttrib</A>.
+  The fill attributes that may be set are 
+  <A HREF="#cdSetFillStyle">Fill Style</A>,
+  <A HREF="#cdSetFillColor">Fill Color</A>, or
+  <A HREF="#cdSetFillHatch">Fill Hatch</A>.
+  The edge attributes that may be set are 
+  <A HREF="#cdSetEdgeType">Edge Type</A>,
+  <A HREF="#cdSetEdgeWidth">Edge Width</A>,
+  <A HREF="#cdSetEdgeColor">Edge Color</A>, or
+  <A HREF="#cdSetEdgeVis">Edge Visibility</A>.
+  Note that it uses Edge attributes not line attributes for drawing the
+  perimeter of the Ellipse.
+  The Ellipse must be within the bounds of the picture.
+  </DD>
+
+<DT>
+<A NAME="cdPolygon">int cdPolygon(cdImagePtr im, cdPointPtr p, int n)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Graphic Primitive: Polygon; Elem Class 4; Elem ID 7<BR>
+  Returns 1 for success, 0 for failure.
+  cdPolygon draws a closed polygon connecting the points specified by
+  <A HREF="#cdPointPtr">cdPointPtr</A>. <em>n</EM> is the number of
+  points in cdPointPtr, (not the index of the last point, which is n-1).
+  This polygon is drawn using the attributes set by
+  <A HREF="#cdSetShapeFillAttrib">cdSetShapeFillAttrib</A>
+  and by <A HREF="#cdSetShapeEdgeAttrib">cdSetShapeEdgeAttrib</A>.
+  The fill attributes that may be set are
+  <A HREF="#cdSetFillStyle">Fill Style</A>,
+  <A HREF="#cdSetFillColor">Fill Color</A>, or
+  <A HREF="#cdSetFillHatch">Fill Hatch</A>.
+  The edge attributes that may be set are
+  <A HREF="#cdSetEdgeType">Edge Type</A>,
+  <A HREF="#cdSetEdgeWidth">Edge Width</A>,
+  <A HREF="#cdSetEdgeColor">Edge Color</A>, or
+  <A HREF="#cdSetEdgeVis">Edge Visibility</A>.
+  Note that it uses Edge attributes not line attributes for drawing the
+  perimeter of the polygon.
+  The polygon must be within the bounds of the picture.
+  </P><P>
+  cdPointPtr is defined in cd.h, basically, it is two arrays of integers
+  p[m].x and p[m].y  containing the x and y values respectively.  n
+  is the number of points in this array (not the index of the last point,
+  which is n-1).  n must be at least 3 (otherwise
+  you really don't have much of a polygon, it is closer to a line.)
+  </P></DD>
+
+</DL>
+
+
+<H3><A NAME="fonts">Font and text-handling functions</A></H3>
+<!-- ***** Font and text-handling Functions ***** -->
+<DL>
+<DT>
+<A NAME="cdSetTextAttrib">int cdSetTextAttrib(cdImagePtr im, int font, int color, int height)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>
+  Returns 1 for success, 0 for failure.
+  cdSetTextAttrib sets the attributes for text elements.
+  The <A HREF="#fonts">Font functions</A> are affected by this.
+  These attributes stay in effect until they are changed, you don't
+  have to call this function every time.  If you call the function with
+  a value of -1 for any of the attributes they will not be changed.  If
+  you call the function with the same value for an attribute as it
+  already has, it will not be changed (so you don't have to worry about
+  bloating your CGM with redundant attribute changes.)
+  It calls three functions. <A HREF="#cdSetTextFont">cdSetTextFont</A>
+  to set the index into the font table, 
+  <A HREF="#cdSetTextColor">cdSetTextColor</A> with <EM>color</EM> to set
+  the forground color of the text, and 
+  <A HREF="#cdSetTextHeight">cdSetTextHeight</A> with <EM>height</EM> to
+  set the height of the text.
+  You may also call any of the three functions individually if you like.
+  </DD>
+
+<DT>
+<A NAME="cdText">int cdText(cdImagePtr im, int x, int y, const char *ts)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Graphic Primitive: Text; Elem Class 4; Elem ID 4<BR>
+  Returns 1 for success, 0 for failure.
+  cdText puts a string of text <EM>ts</EM> starting at position (x,y)
+  The Text is drawn using the attributes set with 
+  <A HREF="#cdSetTextAttrib">cdSetTextAttrib</A>.  The attributes that
+  may be set are:
+  <A HREF="#cdSetTextFont">cdSetTextFont</A>,
+  <A HREF="#cdSetTextColor">cdSetTextColor</A>, or
+  <A HREF="#cdSetTextHeight">cdSetTextHeight</A>.
+  The point where the text starts must be within the bounds of the picture.
+  </DD>
+
+<DT>
+<A NAME="cdSetTextPath">int cdSetTextPath(cdImagePtr im, int tpath)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Text Path; Elem Class 5; Elem ID 17<BR>
+  Returns 1 for success, 0 for failure.
+  sets the path of the text to <EM>tpath</EM>.  tpath is an integer
+  with one of the following values
+  <UL>
+    <LI>0 for right</LI>
+    <LI>1 for left</LI>
+    <LI>2 for up</LI>
+    <LI>3 for down</LI>
+  </UL>
+  These are all relative to the charater base vector and up vector.  If you
+  haven't changed them (with <A HREF="#cdSetTextOrient">cdSetTextOrient</A>
+  then the direction of the text will be right to left for 0, left to right
+  for 1, bottom to top for 2, and top to bottom for 3.  Each individual 
+  letter will still be facing in the normal direction.  If you want to
+  rotate the text use <A HREF="#cdSetTextOrient">cdSetTextOrient</A>.
+  </P><P>
+  Things get more interesting if you use 
+  <A HREF="#cdSetTextOrient">cdSetTextOrient</A> with this function.
+  A more exact definition of <EM>tpath</EM> is
+  <UL>
+    <LI>0 right  -- the direction of the character base vector</LI>
+    <LI>1 left -- 180 degrees from the direction of the character
+      base vector</LI>
+    <LI>2 up -- the direction of the character up vector</LI>
+    <LI>3 down -- 180 degrees from the direction of the character
+      up vector</LI>
+  </UL>
+  </P>
+  </DD>
+
+<DT>
+<A NAME="cdSetTextOrient">int cdSetTextOrient(cdImagePtr im, int xup, int yup, int xbase, int ybase)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Character Orientation; Elem Class 5; Elem ID 16<BR>
+  Returns 1 for success, 0 for failure.
+  (xbase,ybase) is the run and the rise of the line that the text is
+  written along.  For regular text that is rotated, set xup = -ybase
+  and yup = xbase.  Setting it to something different will result in
+  skewed text (which may be what you want.) Text written from bottom to
+  top at a 90 degree angle would have the following parameters
+  xup=-1, yup=0, xbase=0, ybase=1
+  </P><P>
+  This function adds the Orientation to the metafile every time.
+  It does not interpert an attribute value of -1 as no change like many
+  functions do, although if you
+  put in the same numbers it won't re-add it to the meta file.
+  </P></DD>
+
+<DT>
+<A NAME="cdSetTextFont">int cdSetTextFont(cdImagePtr im, int font)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Text Font Index; Elem Class 5; Elem ID 10<BR>
+  Returns 1 for success, 0 for failure.
+  Sets the font index to <EM>font</EM>.  It is an index into the
+  font table, the possible values are:
+  <UL>
+    <LI>1 for Times</LI>
+    <LI>2 for Times Bold</LI>
+    <LI>3 for Times Italic</LI>
+    <LI>4 for Times Bold Italic</LI>
+    <LI>5 for Helvetica</LI>
+    <LI>6 for Helvetica Bold</LI>
+    <LI>7 for Helvetica Italic</LI>
+    <LI>8 for Helvetica Bold Italic</LI>
+  </UL>
+  <EM>font</EM> must be one of these values or the function will fail.
+  See <A HREF="#cdSetTextAttrib">cdSetTextAttrib</A> for more information
+  on this and related functions.
+  </DD>
+
+<DT>
+<A NAME="cdSetTextColor">int cdSetTextColor(cdImagePtr im, int color)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Text Colour; Elem Class 5; Elem ID 14<BR>
+  Returns 1 for success, 0 for failure.
+  Sets the foreground color of text to <EM>color</EM>.  This should be
+  an integer which is an index into the color table that you have
+  previously allocated.  See <A HREF="#cdSetTextAttrib">cdSetTextAttrib</A>
+  for more information on this and related functions.
+  </DD>
+
+<DT>
+<A NAME="cdSetTextHeight">int cdSetTextHeight(cdImagePtr im, int height)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Character Height; Elem Class 5; Elem ID 15<BR>
+  Returns 1 for success, 0 for failure.
+  <EM>height</EM> is an integer for the height of the text you are displaying.
+  Bigger numbers make larger text.  The size of the text is dependent on
+  the size of the picture.
+  See <A HREF="#cdSetTextAttrib">cdSetTextAttrib</A>
+  for more information on this and related functions.
+  </DD>
+  
+</DL>
+
+
+<H3><A NAME="attrib">Line, Edge, and Fill attributes</A></H3>
+<!-- ***** Line, Edge, and Fill Attributes ***** -->
+<DL>
+<DT>
+<A NAME="cdSetLineAttrib">int cdSetLineAttrib(cdImagePtr im, int lntype, int lnwidth, int lncolor)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>
+  Returns 1 for success, 0 for failure.
+  cdSetLineAttrib sets the attributes for lines and  non-closed area elements.
+  The <A HREF="#drawing">drawing functions</A> affected are 
+  <UL>
+    <LI><A HREF="#cdLine">Lines</A></LI>
+    <LI><A HREF="#cdArc3Pt">Arcs</A></LI>
+  </UL>
+  These attributes stay in effect until they are changed, you
+  don't have to call this function every time.  If you call the function with
+  a value of -1 for any of the attributes they will not be changed.  If
+  you call the function with the same value for an attribute as it
+  already has, it will not be changed (so you don't have to worry about
+  bloating your CGM with redundant attribute changes.)
+  It calls three functions.  <A HREF="#cdSetLineType">cdSetLineType</A>
+  with <EM>lntype</EM> to set the line type (solid, dashed, etc), 
+  <A HREF="#cdSetLineWidth">cdSetLineWidth</A> with <EM>lnwidth</EM> to
+  set how wide the line is, and <A HREF="#cdSetLineColor">cdSetLineColor</A>
+  to set the color of the line.
+  You may also call any of the three functions individually if you like.
+  </DD>
+
+<DT>
+<A NAME="cdSetShapeFillAttrib">int cdSetShapeFillAttrib(cdImagePtr im, int instyle, int incolor, int inhatch)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>
+  Returns 1 for success, 0 for failure.
+  cdSetShapeFillAttrib sets the attributes for the interior of closed area
+  elements.
+  The <A HREF="#drawing">drawing functions</A>affected are 
+  <UL>
+    <LI><A HREF="#cdRectangle">Rectangles</A></LI>
+    <LI><A HREF="#cdCircle">Circles</A></LI>
+    <LI><A HREF="#cdArc3PtClose">Closed Arcs</A></LI>
+    <LI><A HREF="#cdEllipse">Ellipses</A></LI>
+  </UL>
+  These attributes stay in effect until they are changed, you
+  don't have to call this function every time.  If you call the function with
+  a value of -1 for any of the attributes they will not be changed.  If
+  you call the function with the same value for an attribute as it
+  already has, it will not be changed (so you don't have to worry about
+  bloating your CGM with repetitive attribute changes.
+  It calls three functions.  
+  <A HREF="#cdSetFillStyle">cdSetFillStyle</A> with <EM>instyle</EM> to set
+  the interior style (solid, hatch, empty), 
+  <A HREF="#cdSetFillColor">cdSetFillColor</A> with <EM>incolor</EM> to set
+  the interior color (used if instyle is solid or hatch), and
+  <A HREF="#cdSetFillHatch">cdSetFillHatch</A> with <EM>inhatch</EM> to set
+  the hatch style (hor lines, vert lines, crosshatch, etc) (used if
+  instyle is hatch).
+  You may also call any of the three functions individually if you like.
+  </DD>
+
+<DT>
+<A NAME="cdSetShapeEdgeAttrib">int cdSetShapeEdgeAttrib(cdImagePtr im, int edtype, int edwidth, int edcolor, int edvis)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>
+  Returns 1 for success, 0 for failure.
+  cdSetShapeEdgeAttrib sets the attributes for the perimeter of
+  Filled area elements.  It might seem logical to use the line attributes
+  instead, but that is not the case.
+  The <A HREF="#drawing">drawing functions</A>affected are 
+  <UL>
+    <LI><A HREF="#cdRectangle">Rectangles</A></LI>
+    <LI><A HREF="#cdCircle">Circles</A></LI>
+    <LI><A HREF="#cdArc3PtClose">Closed Arcs</A></LI>
+    <LI><A HREF="#cdEllipse">Ellipses</A></LI>
+  </UL>
+  These attributes stay in effect until they are changed, you
+  don't have to call this function every time.  If you call the function with
+  a value of -1 for any of the attributes they will not be changed.  If
+  you call the function with the same value for an attribute as it
+  already has, it will not be changed (so you don't have to worry about
+  bloating your CGM with redundant attribute changes.)
+  cdSetShapeEdgeAttrib calls three functions.
+  <A HREF="#cdSetEdgeType">cdSetEdgeType</A> with <EM>edtype</EM> to set
+  the edge type (solid, dashed, etc),
+  <A HREF="#cdSetEdgeWidth">cdSetEdgeWidth</A> with <EM>edwidth</EM> to set
+  the width of the line around the perimeter,
+  <A HREF="#cdSetEdgeColor">cdSetEdgeColor</A> with <EM>edcolor</EM> to set
+  the color of the line around the perimeter, and
+  <A HREF="#cdSetEdgeVis">cdSetEdgeVis</A> with <EM>edvis</EM> to determine
+  if the line around the perimeter is visible.
+  You may also call any of the three functions individually if you like.
+  </DD>
+
+<DT>
+<A NAME="cdSetLineType">int cdSetLineType(cdImagePtr im, int lntype)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Line Type; Elem Class 5; Elem ID 2<BR>
+  Returns 1 for success, 0 for failure.
+  <EM>lntype</EM> is the line type which is an integer with possible values
+  of:
+  <UL>
+    <LI>1 for a solid line</LI>
+    <LI>2 for a dashed line</LI>
+    <LI>3 for a dotted line</LI>
+    <LI>4 for a dash-dot line</LI>
+    <LI>5 for a dash-dot-dot line</LI>
+  </UL>
+  <EM>lntype</EM> must be one of these values or the function will fail. 
+  See <A HREF="#cdSetLineAttrib">cdSetLineAttrib</A> for more information
+  on this and related functions.
+  </DD>
+
+<DT>
+<A NAME="cdSetLineWidth">int cdSetLineWidth(cdImagePtr im, int lnwidth)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Line Width; Elem Class 5; Elem ID 3<BR>
+  Returns 1 for success, 0 for failure.
+  <EM>lnwidth</EM> is an integer giving the width of lines.  With an
+  image of height Y with line width 1 the displayed width will be 1/Y%.
+  As an example, if you image is x=5, y=10, and you set line width = 1,
+  and draw a vertical line, the resulting line will  cover 20% of 
+  horizontal area. (I think anyway).
+  See <A HREF="#cdSetLineAttrib">cdSetLineAttrib</A> for more information
+  on this and related functions.
+  </DD>
+
+<DT>
+<A NAME="cdSetLineColor">int cdSetLineColor(cdImagePtr im, int lncolor)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Line Colour; Elem Class 5; Elem ID 4<BR>
+  Returns 1 for success, 0 for failure.
+  Sets the line color to <EM>lncolor</EM>.  This should be an integer
+  which is an index into the color table that you have previously
+  allocated.
+  See <A HREF="#cdSetLineAttrib">cdSetLineAttrib</A> for more information
+  on this and related functions.
+  </DD>
+
+<DT>
+<A NAME="cdSetFillStyle">int cdSetFillStyle(cdImagePtr im, int instyle)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Interior Style; Elem Class 5; Elem ID 22<BR>
+  Returns 1 for success, 0 for failure.
+  Sets the style of the interior of filled area elements.
+  <EM>instyle</EM> is the interior style which is an integer with
+  possible values of:
+  <UL>
+    <LI>0 for hollow.  No filling, but the boundary (bounding line) of the 
+    filled area is drawn using the fill colour currently selected.  
+    The boundary of a "hollow" filled area is considered to be the
+    representation of the interior.  The boundary is distinct from the edge,
+    and is drawn only for "hollow" filled areas</LI>
+    <LI>1 for solid. Fill the interior using the fill colour currently
+    selected</LI>
+    <LI>3 for hatch.  Fill the interior using the fill colour and hatch index
+    currently selected.</LI>
+    <LI>4 for empty.  No filling is done and no boundary is drawn, i.e.,
+    nothing is done to represent the interior.  The only potentially
+    visible component of an "empty" filled area is the edge, subject
+    to EDGE VISIBILITY and other edge attributes.</LI>
+  </UL>
+  <EM>instyle</EM> must be one of these values or the function will fail. 
+  So, basically, if you want an interior which is transparent and you can
+  see what is underneath it, use "empty"  otherwise fill it in with a
+  hatch or solid color.
+  See <A HREF="#cdSetShapeFillAttrib">cdSetShapeFillAttrib</A> for more
+  information on this and related functions.
+  </DD>
+
+<DT>
+<A NAME="cdSetFillColor">int cdSetFillColor(cdImagePtr im, int incolor)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Fill Colour; Elem Class 5; Elem ID 23<BR>
+  Returns 1 for success, 0 for failure.
+  Sets the fill color to <EM>incolor</EM>.  This should be an integer
+  which is an index into the color table that you have previously
+  allocated.
+  See <A HREF="#cdSetShapeFillAttrib">cdSetShapeFillAttrib</A> for more
+  information on this and related functions.
+  </DD>
+
+<DT>
+<A NAME="cdSetFillHatch">int cdSetFillHatch(cdImagePtr im, int inhatch)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Hatch Index; Elem Class 5; Elem ID 24<BR>
+  Returns 1 for success, 0 for failure.
+  Sets the hatch pattern for the interior of filled-area elements to
+  <EM>inhatch</EM>.  The <A HREF="#cdSetFillStyle">fill style</A>
+  must be set to hatch for this to have an effect.  the value for
+  <EM>inhatch</EM> is the hatch style, which is an integer with possible values
+  of:
+  <UL>
+    <LI>1 for horizontal lines</LI>
+    <LI>2 for vertcal lines</LI>
+    <LI>3 for positive slope parallel lines</LI>
+    <LI>4 for negative slope parallel lines</LI>
+    <LI>5 for horizontal/vertical crosshatch </LI>
+    <LI>6 for positive/negative slope crosshatch </LI>
+  </UL>
+  <EM>lntype</EM> must be one of these values or the function will fail. 
+  See <A HREF="#cdSetShapeFillAttrib">cdSetShapeFillAttrib</A> for more
+  information on this and related functions.
+  </DD>
+
+<DT>
+<A NAME="cdSetEdgeType">int cdSetEdgeType(cdImagePtr im, int edtype)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Edge Type; Elem Class 5; Elem ID 27<BR>
+  Returns 1 for success, 0 for failure.
+  <EM>edtype</EM> is the edge type which is an integer with possible values
+  of:
+  <UL>
+    <LI>1 for a solid line</LI>
+    <LI>2 for a dashed line</LI>
+    <LI>3 for a dotted line</LI>
+    <LI>4 for a dash-dot line</LI>
+    <LI>5 for a dash-dot-dot line</LI>
+  </UL>
+  <EM>edtype</EM> must be one of these values or the function will fail. 
+  See <A HREF="#cdSetShapeFillAttrib">cdSetShapeEdgeAttrib</A> for more
+  information on this and related functions.
+  </DD>
+
+<DT>
+<A NAME="cdSetEdgeWidth">int cdSetEdgeWidth(cdImagePtr im, int edwidth)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Edge Width; Elem Class 5; Elem ID 28<BR>
+  Returns 1 for success, 0 for failure.
+  <EM>edwidth</EM> is an integer giving the width of the perimeter lines.
+  With an image of height X with line width 1 the displayed width will be 1/X%.
+  As an example, if you image is x=5, y=10, and you set line width = 1,
+  and draw a vertical line, the resulting line will  cover 20% of 
+  horizontal area. (I think anyway).
+  See <A HREF="#cdSetShapeFillAttrib">cdSetShapeEdgeAttrib</A> for more
+  information on this and related functions.
+  </DD>
+
+<DT>
+<A NAME="cdSetEdgeColor">int cdSetEdgeColor(cdImagePtr im, int edcolor)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Edge Color; Elem Class 5; Elem ID 29<BR>
+  Returns 1 for success, 0 for failure.
+  Sets the color of the perimeter lines to <EM>edcolor</EM>.  This 
+  should be an integer which is an index into the color table that 
+  you have previously allocated.
+  See <A HREF="#cdSetShapeFillAttrib">cdSetShapeEdgeAttrib</A> for more
+  information on this and related functions.
+  </DD>
+
+<DT>
+<A NAME="cdSetEdgeVis">int cdSetEdgeVis(cdImagePtr im, int edvis)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>Attribute: Edge Visibility; Elem Class 5; Elem ID 30<BR>
+  Returns 1 for success, 0 for failure.
+  <EM>edvis</EM> is an integer that can have one of the following values.
+  <UL>
+    <LI>0 for invisible edges</LI>
+    <LI>1 for visible edges</LI>
+  </UL>
+  If you set the edge visibility to off (invisible edges) than you will
+  not see the edges, regardless of what other edge attributes are set.
+  The other attributes will still be set and turning the edge visibility
+  to on will make edges using the current edge styles.
+  See <A HREF="#cdSetShapeFillAttrib">cdSetShapeEdgeAttrib</A> for more
+  information on this and related functions.
+  </DD>
+
+</DL>
+
+
+<H3><A NAME="colors">Color handling functions</A></H3>
+<!-- ***** Color Handling Functions ***** -->
+<DL>
+<DT>
+<A NAME="cdImageColorAllocate">int cdImageColorAllocate(cdImagePtr im, int r, int g, int b)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>cdImageColorAllocate finds the first available color index in
+  the image specified, sets its RGB values to those requested
+  (255 is the maximum for each), and returns the index of the new color 
+  table entry. When creating a new image, the first time you invoke this
+  function, you are setting the background color for that image.
+  <P>
+  In the event that all <A HREF="#cdMaxColors">cdMaxColors</A> colors
+  (256) have been allocated already, cdImageColorAllocate will return
+  -1 to indicate failure, otherwise it will return the index into the 
+  color table allocated. (Note that most functions return 0 on failure, but
+  0 is a valid color table entry.)
+  </P><P>
+  cdImageColorAllocate does not check for existing colors that match
+  your request, you might want to use 
+  <A HREF="#cdImageColorExact">cdImageColorExact</A> prior to calling this
+  function to keep from defining multiple indexes with the same color.  If
+  color alocation fails, use 
+  <A HREF="#cdImageColorClosest">cdImageColorClosest</A> to find the
+  nearest matching color.
+  </DD>
+
+<DT>
+<A NAME="cdImageColorClosest">int cdImageColorClosest(cdImagePtr im, int r, int g, int b)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>cdImageColorClosest searches the colors which have been
+  defined thus far in the image specified and returns the
+  index of the color with RGB values closest to those of the
+  request. (Closeness is determined by Euclidian distance,
+  which is used to determine the distance in three-dimensional color 
+  space between colors.)
+  <P>
+  If no colors have yet been allocated in the image,
+  gdImageColorClosest returns -1.
+  </P><P>
+  This function is most useful as a backup method for choosing
+  a drawing color when an image already contains
+  <A HREF="#cdMaxColors">cdMaxColors</A> (256) colors and
+  no more can be allocated.
+  See <A HREF="#cdImageColorExact">cdImageColorExact</A>
+  for a method of locating exact matches only.
+  </P></DD>
+
+<DT>
+<A NAME="cdImageColorExact">int cdImageColorExact(cdImagePtr im, int r, int g, int b)</A>
+<STRONG>(Function)</STRONG></DT>
+  <DD>cdImageColorExact searches the colors which have been
+  defined thus far in the image specified and returns the
+  index of the first color with RGB values which exactly
+  match those of the request. If no allocated color matches the
+  request precisely, cdImageColorExact returns -1.
+  See <A HREF="#cdImageColorClosest">cdImageColorClosest</A>
+  for a way to find the color closest to the color requested.
+  </DD>
+
+<DT><A NAME="cdImageColorsTotal">int cdImageColorsTotal(cdImagePtr im)</A>
+<STRONG>(Macro)</STRONG> 
+  <DD>cdImageColorsTotal is a macro which returns the number of
+  colors currently allocated in the image. Use this macro
+  to obtain this information; do not access the structure
+  directly.
+  </DD>
+
+<DT>
+<A NAME="cdImageColorRed">int cdImageColorRed(cdImagePtr im, int c)</A>
+<STRONG>(Macro)</STRONG> 
+  <DD>cdImageColorRed is a macro which returns the red portion
+  of the specified color in the image. Use this macro
+  to obtain this information; do not access the structure
+  directly.
+  </DD>
+
+<DT>
+<A NAME="cdImageColorGreen">int cdImageColorGreen(cdImagePtr im, int c)</A>
+<STRONG>(Macro)</STRONG> 
+  <DD>cdImageColorGreen is a macro which returns the green portion
+  of the specified color in the image. Use this macro
+  to obtain this information; do not access the structure
+  directly.
+  </DD>
+
+<DT>
+<A NAME="cdImageColorBlue">int cdImageColorBlue(cdImagePtr im, int c)</A>
+<STRONG>(Macro)</STRONG> 
+  <DD>cdImageColorBlue is a macro which returns the green portion
+  of the specified color in the image. Use this macro
+  to obtain this information; do not access the structure
+  directly.
+  </DD>
+
+</DL>
+
+
+<H3><A NAME="constants">Constants</A></H3>
+<!-- ***** Constants ***** -->
+
+<DL>
+<DT>
+<A NAME="cdMaxColors">cdMaxColors</A>
+<STRONG>Constant</STRONG></DT>
+  <DD>cdMaxColors is the maximum number of colors that can be allocated in
+  a CGM picture.  the CGM standard allows for many different ways of
+  allocating colors, but I have chosen to limit this library to
+  8 bit indexed color.  This means the <EM>maximum</EM> value of this
+  is 256.  If you really wanted to you could make it smaller though it 
+  would not have an effect on the resulting file size.
+  </DD>
+
+<DT>
+<A NAME="CDSTARTLISTSIZE">CDSTARTLISTSIZE</A>
+<STRONG>Constant</STRONG></DT>
+  <DD>When you create an image, a buffer is allocated to hold the drawing
+  commands.  This is the initial size of the buffer in bytes.  When it is 
+  filled, the size gets increased by
+  <A HREF="#CDGROWLISTSIZE">CDGROWLISTSIZE</A>.
+  If you know you are going to be working with very small CGM's then
+  make this a small number.  If you know your CGM's will be large increase
+  this number.  If CDSTARTLISTSIZE is smaller than the header information
+  than it will have to grow before you do anything.  I wouldn't make it
+  smaller than 1024.  Try to make it as large as the average picture you make.
+  </DD>
+
+<DT>
+<A NAME="CDGROWLISTSIZE">CDGROWLISTSIZE</A>
+<STRONG>Constant</STRONG></DT>
+  <DD>When you create an image, a buffer is allocated to hold the drawing
+  commands.  When the buffer is filled, the size is increased by the amount
+  given in CDGROWLISTSIZE (in bytes).  If you know that most of the CGM's you
+  create will be near the size of <A HREF="#CDSTARTLISTSIZE">CDSTARTLISTSIZE</A>
+  than make this number small.  If there is lots of variablility in the
+  size of your CGM's, make this number large.  If CDGROWLISTSIZE is
+  larger than CDSTARTLISTSIZE, you should probably increase the value
+  of CDSTARTLISTSIZE.  If CDGROWLISTSIZE is smaller than the largest
+  CGM element you create than it will be growing alot,  so I wouldn't
+  make it smaller than about 1024.
+  </DD>
+
+</DL>
+
+
+<H3><A NAME="replacegd">Using cd instead of gd</A></H3>
+<P>
+CD was designed to be easy to use instead of gd (or with gd, if you want
+to be able to produce both).  However, There are significate differences
+between the way CGM handles attributes versus the way gd does.  In particular,
+gd requires you to put the line color in the function call to draw lines,
+CD does not, Color, like the other attributes only need to be set when
+they are changed.  I recomend that you read over the documentation of both
+to see what the differences are, and make appropriate changes to your
+code.  If you really want to make as few changes as possible to your
+code, I have provided two functions to help you.  <EM>cdImageLine</EM>
+takes the same parameters as <EM>gdImageLine</EM> and will draw
+a solid line of the color specified.  <EM>cdImageRectangle</EM>
+draws a hollow rectangle with solid edges of the color specified.  I
+did this by drawing four lines, so it is not a true rectangle.
+Again, I recomend you use <EM>cdLine</EM> and <EM>cdRectangle</EM>
+instead of these, but they are there if you want them.
+
+<H3><A NAME="informing">Please tell us you're using cd!</A></H3>
+<P>
+When you contact us and let us know you are using cd,
+you help us justify the time spent in maintaining and improving
+it. So please let us know. If the results are publicly
+visible on the web, a URL is a wonderful thing to receive, but
+if it's not a publicly visible project, a simple note is just 
+as welcome.
+</P>
+
+
+<HR><EM>
+<A HREF="http://speckle.ncsl.nist.gov/~lorax/index.html">
+G. Edward Johnson</A><BR>
+<A HREF="mailto:lorax@nist.gov" TITLE="WEB: CGM Draw Comment">lorax@nist.gov</A>
+</EM></BR>
+</BODY></HTML>
diff --git a/src/cd/cd1.2.lsm b/src/cd/cd1.2.lsm
new file mode 100644
index 0000000..eaa90e6
--- /dev/null
+++ b/src/cd/cd1.2.lsm
@@ -0,0 +1,11 @@
+Title:		CGMDraw
+Version:	1.2
+Entered-date:	28 Jun 1996
+Description:	C Library for creating CGM vector graphics files.
+Keywords:	Computer Graphics Metafile vector CGM
+Author: 	lorax@nist.gov (G. Edward Johnson)
+Maintained-by:	lorax@nist.gov (G. Edward Johnson)
+Primary-site:	zing.ncsl.nist.gov /cgm/cd1.2.tar.gz
+		34kb 
+Platforms:	Sun, Linux, Ultrix, IRIX, DOS
+Copying-policy:	Freely Redistributable
diff --git a/src/cd/cdmulti.c b/src/cd/cdmulti.c
new file mode 100644
index 0000000..cdfeee2
--- /dev/null
+++ b/src/cd/cdmulti.c
@@ -0,0 +1,98 @@
+/* 
+ * cdmulti is a program to make a cgm file with multiple pictures in it.
+ *
+
+ cdmulti.c: test program for the cgmdraw module.
+
+        Written by G. Edward Johnson <mailto:lorax@nist.gov>
+        Date: June 26, 1996
+        Copyright: cd software produced by NIST, an agency of the 
+	U.S. government, is by statute not subject to copyright
+	in the United States. Recipients of this software assume all 
+	responsibilities associated with its operation, modification
+	and maintenance.
+
+*/
+
+
+#include <malloc.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include "defines.h"
+#include "cd.h"
+
+
+int main () {
+
+	/* you must create a pointer to the image(s) that you will be using
+	 * not suprisingly, it is of type cdImagePtr */
+	cdImagePtr im;
+
+	/* this is a pointer to the output file you will be using */
+	FILE *outf;
+
+	/* these will be index's into the color palette containing
+	 * the corresponding colors */
+	int black, white, blue;
+
+
+	/* Create an image 200 pixels wide by 250 pixels high */
+	im = cdImageCreate(200, 250);
+
+	/* allocate some colors (isn't this fun?) */
+	/* the first color allocated is the background color */
+	white = cdImageColorAllocate (im, 255,255,255);
+	black = cdImageColorAllocate(im, 0, 0, 0);
+	blue = cdImageColorAllocate(im, 0, 0, 255);
+
+	/* set the text attributes */
+	/* font, colorindex, and size respectivily */
+
+	/* font is the style the text is written in. 1 is for Times,
+	 * 5 is for Helvetica. */
+	/* we will have black text for this one */
+	/* Size is a tough one,  but larger numbers give larger text.
+	 * 25 is a not too large size */
+	if (!(cdSetTextAttrib(im, 5, black, 25))) return 0;
+
+
+	/* Now that we have set some attributes, lets do some drawing */
+
+	/* lets put some text in the picture. */
+	/* (20,100) is the point at the lower left corner of the text */
+	if (!(cdText(im, 20, 100, "Hello World"))) return 0;
+
+
+	/* Here's something special, put a second picture in the file */
+	/* we put in a second picture, and reset all defaults.  This means
+	 * we have to re-allocate the colors as well */
+	if (!(cdCgmNewPic(im, 0))) return 0;
+
+	/* allocate some colors (Again!) */
+	/* the first color allocated is the background color */
+	white = cdImageColorAllocate (im, 255,255,255);
+	black = cdImageColorAllocate(im, 0, 0, 0);
+	blue = cdImageColorAllocate(im, 0, 0, 255);
+	/* set text attributes */
+	if (!(cdSetTextAttrib(im, 5, black, 25))) return 0;
+	if (!(cdText(im, 20, 100, "Goodbye World"))) return 0;
+
+
+	/* now write the file out. */
+	outf = fopen("cdmulti.cgm", "wb");
+	if (!outf) return 0;
+	cdImageCgm(im, outf);
+	fclose(outf);
+	outf = 0;
+
+	/* Remember to destroy the image when you are done */
+	cdImageDestroy(im);
+	im = 0;
+
+	printf("I just created a multi picture CGM!!!\n");
+
+	return 1;
+
+}
diff --git a/src/cd/cdsimple.c b/src/cd/cdsimple.c
new file mode 100644
index 0000000..b3ddb40
--- /dev/null
+++ b/src/cd/cdsimple.c
@@ -0,0 +1,109 @@
+/* 
+ * cdsimple is a very simple program that uses the cd library.
+ * it will walk you through the basics.
+ *
+
+ cdsimple.c: test program for the cgmdraw module.
+
+        Written by G. Edward Johnson <mailto:lorax@nist.gov>
+        Date: April 1996
+        Copyright: cd software produced by NIST, an agency of the 
+	U.S. government, is by statute not subject to copyright
+	in the United States. Recipients of this software assume all 
+	responsibilities associated with its operation, modification
+	and maintenance.
+
+*/
+
+
+#include <malloc.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include "defines.h"
+#include "cd.h"
+
+
+int main () {
+
+	/* you must create a pointer to the image(s) that you will be using
+	 * not suprisingly, it is of type cdImagePtr */
+	cdImagePtr im;
+
+	/* this is a pointer to the output file you will be using */
+	FILE *outf;
+
+	/* these will be index's into the color palette containing
+	 * the corresponding colors */
+	int black, white, blue;
+
+
+	/* Create an image 400 pixels wide by 500 pixels high */
+	im = cdImageCreate(400, 500);
+
+	/* allocate some colors (isn't this fun?) */
+	/* the first color allocated is the background color */
+	white = cdImageColorAllocate (im, 255,255,255);
+	black = cdImageColorAllocate(im, 0, 0, 0);
+	blue = cdImageColorAllocate(im, 0, 0, 255);
+
+	/* Set the fill attributes */
+	/* fill, colorindex, and hatch respectivily */
+	/* see the cd documentation for a complete description */
+
+	/* fill is the color that will be on the inside of filled objects
+	 * such as rectangles and polygons.  
+	 * It can be 1 for solid color, 2 for hatch pattern, 4 for empty */
+	/* let's use blue for the fill color */
+	/* we are going to set it to solid, so the hatch pattern doesn't
+	 * matter.  we will signify no change by putting in -1 */
+	if (!(cdSetShapeFillAttrib(im, 1, blue, -1))) return 0;
+
+	/* notice that we also checked to make sure the command actually
+	 * worked. */
+
+	/* we don't want the edges of our shapes to be a different color
+	 * so make them invisible.  0 means invisible, 1 means visible. */
+	if (!(cdSetEdgeVis(im, 0))) return 0;
+
+
+	/* set the text attributes */
+	/* font, colorindex, and size respectivily */
+
+	/* font is the style the text is written in. 1 is for Times,
+	 * 5 is for Helvetica. */
+	/* we will have black text for this one */
+	/* Size is a tough one,  but larger numbers give larger text.
+	 * 25 is a not too large size */
+	if (!(cdSetTextAttrib(im, 5, black, 25))) return 0;
+
+
+
+	/* Now that we have set some attributes, lets do some drawing */
+
+	/* Draw a rectangle (10,450) is upper left, (350,350) is lower right */
+	if (!(cdRectangle(im, 10, 450, 350, 350))) return 0;
+
+	/* lets put some text in the picture too. */
+	/* (100,100) is the point at the lower left corner of the text */
+	if (!(cdText(im, 100, 100, "Hello World"))) return 0;
+
+
+
+	/* now write the file out, lets call it cdsimple.cgm */
+	outf = fopen("cdsimple.cgm", "wb");
+	if (!outf) return 0;
+	cdImageCgm(im, outf);
+	fclose(outf);
+	outf = 0;
+
+	/* Remember to destroy the image when you are done */
+	cdImageDestroy(im);
+	im = 0;
+
+	printf("I just created a simple CGM!!!\n");
+
+	return 1;
+
+}
diff --git a/src/cd/cdtest.c b/src/cd/cdtest.c
new file mode 100644
index 0000000..e1e697e
--- /dev/null
+++ b/src/cd/cdtest.c
@@ -0,0 +1,425 @@
+
+#include <malloc.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include "defines.h"
+#include "cd.h"
+
+/* cdtest.c: test program for the cgmdraw module.
+
+        Written by G. Edward Johnson <mailto:lorax@nist.gov>
+        Date: April 1996
+        Copyright: cd software produced by NIST, an agency of the 
+	U.S. government, is by statute not subject to copyright
+	in the United States. Recipients of this software assume all 
+	responsibilities associated with its operation, modification
+	and maintenance.
+ 
+*/
+
+
+int main () {
+cdImagePtr myimage;
+
+	/* Color indexes */
+        int white;
+        int blue;
+        int red;
+        int green;
+	int black;
+	int lavender;
+	/* points for polygons and polylines */
+	cdPoint points[15];
+	/* output file */
+	FILE *outf;
+
+
+/* create an image, 1000 by 1000 pixels */
+myimage = cdImageCreate(1000, 1000);
+
+/* Allocate the background color */
+white = cdImageColorAllocate (myimage, 255,255,255);
+        red = cdImageColorAllocate(myimage, 255, 0, 0);
+        green = cdImageColorAllocate(myimage, 0, 255, 0);
+        blue = cdImageColorAllocate(myimage, 0, 0, 255);
+	black = cdImageColorAllocate(myimage, 0, 0, 0);
+
+if (cdSetLineColor(myimage, blue)) {
+  fprintf(stderr, "cdSetLineColor Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetLineColor Unsuccessfull\n");
+}
+
+if (cdSetLineColor(myimage, blue)) {
+  fprintf(stderr, "cdSetLineColor Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetLineColor Unsuccessfull\n");
+}
+
+
+if (cdImageLine(myimage, 400, 8, 520, 8, green)) {
+  fprintf(stderr, "cdImageLine Successfull\n");
+}
+else {
+  fprintf(stderr, "cdImageLine Unsuccessfull\n");
+}
+
+if (cdImageLine(myimage, 50, 50, 500, 500, red)) {
+  fprintf(stderr, "cdImageLine Successfull\n");
+}
+else {
+  fprintf(stderr, "cdImageLine Unsuccessfull\n");
+}
+
+if (cdSetLineAttrib(myimage, 2, 3, red)) {
+  fprintf(stderr, "cdSetLineAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetLineAttrib Unsuccessfull\n");
+}
+
+if (cdLine(myimage, 500, 50, 50, 500)) {
+  fprintf(stderr, "cdLine Successfull\n");
+}
+else {
+  fprintf(stderr, "cdLine Unsuccessfull\n");
+}
+
+/* Now, build a rectangle */
+if (cdSetShapeFillAttrib(myimage, 3, blue, 6 )) {  
+  fprintf(stderr, "cdSetShapeFillAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetShapeFillAttrib Unsuccessfull\n");
+}
+
+if (cdSetShapeEdgeAttrib(myimage, 1, 2, green, 1 )) {  
+  fprintf(stderr, "cdSetShapeEdgeAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetShapeEdgeAttrib Unsuccessfull\n");
+}
+
+if (cdRectangle(myimage, 100, 100, 250, 250 )) {  
+  fprintf(stderr, "cdRectangle Successfull\n");
+}
+else {
+  fprintf(stderr, "cdRectangle Unsuccessfull\n");
+}
+
+
+
+/* now check out each of the line styles in order */
+
+if (cdSetLineAttrib(myimage, 5, 4, green)) {
+  fprintf(stderr, "cdSetLineAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetLineAttrib Unsuccessfull\n");
+}
+
+if (cdLine(myimage, 100, 600, 500, 600)) {
+  fprintf(stderr, "cdLine Successfull\n");
+}
+else {
+  fprintf(stderr, "cdLine Unsuccessfull\n");
+}
+
+if (cdSetLineAttrib(myimage, 4, -1, -1)) {
+  fprintf(stderr, "cdSetLineAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetLineAttrib Unsuccessfull\n");
+}
+if (cdLine(myimage, 100, 625, 500, 625)) {
+  fprintf(stderr, "cdLine Successfull\n");
+}
+else {
+  fprintf(stderr, "cdLine Unsuccessfull\n");
+}
+
+if (cdSetLineAttrib(myimage, 3, -1, -1)) {
+  fprintf(stderr, "cdSetLineAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetLineAttrib Unsuccessfull\n");
+}
+if (cdLine(myimage, 100, 650, 500, 650)) {
+  fprintf(stderr, "cdLine Successfull\n");
+}
+else {
+  fprintf(stderr, "cdLine Unsuccessfull\n");
+}
+
+
+if (cdSetLineAttrib(myimage, 2, -1, -1)) {
+  fprintf(stderr, "cdSetLineAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetLineAttrib Unsuccessfull\n");
+}
+if (cdLine(myimage, 100, 675, 500, 675)) {
+  fprintf(stderr, "cdLine Successfull\n");
+}
+else {
+  fprintf(stderr, "cdLine Unsuccessfull\n");
+}
+
+if (cdSetLineAttrib(myimage, 1, -1, -1)) {
+  fprintf(stderr, "cdSetLineAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetLineAttrib Unsuccessfull\n");
+}
+if (cdLine(myimage, 100, 700, 500, 700)) {
+  fprintf(stderr, "cdLine Successfull\n");
+}
+else {
+  fprintf(stderr, "cdLine Unsuccessfull\n");
+}
+
+/* now make a circle */
+if (cdSetShapeFillAttrib(myimage, 1, -1, 6 )) {
+  fprintf(stderr, "cdSetShapeFillAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetShapeFillAttrib Unsuccessfull\n");
+}
+
+if (cdSetShapeEdgeAttrib(myimage, 1, 2, green, 0 )) {
+  fprintf(stderr, "cdSetShapeEdgeAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetShapeEdgeAttrib Unsuccessfull\n");
+}
+
+if (cdCircle(myimage, 500, 500, 25)) {
+  fprintf(stderr, "cdCircle Successfull\n");
+}
+else {
+  fprintf(stderr, "cdCircle Unsuccessfull\n");
+}
+
+/* how about a Circular Arc now */
+if (cdArc3Pt(myimage, 550, 500, 600, 600, 650, 550 )) {
+  fprintf(stderr, "cdArc3Pt Successfull\n");
+}
+else {
+  fprintf(stderr, "cdArc3Pt Unsuccessfull\n");
+}
+
+/* now draw a closed Circular Arc */
+if (cdArc3PtClose(myimage, 550, 200, 600, 300, 650, 250, 0 )) {
+  fprintf(stderr, "cdArc3PtClose Successfull\n");
+}
+else {
+  fprintf(stderr, "cdArc3PtClose Unsuccessfull\n");
+}
+
+/* and now for an ellipse */
+if (cdSetShapeEdgeAttrib(myimage, 1, 2, green, 1 )) {
+  fprintf(stderr, "cdSetShapeEdgeAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetShapeEdgeAttrib Unsuccessfull\n");
+}
+
+if (cdEllipse(myimage, 750, 200, 800, 250, 750, 300 )) {
+  fprintf(stderr, "cdEllipse Successfull\n");
+}
+else {
+  fprintf(stderr, "cdEllipse Unsuccessfull\n");
+}
+
+
+/* Now, the harder ones.  First lets try the polygon stuff */
+/* a polygon with 7 or less points */
+
+points[0].x = 700;
+points[0].y = 700;
+points[1].x = 725;
+points[1].y = 750;
+points[2].x = 775;
+points[2].y = 650;
+
+if (cdPolygon(myimage, points, 3)) {
+  fprintf(stderr, "cdPolygon Successfull\n");
+}
+else {
+  fprintf(stderr, "cdPolygon Unsuccessfull\n");
+}
+
+/* Here's a tough one, a polygon with more than seven points */
+
+points[0].x = 100;
+points[0].y = 100;
+
+points[1].x = 100;
+points[1].y = 400;
+
+points[2].x = 400;
+points[2].y = 400;
+
+points[3].x = 400;
+points[3].y = 100;
+
+points[4].x = 100;
+points[4].y = 100;
+
+points[5].x = 200;
+points[5].y = 200;
+
+points[6].x = 200;
+points[6].y = 300;
+
+points[7].x = 300;
+points[7].y = 300;
+
+points[8].x = 300;
+points[8].y = 200;
+
+points[9].x = 200;
+points[9].y = 200;
+
+points[10].x = 100;
+points[10].y = 100;
+
+if (cdPolygon(myimage, points, 11)) {
+  fprintf(stderr, "cdPolygon Successfull\n");
+}
+else {
+  fprintf(stderr, "cdPolygon Unsuccessfull\n");
+}
+
+
+/* now for poly lines, just like polygons (except they're lines) */
+
+if (cdSetLineAttrib(myimage, 1, 1, red)) {
+  fprintf(stderr, "cdSetLineAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetLineAttrib Unsuccessfull\n");
+}
+
+
+points[0].x = 400;
+points[0].y = 16;
+points[1].x = 520;
+points[1].y = 16;
+if (cdPolyLine(myimage, points, 2)) {
+  fprintf(stderr, "cdPolyLine Successfull\n");
+}
+else {
+  fprintf(stderr, "cdPolyLine Unsuccessfull\n");
+}
+
+points[0].x = 800;
+points[0].y = 650;
+points[1].x = 825;
+points[1].y = 675;
+points[2].x = 850;
+points[2].y = 650;
+points[3].x = 875;
+points[3].y = 700;
+if (cdPolyLine(myimage, points, 4)) {
+  fprintf(stderr, "cdPolyLine Successfull\n");
+}
+else {
+  fprintf(stderr, "cdPolyLine Unsuccessfull\n");
+}
+
+
+/* Hey, things are going so well, lets do some text */
+lavender = cdImageColorAllocate(myimage, 204, 102, 255);
+
+if (cdSetTextAttrib(myimage, 1, lavender, 50)) {
+  fprintf(stderr, "cdSetTextAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetTextAttrib Unsuccessfull\n");
+}
+
+if (cdText(myimage, 50, 800, "CGM Draw Version 1.2")) {
+  fprintf(stderr, "cdText Successfull\n");
+}
+else {
+  fprintf(stderr, "cdText Unsuccessfull\n");
+}
+
+/* More text.  This time test TextPath and TextOrient */
+if (cdSetTextPath(myimage, 3)) {
+  fprintf(stderr, "cdSetTextPath Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetTextPath Unsuccessfull\n");
+}
+
+if (cdText(myimage, 50, 800, "CGM Draw")) {
+  fprintf(stderr, "cdText Successfull\n");
+}
+else {
+  fprintf(stderr, "cdText Unsuccessfull\n");
+}
+
+if (cdSetTextOrient(myimage, 1, 0, 0, -1)) {
+  fprintf(stderr, "cdSetTextOrient Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetTextOrient Unsuccessfull\n");
+}
+
+if (cdSetTextPath(myimage, 0)) {
+  fprintf(stderr, "cdSetTextPath Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetTextPath Unsuccessfull\n");
+}
+
+if (cdText(myimage, 950, 400, "CGM Draw")) {
+  fprintf(stderr, "cdText Successfull\n");
+}
+else {
+  fprintf(stderr, "cdText Unsuccessfull\n");
+}
+
+
+if (cdSetTextOrient(myimage, 0, 1, 1, 0)) {
+  fprintf(stderr, "cdSetTextOrient Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetTextOrient Unsuccessfull\n");
+}
+
+
+if (cdSetTextAttrib(myimage, 5, -1, 25)) {
+  fprintf(stderr, "cdSetTextAttrib Successfull\n");
+}
+else {
+  fprintf(stderr, "cdSetTextAttrib Unsuccessfull\n");
+}
+
+if (cdText(myimage, 5, 5, "G. Edward Johnson")) {
+  fprintf(stderr, "cdText Successfull\n");
+}
+else {
+  fprintf(stderr, "cdText Unsuccessfull\n");
+}
+
+
+
+
+outf = fopen("cdout.cgm", "wb");
+if (!outf) return 0;
+cdImageCgm(myimage, outf);
+fclose(outf);
+outf = 0;
+
+cdImageDestroy(myimage);
+
+
+return 1;  
+}
diff --git a/src/cd/cdtext.c b/src/cd/cdtext.c
new file mode 100644
index 0000000..c540a69
--- /dev/null
+++ b/src/cd/cdtext.c
@@ -0,0 +1,135 @@
+/* 
+ * cdtext is an example program that uses the text attribute commands
+ * cdSetTextPath and cdSetTextOrient
+ *
+
+ cdtext.c: test program for the cgmdraw module.
+
+        Written by G. Edward Johnson <mailto:lorax@nist.gov>
+        Date: May 1996
+        Copyright: cd software produced by NIST, an agency of the 
+	U.S. government, is by statute not subject to copyright
+	in the United States. Recipients of this software assume all 
+	responsibilities associated with its operation, modification
+	and maintenance.
+
+*/
+
+
+#include <malloc.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include "defines.h"
+#include "cd.h"
+
+
+int main () {
+
+	/* you must create a pointer to the image(s) that you will be using
+	 * not suprisingly, it is of type cdImagePtr */
+	cdImagePtr im;
+
+	/* this is a pointer to the output file you will be using */
+	FILE *outf;
+
+	/* these will be index's into the color palette containing
+	 * the corresponding colors */
+	int black, white, blue;
+
+
+	/* Create an image 800 pixels wide by 400 pixels high */
+	im = cdImageCreate(800, 400);
+
+	/* allocate some colors (isn't this fun?) */
+	/* the first color allocated is the background color */
+	white = cdImageColorAllocate (im, 255,255,255);
+	black = cdImageColorAllocate(im, 0, 0, 0);
+	blue = cdImageColorAllocate(im, 0, 0, 255);
+
+
+	/* set the text attributes */
+	/* font, colorindex, and size respectivily */
+
+	/* font is the style the text is written in. 1 is for Times,
+	 * 5 is for Helvetica. */
+	/* we will have black text for this one */
+	/* Size is a tough one,  but larger numbers give larger text.
+	 */
+	if (!(cdSetTextAttrib(im, 5, black, 20))) return 0;
+
+	/* Set some line attributes,  lets make lines solid, width 1, and blue
+	 */
+	if (!(cdSetLineAttrib(im, 1, 1, blue))) return 0;
+
+	/* Draw a couple of grid lines */
+	if (!(cdLine(im, 0,200,799,200))) return 0;
+	if (!(cdLine(im, 200,0,200,399))) return 0;
+	if (!(cdLine(im, 600,0,600,399))) return 0;
+
+
+	/* Show Text going left, up, down, and right, all starting
+	 * from the same point */
+
+	/* Text going to the left */
+	if (!(cdSetTextPath(im, 1))) return 0;
+	if (!(cdText(im, 200, 200, "Text Left"))) return 0;
+	
+	/* Text going UP */
+	if (!(cdSetTextPath(im, 2))) return 0;
+	if (!(cdText(im, 200, 200, "Text Up"))) return 0;
+	
+	/* Text going DOWN */
+	if (!(cdSetTextPath(im, 3))) return 0;
+	if (!(cdText(im, 200, 200, "Text Down"))) return 0;
+
+	/* Text going to the RIGHT */
+	if (!(cdSetTextPath(im, 0))) return 0;
+	if (!(cdText(im, 200, 200, "Text Right"))) return 0;
+
+	/* Show text going at an angle of 0, 45, 90, 135, 180 Degrees
+	 */
+
+	/* Text at no angle */
+	if (!(cdText(im, 600, 200, "CGM Draw"))) return 0;
+
+	/* Text, 45 Degree Angle */
+	if (!(cdSetTextOrient(im, -1, 1, 1, 1))) return 0;
+	if (!(cdText(im, 600, 200, "CGM Draw"))) return 0;
+
+	/* Text, 90 Degree Angle */
+	if (!(cdSetTextOrient(im, -1, 0, 0, 1))) return 0;
+	if (!(cdText(im, 600, 200, "CGM Draw"))) return 0;
+
+	/* Text, 135 Degree Angle */
+	if (!(cdSetTextOrient(im, -1, -1, -1, 1))) return 0;
+	if (!(cdText(im, 600, 200, "CGM Draw"))) return 0;
+
+	/* Text, 180 Degree Angle */
+	if (!(cdSetTextOrient(im, 0, -1, -1, 0))) return 0;
+	if (!(cdText(im, 600, 200, "CGM Draw"))) return 0;
+
+	/* reset the text to 0 angle */
+	if (!(cdSetTextOrient(im, 0, 1, 1, 0))) return 0;
+
+	
+	if (!(cdSetTextAttrib(im, 5, -1, -1))) return 0;
+	if (!(cdText(im, 5, 5, "G. Edward Johnson"))) return 0;
+
+	/* now write the file out, lets call it cdtext.cgm */
+	outf = fopen("cdtext.cgm", "wb");
+	if (!outf) return 0;
+	cdImageCgm(im, outf);
+	fclose(outf);
+	outf = 0;
+
+	/* Remember to destroy the image when you are done */
+	cdImageDestroy(im);
+	im = 0;
+
+	printf("CGM Text Example!!!\n");
+
+	return 1;
+
+}
diff --git a/src/cd/color16.c b/src/cd/color16.c
new file mode 100644
index 0000000..ca7e454
--- /dev/null
+++ b/src/cd/color16.c
@@ -0,0 +1,186 @@
+/* 
+ * Color16 is a test program that is part of the CGM Draw Library.
+ * It Will write out a CGM file that allocates a 16 color pallete
+ * using the function cdImageColor16.  These correspond to the 16
+ * standard Windows colors.
+ *
+
+ color16.c: test program for the cgmdraw module.
+
+        Written by G. Edward Johnson <mailto:lorax@nist.gov>
+        Date: April 1996
+        Copyright: cd software produced by NIST, an agency of the 
+	U.S. government, is by statute not subject to copyright
+	in the United States. Recipients of this software assume all 
+	responsibilities associated with its operation, modification
+	and maintenance.
+
+*/
+
+
+#include <malloc.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include "defines.h"
+#include "cd.h"
+
+
+int main () {
+	cdImagePtr im;
+	FILE *outf;
+
+
+	/* Create an image 500 pixels high by 400 pixels wide */
+	im = cdImageCreate(400, 500);
+
+	/* allocate the 16 windows colors */
+	if (!(cdImageColor16(im))) return 0;
+
+	/* Set the fill attributes */
+	/* fill=solid, colorindex=0, hatch=no change */
+	if (!(cdSetShapeFillAttrib(im, 1, 0, -1))) return 0;
+
+	/* set the text attributes */
+	/* font=helvetica, colorindex=1, size=25 */
+	if (!(cdSetTextAttrib(im, 5, 1, 25))) return 0;
+
+	/* The first color index is white, so lets draw a box around it */
+	/* edge=solid, width=1, color=1 (black), visible=yes */
+	cdSetShapeEdgeAttrib(im, 1, 1, 1, 1);
+
+
+	/* Draw a rectangle (10,450) is upper left, (35,425) is lower right */
+	if (!(cdRectangle(im, 10, 450, 35, 425))) return 0;
+	/* Label it */
+	if (!(cdText(im, 40, 425, "Color Index: 0"))) return 0;
+
+	/* Make the edges invisible */
+	if (!(cdSetEdgeVis(im, 0))) return 0;
+
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 1))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 10, 400, 35, 375))) return 0;
+	/* Label it */
+	if (!(cdText(im, 40, 375, "Color Index: 1"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 2))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 10, 350, 35, 325))) return 0;
+	/* Label it */
+	if (!(cdText(im, 40, 325, "Color Index: 2"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 3))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 10, 300, 35, 275))) return 0;
+	/* Label it */
+	if (!(cdText(im, 40, 275, "Color Index: 3"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 4))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 10, 250, 35, 225))) return 0;
+	/* Label it */
+	if (!(cdText(im, 40, 225, "Color Index: 4"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 5))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 10, 200, 35, 175))) return 0;
+	/* Label it */
+	if (!(cdText(im, 40, 175, "Color Index: 5"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 6))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 10, 150, 35, 125))) return 0;
+	/* Label it */
+	if (!(cdText(im, 40, 125, "Color Index: 6"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 7))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 10, 100, 35, 75))) return 0;
+	/* Label it */
+	if (!(cdText(im, 40, 75, "Color Index: 7"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 8))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 210, 450, 235, 425))) return 0;
+	/* Label it */
+	if (!(cdText(im, 240, 425, "Color Index: 8"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 9))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 210, 400, 235, 375))) return 0;
+	/* Label it */
+	if (!(cdText(im, 240, 375, "Color Index: 9"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 10))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 210, 350, 235, 325))) return 0;
+	/* Label it */
+	if (!(cdText(im, 240, 325, "Color Index: 10"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 11))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 210, 300, 235, 275))) return 0;
+	/* Label it */
+	if (!(cdText(im, 240, 275, "Color Index: 11"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 12))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 210, 250, 235, 225))) return 0;
+	/* Label it */
+	if (!(cdText(im, 240, 225, "Color Index: 12"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 13))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 210, 200, 235, 175))) return 0;
+	/* Label it */
+	if (!(cdText(im, 240, 175, "Color Index: 13"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 14))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 210, 150, 235, 125))) return 0;
+	/* Label it */
+	if (!(cdText(im, 240, 125, "Color Index: 14"))) return 0;
+
+	/* Set the fill color */
+	if (!(cdSetFillColor(im, 15))) return 0;
+	/* Draw a rectangle */
+	if (!(cdRectangle(im, 210, 100, 235, 75))) return 0;
+	/* Label it */
+	if (!(cdText(im, 240, 75, "Color Index: 15"))) return 0;
+
+	/* now put a little thing at the bottom of the picture */
+	if (!cdText(im, 5, 10, "Colors allocated by cdImageColor16")) return 0;
+
+	/* now write the file out, lets call it color16.cgm */
+	outf = fopen("color16.cgm", "wb");
+	if (!outf) return 0;
+	cdImageCgm(im, outf);
+	fclose(outf);
+	outf = 0;
+
+	/* Remember to destroy the image when you are done */
+	cdImageDestroy(im);
+	im = 0;
+
+	printf("CGM with 16 color colortable generated as color16.cgm\n");
+
+	return 1;
+
+}
diff --git a/src/cd/defines.h b/src/cd/defines.h
new file mode 100644
index 0000000..7ee5494
--- /dev/null
+++ b/src/cd/defines.h
@@ -0,0 +1,55 @@
+
+/* defines.h: declarations file for the cgmdraw module.
+
+        Written by G. Edward Johnson <mailto:lorax@nist.gov>
+        Date: April 1996
+        Copyright: cd software produced by NIST, an agency of the 
+	U.S. government, is by statute not subject to copyright
+	in the United States. Recipients of this software assume all 
+	responsibilities associated with its operation, modification
+	and maintenance.
+ 
+*/
+
+#ifndef CDDEF_H
+#define CDDEF_H 1
+
+#define b0 01
+#define b1 02
+#define b2 04
+#define b3 010
+#define b4 020
+#define b5 040
+#define b6 0100
+#define b7 0200
+#define b8 0400
+#define b9 01000
+#define b10 02000
+#define b11 04000
+#define b12 010000
+#define b13 020000
+#define b14 040000
+#define b15 0100000
+
+/* Defines the default values for different attributes.  In general,
+ * these track the CGM specificaition, so changing them is not a good idea.
+ * however, it is generally ok to set them to -1 (undefined) if you want.
+ */
+
+#define CDLTYPE 1
+#define CDLWIDTH 0
+#define CDLCOLOR 1
+#define CDSHAPESTYLE -1
+#define CDSHAPECOLOR 1
+#define CDSHAPEHATCH 1
+#define CDEDGETYPE 1
+#define CDEDGECOLOR -1
+#define CDEDGEWIDTH -1
+#define CDEDGEVIS -1
+#define CDTEXTCOLOR 1
+#define CDTEXTHEIGHT -1
+#define CDTEXTFONT 1
+#define CDTEXTPATH 0
+
+
+#endif
diff --git a/src/cd/makefile.bor b/src/cd/makefile.bor
new file mode 100644
index 0000000..bcb95f0
--- /dev/null
+++ b/src/cd/makefile.bor
@@ -0,0 +1,51 @@
+# Makefile for CGM Draw by G. Edward Johnson
+# You may need to modify this makefile
+# contributed by Wolfgang Glunz <wogl@weisshorn.zfe.siemens.de>
+
+CC=tcc
+#AR=ar
+#CFLAGS= -pedantic -O2
+CFLAGS=
+#LIBS=-L./ -lcd
+LIBS=cd.obj
+
+all: cd.obj cdtest.exe color16.exe cdsimple.exe cdtext.exe cdmulti.exe
+	cdtest;
+	color16;
+	cdsimple;
+	cdtext;
+	cdmulti;
+
+libcd.a: cd.h defines.h cd.obj
+        rm -f libcd.a
+        $(AR) rc libcd.a cd.obj
+
+cd.obj: cd.c cd.h defines.h
+        $(CC) $(CFLAGS) -c cd.c
+
+testmain.obj: testmain.c cd.h defines.h
+        $(CC) $(CFLAGS) -c testmain.c
+
+color16.obj: color16.c cd.h defines.h
+        $(CC) $(CFLAGS) -c color16.c
+
+cdsimple.obj: cdsimple.c cd.h defines.h
+	$(CC) $(CFLAGS) -c cdsimple.c
+
+cdsimple.exe: cdsimple.obj cd.obj
+	$(CC) cdsimple.obj $(LIBS)
+
+color16.exe: color16.obj cd.obj
+        $(CC) color16.obj $(LIBS)
+
+cdtest.exe: cdtest.obj cd.obj
+        $(CC) cdtest.obj $(LIBS)
+
+cdtext.exe: cdtext.obj cd.obj
+	$(CC) cdtext.obj $(LIBS)
+
+cdmulti.exe: cdmulti.obj cd.obj
+	$(CC) cdmulti.obj $(LIBS)
+clean:
+        del *.obj *.a cdtest.exe color16.exe cdsimple.exe cdtext.exe cdmulti.exe
+
diff --git a/src/cd/readme b/src/cd/readme
new file mode 100644
index 0000000..c1944f3
--- /dev/null
+++ b/src/cd/readme
@@ -0,0 +1,52 @@
+
+
+Welcome, and thanks for downloading CGM Draw, a package for creating
+CGM files from a "C" program.  If you are reading this then you probably
+have already unpacked the distribution.  You can make it by typing 
+"make all"  this will make libcd.a  the cd library, as well as two
+example programs, cdtest and color16.  Please read over the documentation
+in cd.html before using the package.
+
+Every effort has been made to ensure that the generated cgm files
+conform to the standard, however, if you do not use the library
+properly, you could generate invalid metafiles that no one is able
+to read, so be careful.
+
+Documentation for cd is included with the package, and is available from
+http://speckle.ncsl.nist.gov/~lorax/cgm/cd.html  
+General information about CGM is available many places on the web, including 
+http://speckle.ncsl.nist.gov/~lsr/cgm.htm
+This distribution may be retrieved via ftp from
+zing.ncsl.nist.gov in the directory "cgm"  it will have the
+name cd followed by the version number.
+
+I have tested CGM Draw on Solaris, Ultrix, Linux, and IRIX.  It 
+should compile and run on just about any Unix system, and probably 
+other systems as well.
+
+Copyright:
+
+CGM Draw software produced by NIST, an agency of the U.S. government, 
+is by statute not subject to copyright in the United States. 
+Recipients of this software assume all responsibilities associated with 
+its operation, modification and maintenance.  Please note however,
+that some of the code in this package is from gd, which is copyright.
+gd's copyright is as follows:
+gd 1.2 is copyright 1994, 1995, Quest Protein Database Center,
+Cold Spring Harbor Labs. Permission granted to copy and distribute
+this work provided that this notice remains intact. Credit
+for the library must be given to the Quest Protein Database Center,
+Cold Spring Harbor Labs, in all derived works. This does not
+affect your ownership of the derived work itself, and the intent
+is to assure proper credit for Quest, not to interfere with your
+use of gd. If you have questions, ask. ("Derived works"
+includes all programs that utilize the library. Credit must
+be given in user-visible documentation.)
+
+
+If you have any questions or comments, please send me e-mail, lorax@nist.gov
+
+Thanks for trying it out. 
+  Edward Johnson
+
+
-- 
cgit v1.2.3