home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume22 / transfig / part03 < prev    next >
Text File  |  1990-10-09  |  46KB  |  1,840 lines

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