Added win32 port contributed by Blake McBride
[s-roff.git] / src / preproc / grn / hdb.cc
blobbf72ea1f7736098d8f880bb1aac18cacb030ab07
1 /* Last non-groff version: hdb.c 1.8 (Berkeley) 84/10/20
3 * Copyright -C- 1982 Barry S. Roitblat
5 * This file contains database routines for the hard copy programs of the
6 * gremlin picture editor.
7 */
9 #include "gprint.h"
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
14 #include "errarg.h"
15 #include "error.h"
17 #define MAXSTRING 128
19 /* imports from main.cc */
21 extern int linenum; /* current line number in input file */
22 extern char gremlinfile[]; /* name of file currently reading */
23 extern int SUNFILE; /* TRUE if SUN gremlin file */
24 extern void savebounds(float x, float y);
26 /* imports from hpoint.cc */
28 extern POINT *PTInit();
29 extern POINT *PTMakePoint(float x, float y, POINT ** pplist);
32 int DBGetType(register char *s);
36 * This routine returns a pointer to an initialized database element which
37 * would be the only element in an empty list.
39 ELT *
40 DBInit(void)
42 return ((ELT *) NULL);
43 } /* end DBInit */
47 * This routine creates a new element with the specified attributes and
48 * links it into database.
50 ELT *
51 DBCreateElt(int type,
52 POINT * pointlist,
53 int brush,
54 int size,
55 char *text,
56 ELT **db)
58 register ELT *temp;
60 temp = (ELT *) malloc(sizeof(ELT));
61 temp->nextelt = *db;
62 temp->type = type;
63 temp->ptlist = pointlist;
64 temp->brushf = brush;
65 temp->size = size;
66 temp->textpt = text;
67 *db = temp;
68 return (temp);
69 } /* end CreateElt */
73 * This routine reads the specified file into a database and returns a
74 * pointer to that database.
76 ELT *
77 DBRead(register FILE *file)
79 register int i;
80 register int done; /* flag for input exhausted */
81 register float nx; /* x holder so x is not set before orienting */
82 int type; /* element type */
83 ELT *elist; /* pointer to the file's elements */
84 POINT *plist; /* pointer for reading in points */
85 char string[MAXSTRING], *txt;
86 float x, y; /* x and y are read in point coords */
87 int len, brush, size;
88 int lastpoint;
90 SUNFILE = FALSE;
91 elist = DBInit();
92 (void) fscanf(file, "%s\n", string);
93 if (strcmp(string, "gremlinfile")) {
94 if (strcmp(string, "sungremlinfile")) {
95 error("`%1' is not a gremlin file", gremlinfile);
96 return (elist);
98 SUNFILE = TRUE;
101 (void) fscanf(file, "%d%f%f\n", &size, &x, &y);
102 /* ignore orientation and file positioning point */
104 done = FALSE;
105 while (!done) {
106 /* if (fscanf(file,"%s\n", string) == EOF) */
107 /* I changed the scanf format because the element */
108 /* can have two words (e.g. CURVE SPLINE) */
109 if (fscanf(file, "\n%[^\n]\n", string) == EOF) {
110 error("`%1', error in file format", gremlinfile);
111 return (elist);
114 type = DBGetType(string); /* interpret element type */
115 if (type < 0) { /* no more data */
116 done = TRUE;
117 (void) fclose(file);
118 } else {
119 #ifdef UW_FASTSCAN
120 (void) xscanf(file, &x, &y); /* always one point */
121 #else
122 (void) fscanf(file, "%f%f\n", &x, &y); /* always one point */
123 #endif /* UW_FASTSCAN */
124 plist = PTInit(); /* NULL point list */
127 * Files created on the SUN have point lists terminated by a line
128 * containing only an asterik ('*'). Files created on the AED have
129 * point lists terminated by the coordinate pair (-1.00 -1.00).
131 if (TEXT(type)) { /* read only first point for TEXT elements */
132 nx = xorn(x, y);
133 y = yorn(x, y);
134 (void) PTMakePoint(nx, y, &plist);
135 savebounds(nx, y);
137 #ifdef UW_FASTSCAN
138 while (xscanf(file, &x, &y));
139 #else
140 lastpoint = FALSE;
141 do {
142 fgets(string, MAXSTRING, file);
143 if (string[0] == '*') { /* SUN gremlin file */
144 lastpoint = TRUE;
145 } else {
146 (void) sscanf(string, "%f%f", &x, &y);
147 if ((x == -1.00 && y == -1.00) && (!SUNFILE))
148 lastpoint = TRUE;
150 } while (!lastpoint);
151 #endif /* UW_FASTSCAN */
152 } else { /* not TEXT element */
153 #ifdef UW_FASTSCAN
154 do {
155 nx = xorn(x, y);
156 y = yorn(x, y);
157 (void) PTMakePoint(nx, y, &plist);
158 savebounds(nx, y);
159 } while (xscanf(file, &x, &y));
160 #else
161 lastpoint = FALSE;
162 while (!lastpoint) {
163 nx = xorn(x, y);
164 y = yorn(x, y);
165 (void) PTMakePoint(nx, y, &plist);
166 savebounds(nx, y);
168 fgets(string, MAXSTRING, file);
169 if (string[0] == '*') { /* SUN gremlin file */
170 lastpoint = TRUE;
171 } else {
172 (void) sscanf(string, "%f%f", &x, &y);
173 if ((x == -1.00 && y == -1.00) && (!SUNFILE))
174 lastpoint = TRUE;
177 #endif /* UW_FASTSCAN */
179 (void) fscanf(file, "%d%d\n", &brush, &size);
180 (void) fscanf(file, "%d", &len); /* text length */
181 (void) getc(file); /* eat blank */
182 txt = (char *) malloc((unsigned) len + 1);
183 for (i = 0; i < len; ++i) { /* read text */
184 txt[i] = getc(file);
186 txt[len] = '\0';
187 (void) DBCreateElt(type, plist, brush, size, txt, &elist);
188 } /* end else */
189 } /* end while not done */ ;
190 return (elist);
191 } /* end DBRead */
195 * Interpret element type in string s.
196 * Old file format consisted of integer element types.
197 * New file format has literal names for element types.
200 DBGetType(register char *s)
202 if (isdigit(s[0]) || (s[0] == '-')) /* old element format or EOF */
203 return (atoi(s));
205 switch (s[0]) {
206 case 'P':
207 return (POLYGON);
208 case 'V':
209 return (VECTOR);
210 case 'A':
211 return (ARC);
212 case 'C':
213 if (s[1] == 'U')
214 return (CURVE);
215 switch (s[4]) {
216 case 'L':
217 return (CENTLEFT);
218 case 'C':
219 return (CENTCENT);
220 case 'R':
221 return (CENTRIGHT);
222 default:
223 fatal("unknown element type");
225 case 'B':
226 switch (s[3]) {
227 case 'L':
228 return (BOTLEFT);
229 case 'C':
230 return (BOTCENT);
231 case 'R':
232 return (BOTRIGHT);
233 default:
234 fatal("unknown element type");
236 case 'T':
237 switch (s[3]) {
238 case 'L':
239 return (TOPLEFT);
240 case 'C':
241 return (TOPCENT);
242 case 'R':
243 return (TOPRIGHT);
244 default:
245 fatal("unknown element type");
247 default:
248 fatal("unknown element type");
251 return 0; /* never reached */
254 #ifdef UW_FASTSCAN
256 * Optimization hack added by solomon@crys.wisc.edu, 12/2/86.
257 * A huge fraction of the time was spent reading floating point numbers from
258 * the input file, but the numbers always have the format 'ddd.dd'. Thus
259 * the following special-purpose version of fscanf.
261 * xscanf(f,xp,yp) does roughly what fscanf(f,"%f%f",xp,yp) does except:
262 * -the next piece of input must be of the form
263 * <space>* <digit>*'.'<digit>* <space>* <digit>*'.'<digit>*
264 * -xscanf eats the character following the second number
265 * -xscanf returns 0 for "end-of-data" indication, 1 otherwise, where
266 * end-of-data is signalled by a '*' [in which case the rest of the
267 * line is gobbled], or by '-1.00 -1.00' [but only if !SUNFILE].
270 xscanf(FILE *f,
271 float *xp,
272 float *yp)
274 register int c, i, j, m, frac;
275 int iscale = 1, jscale = 1; /* x = i/scale, y=j/jscale */
277 while ((c = getc(f)) == ' ');
278 if (c == '*') {
279 while ((c = getc(f)) != '\n');
280 return 0;
282 i = m = frac = 0;
283 while (isdigit(c) || c == '.' || c == '-') {
284 if (c == '-') {
285 m++;
286 c = getc(f);
287 continue;
289 if (c == '.')
290 frac = 1;
291 else {
292 if (frac)
293 iscale *= 10;
294 i = 10 * i + c - '0';
296 c = getc(f);
298 if (m)
299 i = -i;
300 *xp = (double) i / (double) iscale;
302 while ((c = getc(f)) == ' ');
303 j = m = frac = 0;
304 while (isdigit(c) || c == '.' || c == '-') {
305 if (c == '-') {
306 m++;
307 c = getc(f);
308 continue;
310 if (c == '.')
311 frac = 1;
312 else {
313 if (frac)
314 jscale *= 10;
315 j = 10 * j + c - '0';
317 c = getc(f);
319 if (m)
320 j = -j;
321 *yp = (double) j / (double) jscale;
322 return (SUNFILE || i != -iscale || j != -jscale);
324 #endif /* UW_FASTSCAN */
326 /* EOF */