home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume23 / transfig / part05 < prev    next >
Encoding:
Internet Message Format  |  1991-06-19  |  30.6 KB

  1. Path: j.cc.purdue.edu!mentor.cc.purdue.edu!noose.ecn.purdue.edu!samsung!zaphod.mps.ohio-state.edu!usc!apple!bbn.com!papaya.bbn.com!rsalz
  2. From: rsalz@bbn.com (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v23i018:  Tools for creating TeX documents with portable graphics, Part05/06
  5. Message-ID: <2815@litchi.bbn.com>
  6. Date: 31 Aug 90 13:43:24 GMT
  7. Organization: BBN Systems and Technologies, Cambridge MA
  8. Lines: 1171
  9. Approved: rsalz@uunet.UU.NET
  10. X-Checksum-Snefru: 8a059bdc f22e12ec b155b6b2 a054c52c
  11.  
  12. Submitted-by: Micah Beck <beck@cs.cornell.edu>
  13. Posting-number: Volume 23, Issue 18
  14. Archive-name: transfig/part05
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of archive 5 (of 6)."
  23. # Contents:  transfig/fig2dev/dev/genepic.c
  24. # Wrapped by beck@rocky on Thu May 17 15:56:13 1990
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'transfig/fig2dev/dev/genepic.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'transfig/fig2dev/dev/genepic.c'\"
  28. else
  29. echo shar: Extracting \"'transfig/fig2dev/dev/genepic.c'\" \(28053 characters\)
  30. sed "s/^X//" >'transfig/fig2dev/dev/genepic.c' <<'END_OF_FILE'
  31. X/*
  32. X * genepic.c: (E)EPIC driver for fig2dev
  33. X *
  34. X * Converted from fig2epic 5/89 by Micah Beck
  35. X */
  36. X/*==================================================================*/
  37. X/*    fig2epic (Fig to EPIC converter)                 */
  38. X/*         Version 1.1d <March 30, 1988>                */
  39. X/*                                    */
  40. X/*    Written by Conrad Kwok, Division of Computer Science, UCD   */
  41. X/*                                    */
  42. X/*    Permission is granted for freely distribution of this file  */
  43. X/*        provided that this message is included.            */
  44. X/*==================================================================*/
  45. X
  46. X/*====================================================================
  47. X  Changes:
  48. X
  49. X  Version 1.0d:<September 18, 1988>
  50. X  1. Add the option -P for Page mode. Two more configurable parameter---
  51. X     Preamble and Postamble.
  52. X
  53. X  Version 1.1a: <January 18, 1989>
  54. X  1. Fix the bug in closed control splines. The routine convertCS(p) is being
  55. X     called once too often.
  56. X
  57. X  2. Add supports to Variable line width
  58. X  3. Add supports to black, white or shaded area fill.
  59. X
  60. X  Version 1.1b: <Febrary 2, 1989>
  61. X  1. Draw outline for area-filled figures when using dvips.
  62. X
  63. X  Version 1.1c: <Febrary 7, 1989>
  64. X  1. Supports all 5 gray level in area fill.
  65. X
  66. X  Version 1.1d: <March 30, 1989>
  67. X  1. Add supports for Gould NP1 (Bsd4.3) (Recieve the changes from
  68. X        mcvax!presto.irisa.fr!hleroy@uunet.uu.net. Sorry
  69. X        I don't have his/her name)
  70. X  2. Add exit(0) before exit in the main.
  71. X====================================================================*/
  72. X
  73. X  
  74. X#include <stdio.h>
  75. X#include <math.h>
  76. X#include <string.h>
  77. X#include <varargs.h>
  78. X#include <ctype.h>
  79. X#include "object.h"
  80. X#include "fig2dev.h"
  81. X#include "texfonts.h"
  82. X#include "pi.h"
  83. X
  84. X#ifdef MSDOS
  85. X#define getopt egetopt
  86. X#define M_PI 3.14159265358979324
  87. X#endif
  88. X
  89. X#define DrawOutLine
  90. X#ifdef DrawOutLine
  91. Xint OutLine=0;
  92. X#endif
  93. X
  94. X#define TopCoord 840        /* 10.5 in * 80 (DPI)            */
  95. X                /* Actually, it can be any value */
  96. X#define PtPerLine 3
  97. X#define ThinLines 0
  98. X#define ThickLines 1
  99. X#define FALSE 0
  100. X#define TRUE 1
  101. X#define Epic 0
  102. X#define EEpic_emu 1
  103. X#define EEpic 2
  104. X#define None 0
  105. X#define SolidLineBox 1
  106. X#define DashLineBox 2
  107. X#define BothBoxType 3
  108. X#define Normal 0
  109. X#define Economic 1
  110. X#define DottedDash 2
  111. X
  112. Xvoid genepic_ctl_spline(), genepic_int_spline(); 
  113. Xvoid genepic_open_spline(), genepic_closed_spline(); 
  114. X
  115. X/* Structure for Point with "double" values */
  116. Xstruct fp_struct {
  117. X    double x,y;
  118. X};
  119. X
  120. Xtypedef struct fp_struct FPoint;
  121. X
  122. X/* Local to the file only */
  123. Xstatic int CoordSys = 2;
  124. Xstatic double Threshold;
  125. Xstatic int DPI;
  126. Xstatic int CurWidth = 0;
  127. Xstatic int LineStyle = SOLID_LINE;
  128. Xstatic int LLX = 0, LLY = 0;
  129. Xstatic char *LnCmd;
  130. Xstatic int MaxCircleRadius;
  131. Xstatic double DashLen;
  132. Xstatic int PageMode = FALSE;
  133. Xstatic F_pattern *PatternType=UNFILLED;
  134. Xstatic struct {
  135. X    double mag;
  136. X    int size;
  137. X} ScaleTbl[5] = {
  138. X    { 0.6667, 8 },
  139. X    { 0.75  , 9 },
  140. X    { 0.8333, 10 },
  141. X    { 0.9167, 11 },
  142. X    { 1.0   , 12 }
  143. X};
  144. X
  145. X/* Definition of Keywords for some of the configurable parameter */
  146. Xchar *Tlangkw[] = { /* The order must match the definition of corr. constants */
  147. X    "Epic", "EEpicemu", "EEpic", NULL
  148. X};
  149. X
  150. Xchar *EllCmdkw[] = {
  151. X    "ellipse", "oval", NULL
  152. X};
  153. X
  154. Xchar *EllCmdstr[] = {
  155. X    "\\%s%s{%d}{%d}}\n", "\\%s%s(%d,%d)}\n"
  156. X};
  157. X
  158. Xchar *FillCommands[] = {
  159. X    "", "\\blacken", "\\shade", "\\shade", "\\shade", "\\whiten"
  160. X};
  161. X
  162. X#define TEXT_LINE_SEP '\n'
  163. X/* The following two arrays are used to translate characters which
  164. X   are special to LaTeX into characters that print as one would expect.
  165. X   Note that the <> characters aren't really special LaTeX characters
  166. X   but they will not print as themselves unless one is using a font
  167. X   like tt. */
  168. Xchar latex_text_specials[] = "\\{}><^~$&#_%";
  169. Xchar *latex_text_mappings[] = {
  170. X  "$\\backslash$",
  171. X  "$\\{$",
  172. X  "$\\}$",
  173. X  "$>$",
  174. X  "$<$",
  175. X  "\\^{}",
  176. X  "\\~{}",
  177. X  "\\$",
  178. X  "\\&",
  179. X  "\\#",
  180. X  "\\_",
  181. X  "\\%"};
  182. X
  183. X
  184. X/* Configurable parameters */
  185. Xint LowerLeftX=0, LowerLeftY=0;
  186. Xdouble SegLen = 0.0625; /* inch */
  187. Xint Verbose = FALSE;
  188. Xint TopMargin = 5;
  189. Xint BottomMargin = 10;
  190. Xint DotDist = 5;
  191. Xint LineThick = 2;
  192. Xint TeXLang = EEpic;
  193. Xdouble DashScale=1;
  194. Xint EllipseCmd=0;
  195. Xint UseBox=None;
  196. Xint DashType=Normal;
  197. Xchar *Preamble="\\documentstyle[epic,eepic]{article}\n\\begin{document}\n\\begin{center}\n";
  198. Xchar *Postamble="\\end{center}\n\\end{document}\n";
  199. Xint VarWidth=FALSE;
  200. X
  201. Xvoid genepic_option(opt, optarg)
  202. Xchar opt, *optarg;
  203. X{
  204. X      int loop;
  205. X
  206. X        switch (opt) {
  207. X        case 'S':
  208. X            loop = atoi(optarg);
  209. X            if (loop < 8 || loop > 12) {
  210. X                put_msg("Scale must be between 8 and 12 inclusively\n");
  211. X                exit(1);
  212. X            }
  213. X            loop -= 8;
  214. X            mag = ScaleTbl[loop].mag;
  215. X            font_size = ScaleTbl[loop].size;
  216. X            break;
  217. X
  218. X        case 'l':
  219. X            LineThick = atoi(optarg);
  220. X            break;
  221. X
  222. X        case 'v':
  223. X            Verbose = TRUE;
  224. X            break;
  225. X
  226. X    case 'L':
  227. X        for (loop=0; loop < 3; loop++) {
  228. X            if (stricmp(optarg, Tlangkw[loop]) == 0) break;
  229. X        }
  230. X        TeXLang = loop;
  231. X        break;
  232. X
  233. X    case 'w':
  234. X    case 'W':
  235. X        VarWidth = opt=='W';
  236. X        break;
  237. X
  238. X    case 'f':
  239. X    {   int i;
  240. X
  241. X        for ( i = 1; i <= MAXFONT + 1; i++ )
  242. X        if ( !strcmp(optarg, fontnames[i]) ) break;
  243. X
  244. X        if ( i > MAXFONT + 1 )
  245. X        fprintf(stderr,
  246. X            "warning: non-standard font name %s\n", optarg);
  247. X    }
  248. X    
  249. X            fontnames[0] = fontnames[1] = optarg;
  250. X        break;
  251. X
  252. X    case 's':
  253. X        if (font_size <= 0 || font_size > MAXFONTSIZE) {
  254. X        fprintf(stderr,
  255. X            "warning: font size %d out of bounds\n", font_size);
  256. X        }
  257. X        break;
  258. X
  259. X    case 'm':
  260. X        break;
  261. X
  262. X    default:
  263. X        put_msg(Err_badarg, opt, "epic");
  264. X        exit(1);
  265. X        break;
  266. X        }
  267. X}
  268. X
  269. Xstatic fconvertCS(fpt)
  270. XFPoint *fpt;
  271. X{
  272. X    if (CoordSys) {
  273. X        fpt->y = TopCoord - fpt->y;
  274. X    }
  275. X    fpt->x -= LLX;
  276. X    fpt->y -= LLY;
  277. X}
  278. X
  279. XconvertCS(pt)
  280. XF_point *pt;
  281. X{
  282. X    if (CoordSys) {
  283. X        pt->y = TopCoord - pt->y;
  284. X    }
  285. X    pt->x -= LLX;
  286. X    pt->y -= LLY;
  287. X}
  288. X
  289. Xvoid genepic_start(objects)
  290. XF_compound *objects;
  291. X{
  292. X    int temp;
  293. X    F_point pt1, pt2;
  294. X    F_arc *arc;
  295. X    F_compound *comp;
  296. X    F_ellipse *ell;
  297. X    F_line *line;
  298. X    F_spline *spl;
  299. X    F_text *text;
  300. X
  301. X    fontsizes[0] = fontsizes[1] = TEXFONTSIZE(font_size);
  302. X
  303. X    switch (TeXLang) {
  304. X    case Epic:
  305. X        EllipseCmd = 1; /* Oval */
  306. X        LnCmd = "drawline";
  307. X        break;
  308. X    case EEpic_emu:
  309. X    case EEpic:
  310. X        LnCmd = "path";
  311. X        break;
  312. X    default:
  313. X        put_msg("Program error in main\n");
  314. X        break;
  315. X    }
  316. X    if (PageMode) {
  317. X        fputs(Preamble, stdout);
  318. X    }
  319. X
  320. X    DPI = objects->nwcorner.x;
  321. X    if (DPI <= 0) {
  322. X        put_msg("Resolution has to be positive. Default to 80!\n");
  323. X        DPI = 80;
  324. X    }
  325. X    coord_system = objects->nwcorner.y;
  326. X    switch (coord_system) {
  327. X    case 1:
  328. X        CoordSys = 0;
  329. X        break;
  330. X    case 2:
  331. X        CoordSys = 1;
  332. X        break;
  333. X    default:
  334. X        put_msg("Unknown Coordinate system -- %d\n", coord_system);
  335. X        exit(1);
  336. X    }
  337. X    pt1.x = llx;
  338. X    pt1.y = lly;
  339. X    pt2.x = urx;
  340. X    pt2.y = ury;
  341. X    convertCS(&pt1);
  342. X    convertCS(&pt2);
  343. X    if (pt1.x > pt2.x) {
  344. X        temp = pt1.x;
  345. X        pt1.x = pt2.x;
  346. X        pt2.x = temp;
  347. X    }
  348. X    if (pt1.y > pt2.y) {
  349. X        temp = pt1.y;
  350. X        pt1.y = pt2.y;
  351. X        pt2.y = temp;
  352. X    }
  353. X    LLX = pt1.x - LowerLeftX;
  354. X    LLY = pt1.y - LowerLeftY;
  355. X    if (Verbose) {
  356. X        fprintf(tfp, "%%\n%% Language in use is %s\n%%\n", Tlangkw[TeXLang]);
  357. X    }
  358. X    Threshold = 1.0 / DPI * mag;
  359. X    fprintf(tfp, "\\setlength{\\unitlength}{%.4fin}\n", Threshold);
  360. X    MaxCircleRadius = (int) (40 / 72.27 / Threshold);
  361. X    Threshold = SegLen / Threshold;
  362. X    fprintf(tfp, "\\begin{picture}(%d,%d)(%d,%d)\n",
  363. X           pt2.x-pt1.x, pt2.y-pt1.y + TopMargin + BottomMargin,
  364. X           LowerLeftX, LowerLeftY-BottomMargin);
  365. X}
  366. X
  367. Xvoid genepic_end()
  368. X{
  369. X    fprintf(tfp, "\\end{picture}\n");
  370. X    if (PageMode)
  371. X        fputs(Postamble, stdout);
  372. X}
  373. X
  374. Xstatic set_linewidth(w)
  375. Xint w;
  376. X{
  377. X    int old_width;
  378. X
  379. X    if (w < 0) return;
  380. X    old_width=CurWidth;
  381. X    CurWidth = (w >= LineThick) ? (VarWidth ? w : ThickLines) : ThinLines;
  382. X    if (old_width != CurWidth) {
  383. X    if (CurWidth==ThinLines) {
  384. X        fprintf(tfp, "\\thinlines\n");
  385. X    } else if (VarWidth) {
  386. X        fprintf(tfp, "\\allinethickness{%d}%%\n",w);
  387. X    } else {
  388. X        fprintf(tfp, "\\thicklines\n");
  389. X    }
  390. X    }
  391. X}
  392. X
  393. Xset_pattern(type)
  394. XF_pattern *type;
  395. X{
  396. X    static unsigned long patterns[3][32] = {
  397. X    { 0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0,
  398. X      0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0,
  399. X      0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0,
  400. X      0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0},
  401. X    { 0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0,
  402. X      0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0,
  403. X      0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0,
  404. X      0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0},
  405. X    { 0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0,
  406. X      0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0,
  407. X      0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0,
  408. X      0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0}};
  409. X    int count, loop1, loop2, i;
  410. X
  411. X    if (type < DARK_GRAY_FILL || type > LIGHT_GRAY_FILL) return;
  412. X    if (type != PatternType) {
  413. X    PatternType=type;
  414. X    i = (int) PatternType - (int) DARK_GRAY_FILL;
  415. X    fprintf(tfp, "\\texture{");
  416. X    count=0;
  417. X    for (loop1=4; loop1>0;) {
  418. X        for (loop2=8; loop2>0; loop2--) 
  419. X        fprintf(tfp, "%lx ", patterns[i][count++]);
  420. X        if (--loop1 > 0)
  421. X        fprintf(tfp, "\n\t");
  422. X        else
  423. X        fprintf(tfp, "}%\n");
  424. X    }
  425. X    }
  426. X}
  427. X
  428. Xvoid genepic_line(line)
  429. XF_line *line;
  430. X{
  431. X    F_point *p, *q;
  432. X    int pt_count = 0, temp;
  433. X    int boxflag = FALSE, llx, lly, urx, ury;
  434. X    double dtemp;
  435. X
  436. X    set_linewidth(line->thickness);
  437. X    set_style(line->style, line->style_val);
  438. X    p = line->points;
  439. X    q = p->next;
  440. X    convertCS(p);
  441. X    if (q == NULL) {
  442. X    fprintf(tfp, "\\drawline(%d,%d)(%d,%d)\n", p->x, p->y, p->x, p->y);
  443. X    return;
  444. X    }
  445. X    if (line->type == T_BOX) {
  446. X    if (Verbose) {
  447. X        fprintf(tfp, "%%\n%% A box\n%%\n");
  448. X    }
  449. X    switch (LineStyle) {
  450. X    case SOLID_LINE:
  451. X        if (UseBox == BothBoxType || UseBox == SolidLineBox) {
  452. X            boxflag = TRUE;
  453. X        }
  454. X        break;
  455. X    case DASH_LINE:
  456. X        if (UseBox == BothBoxType || UseBox == DashLineBox) {
  457. X            boxflag = TRUE;
  458. X        }
  459. X        break;
  460. X    }
  461. X    if (boxflag) {
  462. X        llx = urx = p->x;
  463. X        lly = ury = p->y;
  464. X        while (q != NULL) {
  465. X            convertCS(q);
  466. X            if (q->x < llx) {
  467. X                llx = q->x;
  468. X            } else if (q->x > urx) {
  469. X                urx = q->x;
  470. X            }
  471. X            if (q->y < lly) {
  472. X                lly = q->y;
  473. X            } else if (q->y > ury) {
  474. X                ury = q->y;
  475. X            }
  476. X            q = q->next;
  477. X        }
  478. X        switch(LineStyle) {
  479. X        case SOLID_LINE:
  480. X            fprintf(tfp, "\\put(%d,%d){\\framebox(%d,%d){}}\n",
  481. X                llx, lly, urx-llx, ury-lly);
  482. X            break;
  483. X        case DASH_LINE:
  484. X        temp = (int) ((urx-llx) / DashLen);
  485. X        dtemp = (double) (urx-llx) / temp;
  486. X            fprintf(tfp, "\\put(%d,%d){\\dashbox{%4.3f}(%d,%d){}}\n",
  487. X                llx, lly, dtemp , urx-llx, ury-lly);
  488. X            break;
  489. X        default:
  490. X            put_msg("Program Error! No other line styles allowed.\n");
  491. X            break;
  492. X        }
  493. X        return;
  494. X      }
  495. X    }
  496. X    set_pattern(line->area_fill);
  497. X    convertCS(q);
  498. X    if (line->back_arrow) {
  499. X    draw_arrow_head(q, p, line->back_arrow->ht, line->back_arrow->wid);
  500. X        if (Verbose) fprintf(tfp, "%%\n");
  501. X    }
  502. X    switch (LineStyle) {
  503. X    case SOLID_LINE:
  504. X    if (q->next != NULL && strcmp(LnCmd,"path")==0) {
  505. X        if (line->area_fill < UNFILLED) line->area_fill = UNFILLED;
  506. X        fprintf(tfp, "%s", FillCommands[(int) line->area_fill]);
  507. X    }
  508. X    fprintf(tfp, "\\%s", LnCmd);
  509. X#ifdef DrawOutLine
  510. X    if (line->area_fill != UNFILLED && OutLine == 0) OutLine=1;
  511. X#endif
  512. X    break;
  513. X    case DASH_LINE:
  514. X        if ((TeXLang==Epic || TeXLang ==EEpic_emu) && DashType == Economic) {
  515. X            fprintf(tfp, "\\drawline[-50]");
  516. X        } else {
  517. X        fprintf(tfp, "\\dashline{%4.3f}", DashLen);
  518. X    }
  519. X    break;
  520. X    case DOTTED_LINE:
  521. X    fprintf(tfp, "\\dottedline{%d}", DotDist);
  522. X    break;
  523. X    default:
  524. X    fprintf(stderr,"Unknown Style\n");
  525. X    exit(1);
  526. X    }
  527. X    fprintf(tfp, "(%d,%d)", p->x, p->y);
  528. X    pt_count++;
  529. X    while(q->next != NULL) {
  530. X    if (++pt_count > PtPerLine) {
  531. X        pt_count=1;
  532. X        fprintf(tfp, "\n\t");
  533. X    }
  534. X    fprintf(tfp, "(%d,%d)", q->x, q->y);
  535. X    p=q;
  536. X    q = q->next;
  537. X    convertCS(q);
  538. X    }
  539. X    fprintf(tfp, "(%d,%d)\n", q->x, q->y);
  540. X#ifdef DrawOutLine
  541. X    if (OutLine == 1) {
  542. X    OutLine=0;
  543. X    fprintf(tfp, "\\%s", LnCmd);
  544. X    p=line->points;
  545. X    pt_count=0;
  546. X    q=p->next;
  547. X    fprintf(tfp, "(%d,%d)", p->x, p->y);
  548. X    pt_count++;
  549. X    while(q->next != NULL) {
  550. X        if (++pt_count > PtPerLine) {
  551. X        pt_count=1;
  552. X        fprintf(tfp, "\n\t");
  553. X        }
  554. X        fprintf(tfp, "(%d,%d)", q->x, q->y);
  555. X        p=q;
  556. X        q = q->next;
  557. X    }
  558. X    fprintf(tfp, "(%d,%d)\n", q->x, q->y);
  559. X    }
  560. X#endif
  561. X    if (line->for_arrow) {
  562. X    draw_arrow_head(p, q, line->for_arrow->ht, line->for_arrow->wid);
  563. X        if (Verbose) fprintf(tfp, "%%\n");
  564. X    }
  565. X}
  566. X
  567. Xset_style(style, dash_len)
  568. Xint style;
  569. Xfloat dash_len;
  570. X{
  571. X    LineStyle = style;
  572. X    if (LineStyle == DASH_LINE) {
  573. X        switch (DashType) {
  574. X        case DottedDash:
  575. X            LineStyle = DOTTED_LINE;
  576. X            break;
  577. X        default:
  578. X            DashLen = dash_len * DashScale;
  579. X            break;
  580. X        }
  581. X    }
  582. X}
  583. X
  584. X
  585. Xvoid genepic_spline(spl)
  586. XF_spline *spl;
  587. X{
  588. X    set_linewidth(spl->thickness);
  589. X    set_style(SOLID_LINE, 0.0);
  590. X    if (int_spline(spl)) {
  591. X    genepic_itp_spline(spl);
  592. X    } else {
  593. X    genepic_ctl_spline(spl);
  594. X    }
  595. X}
  596. X
  597. Xvoid genepic_ctl_spline(spl)
  598. XF_spline *spl;
  599. X{
  600. X    if (closed_spline(spl)) {
  601. X    genepic_closed_spline(spl);
  602. X    } else {
  603. X    genepic_open_spline(spl);
  604. X    }
  605. X}
  606. X
  607. Xstatic void genepic_open_spline(spl)
  608. XF_spline *spl;
  609. X{
  610. X    F_point *p, *q, *r;
  611. X    FPoint first, mid;
  612. X    int pt_count = 0;
  613. X
  614. X    p = spl->points;
  615. X    q = p->next;
  616. X    convertCS(p);
  617. X    convertCS(q);
  618. X    if (spl->back_arrow) {
  619. X    draw_arrow_head(q, p, spl->back_arrow->ht, spl->back_arrow->wid);
  620. X        if (Verbose) fprintf(tfp, "%%\n");
  621. X    }
  622. X    if (q->next == NULL) {
  623. X    fprintf(tfp, "\\%s(%d,%d)(%d,%d)\n", LnCmd,
  624. X           p->x, p->y, q->x, q->y);
  625. X    return;
  626. X    }
  627. X    if (TeXLang == EEpic || TeXLang == EEpic_emu) {
  628. X        fprintf(tfp, "\\spline(%d,%d)\n", p->x, p->y);
  629. X        pt_count++;
  630. X        while(q->next != NULL) {
  631. X             if (++pt_count > PtPerLine) {
  632. X                 pt_count=1;
  633. X                 fprintf(tfp, "\n\t");
  634. X             }
  635. X             fprintf(tfp, "(%d,%d)", q->x, q->y);
  636. X             p=q;
  637. X             q = q->next;
  638. X             convertCS(q);
  639. X        }
  640. X        fprintf(tfp, "(%d,%d)\n", q->x, q->y);
  641. X    } else {
  642. X        fprintf(tfp, "\\%s(%d,%d)\n", LnCmd, p->x, p->y);
  643. X        r = q->next;
  644. X        convertCS(r);
  645. X        first.x = p->x;
  646. X        first.y = p->y;
  647. X        while (r->next != NULL) {
  648. X            mid.x = (q->x + r->x) / 2.0;
  649. X            mid.y = (q->y + r->y) / 2.0;
  650. X            chaikin_curve(first.x, first.y, (double) q->x, (double) q->y,
  651. X                            mid.x, mid.y);
  652. X            first = mid;
  653. X            q=r;
  654. X            r = r->next;
  655. X            convertCS(r);
  656. X        }
  657. X        chaikin_curve(first.x, first.y, (double) q->x, (double) q->y,
  658. X                        (double) r->x, (double) r->y);
  659. X        p=q;
  660. X        q=r;
  661. X    fprintf(tfp, "\n");
  662. X    }
  663. X    if (spl->for_arrow) {
  664. X    draw_arrow_head(p, q, spl->for_arrow->ht, spl->for_arrow->wid);
  665. X        if (Verbose) fprintf(tfp, "%%\n");
  666. X    }
  667. X}
  668. X
  669. Xstatic void genepic_closed_spline(spl)
  670. XF_spline *spl;
  671. X{
  672. X    F_point *p;
  673. X    double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
  674. X    double x1, y1, x2, y2;
  675. X
  676. X    p = spl->points;
  677. X    convertCS(p);
  678. X    x1 = p->x;  y1 = p->y;
  679. X    p = p->next;
  680. X    convertCS(p);
  681. X    x2 = p->x;  y2 = p->y;
  682. X    cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
  683. X    cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
  684. X    for (p = p->next; p != NULL; p = p->next) {
  685. X    fprintf(tfp, "\\%s(%.3f,%.3f)", LnCmd, cx1, cy1);
  686. X    x1 = x2;  y1 = y2;
  687. X    convertCS(p);
  688. X    x2 = p->x;  y2 = p->y;
  689. X    cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
  690. X    cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
  691. X    quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
  692. X    fprintf(tfp, "\n");
  693. X    cx1 = cx4;  cy1 = cy4;
  694. X    cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
  695. X    }
  696. X    x1 = x2;  y1 = y2;
  697. X    p = spl->points->next;
  698. X    x2 = p->x;  y2 = p->y;
  699. X    cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
  700. X    cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
  701. X    fprintf(tfp, "\\%s(%.3f,%.3f)", LnCmd, cx1, cy1);
  702. X    quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
  703. X    fprintf(tfp, "\n");
  704. X}
  705. X
  706. Xchaikin_curve(a1, b1, a2, b2, a3, b3)
  707. Xdouble a1, b1, a2, b2, a3, b3;
  708. X{
  709. X    double xm1, xmid, xm2, ym1, ymid, ym2;
  710. X
  711. X    if (fabs(a1-a3) < Threshold && fabs(b1-b3) < Threshold) {
  712. X        fprintf(tfp, "\t(%.3f,%.3f)\n", a3, b3);
  713. X    } else {
  714. X        xm1 = (a1 + a2) / 2;
  715. X        ym1 = (b1 + b2) / 2;
  716. X        xm2 = (a2 + a3) / 2;
  717. X        ym2 = (b2 + b3) / 2;
  718. X        xmid = (xm1 + xm2) / 2;
  719. X        ymid = (ym1 + ym2) / 2;
  720. X        chaikin_curve(a1, b1, xm1, ym1, xmid, ymid);
  721. X        chaikin_curve(xmid, ymid, xm2, ym2, a3, b3);
  722. X    }
  723. X}
  724. X
  725. Xstatic quadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4)
  726. Xdouble    a1, b1, a2, b2, a3, b3, a4, b4;
  727. X{
  728. X    double    x1, y1, x4, y4;
  729. X    double    xmid, ymid;
  730. X
  731. X    x1 = a1; y1 = b1;
  732. X    x4 = a4; y4 = b4;
  733. X
  734. X    xmid = (a2 + a3) / 2;
  735. X    ymid = (b2 + b3) / 2;
  736. X    if (fabs(x1 - xmid) < Threshold && fabs(y1 - ymid) < Threshold) {
  737. X    fprintf(tfp, "\t(%.3f,%.3f)\n", xmid, ymid);
  738. X    } else {
  739. X    quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2),
  740. X             ((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid);
  741. X    }
  742. X
  743. X    if (fabs(xmid - x4) < Threshold && fabs(ymid - y4) < Threshold) {
  744. X    fprintf(tfp, "\t(%.3f,%.3f)\n", x4, y4);
  745. X    } else {
  746. X    quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4),
  747. X             ((a3+x4)/2), ((b3+y4)/2), x4, y4);
  748. X    }
  749. X}
  750. X
  751. Xgenepic_itp_spline(spl)
  752. XF_spline *spl;
  753. X{
  754. X    F_point *p1, *p2;
  755. X    FPoint pt1l, pt1r, pt2l, pt2r, tmpfpt;
  756. X    F_control *cp1, *cp2;
  757. X
  758. X    p1 = spl->points;
  759. X    convertCS(p1);
  760. X    cp1 = spl->controls;
  761. X    pt1l.x = cp1->lx;
  762. X    pt1l.y = cp1->ly;
  763. X    pt1r.x = cp1->rx;
  764. X    pt1r.y = cp1->ry;
  765. X    fconvertCS(&pt1l);
  766. X    fconvertCS(&pt1r);
  767. X
  768. X    if (spl->back_arrow) {
  769. X    tmpfpt.x = p1->x;
  770. X    tmpfpt.y = p1->y;
  771. X    fdraw_arrow_head(&pt1r, &tmpfpt, 
  772. X        spl->back_arrow->ht, spl->back_arrow->wid);
  773. X        if (Verbose) fprintf(tfp, "%%\n");
  774. X    }
  775. X
  776. X    for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
  777. X     p1 = p2, pt1r = pt2r, p2 = p2->next, cp2 = cp2->next) {
  778. X    fprintf(tfp, "\\%s(%d,%d)", LnCmd, p1->x, p1->y);
  779. X    convertCS(p2);
  780. X    pt2l.x = cp2->lx;
  781. X    pt2l.y = cp2->ly;
  782. X    pt2r.x = cp2->rx;
  783. X    pt2r.y = cp2->ry;
  784. X    fconvertCS(&pt2l);
  785. X    fconvertCS(&pt2r);
  786. X    bezier_spline((double) p1->x, (double) p1->y,
  787. X              pt1r.x, pt1r.y,
  788. X              pt2l.x, pt2l.y,
  789. X              (double) p2->x, (double) p2->y);
  790. X    fprintf(tfp, "\n");
  791. X    }
  792. X
  793. X    if (spl->for_arrow) {
  794. X    tmpfpt.x = p1->x;
  795. X    tmpfpt.y = p1->y;
  796. X    fdraw_arrow_head(&pt2l, &tmpfpt, 
  797. X             spl->for_arrow->ht, spl->for_arrow->wid);
  798. X    if (Verbose) fprintf(tfp, "%%\n");
  799. X    }
  800. X}
  801. X
  802. Xstatic bezier_spline(a0, b0, a1, b1, a2, b2, a3, b3)
  803. Xdouble    a0, b0, a1, b1, a2, b2, a3, b3;
  804. X{
  805. X    double    x0, y0, x3, y3;
  806. X    double    sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid;
  807. X
  808. X    x0 = a0; y0 = b0;
  809. X    x3 = a3; y3 = b3;
  810. X    if (fabs(x0 - x3) < Threshold && fabs(y0 - y3) < Threshold) {
  811. X    fprintf(tfp, "\t(%.3f,%.3f)\n", x3, y3);
  812. X    } else {
  813. X    tx = (a1 + a2) / 2;        ty = (b1 + b2) / 2;
  814. X    sx1 = (x0 + a1) / 2;    sy1 = (y0 + b1) / 2;
  815. X    sx2 = (sx1 + tx) / 2;    sy2 = (sy1 + ty) / 2;
  816. X    tx2 = (a2 + x3) / 2;    ty2 = (b2 + y3) / 2;
  817. X    tx1 = (tx2 + tx) / 2;    ty1 = (ty2 + ty) / 2;
  818. X    xmid = (sx2 + tx1) / 2;    ymid = (sy2 + ty1) / 2;
  819. X
  820. X    bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid);
  821. X    bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3);
  822. X    }
  823. X}
  824. X
  825. Xvoid genepic_ellipse(ell)
  826. XF_ellipse *ell;
  827. X{
  828. X    F_point pt;
  829. X
  830. X    set_linewidth(ell->thickness);
  831. X    pt.x = ell->center.x;
  832. X    pt.y = ell->center.y;
  833. X    convertCS(&pt);
  834. X    if (TeXLang == EEpic || TeXLang == EEpic_emu ||
  835. X      ell->radiuses.x != ell->radiuses.y ||
  836. X          ell->radiuses.x > MaxCircleRadius) {
  837. X    set_pattern(ell->area_fill);
  838. X        fprintf(tfp, "\\put(%d,%d){", pt.x, pt.y );
  839. X#ifndef OLDCODE
  840. X        if (EllipseCmd == 0) {
  841. X        if (ell->area_fill < UNFILLED) ell->area_fill = UNFILLED;
  842. X        fprintf(tfp, "%s", FillCommands[(int) ell->area_fill]);
  843. X#  ifdef DrawOutLine
  844. X        if (ell->area_fill != UNFILLED && OutLine == 0) OutLine = 1;
  845. X#  endif
  846. X        }
  847. X     fprintf(tfp, EllCmdstr[EllipseCmd],EllCmdkw[EllipseCmd], "",
  848. X           2 * ell->radiuses.x, 2 * ell->radiuses.y);
  849. X#  ifdef DrawOutLine
  850. X    if (OutLine == 1) {
  851. X        OutLine=0;
  852. X            fprintf(tfp, "\\put(%d,%d){", pt.x, pt.y );
  853. X        fprintf(tfp, EllCmdstr[EllipseCmd],EllCmdkw[EllipseCmd], "",
  854. X           2 * ell->radiuses.x, 2 * ell->radiuses.y);
  855. X    }
  856. X#  endif
  857. X#else
  858. X    fprintf(tfp, EllCmdstr[EllipseCmd], EllCmdkw[EllipseCmd],
  859. X           (EllipseCmd==0 && ell->area_fill==BLACK_FILL ? "*" : ""),
  860. X           2 * ell->radiuses.x, 2 * ell->radiuses.y);
  861. X#endif
  862. X    } else {
  863. X        fprintf(tfp, "\\put(%d,%d){\\circle", pt.x, pt.y);
  864. X        if (ell->area_fill == BLACK_FILL) {
  865. X            fputc('*', tfp);
  866. X        }
  867. X        fprintf(tfp, "{%d}}\n", 2*ell->radiuses.x);
  868. X    }
  869. X}
  870. X
  871. Xvoid genepic_text(text)
  872. XF_text *text;
  873. X{
  874. X    F_point pt;
  875. X    char *tpos, *cp, *esc_cp, *special_index;
  876. X
  877. X    pt.x=text->base_x;
  878. X    pt.y=text->base_y;
  879. X    convertCS(&pt);
  880. X    switch (text->type) {
  881. X    case T_LEFT_JUSTIFIED:
  882. X    case DEFAULT:
  883. X    tpos = "[lb]";
  884. X    break;
  885. X    case T_CENTER_JUSTIFIED:
  886. X    tpos = "[b]";
  887. X    break;
  888. X    case T_RIGHT_JUSTIFIED:
  889. X    tpos = "[rb]";
  890. X    break;
  891. X    default:
  892. X    fprintf(stderr, "unknown text position type\n");
  893. X    exit(1);
  894. X    }
  895. X    fprintf(tfp, "\\put(%d,%d){\\makebox(0,0)%s{\\raisebox{0pt}[0pt][0pt]{",
  896. X           pt.x, pt.y, tpos);
  897. X    /* Output a shortstack in case there are multiple lines. */
  898. X    fprintf(tfp, "\\shortstack" );
  899. X    /* Output the justification for the shortstack. */
  900. X    switch (text->type) {
  901. X    case T_LEFT_JUSTIFIED:
  902. X    case DEFAULT:
  903. X    fprintf(tfp, "[l]");
  904. X    break;
  905. X    case T_CENTER_JUSTIFIED:
  906. X    break;
  907. X    case T_RIGHT_JUSTIFIED:
  908. X    fprintf(tfp, "[r]");
  909. X    break;
  910. X    default:
  911. X    fprintf(stderr, "unknown text position type\n");
  912. X    exit(1);
  913. X    }
  914. X    fprintf(tfp, "{{\\%s%s ", TEXFONTSIZE(text->size), TEXFONT(text->font));
  915. X    if (text->font && text->font != DEFAULT_FONT)
  916. X    /* This loop escapes special LaTeX characters. */
  917. X    for(cp = text->cstring; *cp; cp++) {
  918. X              if (special_index=strchr(latex_text_specials, *cp)) {
  919. X          /* Write out the replacement.  Implementation note: we can't
  920. X         use puts since that will output an additional newline. */
  921. X          esc_cp=latex_text_mappings[special_index-latex_text_specials];
  922. X          while (*esc_cp)
  923. X        fputc(*esc_cp++, tfp);
  924. X        }
  925. X        else if (*cp == TEXT_LINE_SEP) {
  926. X          /* Handle multi-line text strings. The problem being addressed here
  927. X         is a LaTeX bug where LaTeX is unable to handle a font which
  928. X         spans multiple lines.  What we are doing here is closing off
  929. X         the current font, starting a new line, and then resuming with
  930. X         the current font. */
  931. X          fprintf(tfp, "} \\\\\n");
  932. X          fprintf(tfp, "{\\%s%s ", TEXFONTSIZE(text->size), TEXFONT(text->font));
  933. X        }
  934. X        else
  935. X        fputc(*cp, tfp);
  936. X          }
  937. X    else 
  938. X    for(cp = text->cstring; *cp; cp++) {
  939. X      if (*cp == TEXT_LINE_SEP) {
  940. X          /* Handle multi-line text strings. */
  941. X          fprintf(tfp, "} \\\\\n");
  942. X          fprintf(tfp, "{\\%s%s ", TEXFONTSIZE(text->size), TEXFONT(text->font));
  943. X        }
  944. X        else 
  945. X          fputc(*cp, tfp);
  946. X      }
  947. X    fprintf(tfp, "}}}}}\n");
  948. X}
  949. X
  950. Xvoid genepic_arc(arc)
  951. XF_arc *arc;
  952. X{
  953. X    FPoint pt1, pt2, ctr, tmp;
  954. X    double r1, r2, th1, th2, theta;
  955. X    double dx1, dy1, dx2, dy2;
  956. X    double arrowfactor;
  957. X
  958. X    ctr.x = arc->center.x;
  959. X    ctr.y = arc->center.y;
  960. X    pt1.x = arc->point[0].x;
  961. X    pt1.y = arc->point[0].y;
  962. X    pt2.x = arc->point[2].x;
  963. X    pt2.y = arc->point[2].y;
  964. X    fconvertCS(&ctr);
  965. X    fconvertCS(&pt1);
  966. X    fconvertCS(&pt2);
  967. X
  968. X    dx1 = pt1.x - ctr.x;
  969. X    dy1 = pt1.y - ctr.y;
  970. X    dx2 = pt2.x - ctr.x;
  971. X    dy2 = pt2.y - ctr.y;
  972. X
  973. X    rtop(dx1, dy1, &r1, &th1);
  974. X    rtop(dx2, dy2, &r2, &th2);
  975. X    arrowfactor = (r1+r2) / 30.0;
  976. X    if (arrowfactor > 1) arrowfactor = 1;
  977. X    set_linewidth(arc->thickness);
  978. X    if (arc->for_arrow) {
  979. X    arc_tangent(&ctr, &pt2, arc->direction, &tmp);
  980. X    fdraw_arrow_head(&tmp, &pt2,
  981. X             arc->for_arrow->ht*arrowfactor,
  982. X             arc->for_arrow->wid*arrowfactor);
  983. X        if (Verbose) fprintf(tfp, "%%\n");
  984. X    }
  985. X    if (arc->back_arrow) {
  986. X    arc_tangent(&ctr, &pt1, !arc->direction, &tmp);
  987. X    fdraw_arrow_head(&tmp, &pt1,
  988. X             arc->back_arrow->ht*arrowfactor,
  989. X             arc->back_arrow->wid*arrowfactor);
  990. X        if (Verbose) fprintf(tfp, "%%\n");
  991. X    }
  992. X    if (TeXLang == EEpic) {
  993. X    set_pattern(arc->area_fill);
  994. X        fprintf(tfp, "\\put(%4.3lf,%4.3lf){", ctr.x, ctr.y);
  995. X    } else {
  996. X    fprintf(tfp, "\\drawline");
  997. X    }
  998. X    if (TeXLang == EEpic) {
  999. X    if (arc->area_fill < UNFILLED) arc->area_fill = UNFILLED;
  1000. X    fprintf(tfp, "%s", FillCommands[(int) arc->area_fill]);
  1001. X#ifdef DrawOutLine
  1002. X    if (arc->area_fill != UNFILLED && OutLine==0) OutLine=1;
  1003. X#endif
  1004. X    }
  1005. X    if (arc->direction) {
  1006. X    theta = th2 - th1;
  1007. X    if (theta < 0) theta += 2 * M_PI;
  1008. X    th2 = 2*M_PI-th2;
  1009. X    if (TeXLang == EEpic) {
  1010. X        fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r1, th2, th2+theta);
  1011. X#ifdef DrawOutLine
  1012. X        if (OutLine==1) {
  1013. X        OutLine=0;
  1014. X            fprintf(tfp, "\\put(%4.3lf,%4.3lf){", ctr.x, ctr.y);
  1015. X        fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r1, th2, th2+theta);
  1016. X        }
  1017. X#endif
  1018. X        } else {
  1019. X            drawarc(&ctr, r1, 2*M_PI - th2 - theta, theta);
  1020. X        }
  1021. X    } else {
  1022. X    theta = th1 - th2;
  1023. X    if (theta < 0) theta += 2 * M_PI;
  1024. X    th1 = 2*M_PI-th1;
  1025. X    if (TeXLang == EEpic) {
  1026. X        fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r2, th1, th1+theta);
  1027. X#ifdef DrawOutLine
  1028. X        if (OutLine==1) {
  1029. X        OutLine=0;
  1030. X        fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r2, th1, th1+theta);
  1031. X        }
  1032. X#endif
  1033. X        } else {
  1034. X            drawarc(&ctr, r2, 2*M_PI - th1 - theta, theta);
  1035. X        }
  1036. X    }
  1037. X}
  1038. X
  1039. Xdrawarc(ctr, r, th1, angle)
  1040. XFPoint *ctr;
  1041. Xdouble r, th1, angle;
  1042. X{
  1043. X    double arclength, delta;
  1044. X    int division, pt_count = 0;
  1045. X
  1046. X
  1047. X    division = angle * r / Threshold;
  1048. X    delta = angle / division;
  1049. X    division++;
  1050. X    while (division-- > 0) {
  1051. X        if (++pt_count > PtPerLine) {
  1052. X            fprintf(tfp, "\n\t");
  1053. X            pt_count = 1;
  1054. X        }
  1055. X        fprintf(tfp, "(%.3lf,%.3lf)", ctr->x + cos(th1) * r,
  1056. X                                ctr->y + sin(th1) * r);
  1057. X        th1 += delta;
  1058. X    }
  1059. X    fprintf(tfp, "\n");
  1060. X}
  1061. X
  1062. Xstatic arc_tangent(pt1, pt2, direction, pt3)
  1063. XFPoint *pt1, *pt2, *pt3;
  1064. Xint direction;
  1065. X{
  1066. X    if (direction) {
  1067. X    pt3->x = pt2->x + (pt2->y - pt1->y);
  1068. X    pt3->y = pt2->y - (pt2->x - pt1->x);
  1069. X    } else {
  1070. X    pt3->x = pt2->x - (pt2->y - pt1->y);
  1071. X    pt3->y = pt2->y + (pt2->x - pt1->x);
  1072. X    }
  1073. X}
  1074. X
  1075. Xrtop(x, y, r, th)
  1076. Xdouble x, y, *r, *th;
  1077. X{
  1078. X    *r = hypot(x,y);
  1079. X    *th = acos(x/(*r));
  1080. X    if (*th < 0) *th = M_PI + *th;
  1081. X    if (y < 0) *th = 2*M_PI - *th;
  1082. X}
  1083. X
  1084. Xstatic draw_arrow_head(pt1, pt2, arrowht, arrowwid)
  1085. XF_point *pt1, *pt2;
  1086. Xdouble arrowht, arrowwid;
  1087. X{
  1088. X    FPoint fpt1, fpt2;
  1089. X
  1090. X    fpt1.x = pt1->x;
  1091. X    fpt1.y = pt1->y;
  1092. X    fpt2.x = pt2->x;
  1093. X    fpt2.y = pt2->y;
  1094. X    fdraw_arrow_head(&fpt1, &fpt2, arrowht, arrowwid);
  1095. X}
  1096. X
  1097. Xfdraw_arrow_head(pt1, pt2, arrowht, arrowwid)
  1098. XFPoint *pt1, *pt2;
  1099. Xdouble arrowht, arrowwid;
  1100. X{
  1101. X    double x1, y1, x2, y2;
  1102. X    double x,y, xb,yb,dx,dy,l,sina,cosa;
  1103. X    double xc, yc, xd, yd;
  1104. X
  1105. X    x1 = pt1->x;
  1106. X    y1 = pt1->y;
  1107. X    x2 = pt2->x;
  1108. X    y2 = pt2->y;
  1109. X
  1110. X    if (Verbose) fprintf(tfp, "%%\n%% arrow head\n%%\n");
  1111. X
  1112. X    dx = x2 - x1;  dy = y1 - y2;
  1113. X    l = hypot(dx,dy);
  1114. X    sina = dy / l;  cosa = dx / l;
  1115. X    xb = x2*cosa - y2*sina;
  1116. X    yb = x2*sina + y2*cosa;
  1117. X    x = xb - arrowht;
  1118. X    y = yb - arrowwid / 2;
  1119. X    xc = x*cosa + y*sina;
  1120. X    yc = -x*sina + y*cosa;
  1121. X    y = yb + arrowwid / 2;
  1122. X    xd = x*cosa + y*sina;
  1123. X    yd = -x*sina + y*cosa;
  1124. X
  1125. X    fprintf(tfp, "\\%s(%4.3f,%4.3f)(%4.3f,%4.3f)(%4.3f,%4.3f)\n", LnCmd,
  1126. X        xc, yc, x2, y2, xd, yd);
  1127. X}
  1128. X
  1129. X#ifndef MSDOS
  1130. Xstricmp(s, t)
  1131. Xchar *s, *t;
  1132. X{
  1133. X    char a, b;
  1134. X
  1135. X    for (;;) {
  1136. X        a= *s++; b= *t++;
  1137. X        a = islower(a) ? toupper(a) : a;
  1138. X        b = islower(b) ? toupper(b) : b;
  1139. X        if (a != b) break;
  1140. X        if (a == '\0') return(0);
  1141. X    }
  1142. X    return(a - b);
  1143. X}
  1144. X#endif
  1145. X
  1146. Xstruct driver dev_epic = {
  1147. X         genepic_option,
  1148. X    genepic_start,
  1149. X    genepic_arc,
  1150. X    genepic_ellipse,
  1151. X    genepic_line,
  1152. X    genepic_spline,
  1153. X    genepic_text,
  1154. X    genepic_end,
  1155. X    INCLUDE_TEXT
  1156. X};
  1157. END_OF_FILE
  1158. if test 28053 -ne `wc -c <'transfig/fig2dev/dev/genepic.c'`; then
  1159.     echo shar: \"'transfig/fig2dev/dev/genepic.c'\" unpacked with wrong size!
  1160. fi
  1161. # end of 'transfig/fig2dev/dev/genepic.c'
  1162. fi
  1163. echo shar: End of archive 5 \(of 6\).
  1164. cp /dev/null ark5isdone
  1165. MISSING=""
  1166. for I in 1 2 3 4 5 6 ; do
  1167.     if test ! -f ark${I}isdone ; then
  1168.     MISSING="${MISSING} ${I}"
  1169.     fi
  1170. done
  1171. if test "${MISSING}" = "" ; then
  1172.     echo You have unpacked all 6 archives.
  1173.     rm -f ark[1-9]isdone
  1174. else
  1175.     echo You still need to unpack the following archives:
  1176.     echo "        " ${MISSING}
  1177. fi
  1178. ##  End of shell archive.
  1179. exit 0
  1180. -- 
  1181. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  1182. Use a domain-based address or give alternate paths, or you may lose out.
  1183.