rsalz@bbn.com (Rich Salz) (08/31/90)
Submitted-by: Micah Beck <beck@cs.cornell.edu> Posting-number: Volume 23, Issue 18 Archive-name: transfig/part05 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 5 (of 6)." # Contents: transfig/fig2dev/dev/genepic.c # Wrapped by beck@rocky on Thu May 17 15:56:13 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'transfig/fig2dev/dev/genepic.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'transfig/fig2dev/dev/genepic.c'\" else echo shar: Extracting \"'transfig/fig2dev/dev/genepic.c'\" \(28053 characters\) sed "s/^X//" >'transfig/fig2dev/dev/genepic.c' <<'END_OF_FILE' X/* X * genepic.c: (E)EPIC driver for fig2dev X * X * Converted from fig2epic 5/89 by Micah Beck X */ X/*==================================================================*/ X/* fig2epic (Fig to EPIC converter) */ X/* Version 1.1d <March 30, 1988> */ X/* */ X/* Written by Conrad Kwok, Division of Computer Science, UCD */ X/* */ X/* Permission is granted for freely distribution of this file */ X/* provided that this message is included. */ X/*==================================================================*/ X X/*==================================================================== X Changes: X X Version 1.0d:<September 18, 1988> X 1. Add the option -P for Page mode. Two more configurable parameter--- X Preamble and Postamble. X X Version 1.1a: <January 18, 1989> X 1. Fix the bug in closed control splines. The routine convertCS(p) is being X called once too often. X X 2. Add supports to Variable line width X 3. Add supports to black, white or shaded area fill. X X Version 1.1b: <Febrary 2, 1989> X 1. Draw outline for area-filled figures when using dvips. X X Version 1.1c: <Febrary 7, 1989> X 1. Supports all 5 gray level in area fill. X X Version 1.1d: <March 30, 1989> X 1. Add supports for Gould NP1 (Bsd4.3) (Recieve the changes from X mcvax!presto.irisa.fr!hleroy@uunet.uu.net. Sorry X I don't have his/her name) X 2. Add exit(0) before exit in the main. X====================================================================*/ X X X#include <stdio.h> X#include <math.h> X#include <string.h> X#include <varargs.h> X#include <ctype.h> X#include "object.h" X#include "fig2dev.h" X#include "texfonts.h" X#include "pi.h" X X#ifdef MSDOS X#define getopt egetopt X#define M_PI 3.14159265358979324 X#endif X X#define DrawOutLine X#ifdef DrawOutLine Xint OutLine=0; X#endif X X#define TopCoord 840 /* 10.5 in * 80 (DPI) */ X /* Actually, it can be any value */ X#define PtPerLine 3 X#define ThinLines 0 X#define ThickLines 1 X#define FALSE 0 X#define TRUE 1 X#define Epic 0 X#define EEpic_emu 1 X#define EEpic 2 X#define None 0 X#define SolidLineBox 1 X#define DashLineBox 2 X#define BothBoxType 3 X#define Normal 0 X#define Economic 1 X#define DottedDash 2 X Xvoid genepic_ctl_spline(), genepic_int_spline(); Xvoid genepic_open_spline(), genepic_closed_spline(); X X/* Structure for Point with "double" values */ Xstruct fp_struct { X double x,y; X}; X Xtypedef struct fp_struct FPoint; X X/* Local to the file only */ Xstatic int CoordSys = 2; Xstatic double Threshold; Xstatic int DPI; Xstatic int CurWidth = 0; Xstatic int LineStyle = SOLID_LINE; Xstatic int LLX = 0, LLY = 0; Xstatic char *LnCmd; Xstatic int MaxCircleRadius; Xstatic double DashLen; Xstatic int PageMode = FALSE; Xstatic F_pattern *PatternType=UNFILLED; Xstatic struct { X double mag; X int size; X} ScaleTbl[5] = { X { 0.6667, 8 }, X { 0.75 , 9 }, X { 0.8333, 10 }, X { 0.9167, 11 }, X { 1.0 , 12 } X}; X X/* Definition of Keywords for some of the configurable parameter */ Xchar *Tlangkw[] = { /* The order must match the definition of corr. constants */ X "Epic", "EEpicemu", "EEpic", NULL X}; X Xchar *EllCmdkw[] = { X "ellipse", "oval", NULL X}; X Xchar *EllCmdstr[] = { X "\\%s%s{%d}{%d}}\n", "\\%s%s(%d,%d)}\n" X}; X Xchar *FillCommands[] = { X "", "\\blacken", "\\shade", "\\shade", "\\shade", "\\whiten" X}; X X#define TEXT_LINE_SEP '\n' X/* The following two arrays are used to translate characters which X are special to LaTeX into characters that print as one would expect. X Note that the <> characters aren't really special LaTeX characters X but they will not print as themselves unless one is using a font X like tt. */ Xchar latex_text_specials[] = "\\{}><^~$&#_%"; Xchar *latex_text_mappings[] = { X "$\\backslash$", X "$\\{$", X "$\\}$", X "$>$", X "$<$", X "\\^{}", X "\\~{}", X "\\$", X "\\&", X "\\#", X "\\_", X "\\%"}; X X X/* Configurable parameters */ Xint LowerLeftX=0, LowerLeftY=0; Xdouble SegLen = 0.0625; /* inch */ Xint Verbose = FALSE; Xint TopMargin = 5; Xint BottomMargin = 10; Xint DotDist = 5; Xint LineThick = 2; Xint TeXLang = EEpic; Xdouble DashScale=1; Xint EllipseCmd=0; Xint UseBox=None; Xint DashType=Normal; Xchar *Preamble="\\documentstyle[epic,eepic]{article}\n\\begin{document}\n\\begin{center}\n"; Xchar *Postamble="\\end{center}\n\\end{document}\n"; Xint VarWidth=FALSE; X Xvoid genepic_option(opt, optarg) Xchar opt, *optarg; X{ X int loop; X X switch (opt) { X case 'S': X loop = atoi(optarg); X if (loop < 8 || loop > 12) { X put_msg("Scale must be between 8 and 12 inclusively\n"); X exit(1); X } X loop -= 8; X mag = ScaleTbl[loop].mag; X font_size = ScaleTbl[loop].size; X break; X X case 'l': X LineThick = atoi(optarg); X break; X X case 'v': X Verbose = TRUE; X break; X X case 'L': X for (loop=0; loop < 3; loop++) { X if (stricmp(optarg, Tlangkw[loop]) == 0) break; X } X TeXLang = loop; X break; X X case 'w': X case 'W': X VarWidth = opt=='W'; X break; X X case 'f': X { int i; X X for ( i = 1; i <= MAXFONT + 1; i++ ) X if ( !strcmp(optarg, fontnames[i]) ) break; X X if ( i > MAXFONT + 1 ) X fprintf(stderr, X "warning: non-standard font name %s\n", optarg); X } X X fontnames[0] = fontnames[1] = optarg; X break; X X case 's': X if (font_size <= 0 || font_size > MAXFONTSIZE) { X fprintf(stderr, X "warning: font size %d out of bounds\n", font_size); X } X break; X X case 'm': X break; X X default: X put_msg(Err_badarg, opt, "epic"); X exit(1); X break; X } X} X Xstatic fconvertCS(fpt) XFPoint *fpt; X{ X if (CoordSys) { X fpt->y = TopCoord - fpt->y; X } X fpt->x -= LLX; X fpt->y -= LLY; X} X XconvertCS(pt) XF_point *pt; X{ X if (CoordSys) { X pt->y = TopCoord - pt->y; X } X pt->x -= LLX; X pt->y -= LLY; X} X Xvoid genepic_start(objects) XF_compound *objects; X{ X int temp; X F_point pt1, pt2; X F_arc *arc; X F_compound *comp; X F_ellipse *ell; X F_line *line; X F_spline *spl; X F_text *text; X X fontsizes[0] = fontsizes[1] = TEXFONTSIZE(font_size); X X switch (TeXLang) { X case Epic: X EllipseCmd = 1; /* Oval */ X LnCmd = "drawline"; X break; X case EEpic_emu: X case EEpic: X LnCmd = "path"; X break; X default: X put_msg("Program error in main\n"); X break; X } X if (PageMode) { X fputs(Preamble, stdout); X } X X DPI = objects->nwcorner.x; X if (DPI <= 0) { X put_msg("Resolution has to be positive. Default to 80!\n"); X DPI = 80; X } X coord_system = objects->nwcorner.y; X switch (coord_system) { X case 1: X CoordSys = 0; X break; X case 2: X CoordSys = 1; X break; X default: X put_msg("Unknown Coordinate system -- %d\n", coord_system); X exit(1); X } X pt1.x = llx; X pt1.y = lly; X pt2.x = urx; X pt2.y = ury; X convertCS(&pt1); X convertCS(&pt2); X if (pt1.x > pt2.x) { X temp = pt1.x; X pt1.x = pt2.x; X pt2.x = temp; X } X if (pt1.y > pt2.y) { X temp = pt1.y; X pt1.y = pt2.y; X pt2.y = temp; X } X LLX = pt1.x - LowerLeftX; X LLY = pt1.y - LowerLeftY; X if (Verbose) { X fprintf(tfp, "%%\n%% Language in use is %s\n%%\n", Tlangkw[TeXLang]); X } X Threshold = 1.0 / DPI * mag; X fprintf(tfp, "\\setlength{\\unitlength}{%.4fin}\n", Threshold); X MaxCircleRadius = (int) (40 / 72.27 / Threshold); X Threshold = SegLen / Threshold; X fprintf(tfp, "\\begin{picture}(%d,%d)(%d,%d)\n", X pt2.x-pt1.x, pt2.y-pt1.y + TopMargin + BottomMargin, X LowerLeftX, LowerLeftY-BottomMargin); X} X Xvoid genepic_end() X{ X fprintf(tfp, "\\end{picture}\n"); X if (PageMode) X fputs(Postamble, stdout); X} X Xstatic set_linewidth(w) Xint w; X{ X int old_width; X X if (w < 0) return; X old_width=CurWidth; X CurWidth = (w >= LineThick) ? (VarWidth ? w : ThickLines) : ThinLines; X if (old_width != CurWidth) { X if (CurWidth==ThinLines) { X fprintf(tfp, "\\thinlines\n"); X } else if (VarWidth) { X fprintf(tfp, "\\allinethickness{%d}%%\n",w); X } else { X fprintf(tfp, "\\thicklines\n"); X } X } X} X Xset_pattern(type) XF_pattern *type; X{ X static unsigned long patterns[3][32] = { X { 0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0, X 0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0, X 0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0, X 0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0}, X { 0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0, X 0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0, X 0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0, X 0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0}, X { 0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0, X 0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0, X 0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0, X 0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0}}; X int count, loop1, loop2, i; X X if (type < DARK_GRAY_FILL || type > LIGHT_GRAY_FILL) return; X if (type != PatternType) { X PatternType=type; X i = (int) PatternType - (int) DARK_GRAY_FILL; X fprintf(tfp, "\\texture{"); X count=0; X for (loop1=4; loop1>0;) { X for (loop2=8; loop2>0; loop2--) X fprintf(tfp, "%lx ", patterns[i][count++]); X if (--loop1 > 0) X fprintf(tfp, "\n\t"); X else X fprintf(tfp, "}%\n"); X } X } X} X Xvoid genepic_line(line) XF_line *line; X{ X F_point *p, *q; X int pt_count = 0, temp; X int boxflag = FALSE, llx, lly, urx, ury; X double dtemp; X X set_linewidth(line->thickness); X set_style(line->style, line->style_val); X p = line->points; X q = p->next; X convertCS(p); X if (q == NULL) { X fprintf(tfp, "\\drawline(%d,%d)(%d,%d)\n", p->x, p->y, p->x, p->y); X return; X } X if (line->type == T_BOX) { X if (Verbose) { X fprintf(tfp, "%%\n%% A box\n%%\n"); X } X switch (LineStyle) { X case SOLID_LINE: X if (UseBox == BothBoxType || UseBox == SolidLineBox) { X boxflag = TRUE; X } X break; X case DASH_LINE: X if (UseBox == BothBoxType || UseBox == DashLineBox) { X boxflag = TRUE; X } X break; X } X if (boxflag) { X llx = urx = p->x; X lly = ury = p->y; X while (q != NULL) { X convertCS(q); X if (q->x < llx) { X llx = q->x; X } else if (q->x > urx) { X urx = q->x; X } X if (q->y < lly) { X lly = q->y; X } else if (q->y > ury) { X ury = q->y; X } X q = q->next; X } X switch(LineStyle) { X case SOLID_LINE: X fprintf(tfp, "\\put(%d,%d){\\framebox(%d,%d){}}\n", X llx, lly, urx-llx, ury-lly); X break; X case DASH_LINE: X temp = (int) ((urx-llx) / DashLen); X dtemp = (double) (urx-llx) / temp; X fprintf(tfp, "\\put(%d,%d){\\dashbox{%4.3f}(%d,%d){}}\n", X llx, lly, dtemp , urx-llx, ury-lly); X break; X default: X put_msg("Program Error! No other line styles allowed.\n"); X break; X } X return; X } X } X set_pattern(line->area_fill); X convertCS(q); X if (line->back_arrow) { X draw_arrow_head(q, p, line->back_arrow->ht, line->back_arrow->wid); X if (Verbose) fprintf(tfp, "%%\n"); X } X switch (LineStyle) { X case SOLID_LINE: X if (q->next != NULL && strcmp(LnCmd,"path")==0) { X if (line->area_fill < UNFILLED) line->area_fill = UNFILLED; X fprintf(tfp, "%s", FillCommands[(int) line->area_fill]); X } X fprintf(tfp, "\\%s", LnCmd); X#ifdef DrawOutLine X if (line->area_fill != UNFILLED && OutLine == 0) OutLine=1; X#endif X break; X case DASH_LINE: X if ((TeXLang==Epic || TeXLang ==EEpic_emu) && DashType == Economic) { X fprintf(tfp, "\\drawline[-50]"); X } else { X fprintf(tfp, "\\dashline{%4.3f}", DashLen); X } X break; X case DOTTED_LINE: X fprintf(tfp, "\\dottedline{%d}", DotDist); X break; X default: X fprintf(stderr,"Unknown Style\n"); X exit(1); X } X fprintf(tfp, "(%d,%d)", p->x, p->y); X pt_count++; X while(q->next != NULL) { X if (++pt_count > PtPerLine) { X pt_count=1; X fprintf(tfp, "\n\t"); X } X fprintf(tfp, "(%d,%d)", q->x, q->y); X p=q; X q = q->next; X convertCS(q); X } X fprintf(tfp, "(%d,%d)\n", q->x, q->y); X#ifdef DrawOutLine X if (OutLine == 1) { X OutLine=0; X fprintf(tfp, "\\%s", LnCmd); X p=line->points; X pt_count=0; X q=p->next; X fprintf(tfp, "(%d,%d)", p->x, p->y); X pt_count++; X while(q->next != NULL) { X if (++pt_count > PtPerLine) { X pt_count=1; X fprintf(tfp, "\n\t"); X } X fprintf(tfp, "(%d,%d)", q->x, q->y); X p=q; X q = q->next; X } X fprintf(tfp, "(%d,%d)\n", q->x, q->y); X } X#endif X if (line->for_arrow) { X draw_arrow_head(p, q, line->for_arrow->ht, line->for_arrow->wid); X if (Verbose) fprintf(tfp, "%%\n"); X } X} X Xset_style(style, dash_len) Xint style; Xfloat dash_len; X{ X LineStyle = style; X if (LineStyle == DASH_LINE) { X switch (DashType) { X case DottedDash: X LineStyle = DOTTED_LINE; X break; X default: X DashLen = dash_len * DashScale; X break; X } X } X} X X Xvoid genepic_spline(spl) XF_spline *spl; X{ X set_linewidth(spl->thickness); X set_style(SOLID_LINE, 0.0); X if (int_spline(spl)) { X genepic_itp_spline(spl); X } else { X genepic_ctl_spline(spl); X } X} X Xvoid genepic_ctl_spline(spl) XF_spline *spl; X{ X if (closed_spline(spl)) { X genepic_closed_spline(spl); X } else { X genepic_open_spline(spl); X } X} X Xstatic void genepic_open_spline(spl) XF_spline *spl; X{ X F_point *p, *q, *r; X FPoint first, mid; X int pt_count = 0; X X p = spl->points; X q = p->next; X convertCS(p); X convertCS(q); X if (spl->back_arrow) { X draw_arrow_head(q, p, spl->back_arrow->ht, spl->back_arrow->wid); X if (Verbose) fprintf(tfp, "%%\n"); X } X if (q->next == NULL) { X fprintf(tfp, "\\%s(%d,%d)(%d,%d)\n", LnCmd, X p->x, p->y, q->x, q->y); X return; X } X if (TeXLang == EEpic || TeXLang == EEpic_emu) { X fprintf(tfp, "\\spline(%d,%d)\n", p->x, p->y); X pt_count++; X while(q->next != NULL) { X if (++pt_count > PtPerLine) { X pt_count=1; X fprintf(tfp, "\n\t"); X } X fprintf(tfp, "(%d,%d)", q->x, q->y); X p=q; X q = q->next; X convertCS(q); X } X fprintf(tfp, "(%d,%d)\n", q->x, q->y); X } else { X fprintf(tfp, "\\%s(%d,%d)\n", LnCmd, p->x, p->y); X r = q->next; X convertCS(r); X first.x = p->x; X first.y = p->y; X while (r->next != NULL) { X mid.x = (q->x + r->x) / 2.0; X mid.y = (q->y + r->y) / 2.0; X chaikin_curve(first.x, first.y, (double) q->x, (double) q->y, X mid.x, mid.y); X first = mid; X q=r; X r = r->next; X convertCS(r); X } X chaikin_curve(first.x, first.y, (double) q->x, (double) q->y, X (double) r->x, (double) r->y); X p=q; X q=r; X fprintf(tfp, "\n"); X } X if (spl->for_arrow) { X draw_arrow_head(p, q, spl->for_arrow->ht, spl->for_arrow->wid); X if (Verbose) fprintf(tfp, "%%\n"); X } X} X Xstatic void genepic_closed_spline(spl) XF_spline *spl; X{ X F_point *p; X double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4; X double x1, y1, x2, y2; X X p = spl->points; X convertCS(p); X x1 = p->x; y1 = p->y; X p = p->next; X convertCS(p); X x2 = p->x; y2 = p->y; X cx1 = (x1 + x2) / 2; cy1 = (y1 + y2) / 2; X cx2 = (x1 + 3 * x2) / 4; cy2 = (y1 + 3 * y2) / 4; X for (p = p->next; p != NULL; p = p->next) { X fprintf(tfp, "\\%s(%.3f,%.3f)", LnCmd, cx1, cy1); X x1 = x2; y1 = y2; X convertCS(p); X x2 = p->x; y2 = p->y; X cx3 = (3 * x1 + x2) / 4; cy3 = (3 * y1 + y2) / 4; X cx4 = (x1 + x2) / 2; cy4 = (y1 + y2) / 2; X quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4); X fprintf(tfp, "\n"); X cx1 = cx4; cy1 = cy4; X cx2 = (x1 + 3 * x2) / 4; cy2 = (y1 + 3 * y2) / 4; X } X x1 = x2; y1 = y2; X p = spl->points->next; X x2 = p->x; y2 = p->y; X cx3 = (3 * x1 + x2) / 4; cy3 = (3 * y1 + y2) / 4; X cx4 = (x1 + x2) / 2; cy4 = (y1 + y2) / 2; X fprintf(tfp, "\\%s(%.3f,%.3f)", LnCmd, cx1, cy1); X quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4); X fprintf(tfp, "\n"); X} X Xchaikin_curve(a1, b1, a2, b2, a3, b3) Xdouble a1, b1, a2, b2, a3, b3; X{ X double xm1, xmid, xm2, ym1, ymid, ym2; X X if (fabs(a1-a3) < Threshold && fabs(b1-b3) < Threshold) { X fprintf(tfp, "\t(%.3f,%.3f)\n", a3, b3); X } else { X xm1 = (a1 + a2) / 2; X ym1 = (b1 + b2) / 2; X xm2 = (a2 + a3) / 2; X ym2 = (b2 + b3) / 2; X xmid = (xm1 + xm2) / 2; X ymid = (ym1 + ym2) / 2; X chaikin_curve(a1, b1, xm1, ym1, xmid, ymid); X chaikin_curve(xmid, ymid, xm2, ym2, a3, b3); X } X} X Xstatic quadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4) Xdouble a1, b1, a2, b2, a3, b3, a4, b4; X{ X double x1, y1, x4, y4; X double xmid, ymid; X X x1 = a1; y1 = b1; X x4 = a4; y4 = b4; X X xmid = (a2 + a3) / 2; X ymid = (b2 + b3) / 2; X if (fabs(x1 - xmid) < Threshold && fabs(y1 - ymid) < Threshold) { X fprintf(tfp, "\t(%.3f,%.3f)\n", xmid, ymid); X } else { X quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2), X ((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid); X } X X if (fabs(xmid - x4) < Threshold && fabs(ymid - y4) < Threshold) { X fprintf(tfp, "\t(%.3f,%.3f)\n", x4, y4); X } else { X quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4), X ((a3+x4)/2), ((b3+y4)/2), x4, y4); X } X} X Xgenepic_itp_spline(spl) XF_spline *spl; X{ X F_point *p1, *p2; X FPoint pt1l, pt1r, pt2l, pt2r, tmpfpt; X F_control *cp1, *cp2; X X p1 = spl->points; X convertCS(p1); X cp1 = spl->controls; X pt1l.x = cp1->lx; X pt1l.y = cp1->ly; X pt1r.x = cp1->rx; X pt1r.y = cp1->ry; X fconvertCS(&pt1l); X fconvertCS(&pt1r); X X if (spl->back_arrow) { X tmpfpt.x = p1->x; X tmpfpt.y = p1->y; X fdraw_arrow_head(&pt1r, &tmpfpt, X spl->back_arrow->ht, spl->back_arrow->wid); X if (Verbose) fprintf(tfp, "%%\n"); X } X X for (p2 = p1->next, cp2 = cp1->next; p2 != NULL; X p1 = p2, pt1r = pt2r, p2 = p2->next, cp2 = cp2->next) { X fprintf(tfp, "\\%s(%d,%d)", LnCmd, p1->x, p1->y); X convertCS(p2); X pt2l.x = cp2->lx; X pt2l.y = cp2->ly; X pt2r.x = cp2->rx; X pt2r.y = cp2->ry; X fconvertCS(&pt2l); X fconvertCS(&pt2r); X bezier_spline((double) p1->x, (double) p1->y, X pt1r.x, pt1r.y, X pt2l.x, pt2l.y, X (double) p2->x, (double) p2->y); X fprintf(tfp, "\n"); X } X X if (spl->for_arrow) { X tmpfpt.x = p1->x; X tmpfpt.y = p1->y; X fdraw_arrow_head(&pt2l, &tmpfpt, X spl->for_arrow->ht, spl->for_arrow->wid); X if (Verbose) fprintf(tfp, "%%\n"); X } X} X Xstatic bezier_spline(a0, b0, a1, b1, a2, b2, a3, b3) Xdouble a0, b0, a1, b1, a2, b2, a3, b3; X{ X double x0, y0, x3, y3; X double sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid; X X x0 = a0; y0 = b0; X x3 = a3; y3 = b3; X if (fabs(x0 - x3) < Threshold && fabs(y0 - y3) < Threshold) { X fprintf(tfp, "\t(%.3f,%.3f)\n", x3, y3); X } else { X tx = (a1 + a2) / 2; ty = (b1 + b2) / 2; X sx1 = (x0 + a1) / 2; sy1 = (y0 + b1) / 2; X sx2 = (sx1 + tx) / 2; sy2 = (sy1 + ty) / 2; X tx2 = (a2 + x3) / 2; ty2 = (b2 + y3) / 2; X tx1 = (tx2 + tx) / 2; ty1 = (ty2 + ty) / 2; X xmid = (sx2 + tx1) / 2; ymid = (sy2 + ty1) / 2; X X bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid); X bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3); X } X} X Xvoid genepic_ellipse(ell) XF_ellipse *ell; X{ X F_point pt; X X set_linewidth(ell->thickness); X pt.x = ell->center.x; X pt.y = ell->center.y; X convertCS(&pt); X if (TeXLang == EEpic || TeXLang == EEpic_emu || X ell->radiuses.x != ell->radiuses.y || X ell->radiuses.x > MaxCircleRadius) { X set_pattern(ell->area_fill); X fprintf(tfp, "\\put(%d,%d){", pt.x, pt.y ); X#ifndef OLDCODE X if (EllipseCmd == 0) { X if (ell->area_fill < UNFILLED) ell->area_fill = UNFILLED; X fprintf(tfp, "%s", FillCommands[(int) ell->area_fill]); X# ifdef DrawOutLine X if (ell->area_fill != UNFILLED && OutLine == 0) OutLine = 1; X# endif X } X fprintf(tfp, EllCmdstr[EllipseCmd],EllCmdkw[EllipseCmd], "", X 2 * ell->radiuses.x, 2 * ell->radiuses.y); X# ifdef DrawOutLine X if (OutLine == 1) { X OutLine=0; X fprintf(tfp, "\\put(%d,%d){", pt.x, pt.y ); X fprintf(tfp, EllCmdstr[EllipseCmd],EllCmdkw[EllipseCmd], "", X 2 * ell->radiuses.x, 2 * ell->radiuses.y); X } X# endif X#else X fprintf(tfp, EllCmdstr[EllipseCmd], EllCmdkw[EllipseCmd], X (EllipseCmd==0 && ell->area_fill==BLACK_FILL ? "*" : ""), X 2 * ell->radiuses.x, 2 * ell->radiuses.y); X#endif X } else { X fprintf(tfp, "\\put(%d,%d){\\circle", pt.x, pt.y); X if (ell->area_fill == BLACK_FILL) { X fputc('*', tfp); X } X fprintf(tfp, "{%d}}\n", 2*ell->radiuses.x); X } X} X Xvoid genepic_text(text) XF_text *text; X{ X F_point pt; X char *tpos, *cp, *esc_cp, *special_index; X X pt.x=text->base_x; X pt.y=text->base_y; X convertCS(&pt); X switch (text->type) { X case T_LEFT_JUSTIFIED: X case DEFAULT: X tpos = "[lb]"; X break; X case T_CENTER_JUSTIFIED: X tpos = "[b]"; X break; X case T_RIGHT_JUSTIFIED: X tpos = "[rb]"; X break; X default: X fprintf(stderr, "unknown text position type\n"); X exit(1); X } X fprintf(tfp, "\\put(%d,%d){\\makebox(0,0)%s{\\raisebox{0pt}[0pt][0pt]{", X pt.x, pt.y, tpos); X /* Output a shortstack in case there are multiple lines. */ X fprintf(tfp, "\\shortstack" ); X /* Output the justification for the shortstack. */ X switch (text->type) { X case T_LEFT_JUSTIFIED: X case DEFAULT: X fprintf(tfp, "[l]"); X break; X case T_CENTER_JUSTIFIED: X break; X case T_RIGHT_JUSTIFIED: X fprintf(tfp, "[r]"); X break; X default: X fprintf(stderr, "unknown text position type\n"); X exit(1); X } X fprintf(tfp, "{{\\%s%s ", TEXFONTSIZE(text->size), TEXFONT(text->font)); X if (text->font && text->font != DEFAULT_FONT) X /* This loop escapes special LaTeX characters. */ X for(cp = text->cstring; *cp; cp++) { X if (special_index=strchr(latex_text_specials, *cp)) { X /* Write out the replacement. Implementation note: we can't X use puts since that will output an additional newline. */ X esc_cp=latex_text_mappings[special_index-latex_text_specials]; X while (*esc_cp) X fputc(*esc_cp++, tfp); X } X else if (*cp == TEXT_LINE_SEP) { X /* Handle multi-line text strings. The problem being addressed here X is a LaTeX bug where LaTeX is unable to handle a font which X spans multiple lines. What we are doing here is closing off X the current font, starting a new line, and then resuming with X the current font. */ X fprintf(tfp, "} \\\\\n"); X fprintf(tfp, "{\\%s%s ", TEXFONTSIZE(text->size), TEXFONT(text->font)); X } X else X fputc(*cp, tfp); X } X else X for(cp = text->cstring; *cp; cp++) { X if (*cp == TEXT_LINE_SEP) { X /* Handle multi-line text strings. */ X fprintf(tfp, "} \\\\\n"); X fprintf(tfp, "{\\%s%s ", TEXFONTSIZE(text->size), TEXFONT(text->font)); X } X else X fputc(*cp, tfp); X } X fprintf(tfp, "}}}}}\n"); X} X Xvoid genepic_arc(arc) XF_arc *arc; X{ X FPoint pt1, pt2, ctr, tmp; X double r1, r2, th1, th2, theta; X double dx1, dy1, dx2, dy2; X double arrowfactor; X X ctr.x = arc->center.x; X ctr.y = arc->center.y; X pt1.x = arc->point[0].x; X pt1.y = arc->point[0].y; X pt2.x = arc->point[2].x; X pt2.y = arc->point[2].y; X fconvertCS(&ctr); X fconvertCS(&pt1); X fconvertCS(&pt2); X X dx1 = pt1.x - ctr.x; X dy1 = pt1.y - ctr.y; X dx2 = pt2.x - ctr.x; X dy2 = pt2.y - ctr.y; X X rtop(dx1, dy1, &r1, &th1); X rtop(dx2, dy2, &r2, &th2); X arrowfactor = (r1+r2) / 30.0; X if (arrowfactor > 1) arrowfactor = 1; X set_linewidth(arc->thickness); X if (arc->for_arrow) { X arc_tangent(&ctr, &pt2, arc->direction, &tmp); X fdraw_arrow_head(&tmp, &pt2, X arc->for_arrow->ht*arrowfactor, X arc->for_arrow->wid*arrowfactor); X if (Verbose) fprintf(tfp, "%%\n"); X } X if (arc->back_arrow) { X arc_tangent(&ctr, &pt1, !arc->direction, &tmp); X fdraw_arrow_head(&tmp, &pt1, X arc->back_arrow->ht*arrowfactor, X arc->back_arrow->wid*arrowfactor); X if (Verbose) fprintf(tfp, "%%\n"); X } X if (TeXLang == EEpic) { X set_pattern(arc->area_fill); X fprintf(tfp, "\\put(%4.3lf,%4.3lf){", ctr.x, ctr.y); X } else { X fprintf(tfp, "\\drawline"); X } X if (TeXLang == EEpic) { X if (arc->area_fill < UNFILLED) arc->area_fill = UNFILLED; X fprintf(tfp, "%s", FillCommands[(int) arc->area_fill]); X#ifdef DrawOutLine X if (arc->area_fill != UNFILLED && OutLine==0) OutLine=1; X#endif X } X if (arc->direction) { X theta = th2 - th1; X if (theta < 0) theta += 2 * M_PI; X th2 = 2*M_PI-th2; X if (TeXLang == EEpic) { X fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r1, th2, th2+theta); X#ifdef DrawOutLine X if (OutLine==1) { X OutLine=0; X fprintf(tfp, "\\put(%4.3lf,%4.3lf){", ctr.x, ctr.y); X fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r1, th2, th2+theta); X } X#endif X } else { X drawarc(&ctr, r1, 2*M_PI - th2 - theta, theta); X } X } else { X theta = th1 - th2; X if (theta < 0) theta += 2 * M_PI; X th1 = 2*M_PI-th1; X if (TeXLang == EEpic) { X fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r2, th1, th1+theta); X#ifdef DrawOutLine X if (OutLine==1) { X OutLine=0; X fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r2, th1, th1+theta); X } X#endif X } else { X drawarc(&ctr, r2, 2*M_PI - th1 - theta, theta); X } X } X} X Xdrawarc(ctr, r, th1, angle) XFPoint *ctr; Xdouble r, th1, angle; X{ X double arclength, delta; X int division, pt_count = 0; X X X division = angle * r / Threshold; X delta = angle / division; X division++; X while (division-- > 0) { X if (++pt_count > PtPerLine) { X fprintf(tfp, "\n\t"); X pt_count = 1; X } X fprintf(tfp, "(%.3lf,%.3lf)", ctr->x + cos(th1) * r, X ctr->y + sin(th1) * r); X th1 += delta; X } X fprintf(tfp, "\n"); X} X Xstatic arc_tangent(pt1, pt2, direction, pt3) XFPoint *pt1, *pt2, *pt3; Xint direction; X{ X if (direction) { X pt3->x = pt2->x + (pt2->y - pt1->y); X pt3->y = pt2->y - (pt2->x - pt1->x); X } else { X pt3->x = pt2->x - (pt2->y - pt1->y); X pt3->y = pt2->y + (pt2->x - pt1->x); X } X} X Xrtop(x, y, r, th) Xdouble x, y, *r, *th; X{ X *r = hypot(x,y); X *th = acos(x/(*r)); X if (*th < 0) *th = M_PI + *th; X if (y < 0) *th = 2*M_PI - *th; X} X Xstatic draw_arrow_head(pt1, pt2, arrowht, arrowwid) XF_point *pt1, *pt2; Xdouble arrowht, arrowwid; X{ X FPoint fpt1, fpt2; X X fpt1.x = pt1->x; X fpt1.y = pt1->y; X fpt2.x = pt2->x; X fpt2.y = pt2->y; X fdraw_arrow_head(&fpt1, &fpt2, arrowht, arrowwid); X} X Xfdraw_arrow_head(pt1, pt2, arrowht, arrowwid) XFPoint *pt1, *pt2; Xdouble arrowht, arrowwid; X{ X double x1, y1, x2, y2; X double x,y, xb,yb,dx,dy,l,sina,cosa; X double xc, yc, xd, yd; X X x1 = pt1->x; X y1 = pt1->y; X x2 = pt2->x; X y2 = pt2->y; X X if (Verbose) fprintf(tfp, "%%\n%% arrow head\n%%\n"); X X dx = x2 - x1; dy = y1 - y2; X l = hypot(dx,dy); X sina = dy / l; cosa = dx / l; X xb = x2*cosa - y2*sina; X yb = x2*sina + y2*cosa; X x = xb - arrowht; X y = yb - arrowwid / 2; X xc = x*cosa + y*sina; X yc = -x*sina + y*cosa; X y = yb + arrowwid / 2; X xd = x*cosa + y*sina; X yd = -x*sina + y*cosa; X X fprintf(tfp, "\\%s(%4.3f,%4.3f)(%4.3f,%4.3f)(%4.3f,%4.3f)\n", LnCmd, X xc, yc, x2, y2, xd, yd); X} X X#ifndef MSDOS Xstricmp(s, t) Xchar *s, *t; X{ X char a, b; X X for (;;) { X a= *s++; b= *t++; X a = islower(a) ? toupper(a) : a; X b = islower(b) ? toupper(b) : b; X if (a != b) break; X if (a == '\0') return(0); X } X return(a - b); X} X#endif X Xstruct driver dev_epic = { X genepic_option, X genepic_start, X genepic_arc, X genepic_ellipse, X genepic_line, X genepic_spline, X genepic_text, X genepic_end, X INCLUDE_TEXT X}; END_OF_FILE if test 28053 -ne `wc -c <'transfig/fig2dev/dev/genepic.c'`; then echo shar: \"'transfig/fig2dev/dev/genepic.c'\" unpacked with wrong size! fi # end of 'transfig/fig2dev/dev/genepic.c' fi echo shar: End of archive 5 \(of 6\). cp /dev/null ark5isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.