int has_polygon(register ELT *elist) { while (!DBNullelt(elist)) { if (elist->type == POLYGON) return (1); elist = DBNextElt(elist); } return (0); }
void HGPrintElt(ELT *element, int /* baseline */) { register POINT *p1; register POINT *p2; register int length; register int graylevel; if (!DBNullelt(element) && !Nullpoint((p1 = element->ptlist))) { /* p1 always has first point */ if (TEXT(element->type)) { HGSetFont(element->brushf, element->size); switch (element->size) { case 1: p1->y += adj1; break; case 2: p1->y += adj2; break; case 3: p1->y += adj3; break; case 4: p1->y += adj4; break; default: break; } HGPutText(element->type, *p1, element->textpt); } else { if (element->brushf) /* if there is a brush, the */ HGSetBrush(element->brushf); /* graphics need it set */ switch (element->type) { case ARC: p2 = PTNextPoint(p1); tmove(p2); doarc(*p1, *p2, element->size); cr(); break; case CURVE: length = 0; /* keep track of line length */ drawwig(p1, CURVE); cr(); break; case BSPLINE: length = 0; /* keep track of line length */ drawwig(p1, BSPLINE); cr(); break; case VECTOR: length = 0; /* keep track of line length so */ tmove(p1); /* single lines don't get long */ while (!Nullpoint((p1 = PTNextPoint(p1)))) { HGtline((int) (p1->x * troffscale), (int) (p1->y * troffscale)); if (length++ > LINELENGTH) { length = 0; printf("\\\n"); } } /* end while */ cr(); break; case POLYGON: { /* brushf = style of outline; size = color of fill: * on first pass (polyfill=FILL), do the interior using 'P' * unless size=0 * on second pass (polyfill=OUTLINE), do the outline using a series * of vectors. It might make more sense to use \D'p ...', * but there is no uniform way to specify a 'fill character' * that prints as 'no fill' on all output devices (and * stipple fonts). * If polyfill=BOTH, just use the \D'p ...' command. */ double firstx = p1->x; double firsty = p1->y; length = 0; /* keep track of line length so */ /* single lines don't get long */ if (polyfill == FILL || polyfill == BOTH) { /* do the interior */ char command = (polyfill == BOTH && element->brushf) ? 'p' : 'P'; /* include outline, if there is one and */ /* the -p flag was set */ /* switch based on what gremlin gives */ switch (element->size) { case 1: graylevel = 1; break; case 3: graylevel = 2; break; case 12: graylevel = 3; break; case 14: graylevel = 4; break; case 16: graylevel = 5; break; case 19: graylevel = 6; break; case 21: graylevel = 7; break; case 23: graylevel = 8; break; default: /* who's giving something else? */ graylevel = NSTIPPLES; break; } /* int graylevel = element->size; */ if (graylevel < 0) break; if (graylevel > NSTIPPLES) graylevel = NSTIPPLES; printf("\\D'Fg %.3f'", double(1000 - stipple_index[graylevel]) / 1000.0); cr(); tmove(p1); printf("\\D'%c", command); while (!Nullpoint((PTNextPoint(p1)))) { p1 = PTNextPoint(p1); deltax((double) p1->x); deltay((double) p1->y); if (length++ > LINELENGTH) { length = 0; printf("\\\n"); } } /* end while */ /* close polygon if not done so by user */ if ((firstx != p1->x) || (firsty != p1->y)) { deltax((double) firstx); deltay((double) firsty); } putchar('\''); cr(); break; } /* else polyfill == OUTLINE; only draw the outline */ if (!(element->brushf)) break; length = 0; /* keep track of line length */ tmove(p1); while (!Nullpoint((PTNextPoint(p1)))) { p1 = PTNextPoint(p1); HGtline((int) (p1->x * troffscale), (int) (p1->y * troffscale)); if (length++ > LINELENGTH) { length = 0; printf("\\\n"); } } /* end while */ /* close polygon if not done so by user */ if ((firstx != p1->x) || (firsty != p1->y)) { HGtline((int) (firstx * troffscale), (int) (firsty * troffscale)); } cr(); break; } /* end case POLYGON */ } /* end switch */ } /* end else Text */ } /* end if */ } /* end PrintElt */
void conv(register FILE *fp, int baseline) { register FILE *gfp = NULL; /* input file pointer */ register int done = 0; /* flag to remember if finished */ register ELT *e; /* current element pointer */ ELT *PICTURE; /* whole picture data base pointer */ double temp; /* temporary calculating area */ /* POINT ptr; */ /* coordinates of a point to pass to `mov' */ /* routine */ int flyback; /* flag `want to end up at the top of the */ /* picture?' */ int compat; /* test character after .GE or .GF */ initpic(); /* set defaults, ranges, etc. */ strcpy(GScommand, inputline); /* save `.GS' line for later */ do { done = !doinput(fp); /* test for EOF */ flyback = (*c3 == 'F'); /* and .GE or .GF */ compat = (compatibility_flag || *c4 == '\n' || *c4 == ' ' || *c4 == '\0'); done |= (*c1 == '.' && *c2 == 'G' && (*c3 == 'E' || flyback) && compat); if (done) { if (setdefault) savestate(); if (!gremlinfile[0]) { if (!setdefault) error("at line %1: no picture filename.\n", baseline); return; } char *path; gfp = macro_path.open_file(gremlinfile, &path); if (!gfp) return; PICTURE = DBRead(gfp); /* read picture file */ fclose(gfp); a_delete path; if (DBNullelt(PICTURE)) return; /* If a request is made to make the */ /* picture fit into a specific area, */ /* set the scale to do that. */ if (stipple == (char *) NULL) /* if user forgot stipple */ if (has_polygon(PICTURE)) /* and picture has a polygon */ stipple = (char *)DEFSTIPPLE; /* then set the default */ if ((temp = bottompoint - toppoint) < 0.1) temp = 0.1; temp = (height != 0.0) ? height / (temp * SCREENtoINCH) : BIG; if ((troffscale = rightpoint - leftpoint) < 0.1) troffscale = 0.1; troffscale = (width != 0.0) ? width / (troffscale * SCREENtoINCH) : BIG; if (temp == BIG && troffscale == BIG) troffscale = xscale; else { if (temp < troffscale) troffscale = temp; } /* here, troffscale is the */ /* picture's scaling factor */ if (pointscale) { register int i; /* do pointscaling here, when */ /* scale is known, before output */ for (i = 0; i < SIZES; i++) tsize[i] = (int) (troffscale * (double) tsize[i] + 0.5); } /* change to device units */ troffscale *= SCREENtoINCH * res; /* from screen units */ ytop = (int) (toppoint * troffscale); /* calculate integer */ ybottom = (int) (bottompoint * troffscale); /* versions of the */ xleft = (int) (leftpoint * troffscale); /* picture limits */ xright = (int) (rightpoint * troffscale); /* save stuff in number registers, */ /* register g1 = picture width and */ /* register g2 = picture height, */ /* set vertical spacing, no fill, */ /* and break (to make sure picture */ /* starts on left), and put out the */ /* user's `.GS' line. */ printf(".br\n" ".nr g1 %du\n" ".nr g2 %du\n" "%s" ".nr g3 \\n(.f\n" ".nr g4 \\n(.s\n" "\\0\n" ".sp -1\n", xright - xleft, ybottom - ytop, GScommand); if (stipple) /* stipple requested for this picture */ printf(".st %s\n", stipple); lastx = xleft; /* note where we are (upper left */ lastyline = lasty = ytop; /* corner of the picture) */ /* Just dump everything in the order it appears. * * If -s command-line option, traverse picture twice: First time, * print only the interiors of filled polygons (as borderless * polygons). Second time, print the outline as series of line * segments. This way, postprocessors that overwrite rather than * merge picture elements (such as Postscript) can still have text and * graphics on a shaded background. */ /* if (sflag) */ if (!sflag) { /* changing the default for filled polygons */ e = PICTURE; polyfill = FILL; while (!DBNullelt(e)) { printf(".mk\n"); if (e->type == POLYGON) HGPrintElt(e, baseline); printf(".rt\n"); lastx = xleft; lastyline = lasty = ytop; e = DBNextElt(e); } } e = PICTURE; /* polyfill = !sflag ? BOTH : OUTLINE; */ polyfill = sflag ? BOTH : OUTLINE; /* changing the default */ while (!DBNullelt(e)) { printf(".mk\n"); HGPrintElt(e, baseline); printf(".rt\n"); lastx = xleft; lastyline = lasty = ytop; e = DBNextElt(e); } /* decide where to end picture */ /* I changed everything here. I always use the combination .mk and */ /* .rt so once finished I just space down the heigth of the picture */ /* that is \n(g2u */ if (flyback) { /* end picture at upper left */ /* ptr.x = leftpoint; ptr.y = toppoint; */ } else { /* end picture at lower left */ /* ptr.x = leftpoint; ptr.y = bottompoint; */ printf(".sp \\n(g2u\n"); } /* tmove(&ptr); */ /* restore default line parameters */ /* restore everything to the way it was before the .GS, then put */ /* out the `.GE' line from user */ /* printf("\\D't %du'\\D's %du'\n", DEFTHICK, DEFSTYLE); */ /* groff doesn't understand the \Ds command */ printf("\\D't %du'\n", DEFTHICK); if (flyback) /* make sure we end up at top of */ printf(".sp -1\n"); /* picture if `flying back' */ if (stipple) /* restore stipple to previous */ printf(".st\n"); printf(".br\n" ".ft \\n(g3\n" ".ps \\n(g4\n" "%s", inputline); } else interpret(inputline); /* take commands from the input file */ } while (!done); }