|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 13702 (0x3586) Types: TextFile Names: »genpictex.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦c319c2751⟧ »unix3.0/TeX3.0.tar.Z« └─⟦036c765ac⟧ └─⟦this⟧ »TeX3.0/TeXgraphics/transfig/fig2dev/dev/genpictex.c«
/* * genpictex.C : PiCTeX driver for fig2dev * * Author Micah Beck, Cornell University, 4/88 * (beck@svax.cs.cornell.edu) */ #ifdef hpux #include <sys/types.h> #endif #include <sys/file.h> #include <stdio.h> #include <math.h> #include "pi.h" #include "object.h" #include "fig2dev.h" #include "texfonts.h" extern char *strchr(); extern void fprintf(); extern double sin(), cos(), acos(), fabs(); void genpictex_ctl_spline(), genpictex_itp_spline(); static int coord_system; static double dash_length = -1; static int line_style = SOLID_LINE; static char *linethick = "0.7pt"; static char *plotsymbol = "\\sevrm ."; static void genpictex_option(opt, optarg) char opt, *optarg; { switch (opt) { case 'f': /* set default text font */ { int i; for ( i = 1; i <= MAXFONT + 1; i++ ) if ( !strcmp(optarg, fontnames[i]) ) break; if ( i > MAXFONT + 1 ) fprintf(stderr, "warning: non-standard font name %s\n", optarg); } fontnames[0] = fontnames[1] = optarg; break; case 'l': /* set line thickness */ linethick = optarg; break; case 'p': /* set plot symbol */ plotsymbol = optarg; break; case 's': if (font_size <= 0 || font_size > MAXFONTSIZE) { fprintf(stderr, "warning: font size %d out of bounds\n", font_size); } break; case 'm': case 'L': break; default: put_msg(Err_badarg, opt, "pictex"); exit(1); break; } } #define TOP 10.5 /* top of page is 10.5 inch */ static double ppi; static int CONV = 0; static double convy(a) double a; { return((double)(CONV ? TOP-a : a)); } void genpictex_start(objects) F_compound *objects; { fontsizes[0] = fontsizes[1] = TEXFONTSIZE(font_size); coord_system = objects->nwcorner.y; ppi = objects->nwcorner.x; if (coord_system == 2) CONV = 1; /* PiCTeX start */ fprintf(tfp, "\\mbox{\\beginpicture\n"); fprintf(tfp, "\\setcoordinatesystem units <%6.3fin,%6.3fin>\n", mag, mag); fprintf(tfp, "\\unitlength=%6.3fin\n", mag); fprintf(tfp, "\\linethickness=%s\n", linethick); fprintf(tfp, "\\setplotsymbol ({%s})\n", plotsymbol); fprintf(tfp, "\\setlinear\n"); } void genpictex_end() { /* PiCTeX ending */ fprintf(tfp, "\\linethickness=0pt\n"); fprintf(tfp, "\\putrectangle corners at %6.3f %6.3f and %6.3f %6.3f\n", llx/ppi, convy(lly/ppi), urx/ppi, convy(ury/ppi)); fprintf(tfp, "\\endpicture}\n"); } static set_linewidth(w) int w; { static int cur_thickness = -1; if (w == 0) return; if (w != cur_thickness) { cur_thickness = w; /* fprintf(tfp, "\\linethickness=%6.3fin\n",0.7 * cur_thickness);*/ /* PIC fprintf(tfp, "\"D't %.3fi'\"\n", 0.7 * cur_thickness);*/ } } void genpictex_line(l) F_line *l; { F_point *p, *q; fprintf(tfp, "%%\n%% Fig POLYLINE object\n%%\n"); set_linewidth(l->thickness); set_style(l->style, l->style_val); p = l->points; q = p->next; if (q == NULL) { /* A single point line */ fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f /\n", p->x/ppi, convy(p->y/ppi), p->x/ppi, convy(p->y/ppi)); return; } if (l->back_arrow) draw_arrow_head(q->x/ppi, convy(q->y/ppi), p->x/ppi, convy(p->y/ppi), l->back_arrow->ht/ppi, l->back_arrow->wid/ppi); set_style(l->style, l->style_val); while (q->next != NULL) { putline(p->x, p->y, q->x, q->y); p = q; q = q->next; } putline(p->x, p->y, q->x, q->y); if (l->for_arrow) draw_arrow_head(p->x/ppi, convy(p->y/ppi), q->x/ppi, convy(q->y/ppi), l->for_arrow->ht/ppi, l->for_arrow->wid/ppi); if (l->area_fill && (int)l->area_fill != DEFAULT) fprintf(stderr, "Line area fill not implemented\n"); } /* * set_style - issue style commands as appropriate */ static set_style(style, dash_len) int style; double dash_len; { switch (style) { case SOLID_LINE: if (line_style == SOLID_LINE) break; fprintf(tfp, "\\setsolid\n"); break; case DASH_LINE: if (line_style == DASH_LINE && dash_length == dash_len) break; fprintf(tfp, "\\setdashes <%7.4fin>\n", dash_len/ppi); break; case DOTTED_LINE: if (line_style == DOTTED_LINE) break; fprintf(tfp, "\\setdots \n"); break; } line_style = style; dash_length = dash_len; } /* * putline - use rules if possible */ static putline (start_x, start_y, end_x, end_y) int start_x, start_y, end_x, end_y; { if (line_style == SOLID_LINE && ((start_x == end_x) || (start_y == end_y))) fprintf(tfp, "\\putrule from %6.3f %6.3f to %6.3f %6.3f\n", start_x/ppi, convy(start_y/ppi), end_x/ppi, convy(end_y/ppi)); else { fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f /\n", start_x/ppi, convy(start_y/ppi), end_x/ppi, convy(end_y/ppi)); } } void genpictex_spline(s) F_spline *s; { set_linewidth(s->thickness); set_style(s->style, s->style_val); if (int_spline(s)) genpictex_itp_spline(s); else genpictex_ctl_spline(s); if (s->area_fill && (int)s->area_fill != DEFAULT) fprintf(stderr, "Spline area fill not implemented\n"); } void genpictex_ellipse(e) F_ellipse *e; { fprintf(tfp, "%%\n%% Fig ELLIPSE\n%%\n"); set_linewidth(e->thickness); set_style(e->style, e->style_val); if ((e->area_fill == BLACK_FILL) && (e->radiuses.x == e->radiuses.y)) fprintf(tfp, "\\put{\\circle*{%6.3f}} at %6.3f %6.3f\n", 2*e->radiuses.x/ppi, (e->center.x+e->radiuses.x)/ppi, convy(e->center.y/ppi)); else { fprintf(tfp, "\\ellipticalarc axes ratio %6.3f:%-6.3f 360 degrees \n", e->radiuses.x/ppi, e->radiuses.y/ppi); fprintf(tfp, "\tfrom %6.3f %6.3f center at %6.3f %6.3f\n", (e->center.x+e->radiuses.x)/ppi, convy(e->center.y/ppi), e->center.x/ppi, convy(e->center.y/ppi)); if (e->area_fill && (int)e->area_fill != DEFAULT) fprintf(stderr, "Ellipse area fill not implemented\n"); } } #define HT_OFFSET (0.2 / 72.0) void genpictex_text(t) F_text *t; { double x, y; char *tpos, *cp; fprintf(tfp, "%%\n%% Fig TEXT object\n%%\n"); x = t->base_x/ppi; y = convy(t->base_y/ppi); switch (t->type) { case T_LEFT_JUSTIFIED: case DEFAULT: tpos = "[lB]"; break; case T_CENTER_JUSTIFIED: tpos = "[B]"; break; case T_RIGHT_JUSTIFIED: tpos = "[rB]"; break; default: fprintf(stderr, "Text incorrectly positioned\n"); return; } fprintf(tfp, "\\put {\\%s%s ", TEXFONTSIZE(t->size), TEXFONT(t->font)); if (t->font && t->font !=DEFAULT) /* this loop escapes characters "$&%#_{}" */ /* and deleted characters "~^\" */ for(cp = t->cstring; *cp; cp++) { if (strchr("$&%#_{}", *cp)) (void)fputc('\\', tfp); if (strchr("~^\\", *cp)) fprintf(stderr, "Bad character in text object '%c'\n" ,*cp); else (void)fputc(*cp, tfp); } else fprintf(tfp, "%s", t->cstring); fprintf(tfp, "} %s at %6.3f %6.3f\n", tpos, x, y); } void genpictex_arc(a) F_arc *a; { double x, y; double cx, cy, sx, sy, ex, ey; double dx1, dy1, dx2, dy2, r1, r2, th1, th2, theta; set_linewidth(a->thickness); set_style(a->style, a->style_val); cx = a->center.x/ppi; cy = convy(a->center.y/ppi); sx = a->point[0].x/ppi; sy = convy(a->point[0].y/ppi); ex = a->point[2].x/ppi; ey = convy(a->point[2].y/ppi); if (a->for_arrow) { arc_tangent(cx, cy, ex, ey, a->direction, &x, &y); draw_arrow_head(x, y, ex, ey, a->for_arrow->ht/ppi, a->for_arrow->wid/ppi); } if (a->back_arrow) { arc_tangent(cx, cy, sx, sy, !a->direction, &x, &y); draw_arrow_head(x, y, sx, sy, a->back_arrow->ht/ppi, a->back_arrow->wid/ppi); } dx1 = sx - cx; dy1 = sy - cy; dx2 = ex - cx; dy2 = ey - cy; rtop(dx1, dy1, &r1, &th1); rtop(dx2, dy2, &r2, &th2); theta = th2 - th1; if (theta > 0) theta -= 2*M_PI; set_linewidth(a->thickness); if (a->direction) fprintf(tfp, "\\circulararc %6.3f degrees from %6.3f %6.3f center at %6.3f %6.3f\n", 360+(180/M_PI * theta), sx, sy, cx, cy); else fprintf(tfp, "\\circulararc %6.3f degrees from %6.3f %6.3f center at %6.3f %6.3f\n", -180/M_PI * theta, ex, ey, cx, cy); if (a->area_fill && (int)a->area_fill != DEFAULT) fprintf(stderr, "Arc area fill not implemented\n"); } /* * rtop - rectangular to polar conversion */ static rtop(x, y, r, th) double x, y, *r, *th; { *r = hypot(x,y); *th = acos(x/(*r)); if (y < 0) *th = 2*M_PI - *th; } static arc_tangent(x1, y1, x2, y2, direction, x, y) double x1, y1, x2, y2, *x, *y; int direction; { if (direction) { /* counter clockwise */ *x = x2 + (y2 - y1); *y = y2 - (x2 - x1); } else { *x = x2 - (y2 - y1); *y = y2 + (x2 - x1); } } /* draw arrow heading from (x1, y1) to (x2, y2) */ static draw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid) double x1, y1, x2, y2, arrowht, arrowwid; { double x, y, xb, yb, dx, dy, l, sina, cosa; double xc, yc, xd, yd; int style; double dash; fprintf(tfp, "%%\n%% arrow head\n%%\n"); dx = x2 - x1; dy = y1 - y2; l = hypot(dx, dy); sina = dy / l; cosa = dx / l; xb = x2*cosa - y2*sina; yb = x2*sina + y2*cosa; x = xb - arrowht; y = yb - arrowwid / 2; xc = x*cosa + y*sina; yc = -x*sina + y*cosa; y = yb + arrowwid / 2; xd = x*cosa + y*sina; yd = -x*sina + y*cosa; /* save line style and set to solid */ style = line_style; dash = dash_length; set_style(SOLID_LINE, 0.0); fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f /\n%%\n", xc, yc, x2, y2, xd, yd); /* restore line style */ set_style(style, dash); } #define THRESHOLD .05 /* inch */ static quadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4) double a1, b1, a2, b2, a3, b3, a4, b4; { double x1, y1, x4, y4; double xmid, ymid; x1 = a1; y1 = b1; x4 = a4; y4 = b4; xmid = (a2 + a3) / 2; ymid = (b2 + b3) / 2; if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD) fprintf(tfp, "\t%6.3f %6.3f\n", xmid, ymid); else { quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2), ((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid); } if (fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) fprintf(tfp, "\t%6.3f %6.3f\n", x4, y4); else { quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4), ((a3+x4)/2), ((b3+y4)/2), x4, y4); } } static void genpictex_ctl_spline(s) F_spline *s; { F_point *p; double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4; double x1, y1, x2, y2; fprintf(tfp, "%%\n%% Fig CONTROL PT SPLINE\n%%\n"); p = s->points; x1 = p->x/ppi; y1 = convy(p->y/ppi); p = p->next; x2 = p->x/ppi; y2 = convy(p->y/ppi); cx1 = (x1 + x2) / 2; cy1 = (y1 + y2) / 2; cx2 = (x1 + 3 * x2) / 4; cy2 = (y1 + 3 * y2) / 4; if (closed_spline(s)) { fprintf(tfp, "%% closed spline\n%%\n"); fprintf(tfp, "\\plot\t%6.3f %6.3f \n ", cx1, cy1); } else { fprintf(tfp, "%% open spline\n%%\n"); if (s->back_arrow) draw_arrow_head(cx1, cy1, x1, y1, s->back_arrow->ht/ppi, s->back_arrow->wid/ppi); fprintf(tfp, "\\plot\t%6.3f %6.3f %6.3f %6.3f\n ", x1, y1, cx1, cy1); } for (p = p->next; p != NULL; p = p->next) { x1 = x2; y1 = y2; x2 = p->x/ppi; y2 = convy(p->y/ppi); cx3 = (3 * x1 + x2) / 4; cy3 = (3 * y1 + y2) / 4; cx4 = (x1 + x2) / 2; cy4 = (y1 + y2) / 2; quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4); cx1 = cx4; cy1 = cy4; cx2 = (x1 + 3 * x2) / 4; cy2 = (y1 + 3 * y2) / 4; } x1 = x2; y1 = y2; p = s->points->next; x2 = p->x/ppi; y2 = convy(p->y/ppi); cx3 = (3 * x1 + x2) / 4; cy3 = (3 * y1 + y2) / 4; cx4 = (x1 + x2) / 2; cy4 = (y1 + y2) / 2; if (closed_spline(s)) { quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4); fprintf(tfp, "\t/\n"); } else { fprintf(tfp, "\t /\n\\plot %6.3f %6.3f %6.3f %6.3f /\n", cx1, cy1, x1, y1); if (s->for_arrow) draw_arrow_head(cx1, cy1, x1, y1, s->for_arrow->ht/ppi, s->for_arrow->wid/ppi); } } static void genpictex_itp_spline(s) F_spline *s; { F_point *p1, *p2; F_control *cp1, *cp2; double x1, x2, y1, y2; p1 = s->points; cp1 = s->controls; x2 = p1->x/ppi; y2 = convy(p1->y/ppi); if (s->back_arrow) draw_arrow_head(cp1->rx/ppi, convy(cp1->ry/ppi), x2, y2, s->back_arrow->ht/ppi, s->back_arrow->wid/ppi); fprintf(tfp, "\\plot %6.3f %6.3f ", x2, y2); for (p2 = p1->next, cp2 = cp1->next; p2 != NULL; p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) { x1 = x2; y1 = y2; x2 = p2->x/ppi; y2 = convy(p2->y/ppi); bezier_spline(x1, y1, (double)cp1->rx/ppi, convy(cp1->ry/ppi), (double)cp2->lx/ppi, convy(cp2->ly/ppi), x2, y2); } fprintf(tfp, "\t/\n"); if (s->for_arrow) draw_arrow_head(cp1->lx/ppi, convy(cp1->ly/ppi), x2, y2, s->for_arrow->ht/ppi, s->for_arrow->wid/ppi); } static bezier_spline(a0, b0, a1, b1, a2, b2, a3, b3) double a0, b0, a1, b1, a2, b2, a3, b3; { double x0, y0, x3, y3; double sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid; x0 = a0; y0 = b0; x3 = a3; y3 = b3; if (fabs(x0 - x3) < THRESHOLD && fabs(y0 - y3) < THRESHOLD) fprintf(tfp, "\t%6.3f %6.3f\n", x3, y3); else { tx = (a1 + a2) / 2; ty = (b1 + b2) / 2; sx1 = (x0 + a1) / 2; sy1 = (y0 + b1) / 2; sx2 = (sx1 + tx) / 2; sy2 = (sy1 + ty) / 2; tx2 = (a2 + x3) / 2; ty2 = (b2 + y3) / 2; tx1 = (tx2 + tx) / 2; ty1 = (ty2 + ty) / 2; xmid = (sx2 + tx1) / 2; ymid = (sy2 + ty1) / 2; bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid); bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3); } } struct driver dev_pictex = { genpictex_option, genpictex_start, genpictex_arc, genpictex_ellipse, genpictex_line, genpictex_spline, genpictex_text, genpictex_end, EXCLUDE_TEXT };