1 /*	hdb.c	1.9	(Berkeley) 86/04/14
2  *
3  * Copyright -C- 1982 Barry S. Roitblat
4  *
5  *      This file contains database routines for the hard copy programs of the
6  * gremlin picture editor.
7  */
8 
9 #include "gprint.h"
10 #include <ctype.h>
11 
12 #define MAXSTRING 128
13 
14 /* imports from main.c */
15 
16 extern int linenum;		/* current line number in input file */
17 extern char gremlinfile[];	/* name of file currently reading */
18 extern int SUNFILE;		/* TRUE if SUN gremlin file */
19 
20 /* imports from c */
21 
22 extern char *malloc();
23 extern char *strcpy();
24 extern char *sprintf();
25 
26 /* imports from point.c */
27 
28 extern POINT *PTInit();
29 extern POINT *PTMakePoint();
30 
31 /*
32  * This routine returns a pointer to an initialized database element
33  * which would be the only element in an empty list.
34  */
35 ELT *
36 DBInit()
37 {
38     return((ELT *) NULL);
39 }  /* end DBInit */
40 
41 
42 /*
43  * This routine creates a new element with the specified attributes and
44  * links it into database.
45  */
46 ELT *
47 DBCreateElt(type, pointlist, brush, size, text, db)
48 int type, brush, size;
49 POINT *pointlist;
50 char *text;
51 ELT *(*db);
52 {
53     register ELT *temp;
54 
55     temp = (ELT *) malloc(sizeof(ELT));
56     temp->nextelt = *db;
57     temp->type = type;
58     temp->ptlist = pointlist;
59     temp->brushf = brush;
60     temp->size = size;
61     temp->textpt = text;
62     *db = temp;
63     return(temp);
64 } /* end CreateElt */
65 
66 
67 /*
68  * This routine reads the specified file into a database and
69  * returns a pointer to that database.
70  */
71 ELT *
72 DBRead(file)
73 register FILE *file;
74 {
75     register int i;
76     register int done;		/* flag for input exhausted */
77     register float nx;		/* x holder so x is not set before orienting */
78     int type;			/* element type */
79     ELT *elist;			/* pointer to the file's elements */
80     POINT *plist;		/* pointer for reading in points */
81     char  string[MAXSTRING], *txt;
82     float x, y;			/* x and y are read in point coords */
83     int len, brush, size;
84     int lastpoint;
85 
86 
87     SUNFILE = FALSE;
88     elist = DBInit();
89     (void) fscanf(file,"%s\n",string);
90     if (strcmp(string, "gremlinfile")) {
91 	if (strcmp(string, "sungremlinfile")) {
92 	    error("%s is not a gremlin file", gremlinfile);
93 	    return(elist);
94 	}
95 	SUNFILE = TRUE;
96     }
97     (void) fscanf(file, "%d%f%f\n", &size, &x, &y);
98 			/* ignore orientation and file positioning point */
99     done = FALSE;
100     while (!done) {
101         if (fscanf(file,"%s\n", string) == EOF) {
102             error("%s, error in file format", gremlinfile);
103             return(elist);
104         }
105 	type = DBGetType(string);		/* interpret element type */
106         if (type < 0) {					/* no more data */
107             done = TRUE;
108             (void) fclose(file);
109         } else {
110             (void) fscanf(file, "%f%f\n", &x, &y);	/* always one point */
111             plist = PTInit();				/* NULL point list */
112 
113 	    /* Files created on the SUN have point lists terminated
114 	     * by a line containing only an asterik ('*').  Files
115 	     * created on the AED have point lists terminated by the
116 	     * coordinate pair (-1.00 -1.00).
117 	     */
118 	    if (TEXT(type)) {	/* read only first point for TEXT elements */
119 		nx = xorn(x, y);
120 		y = yorn(x, y);
121                 (void) PTMakePoint(nx, y, &plist);
122 		savebounds(nx, y);
123 
124 		lastpoint = FALSE;
125                 do {
126 		    fgets(string, MAXSTRING, file);
127 		    if (string[0] == '*') {	/* SUN gremlin file */
128 			lastpoint = TRUE;
129 		    }
130 		    else {
131 			(void) sscanf(string, "%f%f", &x, &y);
132 			if ((x == -1.00 && y == -1.00) && (!SUNFILE)) {
133 			    lastpoint = TRUE;
134 			} else {
135 			    savebounds(xorn(x, y), yorn(x, y));
136 			}
137 		    }
138 		} while (!lastpoint);
139 	    }
140 	    else {		/* not TEXT element */
141 		lastpoint = FALSE;
142 		while (!lastpoint) {
143 		    nx = xorn(x, y);
144 		    y = yorn(x, y);
145 		    (void) PTMakePoint(nx, y, &plist);
146 		    savebounds(nx, y);
147 
148 		    fgets(string, MAXSTRING, file);
149 		    if (string[0] == '*') {	/* SUN gremlin file */
150 			lastpoint = TRUE;
151 		    }
152 		    else {
153 			(void) sscanf(string, "%f%f", &x, &y);
154 			if ((x == -1.00 && y == -1.00) && (!SUNFILE))
155 			    lastpoint = TRUE;
156 		    }
157 		}
158 	    }
159             (void) fscanf(file, "%d%d\n", &brush, &size);
160             (void) fscanf(file, "%d", &len);	/* text length */
161 	    (void) getc(file);			/* eat blank */
162             txt = malloc((unsigned) len + 1);
163             for (i=0; i<len; ++i) {		/* read text */
164                 txt[i] = getc(file);
165 	    }
166             txt[len] = '\0';
167             (void) DBCreateElt(type, plist, brush, size, txt, &elist);
168         }  /* end else */
169     }  /* end while not done */;
170     return(elist);
171 } /* end DBRead */
172 
173 
174 /*
175  * Interpret element type in string s.
176  * Old file format consisted of integer element types.
177  * New file format has literal names for element types.
178  */
179 DBGetType(s)
180 register char *s;
181 {
182     if (isdigit(s[0]) || (s[0] == '-'))		/* old element format or EOF */
183 	return(atoi(s));
184 
185     switch (s[0]) {
186 	case 'P':
187 	    return(POLYGON);
188 	case 'V':
189 	    return(VECTOR);
190 	case 'A':
191 	    return(ARC);
192 	case 'C':
193 	    if (s[1] == 'U')
194 		return(CURVE);
195 	    switch (s[4]) {
196 		case 'L':
197 		    return(CENTLEFT);
198 		case 'C':
199 		    return(CENTCENT);
200 		case 'R':
201 		    return(CENTRIGHT);
202 		default:
203 		    error("unknown element type");
204 		    exit(1);
205 	    }
206 	case 'B':
207 	    switch (s[3]) {
208 		case 'L':
209 		    return(BOTLEFT);
210 		case 'C':
211 		    return(BOTCENT);
212 		case 'R':
213 		    return(BOTRIGHT);
214 		default:
215 		    error("unknown element type");
216 		    exit(1);
217 	    }
218 	case 'T':
219 	    switch (s[3]) {
220 		case 'L':
221 		    return(TOPLEFT);
222 		case 'C':
223 		    return(TOPCENT);
224 		case 'R':
225 		    return(TOPRIGHT);
226 		default:
227 		    error("unknown element type");
228 		    exit(1);
229 	    }
230 	default:
231 	    error("unknown element type");
232 	    exit(1);
233     }
234 }
235