home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / transfig-2.1.8 / part07 < prev    next >
Text File  |  1993-10-05  |  64KB  |  2,326 lines

  1. Newsgroups: comp.sources.unix
  2. From: envbvs@epb12.lbl.gov (Brian V. Smith)
  3. Subject: v27i061: transfig-2.1.8 - a set of tools for creating TeX documents with graphics, Part07/07
  4. References: <1.749903574.10622@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: envbvs@epb12.lbl.gov (Brian V. Smith)
  9. Posting-Number: Volume 27, Issue 61
  10. Archive-Name: transfig-2.1.8/part07
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 7 (of 7)."
  19. # Contents:  fig2dev/dev/genepic.c fig2dev/dev/genps.c
  20. # Wrapped by envbvs@epb12.lbl.gov.lbl.gov on Fri Oct  1 14:55:51 1993
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'fig2dev/dev/genepic.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'fig2dev/dev/genepic.c'\"
  24. else
  25. echo shar: Extracting \"'fig2dev/dev/genepic.c'\" \(30473 characters\)
  26. sed "s/^X//" >'fig2dev/dev/genepic.c' <<'END_OF_FILE'
  27. X/*
  28. X * TransFig: Facility for Translating Fig code
  29. X * Copyright (c) 1985 Supoj Sutantavibul
  30. X * Copyright (c) 1991 Micah Beck
  31. X *
  32. X * Permission to use, copy, modify, distribute, and sell this software and its
  33. X * documentation for any purpose is hereby granted without fee, provided that
  34. X * the above copyright notice appear in all copies and that both that
  35. X * copyright notice and this permission notice appear in supporting
  36. X * documentation. The authors make no representations about the suitability 
  37. X * of this software for any purpose.  It is provided "as is" without express 
  38. X * or implied warranty.
  39. X *
  40. X * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  41. X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  42. X * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  43. X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  44. X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  45. X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  46. X * PERFORMANCE OF THIS SOFTWARE.
  47. X *
  48. X */
  49. X
  50. X/*
  51. X * genepic.c: (E)EPIC driver for fig2dev
  52. X *
  53. X * Converted from fig2epic 5/89 by Micah Beck
  54. X */
  55. X/*==================================================================*/
  56. X/*    fig2epic (Fig to EPIC converter)                 */
  57. X/*         Version 1.1d <March 30, 1988>                */
  58. X/*                                    */
  59. X/*    Written by Conrad Kwok, Division of Computer Science, UCD   */
  60. X/*                                    */
  61. X/*    Permission is granted for freely distribution of this file  */
  62. X/*        provided that this message is included.            */
  63. X/*==================================================================*/
  64. X
  65. X/*====================================================================
  66. X  Changes:
  67. X
  68. X  Version 1.0d:<September 18, 1988>
  69. X  1. Add the option -P for Page mode. Two more configurable parameter---
  70. X     Preamble and Postamble.
  71. X
  72. X  Version 1.1a: <January 18, 1989>
  73. X  1. Fix the bug in closed control splines. The routine convertCS(p) is being
  74. X     called once too often.
  75. X
  76. X  2. Add supports to Variable line width
  77. X  3. Add supports to black, white or shaded area fill.
  78. X
  79. X  Version 1.1b: <Febrary 2, 1989>
  80. X  1. Draw outline for area-filled figures when using dvips.
  81. X
  82. X  Version 1.1c: <Febrary 7, 1989>
  83. X  1. Supports all 5 gray level in area fill.
  84. X
  85. X  Version 1.1d: <March 30, 1989>
  86. X  1. Add supports for Gould NP1 (Bsd4.3) (Recieve the changes from
  87. X        mcvax!presto.irisa.fr!hleroy@uunet.uu.net. Sorry
  88. X        I don't have his/her name)
  89. X  2. Add exit(0) before exit in the main.
  90. X====================================================================*/
  91. X
  92. X  
  93. X#include <stdio.h>
  94. X#include <math.h>
  95. X#include <varargs.h>
  96. X#include <ctype.h>
  97. X#include "object.h"
  98. X#include "fig2dev.h"
  99. X#include "texfonts.h"
  100. X#include "pi.h"
  101. X
  102. X#ifdef MSDOS
  103. X#define getopt egetopt
  104. X#define M_PI 3.14159265358979324
  105. X#endif
  106. X
  107. X#define DrawOutLine
  108. X#ifdef DrawOutLine
  109. Xint OutLine=0;
  110. X#endif
  111. X
  112. X#define TopCoord 840        /* 10.5 in * 80 (DPI)            */
  113. X                /* Actually, it can be any value */
  114. X#define PtPerLine 3
  115. X#define ThinLines 0
  116. X#define ThickLines 1
  117. X#define FALSE 0
  118. X#define TRUE 1
  119. X#define Epic 0
  120. X#define EEpic_emu 1
  121. X#define EEpic 2
  122. X#define None 0
  123. X#define SolidLineBox 1
  124. X#define DashLineBox 2
  125. X#define BothBoxType 3
  126. X#define Normal 0
  127. X#define Economic 1
  128. X#define DottedDash 2
  129. X
  130. Xvoid genepic_ctl_spline(), genepic_int_spline(); 
  131. Xvoid genepic_open_spline(), genepic_closed_spline(); 
  132. X
  133. X/* Structure for Point with "double" values */
  134. Xstruct fp_struct {
  135. X    double x,y;
  136. X};
  137. X
  138. Xtypedef struct fp_struct FPoint;
  139. X
  140. X/* Local to the file only */
  141. Xstatic int coord_system;
  142. Xstatic int CoordSys = 2;
  143. Xstatic double Threshold;
  144. Xstatic int DPI;
  145. Xstatic int CurWidth = 0;
  146. Xstatic int LineStyle = SOLID_LINE;
  147. Xstatic int LLX = 0, LLY = 0;
  148. Xstatic char *LnCmd;
  149. Xstatic int MaxCircleRadius;
  150. Xstatic double DashLen;
  151. Xstatic int PageMode = FALSE;
  152. Xstatic int PatternType=UNFILLED;
  153. Xstatic struct {
  154. X    double mag;
  155. X    int size;
  156. X} ScaleTbl[5] = {
  157. X    { 0.6667, 8 },
  158. X    { 0.75  , 9 },
  159. X    { 0.8333, 10 },
  160. X    { 0.9167, 11 },
  161. X    { 1.0   , 12 }
  162. X};
  163. X
  164. X/* Definition of Keywords for some of the configurable parameter */
  165. Xchar *Tlangkw[] = { /* The order must match the definition of corr. constants */
  166. X    "Epic", "EEpicemu", "EEpic", NULL
  167. X};
  168. X
  169. Xchar *EllCmdkw[] = {
  170. X    "ellipse", "oval", NULL
  171. X};
  172. X
  173. Xchar *EllCmdstr[] = {
  174. X    "\\%s%s{%d}{%d}}\n", "\\%s%s(%d,%d)}\n"
  175. X};
  176. X
  177. Xchar *FillCommands[] = {
  178. X    "", "\\whiten",
  179. X    "\\shade", "\\shade", "\\shade",
  180. X    "\\shade", "\\shade", "\\shade",
  181. X    "\\shade", "\\shade", "\\shade",
  182. X    "\\shade", "\\shade", "\\shade",
  183. X    "\\shade", "\\shade", "\\shade",
  184. X    "\\shade", "\\shade", "\\shade",
  185. X    "\\shade", "\\blacken"
  186. X};
  187. X
  188. X#define TEXT_LINE_SEP '\n'
  189. X/* The following two arrays are used to translate characters which
  190. X   are special to LaTeX into characters that print as one would expect.
  191. X   Note that the <> characters aren't really special LaTeX characters
  192. X   but they will not print as themselves unless one is using a font
  193. X   like tt. */
  194. Xchar latex_text_specials[] = "\\{}><^~$&#_%";
  195. Xchar *latex_text_mappings[] = {
  196. X  "$\\backslash$",
  197. X  "$\\{$",
  198. X  "$\\}$",
  199. X  "$>$",
  200. X  "$<$",
  201. X  "\\^{}",
  202. X  "\\~{}",
  203. X  "\\$",
  204. X  "\\&",
  205. X  "\\#",
  206. X  "\\_",
  207. X  "\\%"};
  208. X
  209. X
  210. X/* Configurable parameters */
  211. Xint LowerLeftX=0, LowerLeftY=0;
  212. Xdouble SegLen = 0.0625; /* inch */
  213. Xint Verbose = FALSE;
  214. Xint TopMargin = 5;
  215. Xint BottomMargin = 10;
  216. Xint DotDist = 5;
  217. Xint LineThick = 2;
  218. Xint TeXLang = EEpic;
  219. Xdouble DashScale=1;
  220. Xint EllipseCmd=0;
  221. Xint UseBox=None;
  222. Xint DashType=Normal;
  223. Xchar *Preamble="\\documentstyle[epic,eepic]{article}\n\\begin{document}\n\\begin{center}\n";
  224. Xchar *Postamble="\\end{center}\n\\end{document}\n";
  225. Xint VarWidth=FALSE;
  226. X
  227. Xvoid genepic_option(opt, optarg)
  228. Xchar opt, *optarg;
  229. X{
  230. X      int loop, i;
  231. X
  232. X        switch (opt) {
  233. X    case 'a':
  234. X        fprintf(stderr, "warning: genepic option -a obsolete");
  235. X        break;
  236. X
  237. X    case 'f':
  238. X        for ( i = 1; i <= MAX_FONT; i++ )
  239. X        if ( !strcmp(optarg, texfontnames[i]) ) break;
  240. X
  241. X        if ( i > MAX_FONT)
  242. X        fprintf(stderr,
  243. X            "warning: non-standard font name %s\n", optarg);
  244. X    
  245. X            texfontnames[0] = texfontnames[1] = optarg;
  246. X        break;
  247. X
  248. X        case 'l':
  249. X            LineThick = atoi(optarg);
  250. X            break;
  251. X
  252. X    case 'L':
  253. X        for (loop=0; loop < 3; loop++) {
  254. X            if (stricmp(optarg, Tlangkw[loop]) == 0) break;
  255. X        }
  256. X        TeXLang = loop;
  257. X        break;
  258. X
  259. X
  260. X    case 'm':
  261. X        break;
  262. X
  263. X    case 'P':
  264. X        PageMode = 1;
  265. X        break;
  266. X
  267. X    case 's':
  268. X        font_size = atoi(optarg);
  269. X        if (font_size <= 0 || font_size > MAXFONTSIZE) {
  270. X        fprintf(stderr,
  271. X            "warning: font size %d out of bounds\n", font_size);
  272. X        }
  273. X        break;
  274. X
  275. X        case 'S':
  276. X            loop = atoi(optarg);
  277. X            if (loop < 8 || loop > 12) {
  278. X                put_msg("Scale must be between 8 and 12 inclusively\n");
  279. X                exit(1);
  280. X            }
  281. X            loop -= 8;
  282. X            mag = ScaleTbl[loop].mag;
  283. X            font_size = ScaleTbl[loop].size;
  284. X            break;
  285. X
  286. X        case 'v':
  287. X            Verbose = TRUE;
  288. X            break;
  289. X
  290. X    case 'w':
  291. X    case 'W':
  292. X        VarWidth = opt=='W';
  293. X        break;
  294. X
  295. X    default:
  296. X        put_msg(Err_badarg, opt, "epic");
  297. X        exit(1);
  298. X        break;
  299. X        }
  300. X}
  301. X
  302. Xstatic fconvertCS(fpt)
  303. XFPoint *fpt;
  304. X{
  305. X    if (CoordSys) {
  306. X        fpt->y = TopCoord - fpt->y;
  307. X    }
  308. X    fpt->x -= LLX;
  309. X    fpt->y -= LLY;
  310. X}
  311. X
  312. XconvertCS(pt)
  313. XF_point *pt;
  314. X{
  315. X    if (CoordSys) {
  316. X        pt->y = TopCoord - pt->y;
  317. X    }
  318. X    pt->x -= LLX;
  319. X    pt->y -= LLY;
  320. X}
  321. X
  322. Xvoid genepic_start(objects)
  323. XF_compound *objects;
  324. X{
  325. X    int temp;
  326. X    F_point pt1, pt2;
  327. X    F_arc *arc;
  328. X    F_compound *comp;
  329. X    F_ellipse *ell;
  330. X    F_line *line;
  331. X    F_spline *spl;
  332. X    F_text *text;
  333. X
  334. X    texfontsizes[0] = texfontsizes[1] = TEXFONTSIZE(font_size);
  335. X
  336. X    switch (TeXLang) {
  337. X    case Epic:
  338. X        EllipseCmd = 1; /* Oval */
  339. X        LnCmd = "drawline";
  340. X        break;
  341. X    case EEpic_emu:
  342. X    case EEpic:
  343. X        LnCmd = "path";
  344. X        break;
  345. X    default:
  346. X        put_msg("Program error in main\n");
  347. X        break;
  348. X    }
  349. X    if (PageMode) {
  350. X        fputs(Preamble, stdout);
  351. X    }
  352. X
  353. X    DPI = objects->nwcorner.x;
  354. X    if (DPI <= 0) {
  355. X        put_msg("Resolution has to be positive. Default to 80!\n");
  356. X        DPI = 80;
  357. X    }
  358. X    coord_system = objects->nwcorner.y;
  359. X    switch (coord_system) {
  360. X    case 1:
  361. X        CoordSys = 0;
  362. X        break;
  363. X    case 2:
  364. X        CoordSys = 1;
  365. X        break;
  366. X    default:
  367. X        put_msg("Unknown Coordinate system -- %d\n", coord_system);
  368. X        exit(1);
  369. X    }
  370. X    pt1.x = llx;
  371. X    pt1.y = lly;
  372. X    pt2.x = urx;
  373. X    pt2.y = ury;
  374. X    convertCS(&pt1);
  375. X    convertCS(&pt2);
  376. X    if (pt1.x > pt2.x) {
  377. X        temp = pt1.x;
  378. X        pt1.x = pt2.x;
  379. X        pt2.x = temp;
  380. X    }
  381. X    if (pt1.y > pt2.y) {
  382. X        temp = pt1.y;
  383. X        pt1.y = pt2.y;
  384. X        pt2.y = temp;
  385. X    }
  386. X    LLX = pt1.x - LowerLeftX;
  387. X    LLY = pt1.y - LowerLeftY;
  388. X    if (Verbose) {
  389. X        fprintf(tfp, "%%\n%% Language in use is %s\n%%\n", Tlangkw[TeXLang]);
  390. X    }
  391. X    Threshold = 1.0 / DPI * mag;
  392. X    fprintf(tfp, "\\setlength{\\unitlength}{%.4fin}\n", Threshold);
  393. X    MaxCircleRadius = (int) (40 / 72.27 / Threshold);
  394. X    Threshold = SegLen / Threshold;
  395. X    define_setfigfont(tfp);
  396. X    fprintf(tfp, "\\begin{picture}(%d,%d)(%d,%d)\n",
  397. X           pt2.x-pt1.x, pt2.y-pt1.y + TopMargin + BottomMargin,
  398. X           LowerLeftX, LowerLeftY-BottomMargin);
  399. X}
  400. X
  401. Xvoid genepic_end()
  402. X{
  403. X    fprintf(tfp, "\\end{picture}\n");
  404. X    if (PageMode)
  405. X        fputs(Postamble, stdout);
  406. X}
  407. X
  408. Xstatic set_linewidth(w)
  409. Xint w;
  410. X{
  411. X    int old_width;
  412. X
  413. X    if (w < 0) return;
  414. X    old_width=CurWidth;
  415. X    CurWidth = (w >= LineThick) ? (VarWidth ? w : ThickLines) : ThinLines;
  416. X    if (old_width != CurWidth) {
  417. X    if (CurWidth==ThinLines) {
  418. X        fprintf(tfp, "\\thinlines\n");
  419. X    } else if (VarWidth) {
  420. X        fprintf(tfp, "\\allinethickness{%d}%%\n",w);
  421. X    } else {
  422. X        fprintf(tfp, "\\thicklines\n");
  423. X    }
  424. X    }
  425. X}
  426. X
  427. Xset_pattern(type)
  428. Xint type;
  429. X{
  430. X    static unsigned long patterns[3][32] = {
  431. X    { 0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0,
  432. X      0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0,
  433. X      0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0,
  434. X      0xc0c0c0c0, 0, 0, 0, 0, 0, 0, 0},
  435. X    { 0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0,
  436. X      0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0,
  437. X      0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0,
  438. X      0xcccccccc, 0, 0, 0, 0xcccccccc, 0, 0, 0},
  439. X    { 0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0,
  440. X      0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0,
  441. X      0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0,
  442. X      0x55555555, 0, 0x55555555, 0, 0x55555555, 0, 0x55555555, 0}};
  443. X    int count, loop1, loop2, i;
  444. X
  445. X    if (type <= WHITE_FILL || type >= BLACK_FILL) return;
  446. X    if (type != PatternType) {
  447. X    PatternType=type;
  448. X    i = ((int) PatternType - WHITE_FILL - 1) / 6;
  449. X    fprintf(tfp, "\\texture{");
  450. X    count=0;
  451. X    for (loop1=4; loop1>0;) {
  452. X        for (loop2=8; loop2>0; loop2--) 
  453. X        fprintf(tfp, "%lx ", patterns[i][count++]);
  454. X        if (--loop1 > 0)
  455. X        fprintf(tfp, "\n\t");
  456. X        else
  457. X        fprintf(tfp, "}%\n");
  458. X    }
  459. X    }
  460. X}
  461. X
  462. Xvoid genepic_line(line)
  463. XF_line *line;
  464. X{
  465. X    F_point *p, *q;
  466. X    int pt_count = 0, temp;
  467. X    int boxflag = FALSE, llx, lly, urx, ury;
  468. X    double dtemp;
  469. X
  470. X    set_linewidth(line->thickness);
  471. X    set_style(line->style, line->style_val);
  472. X    p = line->points;
  473. X    q = p->next;
  474. X    convertCS(p);
  475. X    if (q == NULL) {
  476. X    fprintf(tfp, "\\drawline(%d,%d)(%d,%d)\n", p->x, p->y, p->x, p->y);
  477. X    return;
  478. X    }
  479. X    if (line->type == T_ARC_BOX) { /* A box with rounded corners */
  480. X      fprintf(stderr, "Arc box not implemented; substituting box.\n");
  481. X      line->type = T_BOX;
  482. X    }
  483. X    if (line->type == T_BOX) {
  484. X    if (Verbose) {
  485. X        fprintf(tfp, "%%\n%% A box\n%%\n");
  486. X    }
  487. X    switch (LineStyle) {
  488. X    case SOLID_LINE:
  489. X        if (UseBox == BothBoxType || UseBox == SolidLineBox) {
  490. X            boxflag = TRUE;
  491. X        }
  492. X        break;
  493. X    case DASH_LINE:
  494. X        if (UseBox == BothBoxType || UseBox == DashLineBox) {
  495. X            boxflag = TRUE;
  496. X        }
  497. X        break;
  498. X    }
  499. X    if (boxflag) {
  500. X        llx = urx = p->x;
  501. X        lly = ury = p->y;
  502. X        while (q != NULL) {
  503. X            convertCS(q);
  504. X            if (q->x < llx) {
  505. X                llx = q->x;
  506. X            } else if (q->x > urx) {
  507. X                urx = q->x;
  508. X            }
  509. X            if (q->y < lly) {
  510. X                lly = q->y;
  511. X            } else if (q->y > ury) {
  512. X                ury = q->y;
  513. X            }
  514. X            q = q->next;
  515. X        }
  516. X        switch(LineStyle) {
  517. X        case SOLID_LINE:
  518. X            fprintf(tfp, "\\put(%d,%d){\\framebox(%d,%d){}}\n",
  519. X                llx, lly, urx-llx, ury-lly);
  520. X            break;
  521. X        case DASH_LINE:
  522. X        temp = (int) ((urx-llx) / DashLen);
  523. X        dtemp = (double) (urx-llx) / temp;
  524. X            fprintf(tfp, "\\put(%d,%d){\\dashbox{%4.3f}(%d,%d){}}\n",
  525. X                llx, lly, dtemp , urx-llx, ury-lly);
  526. X            break;
  527. X        default:
  528. X            put_msg("Program Error! No other line styles allowed.\n");
  529. X            break;
  530. X        }
  531. X        return;
  532. X      }
  533. X    }
  534. X    set_pattern(line->area_fill);
  535. X    convertCS(q);
  536. X    if (line->back_arrow) {
  537. X    draw_arrow_head(q, p, line->back_arrow->ht, line->back_arrow->wid);
  538. X        if (Verbose) fprintf(tfp, "%%\n");
  539. X    }
  540. X    switch (LineStyle) {
  541. X    case SOLID_LINE:
  542. X    if (q->next != NULL && strcmp(LnCmd,"path")==0) {
  543. X        if (line->area_fill < UNFILLED) line->area_fill = UNFILLED;
  544. X        fprintf(tfp, "%s", FillCommands[line->area_fill]);
  545. X    }
  546. X    fprintf(tfp, "\\%s", LnCmd);
  547. X#ifdef DrawOutLine
  548. X    if (line->area_fill != UNFILLED && OutLine == 0) OutLine=1;
  549. X#endif
  550. X    break;
  551. X    case DASH_LINE:
  552. X        if ((TeXLang==Epic || TeXLang ==EEpic_emu) && DashType == Economic) {
  553. X            fprintf(tfp, "\\drawline[-50]");
  554. X        } else {
  555. X        fprintf(tfp, "\\dashline{%4.3f}", DashLen);
  556. X    }
  557. X    break;
  558. X    case DOTTED_LINE:
  559. X    fprintf(tfp, "\\dottedline{%d}", DotDist);
  560. X    break;
  561. X    default:
  562. X    fprintf(stderr,"Unknown Style\n");
  563. X    exit(1);
  564. X    }
  565. X    fprintf(tfp, "(%d,%d)", p->x, p->y);
  566. X    pt_count++;
  567. X    while(q->next != NULL) {
  568. X    if (++pt_count > PtPerLine) {
  569. X        pt_count=1;
  570. X        fprintf(tfp, "\n\t");
  571. X    }
  572. X    fprintf(tfp, "(%d,%d)", q->x, q->y);
  573. X    p=q;
  574. X    q = q->next;
  575. X    convertCS(q);
  576. X    }
  577. X    fprintf(tfp, "(%d,%d)\n", q->x, q->y);
  578. X#ifdef DrawOutLine
  579. X    if (OutLine == 1) {
  580. X    OutLine=0;
  581. X    fprintf(tfp, "\\%s", LnCmd);
  582. X    p=line->points;
  583. X    pt_count=0;
  584. X    q=p->next;
  585. X    fprintf(tfp, "(%d,%d)", p->x, p->y);
  586. X    pt_count++;
  587. X    while(q->next != NULL) {
  588. X        if (++pt_count > PtPerLine) {
  589. X        pt_count=1;
  590. X        fprintf(tfp, "\n\t");
  591. X        }
  592. X        fprintf(tfp, "(%d,%d)", q->x, q->y);
  593. X        p=q;
  594. X        q = q->next;
  595. X    }
  596. X    fprintf(tfp, "(%d,%d)\n", q->x, q->y);
  597. X    }
  598. X#endif
  599. X    if (line->for_arrow) {
  600. X    draw_arrow_head(p, q, line->for_arrow->ht, line->for_arrow->wid);
  601. X        if (Verbose) fprintf(tfp, "%%\n");
  602. X    }
  603. X}
  604. X
  605. Xset_style(style, dash_len)
  606. Xint style;
  607. Xfloat dash_len;
  608. X{
  609. X    LineStyle = style;
  610. X    if (LineStyle == DASH_LINE) {
  611. X        switch (DashType) {
  612. X        case DottedDash:
  613. X            LineStyle = DOTTED_LINE;
  614. X            break;
  615. X        default:
  616. X            DashLen = dash_len * DashScale;
  617. X            break;
  618. X        }
  619. X    }
  620. X}
  621. X
  622. X
  623. Xvoid genepic_spline(spl)
  624. XF_spline *spl;
  625. X{
  626. X    set_linewidth(spl->thickness);
  627. X    set_style(SOLID_LINE, 0.0);
  628. X    if (int_spline(spl)) {
  629. X    genepic_itp_spline(spl);
  630. X    } else {
  631. X    genepic_ctl_spline(spl);
  632. X    }
  633. X}
  634. X
  635. Xvoid genepic_ctl_spline(spl)
  636. XF_spline *spl;
  637. X{
  638. X    if (closed_spline(spl)) {
  639. X    genepic_closed_spline(spl);
  640. X    } else {
  641. X    genepic_open_spline(spl);
  642. X    }
  643. X}
  644. X
  645. Xstatic void genepic_open_spline(spl)
  646. XF_spline *spl;
  647. X{
  648. X    F_point *p, *q, *r;
  649. X    FPoint first, mid;
  650. X    int pt_count = 0;
  651. X
  652. X    p = spl->points;
  653. X    q = p->next;
  654. X    convertCS(p);
  655. X    convertCS(q);
  656. X    if (spl->back_arrow) {
  657. X    draw_arrow_head(q, p, spl->back_arrow->ht, spl->back_arrow->wid);
  658. X        if (Verbose) fprintf(tfp, "%%\n");
  659. X    }
  660. X    if (q->next == NULL) {
  661. X    fprintf(tfp, "\\%s(%d,%d)(%d,%d)\n", LnCmd,
  662. X           p->x, p->y, q->x, q->y);
  663. X    return;
  664. X    }
  665. X    if (TeXLang == EEpic || TeXLang == EEpic_emu) {
  666. X        fprintf(tfp, "\\spline(%d,%d)\n", p->x, p->y);
  667. X        pt_count++;
  668. X        while(q->next != NULL) {
  669. X             if (++pt_count > PtPerLine) {
  670. X                 pt_count=1;
  671. X                 fprintf(tfp, "\n\t");
  672. X             }
  673. X             fprintf(tfp, "(%d,%d)", q->x, q->y);
  674. X             p=q;
  675. X             q = q->next;
  676. X             convertCS(q);
  677. X        }
  678. X        fprintf(tfp, "(%d,%d)\n", q->x, q->y);
  679. X    } else {
  680. X        fprintf(tfp, "\\%s(%d,%d)\n", LnCmd, p->x, p->y);
  681. X        r = q->next;
  682. X        convertCS(r);
  683. X        first.x = p->x;
  684. X        first.y = p->y;
  685. X        while (r->next != NULL) {
  686. X            mid.x = (q->x + r->x) / 2.0;
  687. X            mid.y = (q->y + r->y) / 2.0;
  688. X            chaikin_curve(first.x, first.y, (double) q->x, (double) q->y,
  689. X                            mid.x, mid.y);
  690. X            first = mid;
  691. X            q=r;
  692. X            r = r->next;
  693. X            convertCS(r);
  694. X        }
  695. X        chaikin_curve(first.x, first.y, (double) q->x, (double) q->y,
  696. X                        (double) r->x, (double) r->y);
  697. X        p=q;
  698. X        q=r;
  699. X    fprintf(tfp, "\n");
  700. X    }
  701. X    if (spl->for_arrow) {
  702. X    draw_arrow_head(p, q, spl->for_arrow->ht, spl->for_arrow->wid);
  703. X        if (Verbose) fprintf(tfp, "%%\n");
  704. X    }
  705. X}
  706. X
  707. Xstatic void genepic_closed_spline(spl)
  708. XF_spline *spl;
  709. X{
  710. X    F_point *p;
  711. X    double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
  712. X    double x1, y1, x2, y2;
  713. X
  714. X    p = spl->points;
  715. X    convertCS(p);
  716. X    x1 = p->x;  y1 = p->y;
  717. X    p = p->next;
  718. X    convertCS(p);
  719. X    x2 = p->x;  y2 = p->y;
  720. X    cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
  721. X    cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
  722. X    for (p = p->next; p != NULL; p = p->next) {
  723. X    fprintf(tfp, "\\%s(%.3f,%.3f)", LnCmd, cx1, cy1);
  724. X    x1 = x2;  y1 = y2;
  725. X    convertCS(p);
  726. X    x2 = p->x;  y2 = p->y;
  727. X    cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
  728. X    cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
  729. X    quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
  730. X    fprintf(tfp, "\n");
  731. X    cx1 = cx4;  cy1 = cy4;
  732. X    cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
  733. X    }
  734. X    x1 = x2;  y1 = y2;
  735. X    p = spl->points->next;
  736. X    x2 = p->x;  y2 = p->y;
  737. X    cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
  738. X    cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
  739. X    fprintf(tfp, "\\%s(%.3f,%.3f)", LnCmd, cx1, cy1);
  740. X    quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
  741. X    fprintf(tfp, "\n");
  742. X}
  743. X
  744. Xchaikin_curve(a1, b1, a2, b2, a3, b3)
  745. Xdouble a1, b1, a2, b2, a3, b3;
  746. X{
  747. X    double xm1, xmid, xm2, ym1, ymid, ym2;
  748. X
  749. X    if (fabs(a1-a3) < Threshold && fabs(b1-b3) < Threshold) {
  750. X        fprintf(tfp, "\t(%.3f,%.3f)\n", a3, b3);
  751. X    } else {
  752. X        xm1 = (a1 + a2) / 2;
  753. X        ym1 = (b1 + b2) / 2;
  754. X        xm2 = (a2 + a3) / 2;
  755. X        ym2 = (b2 + b3) / 2;
  756. X        xmid = (xm1 + xm2) / 2;
  757. X        ymid = (ym1 + ym2) / 2;
  758. X        chaikin_curve(a1, b1, xm1, ym1, xmid, ymid);
  759. X        chaikin_curve(xmid, ymid, xm2, ym2, a3, b3);
  760. X    }
  761. X}
  762. X
  763. Xstatic quadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4)
  764. Xdouble    a1, b1, a2, b2, a3, b3, a4, b4;
  765. X{
  766. X    double    x1, y1, x4, y4;
  767. X    double    xmid, ymid;
  768. X
  769. X    x1 = a1; y1 = b1;
  770. X    x4 = a4; y4 = b4;
  771. X
  772. X    xmid = (a2 + a3) / 2;
  773. X    ymid = (b2 + b3) / 2;
  774. X    if (fabs(x1 - xmid) < Threshold && fabs(y1 - ymid) < Threshold) {
  775. X    fprintf(tfp, "\t(%.3f,%.3f)\n", xmid, ymid);
  776. X    } else {
  777. X    quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2),
  778. X             ((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid);
  779. X    }
  780. X
  781. X    if (fabs(xmid - x4) < Threshold && fabs(ymid - y4) < Threshold) {
  782. X    fprintf(tfp, "\t(%.3f,%.3f)\n", x4, y4);
  783. X    } else {
  784. X    quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4),
  785. X             ((a3+x4)/2), ((b3+y4)/2), x4, y4);
  786. X    }
  787. X}
  788. X
  789. Xgenepic_itp_spline(spl)
  790. XF_spline *spl;
  791. X{
  792. X    F_point *p1, *p2;
  793. X    FPoint pt1l, pt1r, pt2l, pt2r, tmpfpt;
  794. X    F_control *cp1, *cp2;
  795. X
  796. X    p1 = spl->points;
  797. X    convertCS(p1);
  798. X    cp1 = spl->controls;
  799. X    pt1l.x = cp1->lx;
  800. X    pt1l.y = cp1->ly;
  801. X    pt1r.x = cp1->rx;
  802. X    pt1r.y = cp1->ry;
  803. X    fconvertCS(&pt1l);
  804. X    fconvertCS(&pt1r);
  805. X
  806. X    if (spl->back_arrow) {
  807. X    tmpfpt.x = p1->x;
  808. X    tmpfpt.y = p1->y;
  809. X    fdraw_arrow_head(&pt1r, &tmpfpt, 
  810. X        spl->back_arrow->ht, spl->back_arrow->wid);
  811. X        if (Verbose) fprintf(tfp, "%%\n");
  812. X    }
  813. X
  814. X    for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
  815. X     p1 = p2, pt1r = pt2r, p2 = p2->next, cp2 = cp2->next) {
  816. X    fprintf(tfp, "\\%s(%d,%d)", LnCmd, p1->x, p1->y);
  817. X    convertCS(p2);
  818. X    pt2l.x = cp2->lx;
  819. X    pt2l.y = cp2->ly;
  820. X    pt2r.x = cp2->rx;
  821. X    pt2r.y = cp2->ry;
  822. X    fconvertCS(&pt2l);
  823. X    fconvertCS(&pt2r);
  824. X    bezier_spline((double) p1->x, (double) p1->y,
  825. X              pt1r.x, pt1r.y,
  826. X              pt2l.x, pt2l.y,
  827. X              (double) p2->x, (double) p2->y);
  828. X    fprintf(tfp, "\n");
  829. X    }
  830. X
  831. X    if (spl->for_arrow) {
  832. X    tmpfpt.x = p1->x;
  833. X    tmpfpt.y = p1->y;
  834. X    fdraw_arrow_head(&pt2l, &tmpfpt, 
  835. X             spl->for_arrow->ht, spl->for_arrow->wid);
  836. X    if (Verbose) fprintf(tfp, "%%\n");
  837. X    }
  838. X}
  839. X
  840. Xstatic bezier_spline(a0, b0, a1, b1, a2, b2, a3, b3)
  841. Xdouble    a0, b0, a1, b1, a2, b2, a3, b3;
  842. X{
  843. X    double    x0, y0, x3, y3;
  844. X    double    sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid;
  845. X
  846. X    x0 = a0; y0 = b0;
  847. X    x3 = a3; y3 = b3;
  848. X    if (fabs(x0 - x3) < Threshold && fabs(y0 - y3) < Threshold) {
  849. X    fprintf(tfp, "\t(%.3f,%.3f)\n", x3, y3);
  850. X    } else {
  851. X    tx = (a1 + a2) / 2;        ty = (b1 + b2) / 2;
  852. X    sx1 = (x0 + a1) / 2;    sy1 = (y0 + b1) / 2;
  853. X    sx2 = (sx1 + tx) / 2;    sy2 = (sy1 + ty) / 2;
  854. X    tx2 = (a2 + x3) / 2;    ty2 = (b2 + y3) / 2;
  855. X    tx1 = (tx2 + tx) / 2;    ty1 = (ty2 + ty) / 2;
  856. X    xmid = (sx2 + tx1) / 2;    ymid = (sy2 + ty1) / 2;
  857. X
  858. X    bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid);
  859. X    bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3);
  860. X    }
  861. X}
  862. X
  863. Xvoid genepic_ellipse(ell)
  864. XF_ellipse *ell;
  865. X{
  866. X    F_point pt;
  867. X
  868. X    set_linewidth(ell->thickness);
  869. X    pt.x = ell->center.x;
  870. X    pt.y = ell->center.y;
  871. X    convertCS(&pt);
  872. X    if (TeXLang == EEpic || TeXLang == EEpic_emu ||
  873. X      ell->radiuses.x != ell->radiuses.y ||
  874. X          ell->radiuses.x > MaxCircleRadius) {
  875. X    set_pattern(ell->area_fill);
  876. X        fprintf(tfp, "\\put(%d,%d){", pt.x, pt.y );
  877. X#ifndef OLDCODE
  878. X        if (EllipseCmd == 0) {
  879. X        if (ell->area_fill < UNFILLED) ell->area_fill = UNFILLED;
  880. X        fprintf(tfp, "%s", FillCommands[ell->area_fill]);
  881. X#  ifdef DrawOutLine
  882. X        if (ell->area_fill != UNFILLED && OutLine == 0) OutLine = 1;
  883. X#  endif
  884. X        }
  885. X     fprintf(tfp, EllCmdstr[EllipseCmd],EllCmdkw[EllipseCmd], "",
  886. X           2 * ell->radiuses.x, 2 * ell->radiuses.y);
  887. X#  ifdef DrawOutLine
  888. X    if (OutLine == 1) {
  889. X        OutLine=0;
  890. X            fprintf(tfp, "\\put(%d,%d){", pt.x, pt.y );
  891. X        fprintf(tfp, EllCmdstr[EllipseCmd],EllCmdkw[EllipseCmd], "",
  892. X           2 * ell->radiuses.x, 2 * ell->radiuses.y);
  893. X    }
  894. X#  endif
  895. X#else
  896. X    fprintf(tfp, EllCmdstr[EllipseCmd], EllCmdkw[EllipseCmd],
  897. X           (EllipseCmd==0 && ell->area_fill==BLACK_FILL ? "*" : ""),
  898. X           2 * ell->radiuses.x, 2 * ell->radiuses.y);
  899. X#endif
  900. X    } else {
  901. X        fprintf(tfp, "\\put(%d,%d){\\circle", pt.x, pt.y);
  902. X        if (ell->area_fill == BLACK_FILL) {
  903. X            fputc('*', tfp);
  904. X        }
  905. X        fprintf(tfp, "{%d}}\n", 2*ell->radiuses.x);
  906. X    }
  907. X}
  908. X
  909. Xextern char *ISOtoTeX[];
  910. Xvoid genepic_text(text)
  911. XF_text *text;
  912. X{
  913. X    F_point pt;
  914. X    char *tpos, *esc_cp, *special_index;
  915. X    unsigned char   *cp;
  916. X
  917. X    pt.x=text->base_x;
  918. X    pt.y=text->base_y;
  919. X    convertCS(&pt);
  920. X    switch (text->type) {
  921. X    case T_LEFT_JUSTIFIED:
  922. X    case DEFAULT:
  923. X    tpos = "[lb]";
  924. X    break;
  925. X    case T_CENTER_JUSTIFIED:
  926. X    tpos = "[b]";
  927. X    break;
  928. X    case T_RIGHT_JUSTIFIED:
  929. X    tpos = "[rb]";
  930. X    break;
  931. X    default:
  932. X    fprintf(stderr, "unknown text position type\n");
  933. X    exit(1);
  934. X    }
  935. X    fprintf(tfp, "\\put(%d,%d){\\makebox(0,0)%s{\\smash{",
  936. X           pt.x, pt.y, tpos);
  937. X    /* Output a shortstack in case there are multiple lines. */
  938. X    for(cp = (unsigned char*)text->cstring; *cp; cp++) {
  939. X      if (*cp == TEXT_LINE_SEP) {
  940. X    fprintf(tfp, "\\shortstack" );
  941. X    /* Output the justification for the shortstack. */
  942. X    switch (text->type) {
  943. X    case T_LEFT_JUSTIFIED:
  944. X    case DEFAULT:
  945. X    fprintf(tfp, "[l]");
  946. X    break;
  947. X    case T_CENTER_JUSTIFIED:
  948. X    break;
  949. X    case T_RIGHT_JUSTIFIED:
  950. X    fprintf(tfp, "[r]");
  951. X    break;
  952. X    default:
  953. X    fprintf(stderr, "unknown text position type\n");
  954. X    exit(1);
  955. X    }
  956. X    break;
  957. X      }
  958. X    }
  959. X
  960. X    unpsfont(text);
  961. X    { int texsize;
  962. X      double baselineskip;
  963. X
  964. X      texsize = TEXFONTMAG(text);
  965. X      baselineskip = (texsize * 1.2);
  966. X
  967. X      fprintf(tfp, "{{\\SetFigFont{%d}{%.1f}{%s}",
  968. X          texsize, baselineskip, TEXFONT(text->font));
  969. X    }
  970. X
  971. X    if (!special_text(text))
  972. X    /* This loop escapes special LaTeX characters. */
  973. X    for(cp = (unsigned char*)text->cstring; *cp; cp++) {
  974. X              if (special_index=strchr(latex_text_specials, *cp)) {
  975. X          /* Write out the replacement.  Implementation note: we can't
  976. X         use puts since that will output an additional newline. */
  977. X          esc_cp=latex_text_mappings[special_index-latex_text_specials];
  978. X          while (*esc_cp)
  979. X        fputc(*esc_cp++, tfp);
  980. X        }
  981. X        else if (*cp == TEXT_LINE_SEP) {
  982. X          /* Handle multi-line text strings. The problem being addressed here
  983. X         is a LaTeX bug where LaTeX is unable to handle a font which
  984. X         spans multiple lines.  What we are doing here is closing off
  985. X         the current font, starting a new line, and then resuming with
  986. X         the current font. */
  987. X          fprintf(tfp, "} \\\\\n");
  988. X
  989. X           { int texsize;
  990. X         double baselineskip;
  991. X         texsize = TEXFONTMAG(text);
  992. X         baselineskip = (texsize * 1.2);
  993. X         
  994. X         fprintf(tfp, "{\\SetFigFont{%d}{%.1f}{%s}",
  995. X             texsize, baselineskip, TEXFONT(text->font));
  996. X            }
  997. X        }
  998. X        else
  999. X        fputc(*cp, tfp);
  1000. X          }
  1001. X    else 
  1002. X    for(cp = (unsigned char*)text->cstring; *cp; cp++) {
  1003. X      if (*cp == TEXT_LINE_SEP) {
  1004. X          /* Handle multi-line text strings. */
  1005. X          fprintf(tfp, "} \\\\\n");
  1006. X
  1007. X          { int texsize;
  1008. X        double baselineskip;
  1009. X
  1010. X        texsize = TEXFONTMAG(text);
  1011. X        baselineskip = (texsize * 1.2);
  1012. X        
  1013. X        fprintf(tfp, "{\\SetFigFont{%d}{%.1f}{%s}",
  1014. X            texsize, baselineskip, TEXFONT(text->font));
  1015. X          }
  1016. X        }
  1017. X        else
  1018. X            if (*cp >= 0xa0)    /* we escape 8-bit char */
  1019. X                fprintf(tfp, "%s", ISOtoTeX[(int)*cp-0xa0]);
  1020. X        else
  1021. X            fputc(*cp, tfp);
  1022. X      }
  1023. X    fprintf(tfp, "}}}}}\n");
  1024. X}
  1025. X
  1026. Xvoid genepic_arc(arc)
  1027. XF_arc *arc;
  1028. X{
  1029. X    FPoint pt1, pt2, ctr, tmp;
  1030. X    double r1, r2, th1, th2, theta;
  1031. X    double dx1, dy1, dx2, dy2;
  1032. X    double arrowfactor;
  1033. X
  1034. X    ctr.x = arc->center.x;
  1035. X    ctr.y = arc->center.y;
  1036. X    pt1.x = arc->point[0].x;
  1037. X    pt1.y = arc->point[0].y;
  1038. X    pt2.x = arc->point[2].x;
  1039. X    pt2.y = arc->point[2].y;
  1040. X    fconvertCS(&ctr);
  1041. X    fconvertCS(&pt1);
  1042. X    fconvertCS(&pt2);
  1043. X
  1044. X    dx1 = pt1.x - ctr.x;
  1045. X    dy1 = pt1.y - ctr.y;
  1046. X    dx2 = pt2.x - ctr.x;
  1047. X    dy2 = pt2.y - ctr.y;
  1048. X
  1049. X    rtop(dx1, dy1, &r1, &th1);
  1050. X    rtop(dx2, dy2, &r2, &th2);
  1051. X    arrowfactor = (r1+r2) / 30.0;
  1052. X    if (arrowfactor > 1) arrowfactor = 1;
  1053. X    set_linewidth(arc->thickness);
  1054. X    if (arc->for_arrow) {
  1055. X    arc_tangent(&ctr, &pt2, arc->direction, &tmp);
  1056. X    fdraw_arrow_head(&tmp, &pt2,
  1057. X             arc->for_arrow->ht*arrowfactor,
  1058. X             arc->for_arrow->wid*arrowfactor);
  1059. X        if (Verbose) fprintf(tfp, "%%\n");
  1060. X    }
  1061. X    if (arc->back_arrow) {
  1062. X    arc_tangent(&ctr, &pt1, !arc->direction, &tmp);
  1063. X    fdraw_arrow_head(&tmp, &pt1,
  1064. X             arc->back_arrow->ht*arrowfactor,
  1065. X             arc->back_arrow->wid*arrowfactor);
  1066. X        if (Verbose) fprintf(tfp, "%%\n");
  1067. X    }
  1068. X    if (TeXLang == EEpic) {
  1069. X    set_pattern(arc->area_fill);
  1070. X        fprintf(tfp, "\\put(%4.3lf,%4.3lf){", ctr.x, ctr.y);
  1071. X    } else {
  1072. X    fprintf(tfp, "\\drawline");
  1073. X    }
  1074. X    if (TeXLang == EEpic) {
  1075. X    if (arc->area_fill < UNFILLED) arc->area_fill = UNFILLED;
  1076. X    fprintf(tfp, "%s", FillCommands[arc->area_fill]);
  1077. X#ifdef DrawOutLine
  1078. X    if (arc->area_fill != UNFILLED && OutLine==0) OutLine=1;
  1079. X#endif
  1080. X    }
  1081. X    if (arc->direction) {
  1082. X    theta = th2 - th1;
  1083. X    if (theta < 0) theta += 2 * M_PI;
  1084. X    th2 = 2*M_PI-th2;
  1085. X    if (TeXLang == EEpic) {
  1086. X        fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r1, th2, th2+theta);
  1087. X#ifdef DrawOutLine
  1088. X        if (OutLine==1) {
  1089. X        OutLine=0;
  1090. X            fprintf(tfp, "\\put(%4.3lf,%4.3lf){", ctr.x, ctr.y);
  1091. X        fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r1, th2, th2+theta);
  1092. X        }
  1093. X#endif
  1094. X        } else {
  1095. X            drawarc(&ctr, r1, 2*M_PI - th2 - theta, theta);
  1096. X        }
  1097. X    } else {
  1098. X    theta = th1 - th2;
  1099. X    if (theta < 0) theta += 2 * M_PI;
  1100. X    th1 = 2*M_PI-th1;
  1101. X    if (TeXLang == EEpic) {
  1102. X        fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r2, th1, th1+theta);
  1103. X#ifdef DrawOutLine
  1104. X        if (OutLine==1) {
  1105. X        OutLine=0;
  1106. X            fprintf(tfp, "\\put(%4.3lf,%4.3lf){", ctr.x, ctr.y);
  1107. X        fprintf(tfp, "\\arc{%4.3f}{%2.4f}{%2.4f}}\n", 2*r2, th1, th1+theta);
  1108. X        }
  1109. X#endif
  1110. X    } else {
  1111. X            drawarc(&ctr, r2, 2*M_PI - th1 - theta, theta);
  1112. X        }
  1113. X    }
  1114. X}
  1115. X
  1116. Xdrawarc(ctr, r, th1, angle)
  1117. XFPoint *ctr;
  1118. Xdouble r, th1, angle;
  1119. X{
  1120. X    double arclength, delta;
  1121. X    int division, pt_count = 0;
  1122. X
  1123. X
  1124. X    division = angle * r / Threshold;
  1125. X    delta = angle / division;
  1126. X    division++;
  1127. X    while (division-- > 0) {
  1128. X        if (++pt_count > PtPerLine) {
  1129. X            fprintf(tfp, "\n\t");
  1130. X            pt_count = 1;
  1131. X        }
  1132. X        fprintf(tfp, "(%.3lf,%.3lf)", ctr->x + cos(th1) * r,
  1133. X                                ctr->y + sin(th1) * r);
  1134. X        th1 += delta;
  1135. X    }
  1136. X    fprintf(tfp, "\n");
  1137. X}
  1138. X
  1139. Xstatic arc_tangent(pt1, pt2, direction, pt3)
  1140. XFPoint *pt1, *pt2, *pt3;
  1141. Xint direction;
  1142. X{
  1143. X    if (direction) {
  1144. X    pt3->x = pt2->x + (pt2->y - pt1->y);
  1145. X    pt3->y = pt2->y - (pt2->x - pt1->x);
  1146. X    } else {
  1147. X    pt3->x = pt2->x - (pt2->y - pt1->y);
  1148. X    pt3->y = pt2->y + (pt2->x - pt1->x);
  1149. X    }
  1150. X}
  1151. X
  1152. Xrtop(x, y, r, th)
  1153. Xdouble x, y, *r, *th;
  1154. X{
  1155. X    *r = sqrt(x*x+y*y);
  1156. X    *th = acos(x/(*r));
  1157. X    if (*th < 0) *th = M_PI + *th;
  1158. X    if (y < 0) *th = 2*M_PI - *th;
  1159. X}
  1160. X
  1161. Xstatic draw_arrow_head(pt1, pt2, arrowht, arrowwid)
  1162. XF_point *pt1, *pt2;
  1163. Xdouble arrowht, arrowwid;
  1164. X{
  1165. X    FPoint fpt1, fpt2;
  1166. X
  1167. X    fpt1.x = pt1->x;
  1168. X    fpt1.y = pt1->y;
  1169. X    fpt2.x = pt2->x;
  1170. X    fpt2.y = pt2->y;
  1171. X    fdraw_arrow_head(&fpt1, &fpt2, arrowht, arrowwid);
  1172. X}
  1173. X
  1174. Xfdraw_arrow_head(pt1, pt2, arrowht, arrowwid)
  1175. XFPoint *pt1, *pt2;
  1176. Xdouble arrowht, arrowwid;
  1177. X{
  1178. X    double x1, y1, x2, y2;
  1179. X    double x,y, xb,yb,dx,dy,l,sina,cosa;
  1180. X    double xc, yc, xd, yd;
  1181. X
  1182. X    x1 = pt1->x;
  1183. X    y1 = pt1->y;
  1184. X    x2 = pt2->x;
  1185. X    y2 = pt2->y;
  1186. X
  1187. X    dx = x2 - x1;  dy = y1 - y2;
  1188. X    l = sqrt(dx*dx+dy*dy);
  1189. X    if (l == 0) {
  1190. X     return;
  1191. X    }
  1192. X    else {
  1193. X     sina = dy / l;  cosa = dx / l;
  1194. X    }
  1195. X    xb = x2*cosa - y2*sina;
  1196. X    yb = x2*sina + y2*cosa;
  1197. X    x = xb - arrowht;
  1198. X    y = yb - arrowwid / 2;
  1199. X    xc = x*cosa + y*sina;
  1200. X    yc = -x*sina + y*cosa;
  1201. X    y = yb + arrowwid / 2;
  1202. X    xd = x*cosa + y*sina;
  1203. X    yd = -x*sina + y*cosa;
  1204. X
  1205. X    if (Verbose) fprintf(tfp, "%%\n%% arrow head\n%%\n");
  1206. X
  1207. X    fprintf(tfp, "\\%s(%4.3f,%4.3f)(%4.3f,%4.3f)(%4.3f,%4.3f)\n", LnCmd,
  1208. X        xc, yc, x2, y2, xd, yd);
  1209. X}
  1210. X
  1211. X#ifndef MSDOS
  1212. Xstricmp(s, t)
  1213. Xchar *s, *t;
  1214. X{
  1215. X    char a, b;
  1216. X
  1217. X    for (;;) {
  1218. X        a= *s++; b= *t++;
  1219. X        a = islower(a) ? toupper(a) : a;
  1220. X        b = islower(b) ? toupper(b) : b;
  1221. X        if (a != b) break;
  1222. X        if (a == '\0') return(0);
  1223. X    }
  1224. X    return(a - b);
  1225. X}
  1226. X#endif
  1227. X
  1228. Xstruct driver dev_epic = {
  1229. X         genepic_option,
  1230. X    genepic_start,
  1231. X    genepic_arc,
  1232. X    genepic_ellipse,
  1233. X    genepic_line,
  1234. X    genepic_spline,
  1235. X    genepic_text,
  1236. X    genepic_end,
  1237. X    INCLUDE_TEXT
  1238. X};
  1239. END_OF_FILE
  1240. if test 30473 -ne `wc -c <'fig2dev/dev/genepic.c'`; then
  1241.     echo shar: \"'fig2dev/dev/genepic.c'\" unpacked with wrong size!
  1242. fi
  1243. # end of 'fig2dev/dev/genepic.c'
  1244. fi
  1245. if test -f 'fig2dev/dev/genps.c' -a "${1}" != "-c" ; then 
  1246.   echo shar: Will not clobber existing file \"'fig2dev/dev/genps.c'\"
  1247. else
  1248. echo shar: Extracting \"'fig2dev/dev/genps.c'\" \(28838 characters\)
  1249. sed "s/^X//" >'fig2dev/dev/genps.c' <<'END_OF_FILE'
  1250. X/*
  1251. X * TransFig: Facility for Translating Fig code
  1252. X * Copyright (c) 1985 Supoj Sutantavibul
  1253. X * Copyright (c) 1991 Micah Beck
  1254. X *
  1255. X * Permission to use, copy, modify, distribute, and sell this software and its
  1256. X * documentation for any purpose is hereby granted without fee, provided that
  1257. X * the above copyright notice appear in all copies and that both that
  1258. X * copyright notice and this permission notice appear in supporting
  1259. X * documentation. The authors make no representations about the suitability 
  1260. X * of this software for any purpose.  It is provided "as is" without express 
  1261. X * or implied warranty.
  1262. X *
  1263. X * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  1264. X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  1265. X * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  1266. X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  1267. X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  1268. X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  1269. X * PERFORMANCE OF THIS SOFTWARE.
  1270. X *
  1271. X */
  1272. X
  1273. X/* 
  1274. X *    genps.c: PostScript driver for fig2dev
  1275. X *
  1276. X *    Modified by Herbert Bauer to support ISO-Characters,
  1277. X *    multiple page output, color mode etc.
  1278. X *    heb@regent.e-technik.tu-muenchen.de
  1279. X *
  1280. X *    Modified by Eric Picheral to support the whole set of ISO-Latin-1
  1281. X *    Modified by Herve Soulard to allow non-iso coding on special fonts
  1282. X *    Herve.Soulard@inria.fr (8 Apr 1993)
  1283. X
  1284. X*/
  1285. X
  1286. X#include <sys/param.h>
  1287. X#if defined(hpux) || defined(SYSV) || defined(BSD4_3)
  1288. X#include <sys/types.h>
  1289. X#endif
  1290. X#include <sys/file.h>
  1291. X#include <stdio.h>
  1292. X#include <math.h>
  1293. X#include <pwd.h>
  1294. X#include <errno.h>
  1295. Xextern char *sys_errlist[];
  1296. X#include "pi.h"
  1297. X#include "object.h"
  1298. X#include "fig2dev.h"
  1299. X#include "psfonts.h"
  1300. X#include <string.h>
  1301. X#include <time.h>
  1302. X
  1303. X/* for the version nubmer */
  1304. X#include "../../patchlevel.h"
  1305. X
  1306. X#ifdef A4
  1307. X#define        PAGE_WIDTH        595    /* points; 21cm */
  1308. X#define        PAGE_HEIGHT        842    /* points; 29.7cm */
  1309. X#else
  1310. X#define        PAGE_WIDTH        612    /* points; 8.5" */
  1311. X#define        PAGE_HEIGHT        792    /* points; 11" */
  1312. X#endif
  1313. X#define        TRUE            1
  1314. X#define        FALSE            0
  1315. X#define        POINT_PER_INCH        72
  1316. X#define        ULIMIT_FONT_SIZE    300
  1317. X#define     MAXCOLORS         16
  1318. X
  1319. Xint        pagewidth = PAGE_WIDTH;
  1320. Xint        pageheight = PAGE_HEIGHT;
  1321. Xstatic int    coord_system;
  1322. Xint        show_page = 0;
  1323. Xstatic int    cur_thickness;
  1324. Xint        center = 0;
  1325. Xint        landscape = 0;
  1326. Xint        pages;
  1327. Xint        no_obj = 0;
  1328. Xint        multi_page = FALSE;
  1329. X
  1330. Xextern    int    v2_flag, v21_flag;
  1331. X
  1332. Xstatic    arc_tangent();
  1333. Xstatic    draw_arrow_head();
  1334. Xstatic    fill_area();
  1335. Xstatic    iso_text_exist();
  1336. Xstatic    encode_all_fonts();
  1337. Xstatic    ellipse_exist();
  1338. Xstatic    normal_spline_exist();
  1339. X
  1340. X#define GRAYVAL(F)    ((F) <= 21 ? ((F)-1)/20.0 : 1.0)
  1341. X
  1342. X#define        BEGIN_PROLOG    "\
  1343. X/$F2psDict 200 dict def \n\
  1344. X$F2psDict begin\n\
  1345. X$F2psDict /mtrx matrix put\n\
  1346. X/l {lineto} bind def\n\
  1347. X/m {moveto} bind def\n\
  1348. X/s {stroke} bind def\n\
  1349. X/n {newpath} bind def\n\
  1350. X/gs {gsave} bind def\n\
  1351. X/gr {grestore} bind def\n\
  1352. X/clp {closepath} bind def\n\
  1353. X/graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul\n\
  1354. X4 -2 roll mul setrgbcolor} bind def\n\
  1355. X/col-1 {} def\n\
  1356. X/col0 {0 0 0 setrgbcolor} bind def\n\
  1357. X/col1 {0 0 1 setrgbcolor} bind def\n\
  1358. X/col2 {0 1 0 setrgbcolor} bind def\n\
  1359. X/col3 {0 1 1 setrgbcolor} bind def\n\
  1360. X/col4 {1 0 0 setrgbcolor} bind def\n\
  1361. X/col5 {1 0 1 setrgbcolor} bind def\n\
  1362. X/col6 {1 1 0 setrgbcolor} bind def\n\
  1363. X/col7 {1 1 1 setrgbcolor} bind def\n\
  1364. X/col8 {.68 .85 .9 setrgbcolor} bind def\n\
  1365. X/col9 {0 .39 0 setrgbcolor} bind def\n\
  1366. X/col10 {.65 .17 .17 setrgbcolor} bind def\n\
  1367. X/col11 {1 .51 0 setrgbcolor} bind def\n\
  1368. X/col12 {.63 .13 .94 setrgbcolor} bind def\n\
  1369. X/col13 {1 .75 .8 setrgbcolor} bind def\n\
  1370. X/col14 {.7 .13 .13 setrgbcolor} bind def\n\
  1371. X/col15 {1 .84 0 setrgbcolor} bind def\n\
  1372. X"
  1373. X
  1374. X#define        SPECIAL_CHAR_1    "\
  1375. X/reencdict 12 dict def /ReEncode { reencdict begin\n\
  1376. X/newcodesandnames exch def /newfontname exch def /basefontname exch def\n\
  1377. X/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def\n\
  1378. Xbasefontdict { exch dup /FID ne { dup /Encoding eq\n\
  1379. X{ exch dup length array copy newfont 3 1 roll put }\n\
  1380. X{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall\n\
  1381. Xnewfont /FontName newfontname put newcodesandnames aload pop\n\
  1382. X128 1 255 { newfont /Encoding get exch /.notdef put } for\n\
  1383. Xnewcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat\n\
  1384. Xnewfontname newfont definefont pop end } def\n\
  1385. X/isovec [ \n\
  1386. X"
  1387. X#define        SPECIAL_CHAR_2    "\
  1388. X8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde\n\
  1389. X8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis\n\
  1390. X8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron\n\
  1391. X8#220 /dotlessi 8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling\n\
  1392. X8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis\n\
  1393. X8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot\n\
  1394. X8#255 /endash 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus\n\
  1395. X8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph\n\
  1396. X8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine\n\
  1397. X8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf \n\
  1398. X8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute\n\
  1399. X8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring\n\
  1400. X"
  1401. X#define        SPECIAL_CHAR_3    "\
  1402. X8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute\n\
  1403. X8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute\n\
  1404. X8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve\n\
  1405. X8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply\n\
  1406. X8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex\n\
  1407. X8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave\n\
  1408. X8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring\n\
  1409. X8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute\n\
  1410. X8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute\n\
  1411. X8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve\n\
  1412. X8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide\n\
  1413. X8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex\n\
  1414. X8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis \
  1415. X] def\n\
  1416. X"
  1417. X
  1418. X#define        ELLIPSE_PS    " \
  1419. X/DrawEllipse {\n\
  1420. X    /endangle exch def\n\
  1421. X    /startangle exch def\n\
  1422. X    /yrad exch def\n\
  1423. X    /xrad exch def\n\
  1424. X    /y exch def\n\
  1425. X    /x exch def\n\
  1426. X    /savematrix mtrx currentmatrix def\n\
  1427. X    x y translate xrad yrad scale 0 0 1 startangle endangle arc\n\
  1428. X    savematrix setmatrix\n\
  1429. X    } def\n\
  1430. X"
  1431. X/* The original PostScript definition for adding a spline section to the
  1432. X * current path uses recursive bisection.  The following definition using the
  1433. X * curveto operator is more efficient since it executes at compiled rather
  1434. X * than interpreted code speed.  The Bezier control points are 2/3 of the way
  1435. X * from z1 (and z3) to z2.
  1436. X *
  1437. X * ---Rene Llames, 21 July 1988.
  1438. X */
  1439. X#define        SPLINE_PS    " \
  1440. X/DrawSplineSection {\n\
  1441. X    /y3 exch def\n\
  1442. X    /x3 exch def\n\
  1443. X    /y2 exch def\n\
  1444. X    /x2 exch def\n\
  1445. X    /y1 exch def\n\
  1446. X    /x1 exch def\n\
  1447. X    /xa x1 x2 x1 sub 0.666667 mul add def\n\
  1448. X    /ya y1 y2 y1 sub 0.666667 mul add def\n\
  1449. X    /xb x3 x2 x3 sub 0.666667 mul add def\n\
  1450. X    /yb y3 y2 y3 sub 0.666667 mul add def\n\
  1451. X    x1 y1 lineto\n\
  1452. X    xa ya xb yb x3 y3 curveto\n\
  1453. X    } def\n\
  1454. X"
  1455. X#define        END_PROLOG    "\
  1456. X    end\n\
  1457. X/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def\n\
  1458. X/$F2psEnd {$F2psEnteredState restore end} def\n\
  1459. X%%EndProlog\n\
  1460. X"
  1461. X
  1462. Xstatic double        tx, scalex, scaley;
  1463. Xstatic double        dx, dy, origx, origy;
  1464. X
  1465. Xvoid genps_option(opt, optarg)
  1466. Xchar opt;
  1467. Xchar *optarg;
  1468. X{
  1469. X    int i;
  1470. X
  1471. X    switch (opt) {
  1472. X
  1473. X    case 'f':
  1474. X        for ( i = 1; i <= MAX_PSFONT + 1; i++ )
  1475. X            if ( !strcmp(optarg, PSfontnames[i]) ) break;
  1476. X
  1477. X        if ( i > MAX_PSFONT + 1 )
  1478. X            fprintf(stderr,
  1479. X                "warning: non-standard font name %s\n", optarg);
  1480. X
  1481. X            psfontnames[0] = psfontnames[1] = optarg;
  1482. X            PSfontnames[0] = PSfontnames[1] = optarg;
  1483. X            break;
  1484. X
  1485. X    case 'c':
  1486. X            center = 1;
  1487. X        break;
  1488. X
  1489. X    case 's':
  1490. X        if (font_size <= 0 || font_size > ULIMIT_FONT_SIZE) {
  1491. X            fprintf(stderr,
  1492. X                "warning: font size %d out of bounds\n", font_size);
  1493. X        }
  1494. X        break;
  1495. X
  1496. X    case 'P':
  1497. X        show_page = 1;
  1498. X        break;
  1499. X
  1500. X          case 'm':
  1501. X          case 'L':
  1502. X        break;
  1503. X
  1504. X          case 'l':
  1505. X        landscape = 1;
  1506. X        break;
  1507. X
  1508. X    default:
  1509. X        put_msg(Err_badarg, opt, "ps");
  1510. X        exit(1);
  1511. X        break;
  1512. X    }
  1513. X}
  1514. X
  1515. Xvoid genps_start(objects)
  1516. XF_compound    *objects;
  1517. X{
  1518. X    char        host[256];
  1519. X    struct passwd    *who;
  1520. X    time_t        when;
  1521. X    int        itmp;
  1522. X    int        resolution;
  1523. X
  1524. X    resolution = objects->nwcorner.x;
  1525. X    coord_system = objects->nwcorner.y;
  1526. X    scalex = scaley = mag * POINT_PER_INCH / (double)resolution;
  1527. X    /* convert to point unit */
  1528. X    llx = (int)ceil(llx * scalex); lly = (int)ceil(lly * scaley);
  1529. X    urx = (int)ceil(urx * scalex); ury = (int)ceil(ury * scaley);
  1530. X
  1531. X
  1532. X    if (landscape)
  1533. X    {
  1534. X       itmp = pageheight; pageheight = pagewidth; pagewidth = itmp;
  1535. X       itmp = llx; llx = lly; lly = itmp;
  1536. X       itmp = urx; urx = ury; ury = itmp;
  1537. X    }
  1538. X    if (show_page)
  1539. X    {
  1540. X       if (center)
  1541. X       {
  1542. X          if (landscape)
  1543. X          {
  1544. X         origx = (pageheight - urx - llx)/2.0;
  1545. X         origy = (pagewidth - ury - lly)/2.0;
  1546. X          }
  1547. X          else
  1548. X          {
  1549. X         origx = (pagewidth - urx - llx)/2.0;
  1550. X         origy = (pageheight + ury + lly)/2.0;
  1551. X          }
  1552. X       }
  1553. X       else
  1554. X       {
  1555. X          origx = 0.0;
  1556. X          origy = landscape ? 0.0 : pageheight;
  1557. X       }
  1558. X    }
  1559. X    else
  1560. X    {
  1561. X       origx = -llx;
  1562. X       origy = landscape ? -lly : ury;
  1563. X    }
  1564. X
  1565. X    if (coord_system == 2) scaley = -scaley;
  1566. X
  1567. X    if (show_page)
  1568. X        fprintf(tfp, "%%!PS-Adobe-2.0\n");        /* PostScript magic strings */
  1569. X    else
  1570. X        fprintf(tfp, "%%!PS-Adobe-2.0 EPSF-2.0\n");    /* Encapsulated PostScript */
  1571. X    who = getpwuid(getuid());
  1572. X    if (-1 == gethostname(host, sizeof(host)))
  1573. X        (void)strcpy(host, "unknown-host!?!?");
  1574. X    (void) time(&when);
  1575. X    fprintf(tfp, "%%%%Title: %s\n", ((from) ? from : "stdin"));
  1576. X    fprintf(tfp, "%%%%Creator: %s Version %s Patchlevel %s\n", 
  1577. X        prog, VERSION, PATCHLEVEL);
  1578. X    fprintf(tfp, "%%%%CreationDate: %s", ctime(&when));
  1579. X    if (who)
  1580. X       fprintf(tfp, "%%%%For: %s@%s (%s)\n",
  1581. X            who->pw_name, host, who->pw_gecos);
  1582. X
  1583. X    if (!center)
  1584. X       if (landscape)
  1585. X        pages = (urx/pageheight+1)*(ury/pagewidth+1);
  1586. X       else
  1587. X        pages = (urx/pagewidth+1)*(ury/pageheight+1);
  1588. X    else
  1589. X       pages = 1;
  1590. X    if (landscape) {
  1591. X       fprintf(tfp, "%%%%Orientation: Landscape\n");
  1592. X       fprintf(tfp, "%%%%BoundingBox: %d %d %d %d\n", 
  1593. X          (int)origx+llx, (int)origy+lly, (int)origx+urx, (int)origy+ury);
  1594. X    } else {
  1595. X       fprintf(tfp, "%%%%Orientation: Portrait\n");
  1596. X       fprintf(tfp, "%%%%BoundingBox: %d %d %d %d\n", 
  1597. X          (int)origx+llx, (int)origy-ury, (int)origx+urx, (int)origy-lly);
  1598. X    }
  1599. X    fprintf(tfp, "%%%%Pages: %d\n", show_page ? pages : 0 );
  1600. X
  1601. X    fprintf(tfp, "%%%%EndComments\n");
  1602. X    fprintf(tfp, "%s", BEGIN_PROLOG);
  1603. X    if (iso_text_exist(objects))
  1604. X    {
  1605. X       fprintf(tfp, "%s%s%s", SPECIAL_CHAR_1,SPECIAL_CHAR_2,SPECIAL_CHAR_3);
  1606. X       encode_all_fonts(objects);
  1607. X    }
  1608. X    if (ellipse_exist(objects)) fprintf(tfp, "%s\n", ELLIPSE_PS);
  1609. X    if (normal_spline_exist(objects)) fprintf(tfp, "%s\n", SPLINE_PS);
  1610. X    fprintf(tfp, "%s\n", END_PROLOG);
  1611. X    fprintf(tfp, "$F2psBegin\n");
  1612. X     fprintf(tfp, "0 setlinecap 0 setlinejoin\n");
  1613. X  
  1614. X     if ( pages > 1 && show_page && !center )
  1615. X        multi_page = TRUE;
  1616. X     else
  1617. X     {
  1618. X        fprintf (tfp, "%.1f %.1f translate", origx, origy);
  1619. X        if (landscape)
  1620. X        {
  1621. X           fprintf (tfp, " 90 rotate");
  1622. X        }
  1623. X        fprintf (tfp, " %.3f %.3f scale\n", scalex, scaley );
  1624. X    }
  1625. X}
  1626. X
  1627. Xvoid genps_end()
  1628. X{
  1629. X    double dx,dy;
  1630. X    int i, page;
  1631. X    int h,w;
  1632. X  
  1633. X    if (multi_page)
  1634. X    {
  1635. X       page = 1;
  1636. X       h = (landscape? pagewidth: pageheight);
  1637. X       w = (landscape? pageheight: pagewidth);
  1638. X       for (dy=0; dy < (ury-h*0.1); dy += h*0.9)
  1639. X       {
  1640. X     for (dx=0; dx < (urx-w*0.1); dx += w*0.9)
  1641. X     {
  1642. X        fprintf (tfp, "%%%%Page: %d %d\n%.1f %.1f translate", 
  1643. X        page,page,
  1644. X        -(origx+dx), (origy+(landscape?-dy:dy)));
  1645. X        if (landscape)
  1646. X        {
  1647. X           fprintf(tfp, " 90 rotate");
  1648. X        }
  1649. X        fprintf (tfp, " %.3f %.3f scale\n", scalex, scaley);
  1650. X        for (i=0; i<no_obj; i++)
  1651. X        {
  1652. X           fprintf(tfp, "o%d ", i);
  1653. X           if (!(i%20)) fprintf(tfp, "\n", i);
  1654. X        }
  1655. X        fprintf(tfp, "showpage\n");
  1656. X        page++;
  1657. X     }
  1658. X       }
  1659. X    }
  1660. X    else
  1661. X       if (show_page) fprintf(tfp, "showpage\n");
  1662. X    fprintf(tfp, "$F2psEnd\n");
  1663. X}
  1664. Xstatic set_style(s, v)
  1665. Xint    s;
  1666. Xdouble    v;
  1667. X{
  1668. X    if (s == DASH_LINE) {
  1669. X        if (v > 0.0) fprintf(tfp, "\t[%f] 0 setdash\n", v);
  1670. X        }
  1671. X    else if (s == DOTTED_LINE) {
  1672. X        if (v > 0.0) fprintf(tfp, "\t1 setlinecap [1 %f] %f setdash\n", v, v);
  1673. X        }
  1674. X    }
  1675. X
  1676. Xstatic reset_style(s, v)
  1677. Xint    s;
  1678. Xdouble    v;
  1679. X{
  1680. X    if (s == DASH_LINE) {
  1681. X        if (v > 0.0) fprintf(tfp, "\t[] 0 setdash\n");
  1682. X        }
  1683. X    else if (s == DOTTED_LINE) {
  1684. X        if (v > 0.0) fprintf(tfp, "\t[] 0 setdash 0 setlinecap\n");
  1685. X        }
  1686. X    }
  1687. X
  1688. Xstatic set_linewidth(w)
  1689. Xint    w;
  1690. X{
  1691. X    extern int    cur_thickness;
  1692. X
  1693. X    if (w != cur_thickness) {
  1694. X        cur_thickness = w;
  1695. X        fprintf(tfp, "%.3f setlinewidth\n", cur_thickness <= 1 ? 0.5* cur_thickness : cur_thickness -1.0);
  1696. X        }
  1697. X    }
  1698. X
  1699. Xvoid genps_line(l)
  1700. XF_line    *l;
  1701. X{
  1702. X    F_point        *p, *q;
  1703. X    /* JNT */
  1704. X    int        radius, i = 0;
  1705. X    FILE        *epsf;
  1706. X    char        buf[512];
  1707. X    char        *cp;
  1708. X    int        xmin,xmax,ymin,ymax;
  1709. X    int        eps_w, eps_h;
  1710. X    double        fllx, flly, furx, fury;
  1711. X    
  1712. X    if (multi_page)
  1713. X       fprintf(tfp, "/o%d {", no_obj++);
  1714. X    if (l->type != T_EPS_BOX)  /* eps object has no line thickness */
  1715. X        set_linewidth(l->thickness);
  1716. X    radius = l->radius;        /* radius of rounded-corner boxes */
  1717. X    p = l->points;
  1718. X    q = p->next;
  1719. X    if (q == NULL) { /* A single point line */
  1720. X        fprintf(tfp, "n %d %d m %d %d l gs col%d s gr\n",
  1721. X            p->x, p->y, p->x, p->y, l->color > MAXCOLORS ? -1 : l->color);
  1722. X        if (multi_page)
  1723. X           fprintf(tfp, "} bind def\n");
  1724. X        return;
  1725. X        }
  1726. X    if (l->back_arrow && l->thickness > 0)
  1727. X        draw_arrow_head((double)q->x, (double)q->y, (double)p->x,
  1728. X            (double)p->y, l->back_arrow->ht, l->back_arrow->wid,
  1729. X            l->color);
  1730. X    if (l->type != T_EPS_BOX)  /* eps object has no line style */
  1731. X        set_style(l->style, l->style_val);
  1732. X    fprintf(tfp, "%% Polyline\n");
  1733. X
  1734. X    xmin = xmax = p->x;
  1735. X    ymin = ymax = p->y;
  1736. X    while (p->next != NULL) /* find lower left and upper right corne
  1737. Xrs */
  1738. X    {
  1739. X        p=p->next;
  1740. X        if (xmin > p->x)
  1741. X            xmin = p->x;
  1742. X        else if (xmax < p->x)
  1743. X            xmax = p->x;
  1744. X        if (ymin > p->y)
  1745. X            ymin = p->y;
  1746. X        else if (ymax < p->y)
  1747. X            ymax = p->y;
  1748. X        }
  1749. X
  1750. X    if (l->type == T_ARC_BOX)
  1751. X    {
  1752. X        fprintf(tfp, "n %d %d m",xmin+radius, ymin);
  1753. X        fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat",
  1754. X                xmin, ymin, xmin, ymax-radius, radius);
  1755. X        fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc through bl to br */
  1756. X                xmin, ymax, xmax-radius, ymax, radius);
  1757. X        fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc through br to tr */
  1758. X                xmax, ymax, xmax, ymin+radius, radius);
  1759. X        fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc through tr to tl */
  1760. X                xmax, ymin, xmin+radius, ymin, radius);
  1761. X    }
  1762. X    else if (l->type == T_EPS_BOX)  /* encapsulated postscript (eps) file */
  1763. X    {
  1764. X        int             dx, dy, rotation;
  1765. X        int        llx, lly, urx, ury;
  1766. X        double          fllx, flly, furx, fury;
  1767. X
  1768. X        dx = l->points->next->next->x - l->points->x;
  1769. X        dy = l->points->next->next->y - l->points->y;
  1770. X        rotation = 0;
  1771. X        if (dx < 0 && dy < 0)
  1772. X               rotation = 180;
  1773. X        else if (dx < 0 && dy >= 0)
  1774. X               rotation = 270;
  1775. X        else if (dy < 0 && dx >= 0)
  1776. X               rotation = 90;
  1777. X
  1778. X        fprintf(tfp, "%%\n");
  1779. X        fprintf(tfp, "%% Begin Imported EPS File: %s\n", l->eps->file);
  1780. X        fprintf(tfp, "%%\n");
  1781. X        epsf = fopen(l->eps->file, "r");
  1782. X        if (epsf == NULL) {
  1783. X            fprintf (stderr, "Unable to open eps file: %s, error: (%d)\n",
  1784. X                l->eps->file, sys_errlist[errno],errno);
  1785. X            return;
  1786. X        }
  1787. X        while (fgets(buf, 512, epsf) != NULL) {
  1788. X          lower(buf);
  1789. X          if (!strncmp(buf, "%%boundingbox", 13)) {
  1790. X            if (sscanf(buf, "%%%%boundingbox: %lf %lf %lf %lf",
  1791. X                       &fllx, &flly, &furx, &fury) < 4) {
  1792. X              fprintf(stderr,"Bad EPS bitmap file: %s", l->eps->file);
  1793. X              fclose(epsf);
  1794. X              return;
  1795. X            }
  1796. X            llx= floor(fllx);
  1797. X            lly= floor(flly);
  1798. X            urx= ceil(furx);
  1799. X            ury= ceil(fury);
  1800. X            break;
  1801. X          }
  1802. X        }
  1803. X        fclose(epsf);
  1804. X
  1805. X        fprintf(tfp, "n gs\n");
  1806. X        if (((rotation == 90 || rotation == 270) && !l->eps->flipped) ||
  1807. X            (rotation != 90 && rotation != 270 && l->eps->flipped)) {
  1808. X            eps_h = urx - llx;
  1809. X            eps_w = ury - lly;
  1810. X        } else {
  1811. X            eps_w = urx - llx;
  1812. X            eps_h = ury - lly;
  1813. X        }
  1814. X
  1815. X        /* translate the eps stuff to the right spot on the page */
  1816. X        fprintf(tfp, "%d %d translate\n", xmin, ymin);
  1817. X
  1818. X        /* scale the eps stuff to fit into the bounding box */
  1819. X        /* Note: the origin for fig is in the upper-right corner;
  1820. X         *       for postscript its in the lower right hand corner.
  1821. X         *       To fix it, we use a "negative"-y scale factor, then
  1822. X         *       translate the image up on the page */
  1823. X        fprintf(tfp, "%f %f scale\n",
  1824. X            fabs((double)(xmax-xmin)/eps_w), -1.0*(double)(ymax-ymin)/eps_h);
  1825. X        fprintf(tfp, "0 %d translate\n", -eps_h);
  1826. X
  1827. X        /* flip the eps stuff */
  1828. X        /* always translate it back so that the lower-left corner is at the origin */
  1829. X        if (l->eps->flipped && rotation==90) {
  1830. X            fprintf(tfp, "0 %d translate\n", eps_h);
  1831. X            fprintf(tfp, "1 -1 scale\n");
  1832. X        }
  1833. X        if (l->eps->flipped && rotation==270) {
  1834. X            fprintf(tfp, "%d 0 translate\n", eps_w);
  1835. X            fprintf(tfp, "-1 1 scale\n");
  1836. X        }
  1837. X
  1838. X        /* note: fig measures rotation clockwise; postscript is counter-clockwise */
  1839. X        /* always translate it back so that the lower-left corner is at the origin */
  1840. X        switch (rotation) {
  1841. X           case 0:
  1842. X            break;
  1843. X           case 90:
  1844. X            if (l->eps->flipped) break;
  1845. X            fprintf(tfp, "%d %d translate\n", 0, eps_h);
  1846. X            fprintf(tfp, "%d rotate\n", 270);
  1847. X            break;
  1848. X           case 180:
  1849. X            fprintf(tfp, "%d %d translate\n", eps_w, eps_h);
  1850. X            fprintf(tfp, "%d rotate\n", 180);
  1851. X            break;
  1852. X           case 270:
  1853. X            if (l->eps->flipped) break;
  1854. X            fprintf(tfp, "%d %d translate\n", eps_w, 0);
  1855. X            fprintf(tfp, "%d rotate\n", 90);
  1856. X            break;
  1857. X        }
  1858. X
  1859. X        /* translate the eps stuff so that the lower-left corner is at the origin */
  1860. X        fprintf(tfp, "%d %d translate\n", -llx, -lly);
  1861. X        /* save vm so eps file won't change anything */
  1862. X        fprintf(tfp, "save\n");
  1863. X        fprintf(tfp, "%% EPS file follows:\n");
  1864. X        epsf = fopen(l->eps->file, "r");
  1865. X        if (epsf == NULL) {
  1866. X            fprintf (stderr, "Unable to open eps file: %s, error: (%d)\n",
  1867. X                l->eps->file, sys_errlist[errno],errno);
  1868. X            fprintf(tfp, "gr\n");
  1869. X            return;
  1870. X        }
  1871. X        while (fgets(buf, sizeof(buf), epsf) != NULL) {
  1872. X            if (*buf == '%')        /* skip comment lines */
  1873. X                continue;
  1874. X            if ((cp=strstr(buf, "showpage")) != NULL)
  1875. X                strcpy (cp, cp+8);    /* remove showpage */
  1876. X            fputs(buf, tfp);
  1877. X        }
  1878. X        fclose (epsf);
  1879. X        /* restore vm and gsave */
  1880. X        fprintf(tfp, "restore gr\n");
  1881. X        fprintf(tfp, "%%\n");
  1882. X        fprintf(tfp, "%% End Imported EPS File: %s\n", l->eps->file);
  1883. X        fprintf(tfp, "%%\n");
  1884. X    }
  1885. X    else
  1886. X    {
  1887. X        p = l->points;
  1888. X        q = p->next;
  1889. X        fprintf(tfp, "n %d %d m", p->x, p->y);
  1890. X        while (q->next != NULL) {
  1891. X            p = q;
  1892. X            q = q->next;
  1893. X            fprintf(tfp, " %d %d l ", p->x, p->y);
  1894. X                 if (!((++i)%5)) 
  1895. X            fprintf(tfp, "\n");
  1896. X        }
  1897. X    }
  1898. X    if (l->type != T_EPS_BOX) {
  1899. X        if (l->type == T_POLYLINE)
  1900. X            fprintf(tfp, " %d %d l ", q->x, q->y);
  1901. X        else 
  1902. X            fprintf(tfp, " clp ");
  1903. X        if (l->area_fill && (int)l->area_fill != DEFAULT)
  1904. X            fill_area(l->area_fill, l->color);
  1905. X        if (l->thickness > 0)
  1906. X             fprintf(tfp, "gs col%d s gr\n",
  1907. X                l->color > MAXCOLORS ? -1 : l->color);
  1908. X
  1909. X        reset_style(l->style, l->style_val);
  1910. X        if (l->for_arrow && l->thickness > 0)
  1911. X            draw_arrow_head((double)p->x, (double)p->y, (double)q->x,
  1912. X                (double)q->y, l->for_arrow->ht, l->for_arrow->wid,
  1913. X                l->color);
  1914. X    }
  1915. X    if (multi_page)
  1916. X       fprintf(tfp, "} bind def\n");
  1917. X    }
  1918. X
  1919. Xvoid genps_spline(s)
  1920. XF_spline    *s;
  1921. X{
  1922. X    if (multi_page)
  1923. X       fprintf(tfp, "/o%d {", no_obj++);
  1924. X    if (int_spline(s))
  1925. X        genps_itp_spline(s);
  1926. X    else
  1927. X        genps_ctl_spline(s);
  1928. X    if (multi_page)
  1929. X       fprintf(tfp, "} bind def\n");
  1930. X    }
  1931. X
  1932. Xgenps_itp_spline(s)
  1933. XF_spline    *s;
  1934. X{
  1935. X    F_point        *p, *q;
  1936. X    F_control    *a, *b;
  1937. X
  1938. X    set_linewidth(s->thickness);
  1939. X    a = s->controls;
  1940. X    p = s->points;
  1941. X    if (s->back_arrow && s->thickness > 0)
  1942. X        draw_arrow_head(a->rx, a->ry, (double)p->x,
  1943. X            (double)p->y, s->back_arrow->ht, s->back_arrow->wid,
  1944. X            s->color);
  1945. X
  1946. X    set_style(s->style, s->style_val);
  1947. X    fprintf(tfp, "%% Interpolated spline\n");
  1948. X    fprintf(tfp, "n %d %d m\n", p->x, p->y);
  1949. X    for (q = p->next; q != NULL; p = q, q = q->next) {
  1950. X        b = a->next;
  1951. X        fprintf(tfp, "\t%.3f %.3f %.3f %.3f %d %d curveto\n",
  1952. X            a->rx, a->ry, b->lx, b->ly, q->x, q->y);
  1953. X        a = b;
  1954. X        }
  1955. X    if (closed_spline(s)) fprintf(tfp, " clp ");
  1956. X    if (s->area_fill && (int)s->area_fill != DEFAULT)
  1957. X        fill_area(s->area_fill, s->color);
  1958. X    if (s->thickness > 0)
  1959. X        fprintf(tfp, "gs col%d s gr\n", s->color > MAXCOLORS ? -1 : s->color);
  1960. X    reset_style(s->style, s->style_val);
  1961. X
  1962. X    if (s->for_arrow && s->thickness > 0)
  1963. X        draw_arrow_head(a->lx, a->ly, (double)p->x,
  1964. X            (double)p->y, s->for_arrow->ht, s->for_arrow->wid,
  1965. X            s->color);
  1966. X    }
  1967. X
  1968. Xgenps_ctl_spline(s)
  1969. XF_spline    *s;
  1970. X{
  1971. X    double        a, b, c, d, x1, y1, x2, y2, x3, y3;
  1972. X    F_point        *p, *q;
  1973. X
  1974. X    /*
  1975. X    if (first) {
  1976. X        first = FALSE;
  1977. X        fprintf(tfp, "%s\n", SPLINE_PS);
  1978. X        }
  1979. X    */
  1980. X
  1981. X    p = s->points;
  1982. X    x1 = p->x; y1 = p->y;
  1983. X    p = p->next;
  1984. X    c = p->x; d = p->y;
  1985. X    set_linewidth(s->thickness);
  1986. X    x3 = a = (x1 + c) / 2;
  1987. X    y3 = b = (y1 + d) / 2;
  1988. X    if (s->back_arrow && s->thickness > 0) {
  1989. X        draw_arrow_head(c, d, x1, y1, s->back_arrow->ht, s->back_arrow->wid,
  1990. X                s->color);
  1991. X        }
  1992. X    set_style(s->style, s->style_val);
  1993. X    if (! closed_spline(s)) {
  1994. X        fprintf(tfp, "%% Open spline\n");
  1995. X        fprintf(tfp, "n %.3f %.3f m %.3f %.3f l\n",
  1996. X            x1, y1, x3, y3);
  1997. X        }
  1998. X    else {
  1999. X        fprintf(tfp, "%% Closed spline\n");
  2000. X        fprintf(tfp, "n %.3f %.3f m\n", a, b);
  2001. X        }
  2002. X    for (q = p->next; q != NULL; p = q, q = q->next) {
  2003. X        x1 = x3; y1 = y3;
  2004. X        x2 = c;  y2 = d;
  2005. X        c = q->x; d = q->y;
  2006. X        x3 = (x2 + c) / 2;
  2007. X        y3 = (y2 + d) / 2;
  2008. X        fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection\n",
  2009. X            x1, y1, x2, y2, x3, y3);
  2010. X        }
  2011. X    /*
  2012. X    * At this point, (x2,y2) and (c,d) are the position of the 
  2013. X    * next-to-last and last point respectively, in the point list
  2014. X    */
  2015. X    if (closed_spline(s)) {
  2016. X        fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection closepath ",
  2017. X            x3, y3, c, d, a, b);
  2018. X        }
  2019. X    else {
  2020. X        fprintf(tfp, "\t%.3f %.3f l ", c, d);
  2021. X        }
  2022. X    if (s->area_fill && (int)s->area_fill != DEFAULT)
  2023. X        fill_area(s->area_fill, s->color);
  2024. X    if (s->thickness > 0)
  2025. X        fprintf(tfp, "gs col%d s gr\n", s->color > MAXCOLORS ? -1 : s->color);
  2026. X    reset_style(s->style, s->style_val);
  2027. X    if (s->for_arrow && s->thickness > 0) {
  2028. X        draw_arrow_head(x2, y2, c, d, s->for_arrow->ht,
  2029. X                s->for_arrow->wid, s->color);
  2030. X        }
  2031. X    }
  2032. X
  2033. Xvoid genps_ellipse(e)
  2034. XF_ellipse    *e;
  2035. X{
  2036. X    if (multi_page)
  2037. X       fprintf(tfp, "/o%d {", no_obj++);
  2038. X    set_linewidth(e->thickness);
  2039. X    set_style(e->style, e->style_val);
  2040. X    if (e->angle == 0)
  2041. X    {
  2042. X        fprintf(tfp, "%% Ellipse\n");
  2043. X        fprintf(tfp, "n %d %d %d %d 0 360 DrawEllipse ",
  2044. X          e->center.x, e->center.y, e->radiuses.x, e->radiuses.y);
  2045. X    }
  2046. X    else
  2047. X    {
  2048. X        fprintf(tfp, "%% Rotated Ellipse\n");
  2049. X        fprintf(tfp, "gs\n");
  2050. X        fprintf(tfp, "%d %d translate\n",e->center.x, e->center.y);
  2051. X        fprintf(tfp, "%6.3f rotate\n",-e->angle*180/M_PI);
  2052. X        fprintf(tfp, "n 0 0 %d %d 0 360 DrawEllipse ",
  2053. X         e->radiuses.x, e->radiuses.y);
  2054. X    }
  2055. X    if (e->area_fill && (int)e->area_fill != DEFAULT)
  2056. X        fill_area(e->area_fill, e->color);
  2057. X    if (e->thickness > 0)
  2058. X        fprintf(tfp, "gs col%d s gr\n", e->color > MAXCOLORS ? -1 : e->color);
  2059. X    if (e->angle != 0)
  2060. X        fprintf(tfp, "gr\n");
  2061. X    reset_style(e->style, e->style_val);
  2062. X    if (multi_page)
  2063. X       fprintf(tfp, "} bind def\n");
  2064. X    }
  2065. X
  2066. X#define    TEXT_PS        "\
  2067. X/%s%s findfont %.2f scalefont setfont\n\
  2068. X"
  2069. Xvoid genps_text(t)
  2070. XF_text    *t;
  2071. X{
  2072. X    unsigned char        *cp;
  2073. X
  2074. X    if (multi_page)
  2075. X       fprintf(tfp, "/o%d {", no_obj++);
  2076. X    if (PSisomap[t->font+1] == TRUE)
  2077. X       fprintf(tfp, TEXT_PS, PSFONT(t), "-iso", PSFONTMAG(t));
  2078. X    else
  2079. X       fprintf(tfp, TEXT_PS, PSFONT(t), "", PSFONTMAG(t));
  2080. X
  2081. X    fprintf(tfp, "%d %d m \ngs ", t->base_x,  t->base_y);
  2082. X    if (coord_system == 2) fprintf(tfp, "1 -1 scale ");
  2083. X
  2084. X    if (t->angle != 0)
  2085. X       fprintf(tfp, " %.1f rotate ", t->angle*180/M_PI);
  2086. X    /* this loop escapes characters '(', ')', and '\' */
  2087. X    fputc('(', tfp);
  2088. X    for(cp = (unsigned char *)t->cstring; *cp; cp++) {
  2089. X        if (strchr("()\\", *cp)) 
  2090. X        fputc('\\', tfp);
  2091. X        if (*cp>=0x80)
  2092. X        fprintf(tfp,"\\%o", *cp);
  2093. X        else
  2094. X        fputc(*cp, tfp);
  2095. X        }
  2096. X    fputc(')', tfp);
  2097. X
  2098. X    if ((t->type == T_CENTER_JUSTIFIED) || (t->type == T_RIGHT_JUSTIFIED)){
  2099. X
  2100. X          fprintf(tfp, " dup stringwidth pop ");
  2101. X        if (t->type == T_CENTER_JUSTIFIED) fprintf(tfp, "2 div ");
  2102. X        fprintf(tfp, "neg 0 rmoveto ");
  2103. X        }
  2104. X
  2105. X    else if ((t->type != T_LEFT_JUSTIFIED) && (t->type != DEFAULT))
  2106. X        fprintf(stderr, "Text incorrectly positioned\n");
  2107. X
  2108. X    fprintf(tfp, " col%d show gr\n", t->color > MAXCOLORS ? -1 : t->color);
  2109. X
  2110. X    if (multi_page)
  2111. X       fprintf(tfp, "} bind def\n");
  2112. X    }
  2113. X
  2114. Xvoid genps_arc(a)
  2115. XF_arc    *a;
  2116. X{
  2117. X    double        angle1, angle2, dx, dy, radius, x, y;
  2118. X    double        cx, cy, sx, sy, ex, ey;
  2119. X    int        direction;
  2120. X
  2121. X    if (multi_page)
  2122. X       fprintf(tfp, "/o%d {", no_obj++);
  2123. X    cx = a->center.x; cy = a->center.y;
  2124. X    sx = a->point[0].x; sy = a->point[0].y;
  2125. X    ex = a->point[2].x; ey = a->point[2].y;
  2126. X
  2127. X    if (coord_system == 2)
  2128. X        direction = !a->direction;
  2129. X    else
  2130. X        direction = a->direction;
  2131. X    set_linewidth(a->thickness);
  2132. X    if (a->for_arrow && a->thickness > 0) {
  2133. X        arc_tangent(cx, cy, ex, ey, direction, &x, &y);
  2134. X        draw_arrow_head(x, y, ex, ey, a->for_arrow->ht, a->for_arrow->wid, a->color);
  2135. X        }
  2136. X    if (a->back_arrow && a->thickness > 0) {
  2137. X        arc_tangent(cx, cy, sx, sy, !direction, &x, &y);
  2138. X        draw_arrow_head(x, y, sx, sy, a->back_arrow->ht, a->back_arrow->wid, a->color);
  2139. X        }
  2140. X    dx = cx - sx;
  2141. X    dy = cy - sy;
  2142. X    radius = sqrt(dx*dx+dy*dy);
  2143. X    angle1 = atan2(sy-cy, sx-cx) * 180 / M_PI;
  2144. X    angle2 = atan2(ey-cy, ex-cx) * 180 / M_PI;
  2145. X    /* direction = 1 -> Counterclockwise */
  2146. X    set_style(a->style, a->style_val);
  2147. X    fprintf(tfp, "n %.3f %.3f %.3f %.3f %.3f %s\n",
  2148. X        cx, cy, radius, angle1, angle2,
  2149. X        ((direction == 1) ? "arc" : "arcn"));
  2150. X    if (a->area_fill && (int)a->area_fill != DEFAULT)
  2151. X        fill_area(a->area_fill, a->color);
  2152. X    if (a->thickness > 0)
  2153. X        fprintf(tfp, "gs col%d s gr\n", a->color > MAXCOLORS ? -1 : a->color);
  2154. X    reset_style(a->style, a->style_val);
  2155. X    if (multi_page)
  2156. X       fprintf(tfp, "} bind def\n");
  2157. X    }
  2158. X
  2159. Xstatic arc_tangent(x1, y1, x2, y2, direction, x, y)
  2160. Xdouble    x1, y1, x2, y2, *x, *y;
  2161. Xint    direction;
  2162. X{
  2163. X    if (direction) { /* counter clockwise  */
  2164. X        *x = x2 + (y2 - y1);
  2165. X        *y = y2 - (x2 - x1);
  2166. X        }
  2167. X    else {
  2168. X        *x = x2 - (y2 - y1);
  2169. X        *y = y2 + (x2 - x1);
  2170. X        }
  2171. X    }
  2172. X
  2173. X/*    draw arrow heading from (x1, y1) to (x2, y2)    */
  2174. X
  2175. Xstatic draw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid, col)
  2176. Xdouble    x1, y1, x2, y2, arrowht, arrowwid;
  2177. Xint col;
  2178. X{
  2179. X    double    x, y, xb, yb, dx, dy, l, sina, cosa;
  2180. X    double    xc, yc, xd, yd;
  2181. X
  2182. X    dx = x2 - x1;  dy = y1 - y2;
  2183. X    l = sqrt(dx*dx+dy*dy);
  2184. X    if (l == 0) {
  2185. X         return;
  2186. X    }
  2187. X    else {
  2188. X         sina = dy / l;  cosa = dx / l;
  2189. X    }
  2190. X    xb = x2*cosa - y2*sina;
  2191. X    yb = x2*sina + y2*cosa;
  2192. X    x = xb - arrowht;
  2193. X    y = yb - arrowwid / 2;
  2194. X    xc = x*cosa + y*sina;
  2195. X    yc = -x*sina + y*cosa;
  2196. X    y = yb + arrowwid / 2;
  2197. X    xd = x*cosa + y*sina;
  2198. X    yd = -x*sina + y*cosa;
  2199. X    fprintf(tfp, "n %.3f %.3f m %.3f %.3f l %.3f %.3f l gs 2 setlinejoin col%d s gr\n", xc, yc, x2, y2, xd, yd, col > MAXCOLORS ? -1 : col);
  2200. X    }
  2201. X
  2202. Xstatic fill_area(fill, color)
  2203. Xint fill, color;
  2204. X{
  2205. X   if (color < 1)   /* use gray levels for default and black */
  2206. X    fprintf(tfp, "gs %.2f setgray fill gr\n", 1.0 - GRAYVAL(fill));
  2207. X   else
  2208. X    fprintf(tfp, "gs col%d %.2f graycol fill gr ",
  2209. X        color > MAXCOLORS ? -1 : color, GRAYVAL(fill));
  2210. X}
  2211. X
  2212. Xstatic iso_text_exist(ob)
  2213. XF_compound      *ob;
  2214. X{
  2215. X   F_compound    *c;
  2216. X   F_text          *t;
  2217. X   unsigned char   *s;
  2218. X
  2219. X   if (ob->texts != NULL)
  2220. X   {
  2221. X      for (t = ob->texts; t != NULL; t = t->next)
  2222. X      {
  2223. X     for (s = (unsigned char*)t->cstring; *s != '\0'; s++)
  2224. X     {
  2225. X        /* look for characters >= 128 */
  2226. X        if (*s>127) return(1);
  2227. X     }
  2228. X      }
  2229. X   }
  2230. X
  2231. X   for (c = ob->compounds; c != NULL; c = c->next) {
  2232. X       if (iso_text_exist(c)) return(1);
  2233. X       }
  2234. X   return(0);
  2235. X}
  2236. X
  2237. Xstatic encode_all_fonts(ob)
  2238. XF_compound    *ob;
  2239. X{
  2240. X   F_compound *c;
  2241. X   F_text     *t;
  2242. X
  2243. X   if (ob->texts != NULL)
  2244. X   {
  2245. X    for (t = ob->texts; t != NULL; t = t->next)
  2246. X        if (PSisomap[t->font+1] == FALSE)
  2247. X        {
  2248. X        fprintf(tfp, "/%s /%s-iso isovec ReEncode\n", PSFONT(t), PSFONT(t));
  2249. X        PSisomap[t->font+1] = TRUE;
  2250. X        }
  2251. X   }
  2252. X
  2253. X   for (c = ob->compounds; c != NULL; c = c->next) 
  2254. X   {
  2255. X    encode_all_fonts(c);
  2256. X   }
  2257. X}
  2258. X
  2259. Xstatic ellipse_exist(ob)
  2260. XF_compound    *ob;
  2261. X{
  2262. X    F_compound    *c;
  2263. X
  2264. X    if (NULL != ob->ellipses) return(1);
  2265. X
  2266. X    for (c = ob->compounds; c != NULL; c = c->next) {
  2267. X        if (ellipse_exist(c)) return(1);
  2268. X        }
  2269. X
  2270. X    return(0);
  2271. X    }
  2272. X
  2273. Xstatic normal_spline_exist(ob)
  2274. XF_compound    *ob;
  2275. X{
  2276. X    F_spline    *s;
  2277. X    F_compound    *c;
  2278. X
  2279. X    for (s = ob->splines; s != NULL; s = s->next) {
  2280. X        if (normal_spline(s)) return(1);
  2281. X        }
  2282. X
  2283. X    for (c = ob->compounds; c != NULL; c = c->next) {
  2284. X        if (normal_spline_exist(c)) return(1);
  2285. X        }
  2286. X
  2287. X    return(0);
  2288. X    }
  2289. X
  2290. Xstruct driver dev_ps = {
  2291. X         genps_option,
  2292. X    genps_start,
  2293. X    genps_arc,
  2294. X    genps_ellipse,
  2295. X    genps_line,
  2296. X    genps_spline,
  2297. X    genps_text,
  2298. X    genps_end,
  2299. X    INCLUDE_TEXT
  2300. X};
  2301. END_OF_FILE
  2302. if test 28838 -ne `wc -c <'fig2dev/dev/genps.c'`; then
  2303.     echo shar: \"'fig2dev/dev/genps.c'\" unpacked with wrong size!
  2304. fi
  2305. # end of 'fig2dev/dev/genps.c'
  2306. fi
  2307. echo shar: End of archive 7 \(of 7\).
  2308. cp /dev/null ark7isdone
  2309. MISSING=""
  2310. for I in 1 2 3 4 5 6 7 ; do
  2311.     if test ! -f ark${I}isdone ; then
  2312.     MISSING="${MISSING} ${I}"
  2313.     fi
  2314. done
  2315. if test "${MISSING}" = "" ; then
  2316.     echo You have unpacked all 7 archives.
  2317.     rm -f ark[1-9]isdone
  2318. else
  2319.     echo You still need to unpack the following archives:
  2320.     echo "        " ${MISSING}
  2321. fi
  2322. ##  End of shell archive.
  2323. exit 0
  2324.