home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume23 / transfig / part03 < prev    next >
Internet Message Format  |  1991-06-19  |  47KB

  1. Path: j.cc.purdue.edu!mentor.cc.purdue.edu!noose.ecn.purdue.edu!samsung!usc!apple!bbn.com!papaya.bbn.com!rsalz
  2. From: rsalz@bbn.com (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v23i016:  Tools for creating TeX documents with portable graphics, Part03/06
  5. Message-ID: <2813@litchi.bbn.com>
  6. Date: 31 Aug 90 13:43:15 GMT
  7. Organization: BBN Systems and Technologies, Cambridge MA
  8. Lines: 1837
  9. Approved: rsalz@uunet.UU.NET
  10. X-Checksum-Snefru: a215b4c8 2af6306c 1deebccc 959f58a0
  11.  
  12. Submitted-by: Micah Beck <beck@cs.cornell.edu>
  13. Posting-number: Volume 23, Issue 16
  14. Archive-name: transfig/part03
  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 3 (of 6)."
  23. # Contents:  transfig/fig2dev/dev/genpic.c
  24. #   transfig/fig2dev/dev/genpictex.c transfig/fig2dev/read.c
  25. # Wrapped by beck@rocky on Thu May 17 15:56:12 1990
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'transfig/fig2dev/dev/genpic.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'transfig/fig2dev/dev/genpic.c'\"
  29. else
  30. echo shar: Extracting \"'transfig/fig2dev/dev/genpic.c'\" \(11817 characters\)
  31. sed "s/^X//" >'transfig/fig2dev/dev/genpic.c' <<'END_OF_FILE'
  32. X/* 
  33. X *    genpic : PIC driver for fig2dev
  34. X *
  35. X *    Author: Conrad Kwok, UC Davis, 12/88
  36. X *      Modified: Richard Auletta, George Mason Univ., 6/21/89
  37. X *    Added code comments are marked with "rja".
  38. X *      Added: Support for native pic arrowheads.
  39. X *      Added: Support for arrowheads at both ends of lines, arc, splines.
  40. X */
  41. X
  42. X#include <stdio.h>
  43. X#include <math.h>
  44. X#include "object.h"
  45. X#include "fig2dev.h"
  46. X#include "picfonts.h"
  47. X
  48. Xvoid genpic_ctl_spline(), genpic_itp_spline();
  49. Xvoid genpic_open_spline(), genpic_closed_spline();
  50. X
  51. X#define            TOP    10.5    /* top of page is 10.5 inch */
  52. Xstatic double        ppi;
  53. Xstatic int        CONV = 0;
  54. X
  55. Xvoid genpic_option(opt, optarg)
  56. Xchar opt, *optarg;
  57. X{
  58. X    switch (opt) {
  59. X
  60. X    case 'f':        /* set default text font */
  61. X            {   int i;
  62. X
  63. X            for ( i = 1; i <= MAXFONT + 1; i++ )
  64. X            if ( !strcmp(optarg, fontnames[i]) ) break;
  65. X
  66. X            if ( i > MAXFONT + 1 )
  67. X            fprintf(stderr,
  68. X                "warning: non-standard font name %s\n", optarg);
  69. X        }
  70. X        
  71. X        fontnames[0] = fontnames[1] = optarg;
  72. X        break;
  73. X
  74. X    case 's':
  75. X        if (font_size <= 0 || font_size > MAXFONTSIZE) {
  76. X            fprintf(stderr,
  77. X                "warning: font size %d out of bounds\n", font_size);
  78. X        }
  79. X        break;
  80. X
  81. X    case 'm':
  82. X    case 'L':
  83. X        break;
  84. X
  85. X     default:
  86. X        put_msg(Err_badarg, opt, "pic");
  87. X        exit(1);
  88. X    }
  89. X}
  90. X
  91. Xstatic double convy(a)
  92. Xdouble    a;
  93. X{
  94. X    return((double)(CONV ? TOP-a : a));
  95. X}
  96. X
  97. Xvoid genpic_start(objects)
  98. XF_compound    *objects;
  99. X{
  100. X    int        coord_system;
  101. X
  102. X    ppi = objects->nwcorner.x/mag;
  103. X    coord_system = objects->nwcorner.y;
  104. X    if (coord_system == 2) CONV = 1;
  105. X
  106. X    fprintf(tfp, ".PS\n.ps %d\n", font_size);    /* PIC preamble */
  107. X}
  108. X
  109. Xvoid genpic_end()
  110. X{
  111. X    fprintf(tfp, ".PE\n", font_size);    /* PIC ending */
  112. X}
  113. X
  114. X/*
  115. XThe line thickness is, unfortunately, multiple of pixel.
  116. XOne pixel thickness is a little too thick on the hard copy
  117. Xso I scale it with 0.7; i.e., it's a kludge.  The best way is
  118. Xto allow thickness in fraction of pixel.
  119. X
  120. XNote that the current version of psdit (a ditroff to postcript filter)
  121. Xwon't take the legitimate line thickness command.
  122. X*/
  123. Xstatic set_linewidth(w)
  124. Xint    w;
  125. X{
  126. X    static int    cur_thickness = -1;
  127. X
  128. X    /*
  129. X    if (w == 0) return;
  130. X    if (w != cur_thickness) {
  131. X        cur_thickness = w;
  132. X        fprintf(tfp, "\"\\D't %.5fi'\"\n", 0.7 * cur_thickness / ppi);
  133. X        }
  134. X    */
  135. X    }
  136. X
  137. Xstatic set_style(s, v)
  138. Xint    s;
  139. Xfloat    v;
  140. X{
  141. X    static float    style_val = -1;
  142. X
  143. X    if (s == DASH_LINE || s == DOTTED_LINE) {
  144. X        if (v == style_val) return;
  145. X        if (v == 0.0) return;
  146. X        style_val = v;
  147. X        fprintf(tfp, "dashwid = %.3fi\n", style_val/ppi);
  148. X        }
  149. X    }
  150. X
  151. Xvoid genpic_line(l)
  152. XF_line    *l;
  153. X{
  154. X    F_point        *p, *q;
  155. X
  156. X    set_linewidth(l->thickness);
  157. X    set_style(l->style, l->style_val);
  158. X    p = l->points;
  159. X    q = p->next;
  160. X    if (q == NULL) { /* A single point line */
  161. X        fprintf(tfp, "line from %.3f,%.3f to %.3f,%.3f\n",
  162. X            p->x/ppi, convy(p->y/ppi), p->x/ppi, convy(p->y/ppi));
  163. X        return;
  164. X        }
  165. X
  166. X
  167. X    if (l->style == DASH_LINE && l->style_val > 0.0)
  168. X        fprintf(tfp, "line dashed");
  169. X    else if (l->style == DOTTED_LINE && l->style_val > 0.0)
  170. X        fprintf(tfp, "line dotted");
  171. X    else
  172. X        fprintf(tfp, "line");
  173. X
  174. X    /*rja: Place arrowheads or lack there of on the line*/
  175. X    if ((l->for_arrow) && (l->back_arrow))
  176. X        fprintf(tfp, " <-> from");
  177. X    else if (l->back_arrow)
  178. X        fprintf(tfp, " <- from");
  179. X    else if (l->for_arrow)
  180. X        fprintf(tfp, " -> from");
  181. X        else
  182. X        fprintf(tfp, " from ");
  183. X
  184. X    fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
  185. X    while (q->next != NULL) {
  186. X        p = q;
  187. X        q = q->next;
  188. X        fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
  189. X        }
  190. X    fprintf(tfp, " %.3f,%.3f\n", q->x/ppi, convy(q->y/ppi));
  191. X    }
  192. X
  193. Xvoid genpic_spline(s)
  194. XF_spline    *s;
  195. X{
  196. X    if (int_spline(s))
  197. X        genpic_itp_spline(s);
  198. X    else
  199. X        genpic_ctl_spline(s);
  200. X    }
  201. X
  202. Xvoid genpic_ctl_spline(s)
  203. XF_spline    *s;
  204. X{
  205. X    if (closed_spline(s))
  206. X        genpic_closed_spline(s);
  207. X    else
  208. X        genpic_open_spline(s);
  209. X    }
  210. X
  211. Xvoid genpic_open_spline(s)
  212. XF_spline    *s;
  213. X{
  214. X    double        x1, y1, x2, y2;
  215. X    F_point        *p, *q;
  216. X
  217. X    p = s->points;
  218. X    x1 = p->x/ppi; y1 = convy(p->y/ppi);
  219. X    p = p->next;
  220. X    x2 = p->x/ppi; y2 = convy(p->y/ppi);
  221. X
  222. X
  223. X    /* Pic's spline supports only solid line style */
  224. X    /* set_linewidth(s->thickness); */
  225. X
  226. X    if (p->next == NULL) {
  227. X        fprintf(tfp, "line");
  228. X
  229. X           /*rja: Attach arrowhead as required */
  230. X        if ((s->for_arrow) && (s->back_arrow))
  231. X           fprintf(tfp, " <->");
  232. X        else if (s->back_arrow)
  233. X           fprintf(tfp, " <-");
  234. X        else if (s->for_arrow)
  235. X           fprintf(tfp, " ->");
  236. X
  237. X        fprintf(tfp, " from %.3f,%.3f to %.3f,%.3f\n", x1, y1, x2, y2);
  238. X        return;
  239. X        }
  240. X
  241. X    fprintf(tfp, "spline"); 
  242. X
  243. X           /*rja: Attach arrowhead as required */
  244. X        if ((s->for_arrow) && (s->back_arrow))
  245. X           fprintf(tfp, " <->");
  246. X        else if (s->back_arrow)
  247. X           fprintf(tfp, " <-");
  248. X        else if (s->for_arrow)
  249. X           fprintf(tfp, " ->");
  250. X
  251. X    fprintf(tfp, " from %.3f,%.3f to %.3f,%.3f", x1, y1, x2, y2);
  252. X
  253. X    for (q = p->next; q->next != NULL; p = q, q = q->next)
  254. X        fprintf(tfp, " to %.3f,%.3f", q->x/ppi, convy(q->y/ppi));
  255. X    fprintf(tfp, " to %.3f,%.3f\n", (x2=q->x/ppi), (y2=convy(q->y/ppi)));
  256. X
  257. X    }
  258. X
  259. Xvoid genpic_ellipse(e)
  260. XF_ellipse    *e;
  261. X{
  262. X    set_linewidth(e->thickness);
  263. X    fprintf(tfp, "ellipse at %.3f,%.3f wid %.3f ht %.3f\n",
  264. X        e->center.x/ppi, convy(e->center.y/ppi),
  265. X        2 * e->radiuses.x/ppi, 2 * e->radiuses.y/ppi);
  266. X    }
  267. X
  268. X/*
  269. XText is display on the screen with the base line starting at
  270. X(base_x, base_y); some characters extend below this line.
  271. XPic displays the center of the height of text at the given
  272. Xcoordinate. HT_OFFSET is use to compensate all the above factors
  273. Xso text position in fig 1.4 should be at the same position on
  274. Xthe screen as on the hard copy.
  275. X*/
  276. X#define            HT_OFFSET    (0.2 / 72.0)
  277. X
  278. Xvoid genpic_text(t)
  279. XF_text    *t;
  280. X{
  281. X    float    y;
  282. X        char *tpos;
  283. X    int all_default = 0;
  284. X
  285. X    /* all_default = all_default && t->font <= 0 && t->size <= 0 ; */
  286. X
  287. X    if (all_default)
  288. X      fprintf(tfp, "\"");
  289. X    else
  290. X      fprintf(tfp, "\"\\s%d\\f%s", PICFONTSIZE(t->size), PICFONT(t->font) );
  291. X
  292. X        switch (t->type) {
  293. X        case T_LEFT_JUSTIFIED:
  294. X        case DEFAULT:
  295. X            tpos = "ljust";
  296. X            break;
  297. X        case T_CENTER_JUSTIFIED:
  298. X            tpos = "";
  299. X            break;
  300. X        case T_RIGHT_JUSTIFIED:
  301. X            tpos = "rjust";
  302. X            break;
  303. X        default:
  304. X            fprintf(stderr, "unknown text position type\n");
  305. X            exit(1);
  306. X        }    
  307. X    y = convy(t->base_y/ppi) + PICFONTSIZE(t->size) * HT_OFFSET;
  308. X
  309. X    if (all_default)    
  310. X        fprintf(tfp, "%s\" at %.3f,%.3f %s\n",
  311. X            t->cstring, t->base_x/ppi, y, tpos);
  312. X    else
  313. X        fprintf(tfp, "%s\\fP\" at %.3f,%.3f %s\n",
  314. X            t->cstring, t->base_x/ppi, y, tpos);
  315. X    }
  316. X
  317. Xvoid genpic_arc(a)
  318. XF_arc    *a;
  319. X{
  320. X    double        x, y;
  321. X    double        cx, cy, sx, sy, ex, ey;
  322. X
  323. X    cx = a->center.x/ppi; cy = convy(a->center.y/ppi);
  324. X    sx = a->point[0].x/ppi; sy = convy(a->point[0].y/ppi);
  325. X    ex = a->point[2].x/ppi; ey = convy(a->point[2].y/ppi);
  326. X
  327. X    set_linewidth(a->thickness);
  328. X
  329. X        fprintf(tfp, "arc ");
  330. X
  331. X           /*rja: Attach arrowhead as required */
  332. X        if ((a->for_arrow) && (a->back_arrow))
  333. X           fprintf(tfp, " <->");
  334. X        else if (a->back_arrow)
  335. X           fprintf(tfp, " <-");
  336. X        else if (a->for_arrow)
  337. X           fprintf(tfp, " ->");
  338. X
  339. X
  340. X    if (a->direction)
  341. X        fprintf(tfp, " at %.3f,%.3f from %.3f,%.3f to %.3f,%.3f\n",
  342. X            cx, cy, sx, sy, ex, ey);
  343. X    else
  344. X        fprintf(tfp, " at %.3f,%.3f from %.3f,%.3f to %.3f,%.3f cw\n",
  345. X            cx, cy, sx, sy, ex, ey);
  346. X
  347. X    }
  348. X
  349. Xarc_tangent(x1, y1, x2, y2, direction, x, y)
  350. Xdouble    x1, y1, x2, y2, *x, *y;
  351. Xint    direction;
  352. X{
  353. X    if (direction) { /* counter clockwise  */
  354. X        *x = x2 + (y2 - y1);
  355. X        *y = y2 - (x2 - x1);
  356. X        }
  357. X    else {
  358. X        *x = x2 - (y2 - y1);
  359. X        *y = y2 + (x2 - x1);
  360. X        }
  361. X    }
  362. X
  363. X/*    draw arrow heading from (x1, y1) to (x2, y2)    */
  364. X
  365. Xdraw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid)
  366. Xdouble    x1, y1, x2, y2, arrowht, arrowwid;
  367. X{
  368. X    double    x, y, xb, yb, dx, dy, l, sina, cosa;
  369. X    double    xc, yc, xd, yd;
  370. X
  371. X    dx = x2 - x1;  dy = y1 - y2;
  372. X    l = sqrt((dx*dx + dy*dy));
  373. X    sina = dy / l;  cosa = dx / l;
  374. X    xb = x2*cosa - y2*sina;
  375. X    yb = x2*sina + y2*cosa;
  376. X    x = xb - arrowht;
  377. X    y = yb - arrowwid / 2;
  378. X    xc = x*cosa + y*sina;
  379. X    yc = -x*sina + y*cosa;
  380. X    y = yb + arrowwid / 2;
  381. X    xd = x*cosa + y*sina;
  382. X    yd = -x*sina + y*cosa;
  383. X    fprintf(tfp, "line from %.3f,%.3f to %.3f,%.3f to %.3f,%.3f\n",
  384. X        xc, yc, x2, y2, xd, yd);
  385. X    }
  386. X
  387. X#define        THRESHOLD    .05    /* inch */
  388. X
  389. Xquadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4)
  390. Xdouble    a1, b1, a2, b2, a3, b3, a4, b4;
  391. X{
  392. X    double    x1, y1, x4, y4;
  393. X    double    xmid, ymid;
  394. X
  395. X    x1 = a1; y1 = b1;
  396. X    x4 = a4; y4 = b4;
  397. X
  398. X    xmid = (a2 + a3) / 2;
  399. X    ymid = (b2 + b3) / 2;
  400. X    if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD) {
  401. X        fprintf(tfp, "\tto %.3f,%.3f\\\n", xmid, ymid);
  402. X        }
  403. X    else {
  404. X        quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2),
  405. X            ((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid);
  406. X        }
  407. X
  408. X    if (fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) {
  409. X        fprintf(tfp, "\tto %.3f,%.3f\\\n", x4, y4);
  410. X        }
  411. X    else {
  412. X        quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4),
  413. X            ((a3+x4)/2), ((b3+y4)/2), x4, y4);
  414. X        }
  415. X    }
  416. X
  417. Xvoid genpic_closed_spline(s)
  418. XF_spline    *s;
  419. X{
  420. X    F_point    *p;
  421. X    double    cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
  422. X    double    x1, y1, x2, y2;
  423. X
  424. X    p = s->points;
  425. X    x1 = p->x/ppi;  y1 = convy(p->y/ppi);
  426. X    p = p->next;
  427. X    x2 = p->x/ppi;  y2 = convy(p->y/ppi);
  428. X    cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
  429. X    cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
  430. X
  431. X    for (p = p->next; p != NULL; p = p->next) {
  432. X        fprintf(tfp, "line from %.3f,%.3f ", cx1, cy1);
  433. X        x1 = x2;  y1 = y2;
  434. X        x2 = p->x/ppi;  y2 = convy(p->y/ppi);
  435. X        cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
  436. X        cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
  437. X        quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
  438. X        fprintf(tfp, "\n");
  439. X        cx1 = cx4;  cy1 = cy4;
  440. X        cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
  441. X        }
  442. X    x1 = x2;  y1 = y2;
  443. X    p = s->points->next;
  444. X    x2 = p->x/ppi;  y2 = convy(p->y/ppi);
  445. X    cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
  446. X    cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
  447. X    fprintf(tfp, "line from %.3f,%.3f ", cx1, cy1);
  448. X    quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
  449. X    fprintf(tfp, "\n");
  450. X    }
  451. X
  452. Xvoid genpic_itp_spline(s)
  453. XF_spline    *s;
  454. X{
  455. X    F_point        *p1, *p2, *pfirst;
  456. X    F_control    *cp1, *cp2;
  457. X    double        x1, x2, y1, y2;
  458. X
  459. X    p1 = s->points;
  460. X    cp1 = s->controls;
  461. X    cp2 = cp1->next;
  462. X    x2 = p1->x/ppi; y2 = convy(p1->y/ppi);
  463. X
  464. X         pfirst = p1->next;/*save first to test in loop*/
  465. X    for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
  466. X        p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
  467. X
  468. X        fprintf(tfp, "line ");
  469. X
  470. X           /*rja: Attach arrowhead as required */
  471. X
  472. X        if ((s->back_arrow) && (p2 == pfirst))
  473. X           fprintf(tfp, " <- ");
  474. X        else if ((s->for_arrow) && (p2->next == NULL))
  475. X           fprintf(tfp, " -> ");
  476. X
  477. X        fprintf(tfp, " from %.3f,%.3f ", x2, y2);
  478. X
  479. X        x1 = x2; y1 = y2;
  480. X        x2 = p2->x/ppi; y2 = convy(p2->y/ppi);
  481. X        bezier_spline(x1, y1, (double)cp1->rx/ppi, convy(cp1->ry/ppi),
  482. X        (double)cp2->lx/ppi, convy(cp2->ly/ppi), x2, y2);
  483. X        fprintf(tfp, "\n");
  484. X        }
  485. X
  486. X    }
  487. X
  488. Xbezier_spline(a0, b0, a1, b1, a2, b2, a3, b3)
  489. Xdouble    a0, b0, a1, b1, a2, b2, a3, b3;
  490. X{
  491. X    double    x0, y0, x3, y3;
  492. X    double    sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid;
  493. X
  494. X    x0 = a0; y0 = b0;
  495. X    x3 = a3; y3 = b3;
  496. X    if (fabs(x0 - x3) < THRESHOLD && fabs(y0 - y3) < THRESHOLD) {
  497. X        fprintf(tfp, "\tto %.3f,%.3f\\\n", x3, y3);
  498. X        }
  499. X    else {
  500. X        tx = (a1 + a2) / 2;        ty = (b1 + b2) / 2;
  501. X        sx1 = (x0 + a1) / 2;    sy1 = (y0 + b1) / 2;
  502. X        sx2 = (sx1 + tx) / 2;    sy2 = (sy1 + ty) / 2;
  503. X        tx2 = (a2 + x3) / 2;    ty2 = (b2 + y3) / 2;
  504. X        tx1 = (tx2 + tx) / 2;    ty1 = (ty2 + ty) / 2;
  505. X        xmid = (sx2 + tx1) / 2;    ymid = (sy2 + ty1) / 2;
  506. X
  507. X        bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid);
  508. X        bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3);
  509. X        }
  510. X    }
  511. X
  512. Xstruct driver dev_pic = {
  513. X         genpic_option,
  514. X    genpic_start,
  515. X    genpic_arc,
  516. X    genpic_ellipse,
  517. X    genpic_line,
  518. X    genpic_spline,
  519. X    genpic_text,
  520. X    genpic_end,
  521. X    INCLUDE_TEXT
  522. X};
  523. END_OF_FILE
  524. if test 11817 -ne `wc -c <'transfig/fig2dev/dev/genpic.c'`; then
  525.     echo shar: \"'transfig/fig2dev/dev/genpic.c'\" unpacked with wrong size!
  526. fi
  527. # end of 'transfig/fig2dev/dev/genpic.c'
  528. fi
  529. if test -f 'transfig/fig2dev/dev/genpictex.c' -a "${1}" != "-c" ; then 
  530.   echo shar: Will not clobber existing file \"'transfig/fig2dev/dev/genpictex.c'\"
  531. else
  532. echo shar: Extracting \"'transfig/fig2dev/dev/genpictex.c'\" \(13702 characters\)
  533. sed "s/^X//" >'transfig/fig2dev/dev/genpictex.c' <<'END_OF_FILE'
  534. X/* 
  535. X *    genpictex.C : PiCTeX driver for fig2dev
  536. X *
  537. X *     Author Micah Beck, Cornell University, 4/88
  538. X *    (beck@svax.cs.cornell.edu)
  539. X*/
  540. X#ifdef hpux
  541. X#include <sys/types.h>
  542. X#endif
  543. X#include <sys/file.h>
  544. X#include <stdio.h>
  545. X#include <math.h>
  546. X#include "pi.h"
  547. X#include "object.h"
  548. X#include "fig2dev.h"
  549. X#include "texfonts.h"
  550. X
  551. Xextern char *strchr();
  552. Xextern void fprintf();
  553. Xextern double sin(), cos(), acos(), fabs();
  554. X
  555. Xvoid genpictex_ctl_spline(), genpictex_itp_spline();
  556. X
  557. Xstatic int        coord_system;
  558. Xstatic double        dash_length = -1;
  559. Xstatic int        line_style = SOLID_LINE;
  560. Xstatic char         *linethick = "0.7pt";
  561. Xstatic char        *plotsymbol = "\\sevrm .";
  562. X
  563. Xstatic void genpictex_option(opt, optarg)
  564. Xchar opt, *optarg;
  565. X{
  566. X    switch (opt) {
  567. X
  568. X        case 'f':            /* set default text font */
  569. X            {   int i;
  570. X
  571. X            for ( i = 1; i <= MAXFONT + 1; i++ )
  572. X            if ( !strcmp(optarg, fontnames[i]) ) break;
  573. X
  574. X            if ( i > MAXFONT + 1 )
  575. X            fprintf(stderr,
  576. X                "warning: non-standard font name %s\n", optarg);
  577. X        }
  578. X        
  579. X            fontnames[0] = fontnames[1] = optarg;
  580. X            break;
  581. X
  582. X        case 'l':            /* set line thickness */
  583. X            linethick = optarg;
  584. X            break;
  585. X
  586. X        case 'p':            /* set plot symbol */
  587. X            plotsymbol = optarg;
  588. X            break;
  589. X
  590. X        case 's':
  591. X            if (font_size <= 0 || font_size > MAXFONTSIZE) {
  592. X            fprintf(stderr,
  593. X                "warning: font size %d out of bounds\n", font_size);
  594. X            }
  595. X            break;
  596. X
  597. X        case 'm':
  598. X        case 'L':
  599. X            break;
  600. X
  601. X    default:
  602. X        put_msg(Err_badarg, opt, "pictex");
  603. X        exit(1);
  604. X        break;
  605. X    }
  606. X}
  607. X
  608. X#define            TOP    10.5    /* top of page is 10.5 inch */
  609. Xstatic double        ppi;
  610. Xstatic int        CONV = 0;
  611. X
  612. Xstatic double convy(a)
  613. Xdouble    a;
  614. X{
  615. X    return((double)(CONV ? TOP-a : a));
  616. X}
  617. X
  618. Xvoid genpictex_start(objects)
  619. XF_compound    *objects;
  620. X{
  621. X    fontsizes[0] = fontsizes[1] = TEXFONTSIZE(font_size);
  622. X
  623. X    coord_system = objects->nwcorner.y;
  624. X    ppi = objects->nwcorner.x;
  625. X    if (coord_system == 2) CONV = 1;
  626. X
  627. X    /* PiCTeX start */
  628. X    fprintf(tfp, "\\mbox{\\beginpicture\n");
  629. X    fprintf(tfp, "\\setcoordinatesystem units <%6.3fin,%6.3fin>\n",
  630. X            mag, mag);
  631. X    fprintf(tfp, "\\unitlength=%6.3fin\n", mag);
  632. X    fprintf(tfp, "\\linethickness=%s\n", linethick);
  633. X    fprintf(tfp, "\\setplotsymbol ({%s})\n", plotsymbol);
  634. X    fprintf(tfp, "\\setlinear\n");
  635. X}
  636. X
  637. Xvoid genpictex_end()
  638. X{
  639. X    /* PiCTeX ending */
  640. X    fprintf(tfp, "\\linethickness=0pt\n");
  641. X        fprintf(tfp, "\\putrectangle corners at %6.3f %6.3f and %6.3f %6.3f\n",
  642. X        llx/ppi, convy(lly/ppi), urx/ppi, convy(ury/ppi));
  643. X    fprintf(tfp, "\\endpicture}\n");
  644. X}
  645. X
  646. Xstatic set_linewidth(w)
  647. Xint    w;
  648. X{
  649. X    static int    cur_thickness = -1;
  650. X
  651. X    if (w == 0) return;
  652. X    if (w != cur_thickness) {
  653. X        cur_thickness = w;
  654. X/*    fprintf(tfp, "\\linethickness=%6.3fin\n",0.7 * cur_thickness);*/
  655. X/* PIC  fprintf(tfp, "\"D't %.3fi'\"\n", 0.7 * cur_thickness);*/
  656. X        }
  657. X    }
  658. X
  659. Xvoid genpictex_line(l)
  660. XF_line    *l;
  661. X{
  662. X    F_point        *p, *q;
  663. X
  664. X    fprintf(tfp, "%%\n%% Fig POLYLINE object\n%%\n");
  665. X
  666. X    set_linewidth(l->thickness);
  667. X    set_style(l->style, l->style_val);
  668. X
  669. X    p = l->points;
  670. X    q = p->next;
  671. X
  672. X    if (q == NULL) { /* A single point line */
  673. X        fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f /\n",
  674. X            p->x/ppi, convy(p->y/ppi), p->x/ppi, convy(p->y/ppi));
  675. X        return;
  676. X        }
  677. X    if (l->back_arrow)
  678. X        draw_arrow_head(q->x/ppi, convy(q->y/ppi), p->x/ppi,
  679. X        convy(p->y/ppi), l->back_arrow->ht/ppi, l->back_arrow->wid/ppi);
  680. X    set_style(l->style, l->style_val);
  681. X
  682. X    while (q->next != NULL) {
  683. X
  684. X        putline(p->x, p->y, q->x, q->y);
  685. X        p = q;
  686. X        q = q->next;
  687. X        }
  688. X
  689. X    putline(p->x, p->y, q->x, q->y);
  690. X    if (l->for_arrow)
  691. X        draw_arrow_head(p->x/ppi, convy(p->y/ppi), q->x/ppi,
  692. X        convy(q->y/ppi), l->for_arrow->ht/ppi, l->for_arrow->wid/ppi);
  693. X
  694. X    if (l->area_fill && (int)l->area_fill != DEFAULT)
  695. X        fprintf(stderr, "Line area fill not implemented\n");
  696. X    }
  697. X
  698. X/* 
  699. X * set_style - issue style commands as appropriate
  700. X */
  701. Xstatic set_style(style, dash_len)
  702. Xint style;
  703. Xdouble dash_len;
  704. X{
  705. X    switch (style) {
  706. X     case SOLID_LINE:
  707. X        if (line_style == SOLID_LINE) break;
  708. X        fprintf(tfp, "\\setsolid\n");
  709. X        break;
  710. X
  711. X    case DASH_LINE:
  712. X        if (line_style == DASH_LINE && dash_length == dash_len)
  713. X        break;
  714. X        fprintf(tfp, "\\setdashes <%7.4fin>\n", dash_len/ppi);
  715. X        break;
  716. X
  717. X    case DOTTED_LINE:
  718. X        if (line_style == DOTTED_LINE)
  719. X        break;
  720. X        fprintf(tfp, "\\setdots \n");
  721. X        break;
  722. X        }
  723. X
  724. X    line_style = style;
  725. X    dash_length = dash_len;
  726. X    }
  727. X
  728. X/*
  729. X * putline - use rules if possible
  730. X */
  731. Xstatic putline (start_x, start_y, end_x, end_y)
  732. Xint    start_x, start_y, end_x, end_y;
  733. X{
  734. X    if (line_style == SOLID_LINE &&
  735. X        ((start_x == end_x) || (start_y == end_y)))
  736. X    fprintf(tfp, "\\putrule from %6.3f %6.3f to %6.3f %6.3f\n",
  737. X        start_x/ppi, convy(start_y/ppi), end_x/ppi, convy(end_y/ppi));
  738. X
  739. X    else {
  740. X    fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f /\n",
  741. X        start_x/ppi, convy(start_y/ppi), end_x/ppi, convy(end_y/ppi));
  742. X    }
  743. X}
  744. X
  745. X
  746. Xvoid genpictex_spline(s)
  747. XF_spline    *s;
  748. X{
  749. X    set_linewidth(s->thickness);
  750. X    set_style(s->style, s->style_val);
  751. X
  752. X    if (int_spline(s))
  753. X        genpictex_itp_spline(s);
  754. X    else
  755. X        genpictex_ctl_spline(s);
  756. X
  757. X    if (s->area_fill && (int)s->area_fill != DEFAULT)
  758. X        fprintf(stderr, "Spline area fill not implemented\n");
  759. X}
  760. X
  761. Xvoid genpictex_ellipse(e)
  762. XF_ellipse    *e;
  763. X{
  764. X    fprintf(tfp, "%%\n%% Fig ELLIPSE\n%%\n");
  765. X
  766. X    set_linewidth(e->thickness);
  767. X    set_style(e->style, e->style_val);
  768. X
  769. X    if ((e->area_fill == BLACK_FILL) && (e->radiuses.x == e->radiuses.y))
  770. X         fprintf(tfp, "\\put{\\circle*{%6.3f}} at %6.3f %6.3f\n",
  771. X            2*e->radiuses.x/ppi,
  772. X            (e->center.x+e->radiuses.x)/ppi, convy(e->center.y/ppi));
  773. X
  774. X    else {
  775. X
  776. X        fprintf(tfp, "\\ellipticalarc axes ratio %6.3f:%-6.3f 360 degrees \n",
  777. X            e->radiuses.x/ppi, e->radiuses.y/ppi);
  778. X        fprintf(tfp, "\tfrom %6.3f %6.3f center at %6.3f %6.3f\n",
  779. X            (e->center.x+e->radiuses.x)/ppi, convy(e->center.y/ppi),
  780. X            e->center.x/ppi, convy(e->center.y/ppi));
  781. X        if (e->area_fill && (int)e->area_fill != DEFAULT)
  782. X            fprintf(stderr, "Ellipse area fill not implemented\n");
  783. X        }
  784. X    }
  785. X
  786. X#define            HT_OFFSET    (0.2 / 72.0)
  787. X
  788. Xvoid genpictex_text(t)
  789. XF_text    *t;
  790. X{
  791. X    double    x, y;
  792. X    char *tpos, *cp;
  793. X
  794. X        fprintf(tfp, "%%\n%% Fig TEXT object\n%%\n");
  795. X
  796. X    x = t->base_x/ppi;
  797. X    y = convy(t->base_y/ppi);
  798. X
  799. X    switch (t->type) {
  800. X
  801. X        case T_LEFT_JUSTIFIED:
  802. X        case DEFAULT:
  803. X            tpos = "[lB]";
  804. X        break;
  805. X
  806. X        case T_CENTER_JUSTIFIED:
  807. X            tpos = "[B]";
  808. X        break;
  809. X
  810. X        case T_RIGHT_JUSTIFIED:
  811. X            tpos = "[rB]";
  812. X        break;
  813. X
  814. X        default:
  815. X        fprintf(stderr, "Text incorrectly positioned\n");
  816. X        return;
  817. X        }
  818. X
  819. X    fprintf(tfp, "\\put {\\%s%s ",
  820. X        TEXFONTSIZE(t->size), TEXFONT(t->font));
  821. X
  822. X    if (t->font && t->font !=DEFAULT)
  823. X
  824. X        /* this loop escapes characters "$&%#_{}" */
  825. X        /* and deleted characters "~^\" */
  826. X        for(cp = t->cstring; *cp; cp++) {
  827. X                  if (strchr("$&%#_{}", *cp)) (void)fputc('\\', tfp);
  828. X                  if (strchr("~^\\", *cp))
  829. X            fprintf(stderr,
  830. X                "Bad character in text object '%c'\n" ,*cp);
  831. X            else
  832. X            (void)fputc(*cp, tfp);
  833. X              }
  834. X    else 
  835. X        fprintf(tfp, "%s", t->cstring);
  836. X
  837. X     fprintf(tfp, "} %s at %6.3f %6.3f\n",
  838. X        tpos, x, y);
  839. X    }
  840. X
  841. Xvoid genpictex_arc(a)
  842. XF_arc    *a;
  843. X{
  844. X    double        x, y;
  845. X    double        cx, cy, sx, sy, ex, ey;
  846. X    double        dx1, dy1, dx2, dy2, r1, r2, th1, th2, theta;
  847. X
  848. X    set_linewidth(a->thickness);
  849. X    set_style(a->style, a->style_val);
  850. X
  851. X    cx = a->center.x/ppi; cy = convy(a->center.y/ppi);
  852. X    sx = a->point[0].x/ppi; sy = convy(a->point[0].y/ppi);
  853. X    ex = a->point[2].x/ppi; ey = convy(a->point[2].y/ppi);
  854. X
  855. X    if (a->for_arrow) {
  856. X        arc_tangent(cx, cy, ex, ey, a->direction, &x, &y);
  857. X        draw_arrow_head(x, y, ex, ey,
  858. X            a->for_arrow->ht/ppi, a->for_arrow->wid/ppi);
  859. X        }
  860. X    if (a->back_arrow) {
  861. X        arc_tangent(cx, cy, sx, sy, !a->direction, &x, &y);
  862. X        draw_arrow_head(x, y, sx, sy,
  863. X            a->back_arrow->ht/ppi, a->back_arrow->wid/ppi);
  864. X        }
  865. X
  866. X    dx1 = sx - cx;
  867. X    dy1 = sy - cy;
  868. X    dx2 = ex - cx;
  869. X    dy2 = ey - cy;
  870. X        
  871. X    rtop(dx1, dy1, &r1, &th1);
  872. X    rtop(dx2, dy2, &r2, &th2);
  873. X    theta = th2 - th1;
  874. X    if (theta > 0) theta -= 2*M_PI;
  875. X
  876. X    set_linewidth(a->thickness);
  877. X
  878. X    if (a->direction)
  879. X        fprintf(tfp, "\\circulararc %6.3f degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
  880. X            360+(180/M_PI * theta), sx, sy, cx, cy);
  881. X    else
  882. X        fprintf(tfp, "\\circulararc %6.3f degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
  883. X            -180/M_PI * theta, ex, ey, cx, cy);
  884. X
  885. X    if (a->area_fill && (int)a->area_fill != DEFAULT)
  886. X        fprintf(stderr, "Arc area fill not implemented\n");
  887. X    }
  888. X
  889. X
  890. X
  891. X/*
  892. X * rtop - rectangular to polar conversion
  893. X */
  894. Xstatic rtop(x, y, r, th)
  895. Xdouble x, y, *r, *th;
  896. X{
  897. X    *r = hypot(x,y);
  898. X    *th = acos(x/(*r));
  899. X
  900. X    if (y < 0) *th = 2*M_PI - *th;
  901. X}
  902. X
  903. Xstatic arc_tangent(x1, y1, x2, y2, direction, x, y)
  904. Xdouble    x1, y1, x2, y2, *x, *y;
  905. Xint    direction;
  906. X{
  907. X    if (direction) { /* counter clockwise  */
  908. X        *x = x2 + (y2 - y1);
  909. X        *y = y2 - (x2 - x1);
  910. X        }
  911. X    else {
  912. X        *x = x2 - (y2 - y1);
  913. X        *y = y2 + (x2 - x1);
  914. X        }
  915. X    }
  916. X
  917. X/*    draw arrow heading from (x1, y1) to (x2, y2)    */
  918. X
  919. Xstatic draw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid)
  920. Xdouble    x1, y1, x2, y2, arrowht, arrowwid;
  921. X{
  922. X    double    x, y, xb, yb, dx, dy, l, sina, cosa;
  923. X    double    xc, yc, xd, yd;
  924. X    int style;
  925. X    double dash;
  926. X
  927. X        fprintf(tfp, "%%\n%% arrow head\n%%\n");
  928. X
  929. X    dx = x2 - x1;  dy = y1 - y2;
  930. X    l = hypot(dx, dy);
  931. X    sina = dy / l;  cosa = dx / l;
  932. X    xb = x2*cosa - y2*sina;
  933. X    yb = x2*sina + y2*cosa;
  934. X    x = xb - arrowht;
  935. X    y = yb - arrowwid / 2;
  936. X    xc = x*cosa + y*sina;
  937. X    yc = -x*sina + y*cosa;
  938. X    y = yb + arrowwid / 2;
  939. X    xd = x*cosa + y*sina;
  940. X    yd = -x*sina + y*cosa;
  941. X
  942. X    /* save line style and set to solid */
  943. X    style = line_style;
  944. X    dash = dash_length;
  945. X    set_style(SOLID_LINE, 0.0);
  946. X
  947. X    fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f /\n%%\n",
  948. X        xc, yc, x2, y2, xd, yd);
  949. X
  950. X    /* restore line style */
  951. X    set_style(style, dash);
  952. X    }
  953. X
  954. X#define        THRESHOLD    .05    /* inch */
  955. X
  956. Xstatic quadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4)
  957. Xdouble    a1, b1, a2, b2, a3, b3, a4, b4;
  958. X{
  959. X    double    x1, y1, x4, y4;
  960. X    double    xmid, ymid;
  961. X
  962. X    x1 = a1; y1 = b1;
  963. X    x4 = a4; y4 = b4;
  964. X    xmid = (a2 + a3) / 2;
  965. X    ymid = (b2 + b3) / 2;
  966. X    if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD)
  967. X        fprintf(tfp, "\t%6.3f %6.3f\n", xmid, ymid);
  968. X
  969. X    else {
  970. X        quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2),
  971. X            ((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid);
  972. X        }
  973. X
  974. X    if (fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD)
  975. X        fprintf(tfp, "\t%6.3f %6.3f\n", x4, y4);
  976. X
  977. X    else {
  978. X        quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4),
  979. X            ((a3+x4)/2), ((b3+y4)/2), x4, y4);
  980. X        }
  981. X    }
  982. X
  983. Xstatic void genpictex_ctl_spline(s)
  984. XF_spline    *s;
  985. X{
  986. X    F_point    *p;
  987. X    double    cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
  988. X    double    x1, y1, x2, y2;
  989. X
  990. X        fprintf(tfp, "%%\n%% Fig CONTROL PT SPLINE\n%%\n");
  991. X
  992. X    p = s->points;
  993. X    x1 = p->x/ppi;  y1 = convy(p->y/ppi);
  994. X    p = p->next;
  995. X    x2 = p->x/ppi;  y2 = convy(p->y/ppi);
  996. X    cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
  997. X    cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
  998. X
  999. X    if (closed_spline(s)) {
  1000. X        fprintf(tfp, "%% closed spline\n%%\n");
  1001. X        fprintf(tfp, "\\plot\t%6.3f %6.3f \n ", cx1, cy1);
  1002. X        }
  1003. X    else {
  1004. X        fprintf(tfp, "%% open spline\n%%\n");
  1005. X        if (s->back_arrow)
  1006. X            draw_arrow_head(cx1, cy1, x1, y1,
  1007. X            s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);
  1008. X        fprintf(tfp, "\\plot\t%6.3f %6.3f %6.3f %6.3f\n ",
  1009. X        x1, y1, cx1, cy1);
  1010. X        }
  1011. X
  1012. X    for (p = p->next; p != NULL; p = p->next) {
  1013. X        x1 = x2;  y1 = y2;
  1014. X        x2 = p->x/ppi;  y2 = convy(p->y/ppi);
  1015. X        cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
  1016. X        cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
  1017. X        quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
  1018. X        cx1 = cx4;  cy1 = cy4;
  1019. X        cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
  1020. X        }
  1021. X    x1 = x2;  y1 = y2;
  1022. X    p = s->points->next;
  1023. X    x2 = p->x/ppi;  y2 = convy(p->y/ppi);
  1024. X    cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
  1025. X    cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
  1026. X    if (closed_spline(s)) {
  1027. X        quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
  1028. X        fprintf(tfp, "\t/\n");
  1029. X        }
  1030. X    else {
  1031. X        fprintf(tfp, "\t /\n\\plot %6.3f %6.3f %6.3f %6.3f /\n",
  1032. X        cx1, cy1, x1, y1);
  1033. X        if (s->for_arrow)
  1034. X            draw_arrow_head(cx1, cy1, x1, y1,
  1035. X            s->for_arrow->ht/ppi, s->for_arrow->wid/ppi);
  1036. X        }
  1037. X
  1038. X    }
  1039. X
  1040. Xstatic void genpictex_itp_spline(s)
  1041. XF_spline    *s;
  1042. X{
  1043. X    F_point        *p1, *p2;
  1044. X    F_control    *cp1, *cp2;
  1045. X    double        x1, x2, y1, y2;
  1046. X
  1047. X    p1 = s->points;
  1048. X    cp1 = s->controls;
  1049. X    x2 = p1->x/ppi; y2 = convy(p1->y/ppi);
  1050. X
  1051. X    if (s->back_arrow)
  1052. X        draw_arrow_head(cp1->rx/ppi, convy(cp1->ry/ppi), x2, y2,
  1053. X        s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);
  1054. X
  1055. X    fprintf(tfp, "\\plot %6.3f %6.3f ", x2, y2);
  1056. X    for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
  1057. X        p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
  1058. X        x1 = x2; y1 = y2;
  1059. X        x2 = p2->x/ppi; y2 = convy(p2->y/ppi);
  1060. X        bezier_spline(x1, y1, (double)cp1->rx/ppi, convy(cp1->ry/ppi),
  1061. X        (double)cp2->lx/ppi, convy(cp2->ly/ppi), x2, y2);
  1062. X        }
  1063. X    fprintf(tfp, "\t/\n");
  1064. X
  1065. X    if (s->for_arrow)
  1066. X        draw_arrow_head(cp1->lx/ppi, convy(cp1->ly/ppi), x2, y2,
  1067. X        s->for_arrow->ht/ppi, s->for_arrow->wid/ppi);
  1068. X    }
  1069. X
  1070. Xstatic bezier_spline(a0, b0, a1, b1, a2, b2, a3, b3)
  1071. Xdouble    a0, b0, a1, b1, a2, b2, a3, b3;
  1072. X{
  1073. X    double    x0, y0, x3, y3;
  1074. X    double    sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid;
  1075. X
  1076. X    x0 = a0; y0 = b0;
  1077. X    x3 = a3; y3 = b3;
  1078. X    if (fabs(x0 - x3) < THRESHOLD && fabs(y0 - y3) < THRESHOLD)
  1079. X        fprintf(tfp, "\t%6.3f %6.3f\n", x3, y3);
  1080. X
  1081. X    else {
  1082. X        tx = (a1 + a2) / 2;        ty = (b1 + b2) / 2;
  1083. X        sx1 = (x0 + a1) / 2;    sy1 = (y0 + b1) / 2;
  1084. X        sx2 = (sx1 + tx) / 2;    sy2 = (sy1 + ty) / 2;
  1085. X        tx2 = (a2 + x3) / 2;    ty2 = (b2 + y3) / 2;
  1086. X        tx1 = (tx2 + tx) / 2;    ty1 = (ty2 + ty) / 2;
  1087. X        xmid = (sx2 + tx1) / 2;    ymid = (sy2 + ty1) / 2;
  1088. X
  1089. X        bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid);
  1090. X        bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3);
  1091. X        }
  1092. X    }
  1093. X
  1094. Xstruct driver dev_pictex = {
  1095. X         genpictex_option,
  1096. X    genpictex_start,
  1097. X    genpictex_arc,
  1098. X    genpictex_ellipse,
  1099. X    genpictex_line,
  1100. X    genpictex_spline,
  1101. X    genpictex_text,
  1102. X    genpictex_end,
  1103. X    EXCLUDE_TEXT
  1104. X};
  1105. X
  1106. END_OF_FILE
  1107. if test 13702 -ne `wc -c <'transfig/fig2dev/dev/genpictex.c'`; then
  1108.     echo shar: \"'transfig/fig2dev/dev/genpictex.c'\" unpacked with wrong size!
  1109. fi
  1110. # end of 'transfig/fig2dev/dev/genpictex.c'
  1111. fi
  1112. if test -f 'transfig/fig2dev/read.c' -a "${1}" != "-c" ; then 
  1113.   echo shar: Will not clobber existing file \"'transfig/fig2dev/read.c'\"
  1114. else
  1115. echo shar: Extracting \"'transfig/fig2dev/read.c'\" \(16332 characters\)
  1116. sed "s/^X//" >'transfig/fig2dev/read.c' <<'END_OF_FILE'
  1117. X#include <stdio.h>
  1118. X#include <ctype.h>
  1119. X#include <errno.h>
  1120. X#include "alloc.h"
  1121. X#include "object.h"
  1122. X
  1123. X#ifdef hpux
  1124. X#define bzero(s,n) memset((s),'\0',(n))
  1125. X#endif
  1126. X
  1127. X#ifdef gould
  1128. Xextern int            errno;
  1129. X#endif
  1130. X
  1131. Xextern void        fprintf(), ungetc();
  1132. Xextern F_arrow        *make_arrow();
  1133. Xextern char        *calloc();
  1134. X
  1135. Xstatic F_ellipse    *read_ellipseobject();
  1136. Xstatic F_line        *read_lineobject();
  1137. Xstatic F_text        *read_textobject();
  1138. Xstatic F_spline        *read_splineobject();
  1139. Xstatic F_arc        *read_arcobject();
  1140. Xstatic F_compound    *read_compoundobject();
  1141. X
  1142. X#define            BUF_SIZE        1024
  1143. X
  1144. Xchar            buf[BUF_SIZE];
  1145. Xint            line_no = 0;
  1146. Xint            num_object;
  1147. Xint            tfx_flag;    /* TFX compatible */
  1148. Xint            x_flag;        /* xfig1.4X or 2.0 compatible */
  1149. Xint            v2_flag;    /* xfig2.0  compatible */
  1150. X
  1151. Xread_fail_message(file, err)
  1152. Xchar    *file;
  1153. Xint    err;
  1154. X{
  1155. X    extern char    *sys_errlist[];
  1156. X
  1157. X    if (err == 0)        /* Successful read */
  1158. X        return;
  1159. X    else if (err == ENAMETOOLONG)
  1160. X        put_msg("File name \"%s\" is too long", file);
  1161. X    else if (err == ENOENT)
  1162. X        put_msg("File \"%s\" does not exist", file);
  1163. X    else if (err == ENOTDIR)
  1164. X        put_msg("A name in the path \"%s\" is not a directory", file);
  1165. X    else if (err == EACCES)
  1166. X        put_msg("Read access to file \"%s\" is blocked", file);
  1167. X    else if (err == EISDIR)
  1168. X        put_msg("File \"%s\" is a directory", file);
  1169. X    else if (err == -2) {
  1170. X        put_msg("File \"%s\" is empty", file);
  1171. X        }
  1172. X    else if (err == -1) {
  1173. X        /* Format error; relevant error message is already delivered */
  1174. X        }
  1175. X    else
  1176. X        put_msg("File \"%s\" is not accessable; %s", file, sys_errlist[err]);
  1177. X    }
  1178. X
  1179. X/**********************************************************
  1180. XRead_fig returns :
  1181. X
  1182. X     0 : successful read.
  1183. X    -1 : File is in incorrect format
  1184. X    -2 : File is empty
  1185. Xerr_no : if file can not be read for various reasons
  1186. X
  1187. XThe resolution (ppi) and the cooridnate system (coord_sys) are
  1188. Xstored in obj->nwcorner.x and obj->nwcorner.x respectively.
  1189. X**********************************************************/
  1190. X
  1191. Xread_fig(file_name, obj)
  1192. Xchar        *file_name;
  1193. XF_compound    *obj;
  1194. X{
  1195. X    FILE        *fp;
  1196. X
  1197. X    if ((fp = fopen(file_name, "r")) == NULL)
  1198. X        return(errno);
  1199. X    else
  1200. X        return(readfp_fig(fp, obj));
  1201. X    }
  1202. X
  1203. Xreadfp_fig(fp, obj)
  1204. XFILE    *fp;
  1205. XF_compound    *obj;
  1206. X{
  1207. X    char        c;
  1208. X    int        status;
  1209. X
  1210. X    num_object = 0;
  1211. X    c = fgetc(fp);
  1212. X    if (feof(fp)) return(-2);
  1213. X    ungetc(c, fp);
  1214. X    bzero((char*)obj, COMOBJ_SIZE);
  1215. X    if (c == '#')
  1216. X        status = read_objects(fp, obj);
  1217. X    else
  1218. X        status = read_1_3_objects(fp, obj);
  1219. X    (void)fclose(fp);
  1220. X    return(status);
  1221. X    }
  1222. X    
  1223. Xint
  1224. Xread_objects(fp, obj)
  1225. XFILE        *fp;
  1226. XF_compound    *obj;
  1227. X{
  1228. X    F_ellipse    *e, *le = NULL;
  1229. X    F_line        *l, *ll = NULL;
  1230. X    F_text        *t, *lt = NULL;
  1231. X    F_spline    *s, *ls = NULL;
  1232. X    F_arc        *a, *la = NULL;
  1233. X    F_compound    *c, *lc = NULL;
  1234. X    int        object, ppi, coord_sys;
  1235. X
  1236. X    bzero((char*)obj, COMOBJ_SIZE);
  1237. X    (void)fgets(buf, BUF_SIZE, fp);    /* get the version line */
  1238. X    tfx_flag = (!strncmp(&buf[strlen(buf)-3], "TFX", 3)); /* check for TFX */
  1239. X    v2_flag = (!strncmp(buf, "#FIG 2", 6));    /* v2.0 and later have extra
  1240. X                           field for arc_box radius */
  1241. X    x_flag = v2_flag || (!strncmp(buf, "#FIG 1.4X", 9));    /* non-TFX */
  1242. X
  1243. X    line_no++;
  1244. X    if (get_line(fp) < 0) {
  1245. X        put_msg("File is truncated");
  1246. X        return(-1);
  1247. X        }
  1248. X    if (2 != sscanf(buf,"%d%d\n", &ppi, &coord_sys)) {
  1249. X        put_msg("Incomplete data at line %d", line_no);
  1250. X        return(-1);
  1251. X        }
  1252. X
  1253. X    obj->nwcorner.x = ppi;
  1254. X    obj->nwcorner.y = coord_sys;
  1255. X    while (get_line(fp) > 0) {
  1256. X        if (1 != sscanf(buf, "%d", &object)) {
  1257. X        put_msg("Incorrect format at line %d", line_no);
  1258. X        return(-1);
  1259. X        }
  1260. X        switch (object) {
  1261. X        case O_POLYLINE :
  1262. X            if ((l = read_lineobject(fp)) == NULL) return(-1);
  1263. X            if (ll)
  1264. X            ll = (ll->next = l);
  1265. X            else 
  1266. X            ll = obj->lines = l;
  1267. X            num_object++;
  1268. X            break;
  1269. X        case O_SPLINE :
  1270. X            if ((s = read_splineobject(fp)) == NULL) return(-1);
  1271. X            if (ls)
  1272. X            ls = (ls->next = s);
  1273. X            else 
  1274. X            ls = obj->splines = s;
  1275. X            num_object++;
  1276. X            break;
  1277. X        case O_ELLIPSE :
  1278. X            if ((e = read_ellipseobject()) == NULL) return(-1);
  1279. X            if (le)
  1280. X            le = (le->next = e);
  1281. X            else 
  1282. X            le = obj->ellipses = e;
  1283. X            num_object++;
  1284. X            break;
  1285. X        case O_ARC :
  1286. X            if ((a = read_arcobject(fp)) == NULL) return(-1);
  1287. X            if (la)
  1288. X            la = (la->next = a);
  1289. X            else 
  1290. X            la = obj->arcs = a;
  1291. X            num_object++;
  1292. X            break;
  1293. X        case O_TEXT :
  1294. X            if ((t = read_textobject(fp)) == NULL) return(-1);
  1295. X            if (lt)
  1296. X            lt = (lt->next = t);
  1297. X            else 
  1298. X            lt = obj->texts = t;
  1299. X            num_object++;
  1300. X            break;
  1301. X        case O_COMPOUND :
  1302. X            if ((c = read_compoundobject(fp)) == NULL) return(-1);
  1303. X            if (lc)
  1304. X            lc = (lc->next = c);
  1305. X            else 
  1306. X            lc = obj->compounds = c;
  1307. X            num_object++;
  1308. X            break;
  1309. X        default :
  1310. X            put_msg("Incorrect object code at line %d", line_no);
  1311. X            return(-1);
  1312. X        } /*  switch */
  1313. X        } /*  while */
  1314. X    if (feof(fp))
  1315. X        return(0);
  1316. X    else
  1317. X        return(errno);
  1318. X    } /*  read_objects */
  1319. X
  1320. Xstatic F_arc *
  1321. Xread_arcobject(fp)
  1322. XFILE    *fp;
  1323. X{
  1324. X    F_arc    *a;
  1325. X    int    n, fa, ba;
  1326. X    int    type, style;
  1327. X    double    thickness, wid, ht;
  1328. X
  1329. X    if (NULL == (Arc_malloc(a))) {
  1330. X        put_msg(Err_mem);
  1331. X        return(NULL);
  1332. X        }
  1333. X    a->pen = NULL;
  1334. X    a->area_fill = NULL;
  1335. X    a->for_arrow = NULL;
  1336. X    a->back_arrow = NULL;
  1337. X    a->next = NULL;
  1338. X    n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%d%d%lf%lf%d%d%d%d%d%d\n",
  1339. X        &a->type, &a->style, &a->thickness, 
  1340. X        &a->color, &a->depth, &a->pen, &a->area_fill, 
  1341. X        &a->style_val, &a->direction, &fa, &ba,
  1342. X        &a->center.x, &a->center.y, 
  1343. X        &a->point[0].x, &a->point[0].y, 
  1344. X        &a->point[1].x, &a->point[1].y, 
  1345. X        &a->point[2].x, &a->point[2].y);
  1346. X    if (n != 19) {
  1347. X        put_msg(Err_incomp, "arc", line_no);
  1348. X        free((char*)a);
  1349. X        return(NULL);
  1350. X        }
  1351. X
  1352. X    skip_comment(fp);
  1353. X    if (fa) {
  1354. X        line_no++;
  1355. X        if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
  1356. X        fprintf(stderr, Err_incomp, "arc", line_no);
  1357. X        return(NULL);
  1358. X        }
  1359. X        skip_line(fp);
  1360. X        a->for_arrow = make_arrow(type, style, thickness, wid, ht);
  1361. X        skip_comment(fp);
  1362. X        }
  1363. X    skip_comment(fp);
  1364. X    if (ba) {
  1365. X        line_no++;
  1366. X        if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
  1367. X        fprintf(stderr, Err_incomp, "arc", line_no);
  1368. X        return(NULL);
  1369. X        }
  1370. X        skip_line(fp);
  1371. X        a->back_arrow = make_arrow(type, style, thickness, wid, ht);
  1372. X        }
  1373. X    return(a);
  1374. X    }
  1375. X
  1376. Xstatic F_compound *
  1377. Xread_compoundobject(fp)
  1378. XFILE    *fp;
  1379. X{
  1380. X    F_arc        *a, *la = NULL;
  1381. X    F_ellipse    *e, *le = NULL;
  1382. X    F_line        *l, *ll = NULL;
  1383. X    F_spline    *s, *ls = NULL;
  1384. X    F_text        *t, *lt = NULL;
  1385. X    F_compound    *com, *c, *lc = NULL;
  1386. X    int        n, object;
  1387. X
  1388. X    Compound_malloc(com);
  1389. X    com->arcs = NULL;
  1390. X    com->ellipses = NULL;
  1391. X    com->lines = NULL;
  1392. X    com->splines = NULL;
  1393. X    com->texts = NULL;
  1394. X    com->compounds = NULL;
  1395. X    com->next = NULL;
  1396. X    n = sscanf(buf, "%*d%d%d%d%d\n", &com->nwcorner.x, &com->nwcorner.y,
  1397. X        &com->secorner.x, &com->secorner.y);
  1398. X    if (4 != n) {
  1399. X        put_msg(Err_incomp, "compound", line_no);
  1400. X        free((char*)com);
  1401. X        return(NULL);
  1402. X        }
  1403. X    while (get_line(fp) > 0) {
  1404. X        if (1 != sscanf(buf, "%d", &object)) {
  1405. X        put_msg(Err_incomp, "compound", line_no);
  1406. X        free_compound(&com);
  1407. X        return(NULL);
  1408. X        }
  1409. X        switch (object) {
  1410. X        case O_POLYLINE :
  1411. X            if ((l = read_lineobject(fp)) == NULL) { 
  1412. X            free_line(&l);
  1413. X            return(NULL);
  1414. X            }
  1415. X            if (ll)
  1416. X            ll = (ll->next = l);
  1417. X            else 
  1418. X            ll = com->lines = l;
  1419. X            break;
  1420. X        case O_SPLINE :
  1421. X            if ((s = read_splineobject(fp)) == NULL) { 
  1422. X            free_spline(&s);
  1423. X            return(NULL);
  1424. X            }
  1425. X            if (ls)
  1426. X            ls = (ls->next = s);
  1427. X            else 
  1428. X            ls = com->splines = s;
  1429. X            break;
  1430. X        case O_ELLIPSE :
  1431. X            if ((e = read_ellipseobject()) == NULL) { 
  1432. X            free_ellipse(&e);
  1433. X            return(NULL);
  1434. X            }
  1435. X            if (le)
  1436. X            le = (le->next = e);
  1437. X            else 
  1438. X            le = com->ellipses = e;
  1439. X            break;
  1440. X        case O_ARC :
  1441. X            if ((a = read_arcobject(fp)) == NULL) { 
  1442. X            free_arc(&a);
  1443. X            return(NULL);
  1444. X            }
  1445. X            if (la)
  1446. X            la = (la->next = a);
  1447. X            else 
  1448. X            la = com->arcs = a;
  1449. X            break;
  1450. X        case O_TEXT :
  1451. X            if ((t = read_textobject(fp)) == NULL) { 
  1452. X            free_text(&t);
  1453. X            return(NULL);
  1454. X            }
  1455. X            if (lt)
  1456. X            lt = (lt->next = t);
  1457. X            else 
  1458. X            lt = com->texts = t;
  1459. X            break;
  1460. X        case O_COMPOUND :
  1461. X            if ((c = read_compoundobject(fp)) == NULL) { 
  1462. X            free_compound(&c);
  1463. X            return(NULL);
  1464. X            }
  1465. X            if (lc)
  1466. X            lc = (lc->next = c);
  1467. X            else 
  1468. X            lc = com->compounds = c;
  1469. X            break;
  1470. X        case O_END_COMPOUND :
  1471. X            return(com);
  1472. X        default :
  1473. X            put_msg("Wrong object code at line %d", line_no);
  1474. X            return(NULL);
  1475. X        } /*  switch */
  1476. X        }
  1477. X    if (feof(fp))
  1478. X        return(com);
  1479. X    else
  1480. X        return(NULL);
  1481. X    }
  1482. X
  1483. Xstatic F_ellipse *
  1484. Xread_ellipseobject()
  1485. X{
  1486. X    F_ellipse    *e;
  1487. X    int        n;
  1488. X
  1489. X    Ellipse_malloc(e);
  1490. X    e->area_fill = NULL;
  1491. X    e->pen = NULL;
  1492. X    e->next = NULL;
  1493. X    n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%lf%d%d%d%d%d%d%d%d\n",
  1494. X        &e->type, &e->style, &e->thickness,
  1495. X        &e->color, &e->depth, &e->pen, &e->area_fill,
  1496. X        &e->style_val, &e->direction, &e->angle,
  1497. X        &e->center.x, &e->center.y, 
  1498. X        &e->radiuses.x, &e->radiuses.y, 
  1499. X        &e->start.x, &e->start.y, 
  1500. X        &e->end.x, &e->end.y);
  1501. X    if (n != 18) {
  1502. X        put_msg(Err_incomp, "ellipse", line_no);
  1503. X        free((char*)e);
  1504. X        return(NULL);
  1505. X        }
  1506. X    return(e);
  1507. X    }
  1508. X
  1509. Xstatic F_line *
  1510. Xread_lineobject(fp)
  1511. XFILE    *fp;
  1512. X{
  1513. X    F_line    *l;
  1514. X    F_point    *p, *q;
  1515. X    int    n, x, y, fa, ba;
  1516. X    int    type, style;
  1517. X    double    thickness, wid, ht;
  1518. X
  1519. X    Line_malloc(l);
  1520. X    l->points = NULL;
  1521. X    l->pen = NULL;
  1522. X    l->area_fill = NULL;
  1523. X    l->for_arrow = NULL;
  1524. X    l->back_arrow = NULL;
  1525. X    l->next = NULL;
  1526. X
  1527. X    sscanf(buf,"%*d%d",&l->type);    /* get the line type */
  1528. X    /* 2.0 or later has separate radius parm for arc-box corners */
  1529. X    if (l->type == T_ARC_BOX && v2_flag)
  1530. X        {
  1531. X        n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%d%d",
  1532. X        &l->type, &l->style, &l->thickness, &l->color,
  1533. X        &l->depth, &l->pen, &l->area_fill, &l->style_val, &l->radius, &fa, &ba);
  1534. X        }
  1535. X    /* old format uses pen for radius of arc-box corners */
  1536. X    else
  1537. X        {
  1538. X        n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%d",
  1539. X        &l->type, &l->style, &l->thickness, &l->color,
  1540. X        &l->depth, &l->pen, &l->area_fill, &l->style_val, &fa, &ba);
  1541. X        if (l->type == T_ARC_BOX)
  1542. X        {
  1543. X        l->radius = (int) l->pen;
  1544. X        l->pen = 0;
  1545. X        }
  1546. X        else
  1547. X        l->radius = 0;
  1548. X        }
  1549. X    if ((!v2_flag && n!=10) || 
  1550. X         (v2_flag && (l->type == T_ARC_BOX && n!=11) ||
  1551. X             (l->type != T_ARC_BOX && n!=10))) {
  1552. X        put_msg(Err_incomp, "line", line_no);
  1553. X        free((char*)l);
  1554. X        return(NULL);
  1555. X        }
  1556. X    skip_comment(fp);
  1557. X    if (fa) {
  1558. X        line_no++;
  1559. X        if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
  1560. X        fprintf(stderr, Err_incomp, "line", line_no);
  1561. X        return(NULL);
  1562. X        }
  1563. X        skip_line(fp);
  1564. X        l->for_arrow = make_arrow(type, style, thickness, wid, ht);
  1565. X        skip_comment(fp);
  1566. X        }
  1567. X    if (ba) {
  1568. X        line_no++;
  1569. X        if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
  1570. X        fprintf(stderr, Err_incomp, "line", line_no);
  1571. X        return(NULL);
  1572. X        }
  1573. X        skip_line(fp);
  1574. X        l->back_arrow = make_arrow(type, style, thickness, wid, ht);
  1575. X        skip_comment(fp);
  1576. X        }
  1577. X
  1578. X    if (NULL == (l->points = Point_malloc(p))) {
  1579. X        put_msg(Err_mem);
  1580. X        return(NULL);
  1581. X        }
  1582. X    p->next = NULL;
  1583. X    if (fscanf(fp, "%d%d", &p->x, &p->y) != 2) {
  1584. X        put_msg(Err_incomp, "line", line_no);
  1585. X        free_linestorage(l);
  1586. X        return(NULL);
  1587. X        }
  1588. X    for (;;) {
  1589. X        if (fscanf(fp, "%d%d", &x, &y) != 2) {
  1590. X        put_msg(Err_incomp, "line", line_no);
  1591. X        free_linestorage(l);
  1592. X        return(NULL);
  1593. X        }
  1594. X        if (x == 9999) break;
  1595. X        if (NULL == (Point_malloc(q))) {
  1596. X        put_msg(Err_mem);
  1597. X        free_linestorage(l);
  1598. X        return(NULL);
  1599. X        }
  1600. X        q->x = x;
  1601. X        q->y = y;
  1602. X        q->next = NULL;
  1603. X        p->next = q;
  1604. X        p = q;
  1605. X        }
  1606. X    skip_line(fp);
  1607. X    return(l);
  1608. X    }
  1609. X
  1610. Xstatic F_spline *
  1611. Xread_splineobject(fp)
  1612. XFILE    *fp;
  1613. X{
  1614. X    F_spline    *s;
  1615. X    F_point        *p, *q;
  1616. X    F_control    *cp, *cq;
  1617. X    int        c, n, x, y, fa, ba;
  1618. X    int        type, style;
  1619. X    double        thickness, wid, ht;
  1620. X    double        lx, ly, rx, ry;
  1621. X
  1622. X    Spline_malloc(s);
  1623. X    s->points = NULL;
  1624. X    s->controls = NULL;
  1625. X    s->pen = NULL;
  1626. X    s->area_fill = NULL;
  1627. X    s->for_arrow = NULL;
  1628. X    s->back_arrow = NULL;
  1629. X    s->next = NULL;
  1630. X
  1631. X    n = sscanf(buf, "%*d%d%d%d%d%d%d%d%lf%d%d",
  1632. X            &s->type, &s->style, &s->thickness, &s->color,
  1633. X        &s->depth, &s->pen, &s->area_fill, &s->style_val, &fa, &ba);
  1634. X    if (n != 10) {
  1635. X        put_msg(Err_incomp, "spline", line_no);
  1636. X        free((char*)s);
  1637. X        return(NULL);
  1638. X        }
  1639. X    skip_comment(fp);
  1640. X    if (fa) {
  1641. X        line_no++;
  1642. X        if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
  1643. X        fprintf(stderr, Err_incomp, "spline", line_no);
  1644. X        return(NULL);
  1645. X        }
  1646. X        skip_line(fp);
  1647. X        s->for_arrow = make_arrow(type, style, thickness, wid, ht);
  1648. X        skip_comment(fp);
  1649. X        }
  1650. X    if (ba) {
  1651. X        line_no++;
  1652. X        if (5 != fscanf(fp, "%d%d%lf%lf%lf", &type, &style, &thickness, &wid, &ht)) {
  1653. X        fprintf(stderr, Err_incomp, "spline", line_no);
  1654. X        return(NULL);
  1655. X        }
  1656. X        skip_line(fp);
  1657. X        s->back_arrow = make_arrow(type, style, thickness, wid, ht);
  1658. X        skip_comment(fp);
  1659. X        }
  1660. X
  1661. X    /* Read points */
  1662. X    if ((n = fscanf(fp, "%d%d", &x, &y)) != 2) {
  1663. X        put_msg(Err_incomp, "spline", line_no);
  1664. X        free_splinestorage(s);
  1665. X        return(NULL);
  1666. X        };
  1667. X    if (NULL == (s->points = Point_malloc(p))) {
  1668. X        put_msg(Err_mem);
  1669. X        free_splinestorage(s);
  1670. X        return(NULL);
  1671. X        }
  1672. X    p->x = x; p->y = y;
  1673. X    for (c = 1;;) {
  1674. X        if (fscanf(fp, "%d%d", &x, &y) != 2) {
  1675. X        put_msg(Err_incomp, "spline", line_no);
  1676. X        p->next = NULL;
  1677. X        free_splinestorage(s);
  1678. X        return(NULL);
  1679. X        };
  1680. X        if (x == 9999) break;
  1681. X        if (NULL == (Point_malloc(q))) {
  1682. X        put_msg(Err_mem);
  1683. X        free_splinestorage(s);
  1684. X        return(NULL);
  1685. X        }
  1686. X        q->x = x;
  1687. X        q->y = y;
  1688. X        p->next = q;
  1689. X        p = q;
  1690. X        c++;
  1691. X        }
  1692. X    p->next = NULL;
  1693. X    skip_line(fp);
  1694. X
  1695. X    if (normal_spline(s)) return(s);
  1696. X
  1697. X    skip_comment(fp);
  1698. X    /* Read controls */
  1699. X    if ((n = fscanf(fp, "%lf%lf%lf%lf", &lx, &ly, &rx, &ry)) != 4) {
  1700. X        put_msg(Err_incomp, "spline", line_no);
  1701. X        free_splinestorage(s);
  1702. X        return(NULL);
  1703. X        };
  1704. X    if (NULL == (s->controls = Control_malloc(cp))) {
  1705. X        put_msg(Err_mem);
  1706. X        free_splinestorage(s);
  1707. X        return(NULL);
  1708. X        }
  1709. X    cp->lx = lx; cp->ly = ly;
  1710. X    cp->rx = rx; cp->ry = ry;
  1711. X    while (--c) {
  1712. X        if (fscanf(fp, "%lf%lf%lf%lf", &lx, &ly, &rx, &ry) != 4) {
  1713. X        put_msg(Err_incomp, "spline", line_no);
  1714. X        cp->next = NULL;
  1715. X        free_splinestorage(s);
  1716. X        return(NULL);
  1717. X        };
  1718. X        if (NULL == (Control_malloc(cq))) {
  1719. X        put_msg(Err_mem);
  1720. X        cp->next = NULL;
  1721. X        free_splinestorage(s);
  1722. X        return(NULL);
  1723. X        }
  1724. X        cq->lx = lx; cq->ly = ly;
  1725. X        cq->rx = rx; cq->ry = ry;
  1726. X        cp->next = cq;
  1727. X        cp = cq;
  1728. X        }
  1729. X    cp->next = NULL;
  1730. X
  1731. X    skip_line(fp);
  1732. X    return(s);
  1733. X    }
  1734. X
  1735. Xstatic F_text *
  1736. Xread_textobject(fp)
  1737. XFILE    *fp;
  1738. X{
  1739. X    F_text    *t;
  1740. X    int    n, ignore = 0;
  1741. X    char    s[BUF_SIZE], s_temp[BUF_SIZE], junk[2];
  1742. X
  1743. X    Text_malloc(t);
  1744. X    t->font = NULL;
  1745. X    t->size = NULL;
  1746. X    t->next = NULL;
  1747. X    /* The text object is terminated by a CONTROL-A, so we read
  1748. X       everything up to the CONTROL-A and then read that character.
  1749. X       If we do not find the CONTROL-A on this line then this must
  1750. X       be a multi-line text object and we will have to read more. */
  1751. X    n = sscanf(buf,"%*d%d%d%d%d%d%d%lf%d%d%d%d%d%[^\1]%[\1]",
  1752. X        &t->type, &t->font, &t->size, &t->pen,
  1753. X        &t->color, &t->depth, &t->angle,
  1754. X        &t->style, &t->height, &t->length, 
  1755. X        &t->base_x, &t->base_y, s, junk);
  1756. X    if ((n != 14) && (n != 13)) {
  1757. X      put_msg(Err_incomp, "text", line_no);
  1758. X      free((char*)t);
  1759. X/*       return(NULL); */
  1760. X    }
  1761. X    if (n == 13) {
  1762. X      /* Read in the remainder of the text object. */
  1763. X      do {
  1764. X        fgets(buf, BUF_SIZE, fp);
  1765. X        line_no++;  /* As is done in get_line */
  1766. X        n = sscanf(buf,"%[^\1]%[\1]", s_temp, junk);
  1767. X        /* Safety check */
  1768. X        if (strlen(s)+1 + strlen(s_temp)+1 > BUF_SIZE) {
  1769. X          /* Too many characters.  Ignore the rest. */
  1770. X          ignore = 1;
  1771. X        }
  1772. X        if (!ignore)
  1773. X          strcat(s, s_temp);
  1774. X      } while (n == 1);
  1775. X    }
  1776. X    if (strlen(s) == 0) (void)strcpy(s, " ");
  1777. X    t->cstring = (char*)calloc((unsigned)(strlen(s)), sizeof(char));
  1778. X    if (NULL == t->cstring) {
  1779. X        put_msg(Err_mem);
  1780. X        free((char*)t);
  1781. X        return(NULL);
  1782. X        }
  1783. X    (void)strcpy(t->cstring, s+1);
  1784. X     if (!tfx_flag && !x_flag) 
  1785. X         t->size = 0;    /* 1.4(not X) and earlier had garbage in size*/
  1786. X    if (t->style > 1) {
  1787. X        put_msg(
  1788. X            "Text styles not supported; default font substituted\n");
  1789. X        t->style = t->font = DEFAULT;
  1790. X    }
  1791. X    return(t);
  1792. X    }
  1793. X
  1794. Xget_line(fp)
  1795. XFILE    *fp;
  1796. X{
  1797. X    while (1) {
  1798. X        if (NULL == fgets(buf, BUF_SIZE, fp)) {
  1799. X        return(-1);
  1800. X        }
  1801. X        line_no++;
  1802. X        if (*buf != '\n' && *buf != '#') return(1);
  1803. X            /* Skip empty and comment lines */
  1804. X        }
  1805. X    }
  1806. X
  1807. Xskip_comment(fp)
  1808. XFILE    *fp;
  1809. X{
  1810. X    char c;
  1811. X
  1812. X    while ((c = fgetc(fp)) == '#') skip_line(fp);
  1813. X    if (c != '#') ungetc(c, fp);
  1814. X    }
  1815. X
  1816. Xskip_line(fp)
  1817. XFILE    *fp;
  1818. X{
  1819. X    while (fgetc(fp) != '\n') {
  1820. X        if (feof(fp)) return;
  1821. X        }
  1822. X    }
  1823. END_OF_FILE
  1824. if test 16332 -ne `wc -c <'transfig/fig2dev/read.c'`; then
  1825.     echo shar: \"'transfig/fig2dev/read.c'\" unpacked with wrong size!
  1826. fi
  1827. # end of 'transfig/fig2dev/read.c'
  1828. fi
  1829. echo shar: End of archive 3 \(of 6\).
  1830. cp /dev/null ark3isdone
  1831. MISSING=""
  1832. for I in 1 2 3 4 5 6 ; do
  1833.     if test ! -f ark${I}isdone ; then
  1834.     MISSING="${MISSING} ${I}"
  1835.     fi
  1836. done
  1837. if test "${MISSING}" = "" ; then
  1838.     echo You have unpacked all 6 archives.
  1839.     rm -f ark[1-9]isdone
  1840. else
  1841.     echo You still need to unpack the following archives:
  1842.     echo "        " ${MISSING}
  1843. fi
  1844. ##  End of shell archive.
  1845. exit 0
  1846. -- 
  1847. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  1848. Use a domain-based address or give alternate paths, or you may lose out.
  1849.