aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <>2009-02-08 17:13:33 +0000
committerroot <>2009-02-08 17:13:33 +0000
commit43a13e2e02f2b92d912541ae3477b78f7ebd305c (patch)
treec1585d29ae179a8f65ce949925df82da42f67a8e
parente05584961b0c6aa3dbd33fc9d9d49902ddae8d00 (diff)
downloadlibjwg-43a13e2e02f2b92d912541ae3477b78f7ebd305c.tar.gz
libjwg-43a13e2e02f2b92d912541ae3477b78f7ebd305c.tar.bz2
libjwg-43a13e2e02f2b92d912541ae3477b78f7ebd305c.zip
*** empty log message ***
-rw-r--r--src/cd/Makefile52
-rw-r--r--src/cd/cd.announce54
-rw-r--r--src/cd/cd.c2372
-rw-r--r--src/cd/cd.h209
-rw-r--r--src/cd/cd.html1156
-rw-r--r--src/cd/cd1.2.lsm11
-rw-r--r--src/cd/cdmulti.c98
-rw-r--r--src/cd/cdsimple.c109
-rw-r--r--src/cd/cdtest.c425
-rw-r--r--src/cd/cdtext.c135
-rw-r--r--src/cd/color16.c186
-rw-r--r--src/cd/defines.h55
-rw-r--r--src/cd/makefile.bor51
-rw-r--r--src/cd/readme52
14 files changed, 4965 insertions, 0 deletions
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
+
+