/contrib/groff/src/preproc/grn/hdb.cpp

https://bitbucket.org/freebsd/freebsd-head/ · C++ · 346 lines · 265 code · 31 blank · 50 comment · 82 complexity · 69ab384bcfeccbc73a59345808b1876c MD5 · raw file

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