home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / fchart.lzh / fchart.3 < prev    next >
Encoding:
Text File  |  1990-06-09  |  51.7 KB  |  1,705 lines

  1.  
  2. #!/bin/sh
  3. # This is part 03 of Fchart
  4. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  5.  then TOUCH=touch
  6.  else TOUCH=true
  7. fi
  8. # ============= flblarr.c ==============
  9. echo "x - extracting flblarr.c (Text)"
  10. sed 's/^X//' << 'SHAR_EOF' > flblarr.c &&
  11. X/*
  12. X *
  13. X *  Fchart  --  flblarr.c
  14. X *
  15. X *  Copyright (C) 1990 Piotr Filip Sawicki
  16. X *
  17. X * Permission to use, copy, and distribute this software and its
  18. X * documentation for any purpose with or without fee is hereby granted,
  19. X * provided that the above copyright notice appear in all copies and
  20. X * that both that copyright notice and this permission notice appear
  21. X * in supporting documentation.
  22. X *
  23. X * Permission to modify the software is granted, but not the right to
  24. X * distribute the modified code.  Modifications are to be distributed
  25. X * as patches to released version.
  26. X *
  27. X *  Please e-mail any useful additions to fs@uwasa.fi so they may be
  28. X *  included in later releases.
  29. X *
  30. X *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
  31. X */
  32. X
  33. X#include <stdio.h>
  34. X#include <math.h>
  35. X#include "plot.h"
  36. X#include "fchart.h"
  37. X    
  38. Xstruct label_def *first_label = NULL;
  39. Xstruct linearrow_def *first_arrow = NULL;
  40. X
  41. Xextern char *strcpy(),*strcat();
  42. Xextern int strlen();
  43. X
  44. X/* input data, parsing variables */
  45. Xextern struct lexical_unit token[];
  46. Xextern char input_line[];
  47. Xextern int num_tokens, c_token;
  48. X
  49. Xextern double real();
  50. X
  51. X/******** Local functions ********/
  52. Xstatic int assign_label_tag();
  53. Xstatic int assign_arrow_tag();
  54. Xstatic void delete_label();
  55. Xstatic void delete_arrow();
  56. X
  57. X/* not static: used by fcmd.c */
  58. Xvoid show_labels(), show_arrow();        
  59. Xvoid set_label();
  60. Xvoid set_nolabel();
  61. Xvoid set_arrow();
  62. Xvoid set_noarrow();
  63. X
  64. X/* process a 'set label' command */
  65. X/* set label {tag} {label_text} {at {page|picture} x,y} {pos} {height h} {width w} */
  66. Xvoid
  67. Xset_label()
  68. X{
  69. X    struct label_def *this_label = NULL;
  70. X    struct label_def *new_label = NULL;
  71. X    struct label_def *prev_label = NULL;
  72. X    double x, y, h, w, a;
  73. X    char text[MAX_LINE_LEN+1];
  74. X    enum JUSTIFY just = LEFT;
  75. X    enum LAB_ROT rot;
  76. X    int tag;
  77. X    BOOLEAN set_text, set_position, set_just=FALSE, set_h, set_w, set_r;
  78. X    BOOLEAN page_label;
  79. X    
  80. X    /* get tag */
  81. X    if (!END_OF_COMMAND && isnumber(c_token)) {
  82. X        tag = (int)real(c_token);
  83. X        if (tag == 0)
  84. X            int_error("tag must be > zero", c_token);
  85. X        c_token++;
  86. X    } else
  87. X        tag = assign_label_tag(); /* default next tag */
  88. X    
  89. X    /* get text */
  90. X    if (!END_OF_COMMAND && isstring(c_token)) {
  91. X        quote_str(text, c_token);
  92. X        c_token++;
  93. X        set_text = TRUE;
  94. X    } else {
  95. X        text[0] = '\0';        /* default no text */
  96. X        set_text = FALSE;
  97. X    }
  98. X        
  99. X    /* get justification -- why not here ? */
  100. X    if (!END_OF_COMMAND) {
  101. X        if (almost_equals(c_token,"l$eft")) {
  102. X            just = LEFT;
  103. X            set_just = TRUE;
  104. X            c_token++;
  105. X        }
  106. X        else if (almost_equals(c_token,"c$entre")
  107. X                 || almost_equals(c_token,"c$enter")) {
  108. X            just = CENTRE;
  109. X            set_just = TRUE;
  110. X            c_token++;
  111. X        }
  112. X        else if (almost_equals(c_token,"ri$ght")) {
  113. X            just = RIGHT;
  114. X            set_just = TRUE;
  115. X            c_token++;
  116. X        }
  117. X    }
  118. X
  119. X    /* get position */
  120. X    if (!END_OF_COMMAND && equals(c_token, "at")) {
  121. X        c_token++;
  122. X        if (END_OF_COMMAND)
  123. X            int_error("coordinates expected", c_token);
  124. X        if (almost_equals(c_token, "pa$ge")) {
  125. X            c_token++;
  126. X            page_label = TRUE;
  127. X        }
  128. X        else if (almost_equals(c_token, "pi$cture")) {
  129. X            c_token++;
  130. X            page_label = FALSE;
  131. X        }
  132. X        else if (!isnumber(c_token))
  133. X            int_error("'page' or 'picture' expected", c_token);
  134. X        else
  135. X            page_label = FALSE;
  136. X        x = real(c_token++);
  137. X        if (!equals(c_token,","))
  138. X            int_error("',' expected", c_token);
  139. X        else
  140. X            c_token++;
  141. X        y = real(c_token++);
  142. X        set_position = TRUE;
  143. X    } else {
  144. X        x = y = 0;            /* default at origin */
  145. X        page_label = FALSE;
  146. X        set_position = FALSE;
  147. X    }
  148. X    
  149. X    /* get justification */
  150. X    if (!END_OF_COMMAND) {
  151. X        if (almost_equals(c_token,"l$eft")) {
  152. X            if (set_just)
  153. X                int_error("only one justification is allowed", c_token);
  154. X            just = LEFT;
  155. X            set_just = TRUE;
  156. X            c_token++;
  157. X        }
  158. X        else if (almost_equals(c_token,"c$entre")
  159. X                 || almost_equals(c_token,"c$enter")) {
  160. X            if (set_just)
  161. X                int_error("only one justification is allowed", c_token);
  162. X            just = CENTRE;
  163. X            set_just = TRUE;
  164. X            c_token++;
  165. X        }
  166. X        else if (almost_equals(c_token,"ri$ght")) {
  167. X            if (set_just)
  168. X                int_error("only one justification is allowed", c_token);
  169. X            just = RIGHT;
  170. X            set_just = TRUE;
  171. X            c_token++;
  172. X        }
  173. X    }
  174. X
  175. X    /* get height */
  176. X    if (!END_OF_COMMAND && almost_equals(c_token, "he$ight")) {
  177. X        c_token++;
  178. X        h = real(c_token++);
  179. X        set_h = TRUE;
  180. X    }
  181. X    else {
  182. X        h = 0.0;
  183. X        set_h = FALSE;
  184. X    }
  185. X
  186. X    /* get width */
  187. X    if (!END_OF_COMMAND && almost_equals(c_token, "wi$dth")) {
  188. X        c_token++;
  189. X        w = real(c_token++);
  190. X        set_w = TRUE;
  191. X    }
  192. X    else {
  193. X        w = 0.0;
  194. X        set_w = FALSE;
  195. X    }
  196. X
  197. X    /* get angle */
  198. X    if (!END_OF_COMMAND && almost_equals(c_token, "ro$tation")) {
  199. X        int sign = 1;
  200. X        c_token++;
  201. X        if (equals(c_token, "-")) {
  202. X            c_token++;
  203. X            sign = -1;
  204. X        }
  205. X        a = (double)sign * real(c_token++);
  206. X        rot = L_RANDOM;
  207. X        set_r = TRUE;
  208. X    }
  209. X    else if (!END_OF_COMMAND) {
  210. X        if (almost_equals(c_token, "di$rection")) {
  211. X            c_token++;
  212. X            set_r = TRUE;        /* empty direction defaults to normal */
  213. X        }
  214. X        else
  215. X            set_r = FALSE;
  216. X        if (!END_OF_COMMAND && (almost_equals(c_token, "n$orth") ||
  217. X            almost_equals(c_token, "v$ertical") || almost_equals(c_token, "u$p"))) {
  218. X            c_token++;
  219. X            rot = L_BOTTOM;
  220. X            set_r = TRUE;
  221. X        }
  222. X        else if (!END_OF_COMMAND && (almost_equals(c_token, "s$outh") ||
  223. X                 almost_equals(c_token, "do$wn"))) {
  224. X            c_token++;
  225. X            rot = L_TOP;
  226. X            set_r = TRUE;
  227. X        }
  228. X        else if (!END_OF_COMMAND && (almost_equals(c_token, "we$st") ||
  229. X                 almost_equals(c_token, "l$eft"))) {
  230. X            c_token++;
  231. X            rot = L_UPSIDE;
  232. X            set_r = TRUE;
  233. X        }
  234. X        else if (!END_OF_COMMAND && (almost_equals(c_token, "ho$rizontal") ||
  235. X                 almost_equals(c_token, "e$ast") || almost_equals(c_token, "ri$ght"))) {
  236. X            c_token++;
  237. X            rot = L_NORMAL;
  238. X            set_r = TRUE;
  239. X        }
  240. X        else {
  241. X            rot = L_NORMAL;
  242. X        }
  243. X    }
  244. X    else {
  245. X        rot = L_NORMAL;
  246. X        set_r = FALSE;
  247. X    }
  248. X        
  249. X    if (!END_OF_COMMAND)
  250. X        int_error("extraneous or out-of-order arguments in set label", c_token);
  251. X    
  252. X    /* OK! add label */
  253. X    if (first_label != NULL) { /* skip to last label */
  254. X        for (this_label = first_label; this_label != NULL ; 
  255. X             prev_label = this_label, this_label = this_label->next)
  256. X            /* is this the label we want? */
  257. X            if (tag <= this_label->tag)
  258. X                break;
  259. X    }
  260. X    if (this_label != NULL && tag == this_label->tag) {
  261. X        /* changing the label */
  262. X        if (set_position) {
  263. X            this_label->x = x;
  264. X            this_label->y = y;
  265. X            this_label->paged = page_label;
  266. X        }
  267. X        if (set_text)
  268. X            (void) strcpy(this_label->text, text);
  269. X        if (set_just)
  270. X            this_label->pos = just;
  271. X        if (set_h)
  272. X            this_label->h = h;
  273. X        if (set_w)
  274. X            this_label->w = w;
  275. X        if (set_r) {
  276. X            this_label->rot = rot;
  277. X            this_label->a = a;
  278. X        }
  279. X    } else {
  280. X        /* adding the label */
  281. X        new_label = (struct label_def *) 
  282. X            alloc ( (unsigned int) sizeof(struct label_def), "label");
  283. X        if (prev_label != NULL)
  284. X            prev_label->next = new_label; /* add it to end of list */
  285. X        else 
  286. X            first_label = new_label; /* make it start of list */
  287. X        new_label->tag = tag;
  288. X        new_label->next = this_label;
  289. X        new_label->x = x;
  290. X        new_label->y = y;
  291. X        (void) strcpy(new_label->text, text);
  292. X        new_label->pos = just;
  293. X        new_label->h = h;
  294. X        new_label->w = w;
  295. X        new_label->rot = rot;
  296. X        new_label->a = a;
  297. X        new_label->paged = page_label;
  298. X    }
  299. X}
  300. X
  301. X/* process 'set nolabel' command */
  302. X/* set nolabel {tag} */
  303. Xvoid
  304. Xset_nolabel()
  305. X{
  306. X    struct label_def *this_label;
  307. X    struct label_def *prev_label; 
  308. X    int tag;
  309. X    
  310. X    if (END_OF_COMMAND) {        /* delete all labels */
  311. X        while (first_label != NULL)
  312. X            delete_label((struct label_def *)NULL, first_label);
  313. X    }
  314. X    else {
  315. X        tag = (int)real(c_token++);
  316. X        if (!END_OF_COMMAND)
  317. X            int_error("extraneous arguments to set nolabel", c_token);
  318. X        for (this_label = first_label, prev_label = NULL;
  319. X             this_label != NULL;
  320. X             prev_label = this_label, this_label = this_label->next) {
  321. X            if (this_label->tag == tag) {
  322. X                delete_label(prev_label, this_label);
  323. X                return;        /* exit, our job is done */
  324. X            }
  325. X        }
  326. X        int_error("label not found", c_token);
  327. X    }
  328. X}
  329. X
  330. X/* assign a new label tag */
  331. X/* labels are kept sorted by tag number, so this is easy */
  332. Xstatic int                /* the lowest unassigned tag number */
  333. Xassign_label_tag()
  334. X{
  335. X    struct label_def *this_label;
  336. X    int last = 0;            /* previous tag value */
  337. X    
  338. X    for (this_label = first_label; this_label != NULL;
  339. X         this_label = this_label->next)
  340. X        if (this_label->tag == last+1)
  341. X            last++;
  342. X        else
  343. X            break;
  344. X    
  345. X    return (last+1);
  346. X}
  347. X
  348. X/* delete label from linked list started by first_label.
  349. X * called with pointers to the previous label (prev) and the 
  350. X * label to delete (this).
  351. X * If there is no previous label (the label to delete is
  352. X * first_label) then call with prev = NULL.
  353. X */
  354. Xstatic void
  355. Xdelete_label(prev,this)
  356. Xstruct label_def *prev, *this;
  357. X{
  358. X    if (this!=NULL)    {        /* there really is something to delete */
  359. X        if (prev!=NULL)        /* there is a previous label */
  360. X            prev->next = this->next; 
  361. X        else                /* this = first_label so change first_label */
  362. X            first_label = this->next;
  363. X        free((char *)this);
  364. X    }
  365. X}
  366. X
  367. X
  368. X/* process a 'set arrow' and 'set line' command */
  369. X/* set arrow|line {tag} {from { {page|picture} x,y} {to {page|picture} x,y} */
  370. Xvoid
  371. Xset_arrow(arrow)
  372. XBOOLEAN arrow;
  373. X{
  374. X    struct linearrow_def *this_arrow = NULL;
  375. X    struct linearrow_def *new_arrow = NULL;
  376. X    struct linearrow_def *prev_arrow = NULL;
  377. X    double sx, sy;
  378. X    double ex, ey;
  379. X    int tag;
  380. X    BOOLEAN set_start, set_end;
  381. X    BOOLEAN sp, ep;
  382. X    
  383. X    /* get tag */
  384. X    if (!END_OF_COMMAND && isnumber(c_token)) {
  385. X        tag = (int)real(c_token++);
  386. X        if (tag == 0)
  387. X            int_error("tag must be > zero", c_token);
  388. X    } else
  389. X        tag = assign_arrow_tag(); /* default next tag */
  390. X    
  391. X    /* get start position */
  392. X    if (!END_OF_COMMAND && almost_equals(c_token, "f$rom")) {
  393. X        c_token++;
  394. X        if (END_OF_COMMAND)
  395. X            int_error("start coordinates expected", c_token);
  396. X        else if (almost_equals(c_token, "pa$ge")) {
  397. X            c_token++;
  398. X            sp = TRUE;
  399. X        }
  400. X        else if (almost_equals(c_token, "pi$cture")) {
  401. X            c_token++;
  402. X            sp = FALSE;
  403. X        }
  404. X        else
  405. X            sp = FALSE;
  406. X
  407. X        sx = real(c_token++);
  408. X        if (!equals(c_token,","))
  409. X            int_error("',' expected",c_token);
  410. X        c_token++;
  411. X        sy = real(c_token++);
  412. X        set_start = TRUE;
  413. X    } else {
  414. X        sx = sy = 0;            /* default at origin */
  415. X        sp = FALSE;
  416. X        set_start = FALSE;
  417. X    }
  418. X    
  419. X    /* get end position */
  420. X    if (!END_OF_COMMAND && almost_equals(c_token, "t$o")) {
  421. X        c_token++;
  422. X        if (END_OF_COMMAND)
  423. X            int_error("end coordinates expected", c_token);
  424. X        else if (almost_equals(c_token, "pa$ge")) {
  425. X            c_token++;
  426. X            ep = TRUE;
  427. X        }
  428. X        else if (almost_equals(c_token, "pi$cture")) {
  429. X            c_token++;
  430. X            ep = FALSE;
  431. X        }
  432. X        else
  433. X            ep = FALSE;
  434. X
  435. X        ex = real(c_token++);
  436. X        if (!equals(c_token,","))
  437. X            int_error("',' expected",c_token);
  438. X        c_token++;
  439. X        ey = real(c_token++);
  440. X        set_end = TRUE;
  441. X    } else {
  442. X        ex = ey = 0;            /* default at origin */
  443. X        ep = FALSE;
  444. X        set_end = FALSE;
  445. X    }
  446. X    
  447. X    /* get start position - what the heck, either order is ok */
  448. X    if (!END_OF_COMMAND && almost_equals(c_token, "f$rom")) {
  449. X        if (set_start)
  450. X            int_error("only one 'from' is allowed", c_token);
  451. X        c_token++;
  452. X        if (END_OF_COMMAND)
  453. X            int_error("start coordinates expected", c_token);
  454. X        else if (almost_equals(c_token, "pa$ge")) {
  455. X            c_token++;
  456. X            sp = TRUE;
  457. X        }
  458. X        else if (almost_equals(c_token, "pi$cture")) {
  459. X            c_token++;
  460. X            sp = FALSE;
  461. X        }
  462. X        else
  463. X            sp = FALSE;
  464. X
  465. X        sx = real(c_token++);
  466. X        if (!equals(c_token,","))
  467. X            int_error("',' expected",c_token);
  468. X        c_token++;
  469. X        sy = real(c_token++);
  470. X        set_start = TRUE;
  471. X    }
  472. X    
  473. X    if (!END_OF_COMMAND)
  474. X        int_error("extraneous or out-of-order arguments in set arrow/line", c_token);
  475. X    
  476. X    /* OK! add arrow */
  477. X    if (first_arrow != NULL) { /* skip to last arrow */
  478. X        for (this_arrow = first_arrow; this_arrow != NULL ; 
  479. X             prev_arrow = this_arrow, this_arrow = this_arrow->next)
  480. X            /* is this the arrow we want? */
  481. X            if (tag <= this_arrow->tag)
  482. X                break;
  483. X    }
  484. X    if (this_arrow != NULL && tag == this_arrow->tag) {
  485. X        /* changing the arrow */
  486. X        if (set_start) {
  487. X            this_arrow->sx = sx;
  488. X            this_arrow->sy = sy;
  489. X            this_arrow->startp = sp;
  490. X        }
  491. X        if (set_end) {
  492. X            this_arrow->ex = ex;
  493. X            this_arrow->ey = ey;
  494. X            this_arrow->endp = ep;
  495. X        }
  496. X        this_arrow->arrow = arrow;
  497. X    } else {
  498. X        /* adding the arrow */
  499. X        new_arrow = (struct linearrow_def *) 
  500. X            alloc ( (unsigned int) sizeof(struct linearrow_def), "arrow");
  501. X        if (prev_arrow != NULL)
  502. X            prev_arrow->next = new_arrow; /* add it to end of list */
  503. X        else 
  504. X            first_arrow = new_arrow; /* make it start of list */
  505. X        new_arrow->tag = tag;
  506. X        new_arrow->next = this_arrow;
  507. X        new_arrow->sx = sx;
  508. X        new_arrow->sy = sy;
  509. X        new_arrow->startp = sp;
  510. X        new_arrow->ex = ex;
  511. X        new_arrow->ey = ey;
  512. X        new_arrow->endp = ep;
  513. X        new_arrow->arrow = arrow;
  514. X    }
  515. X}
  516. X
  517. X/* process 'set noarrow' and 'set noline' command */
  518. X/* set noarrow {tag} */
  519. Xvoid
  520. Xset_noarrow()
  521. X{
  522. X    struct linearrow_def *this_arrow;
  523. X    struct linearrow_def *prev_arrow; 
  524. X    int tag;
  525. X    
  526. X    if (END_OF_COMMAND) {
  527. X        /* delete all arrows */
  528. X        while (first_arrow != NULL)
  529. X            delete_arrow((struct linearrow_def *)NULL,first_arrow);
  530. X    }
  531. X    else {
  532. X        /* get tag */
  533. X        tag = (int)real(c_token++);
  534. X        if (!END_OF_COMMAND)
  535. X            int_error("extraneous arguments to set noarrow/noline", c_token);
  536. X        for (this_arrow = first_arrow, prev_arrow = NULL;
  537. X             this_arrow != NULL;
  538. X             prev_arrow = this_arrow, this_arrow = this_arrow->next) {
  539. X            if (this_arrow->tag == tag) {
  540. X                delete_arrow(prev_arrow, this_arrow);
  541. X                return;        /* exit, our job is done */
  542. X            }
  543. X        }
  544. X        int_error("arrow/line not found", c_token);
  545. X    }
  546. X}
  547. X
  548. X/* assign a new arrow tag */
  549. X/* arrows are kept sorted by tag number, so this is easy */
  550. Xstatic int                /* the lowest unassigned tag number */
  551. Xassign_arrow_tag()
  552. X{
  553. X    struct linearrow_def *this_arrow;
  554. X    int last = 0;            /* previous tag value */
  555. X    
  556. X    for (this_arrow = first_arrow; this_arrow != NULL;
  557. X         this_arrow = this_arrow->next)
  558. X        if (this_arrow->tag == last+1)
  559. X            last++;
  560. X        else
  561. X            break;
  562. X    
  563. X    return (last+1);
  564. X}
  565. X
  566. X/* delete arrow from linked list started by first_arrow.
  567. X * called with pointers to the previous arrow (prev) and the 
  568. X * arrow to delete (this).
  569. X * If there is no previous arrow (the arrow to delete is
  570. X * first_arrow) then call with prev = NULL.
  571. X */
  572. Xstatic void
  573. Xdelete_arrow(prev,this)
  574. Xstruct linearrow_def *prev, *this;
  575. X{
  576. X    if (this!=NULL)    {        /* there really is something to delete */
  577. X        if (prev!=NULL)        /* there is a previous arrow */
  578. X            prev->next = this->next; 
  579. X        else                /* this = first_arrow so change first_arrow */
  580. X            first_arrow = this->next;
  581. X        free((char *)this);
  582. X    }
  583. X}
  584. X
  585. Xvoid
  586. Xshow_labels(tag, fp, save)
  587. Xint tag;                /* 0 means show all */
  588. XFILE *fp;
  589. XBOOLEAN save;
  590. X{
  591. X    struct label_def *this_label;
  592. X    BOOLEAN showed = FALSE;
  593. X    
  594. X    for (this_label = first_label; this_label != NULL;
  595. X         this_label = this_label->next) {
  596. X        if (tag == 0 || tag == this_label->tag) {
  597. X            showed = TRUE;
  598. X            fprintf(fp,"%slabel %d \"%s\" %s at %s %lg,%lg",
  599. X                    save ? "set " : "\t",
  600. X                    this_label->tag, this_label->text,
  601. X                    (this_label->pos==LEFT ? "left" : (this_label->pos==RIGHT ? "right" : "centre")),
  602. X                    this_label->paged ? "page" : "picture",
  603. X                    this_label->x, this_label->y);
  604. X            if (this_label->h != 0.0)
  605. X                fprintf(fp, " height %lg", this_label->h);
  606. X            if (this_label->w != 0.0)
  607. X                fprintf(fp, " width %lg", this_label->w);
  608. X            switch(this_label->rot) {
  609. X                case L_NORMAL: {
  610. X                    break;
  611. X                }
  612. X                case L_UPSIDE: {
  613. X                    fprintf(fp, " direction left");
  614. X                    break;
  615. X                }
  616. X                case L_BOTTOM: {
  617. X                    fprintf(fp, " vertical");
  618. X                    break;
  619. X                }
  620. X                case L_TOP: {
  621. X                    fprintf(fp, " direction down");
  622. X                    break;
  623. X                }
  624. X                case L_RANDOM: {
  625. X                    fprintf(fp, " rotation %lg", this_label->a);
  626. X                    break;
  627. X                }
  628. X            }
  629. X            fputc('\n',fp);
  630. X        }
  631. X    }
  632. X    if (tag > 0 && !showed)
  633. X        int_error("label not found", c_token);
  634. X}
  635. X
  636. Xvoid
  637. Xshow_arrow(tag, fp, save)
  638. Xint tag;                /* 0 means show all */
  639. XFILE *fp;
  640. XBOOLEAN save;
  641. X{
  642. X    struct linearrow_def *this_arrow;
  643. X    BOOLEAN showed = FALSE;
  644. X    
  645. X    for (this_arrow = first_arrow; this_arrow != NULL;
  646. X         this_arrow = this_arrow->next) {
  647. X        if (tag == 0 || tag == this_arrow->tag) {
  648. X            showed = TRUE;
  649. X            fprintf(fp,"%s%s %d from %s %lg,%lg to %s %lg,%lg\n",
  650. X                    save ? "set " : "\t",
  651. X                    this_arrow->arrow ? "arrow" : "line",
  652. X                    this_arrow->tag,
  653. X                    this_arrow->startp ? "page" : "picture",
  654. X                    this_arrow->sx, this_arrow->sy,
  655. X                    this_arrow->endp ? "page" : "picture",
  656. X                    this_arrow->ex, this_arrow->ey);
  657. X        }
  658. X    }
  659. X    if (tag > 0 && !showed)
  660. X        int_error("arrow not found", c_token);
  661. X}
  662. X
  663. X
  664. X
  665. X
  666. X
  667. X
  668. X
  669. X
  670. X
  671. SHAR_EOF
  672. $TOUCH -am 0604152590 flblarr.c &&
  673. chmod 0666 flblarr.c ||
  674. echo "restore of flblarr.c failed"
  675. set `wc -c flblarr.c`;Wc_c=$1
  676. if test "$Wc_c" != "16228"; then
  677.     echo original size 16228, current size $Wc_c
  678. fi
  679. # ============= fmisc.c ==============
  680. echo "x - extracting fmisc.c (Text)"
  681. sed 's/^X//' << 'SHAR_EOF' > fmisc.c &&
  682. X/* Fchart - fmisc.c */
  683. X/*
  684. X * Gnuplot code
  685. X * Copyright (C) 1986, 1987, 1990   Thomas Williams, Colin Kelley
  686. X *
  687. X * Permission to use, copy, and distribute this software and its
  688. X * documentation for any purpose with or without fee is hereby granted,
  689. X * provided that the above copyright notice appear in all copies and
  690. X * that both that copyright notice and this permission notice appear
  691. X * in supporting documentation.
  692. X *
  693. X * Permission to modify the software is granted, but not the right to
  694. X * distribute the modified code.  Modifications are to be distributed
  695. X * as patches to released version.
  696. X *
  697. X * This software  is provided "as is" without express or implied warranty.
  698. X *
  699. X *
  700. X * AUTHORS
  701. X *
  702. X *   Original Software:
  703. X *     Thomas Williams,  Colin Kelley.
  704. X *
  705. X *   Gnuplot 2.0 additions:
  706. X *       Russell Lang, Dave Kotz, John Campbell.
  707. X *
  708. X *   Fchart changes and additions:
  709. X *       Piotr Filip Sawicki
  710. X *
  711. X * send your comments or suggestions to fs@uwasa.fi
  712. X *
  713. X */
  714. X
  715. X#include <stdio.h>
  716. X#include "plot.h"
  717. X#include "fchart.h"
  718. X#include "help.h"
  719. X
  720. X#ifdef __TURBOC__
  721. X#include <graphics.h>
  722. X#endif
  723. X
  724. Xextern BOOLEAN autoscale;
  725. Xextern BOOLEAN auto_label;
  726. Xextern BOOLEAN log_y;
  727. Xextern BOOLEAN b_clockwise, p_clockwise;
  728. Xextern BOOLEAN draw_border;
  729. Xextern FILE* outfile;
  730. Xextern char outstr[];
  731. Xextern int samples;
  732. Xextern int term;
  733. Xextern double zero;
  734. Xextern double base;
  735. Xextern double radexp;
  736. Xextern double b_wid, b_spc, b_int;
  737. Xextern float xsize, ysize;
  738. Xextern double roff, loff, toff, boff;
  739. Xextern enum GRAV_DIR gravity, explode;
  740. Xextern enum INP_STYLE inp_style;
  741. Xextern enum DRAW_STYLE data_style;
  742. Xextern enum FONT_STYLE vect_font;
  743. Xextern struct pair data_place, label_plac;
  744. Xextern int HLitem;
  745. Xextern struct dfile data_head;
  746. Xextern int xmin, xmax;
  747. Xextern double treshold;
  748. Xextern char thrname[];
  749. Xextern char tic_form[];
  750. Xextern int strunc;
  751. X
  752. Xextern BOOLEAN screen_ok;
  753. X
  754. Xextern int c_token, num_tokens;
  755. Xextern struct termentry term_tbl[];
  756. X
  757. Xextern char *sprintf(),*strcpy();
  758. Xstatic char *grav_name();
  759. X
  760. Xextern void show_labels(), show_arrow();
  761. X
  762. Xchar *alloc(size, message)
  763. Xunsigned size;
  764. Xchar *message;
  765. X{
  766. X    char *malloc();
  767. X    char *p;                /* the new allocation */
  768. X    char errbuf[100];       /* error message string */
  769. X    extern char *malloc();
  770. X
  771. X    p = malloc(size);
  772. X    if (p == (char *)NULL) {
  773. X
  774. X#ifndef VMS
  775. X       FreeHelp();          /* out of memory, try to make some room */
  776. X#endif
  777. X
  778. X       p = malloc(size);        /* try again */
  779. X       if (p == (char *)NULL) {
  780. X          /* really out of memory */
  781. X          if (message != NULL) {
  782. X             (void) sprintf(errbuf, "out of memory for %s", message);
  783. X             int_error(errbuf, NO_CARET);
  784. X             /* NOTREACHED */
  785. X          }
  786. X          /* else we return NULL */
  787. X       }
  788. X    }
  789. X
  790. X    return(p);
  791. X}
  792. X    
  793. Xdestroy(p)        /* destroy dfile structure p and all the following */
  794. Xstruct dfile *p;
  795. X{
  796. Xstruct dfile *t;
  797. Xstruct chunk *a, *b;
  798. Xint i;
  799. X
  800. X    while (p) {
  801. X        for (a=p->data; a; ) {
  802. X            free((char *)a->dval);
  803. X            if (a->vlbl) {
  804. X                for (i=0; i<a->used; i++)
  805. X                    if (a->vlbl[i])
  806. X                        free(a->vlbl[i]);
  807. X                free((char *)a->vlbl);
  808. X            }
  809. X            b = a;
  810. X            a = a->next;
  811. X            free((char *)b);
  812. X        }
  813. X        if (p->fname) free(p->fname);
  814. X        t = p;
  815. X        p = p->dnxt;
  816. X        free((char *)t);
  817. X    }
  818. X}
  819. X
  820. Xload_file(fp)
  821. XFILE *fp;
  822. X{
  823. X    register int len;
  824. X    extern char input_line[];
  825. X    int start, left, more, stop = FALSE;
  826. X
  827. X    if (!fp)
  828. X        os_error("Cannot open load file",c_token);
  829. X    
  830. X    while (!stop) {      /* read all commands in file */
  831. X        /* read one command */
  832. X        left = MAX_LINE_LEN;
  833. X        start = 0;
  834. X        more = TRUE;
  835. X        
  836. X        while (more) {
  837. X            if (fgets(&(input_line[start]), left, fp) == NULL) {
  838. X                stop = TRUE; /* EOF in file */
  839. X                input_line[start] = '\0';
  840. X                more = FALSE;
  841. X            } else {
  842. X                len = strlen(input_line) - 1;
  843. X                if (input_line[len] == '\n') { /* remove any newline */
  844. X                    input_line[len] = '\0';
  845. X                    /* Look, len was 1-1 = 0 before, take care here! */
  846. X                    if (len > 0) --len;
  847. X                } else if (len+1 >= left)
  848. X                    int_error("Input line too long",NO_CARET);
  849. X                
  850. X                if (input_line[len] == '\\') { /* line continuation */
  851. X                    start = len;
  852. X                    left -= len;
  853. X                } else
  854. X                    more = FALSE;
  855. X            }
  856. X        }
  857. X        
  858. X        if (strlen(input_line) > 0) {
  859. X            screen_ok = FALSE; /* make sure command line is
  860. X                                  echoed on error */
  861. X            do_line();
  862. X        }
  863. X    }
  864. X}
  865. X
  866. Xsave_sets(fp)        /* save all current settings */
  867. XFILE *fp;
  868. X{
  869. X    char comm[MAX_LINE_LEN+1];
  870. X    
  871. X    if (!fp)
  872. X        os_error("Cannot open save file",c_token);
  873. X
  874. X    for(c_token++; !END_OF_COMMAND; c_token++) {
  875. X        if (equals(c_token,",")) continue;
  876. X        if (!isstring(c_token)) break;        /* causes error, but later */
  877. X        quote_str(comm, c_token);
  878. X        fprintf(fp,"# %s\n",comm);
  879. X    }
  880. X
  881. X    (void) putc('\n',fp);
  882. X    fprintf(fp,"set %sautolabel\n", auto_label ? "" : "no");
  883. X    fprintf(fp,"set %struncate", strunc==-1 ? "no" : "");
  884. X    if (strunc>0)
  885. X        fprintf(fp," %d", strunc);
  886. X    (void) putc('\n',fp);
  887. X    fprintf(fp,"set cust ");
  888. X    if (data_place.from != -1) {
  889. X        show_segment(data_place.from,data_place.upto,fp);
  890. X        (void) putc(' ',fp);
  891. X        if (label_plac.from != -1)
  892. X            show_segment(label_plac.from,label_plac.upto,fp);
  893. X    }
  894. X    (void) putc('\n',fp);
  895. X    fprintf(fp,"set font ");
  896. X    switch (vect_font) {
  897. X        case F_NEVER: {
  898. X            fprintf(fp,"never\n");
  899. X            break;
  900. X        }
  901. X        case F_WHENN: {
  902. X            fprintf(fp,"when_needed\n");
  903. X            break;
  904. X        }
  905. X        case F_ROTAT: {
  906. X            fprintf(fp,"rotated\n");
  907. X            break;
  908. X        }
  909. X        case F_ALWYS: {
  910. X            fprintf(fp,"always\n");
  911. X            break;
  912. X        }
  913. X    }
  914. X    fprintf(fp,"set format \"%s\"\n", tic_form);
  915. X    fprintf(fp,"set %sframe\n", draw_border ? "" : "no");
  916. X    fprintf(fp,"set highlight ");
  917. X    switch (HLitem) {
  918. X        case HL_MIN: {
  919. X            fprintf(fp,"min\n");
  920. X            break;
  921. X        }
  922. X        case HL_MAX: {
  923. X            fprintf(fp,"max\n");
  924. X            break;
  925. X        }
  926. X        case HL_NON: {
  927. X            fprintf(fp,"none\n");
  928. X            break;
  929. X        }
  930. X        default: {
  931. X            fprintf(fp,"%d\n",HLitem);
  932. X            break;
  933. X        }
  934. X    }
  935. X    fprintf(fp,"set input ");
  936. X    switch (inp_style) {
  937. X        case GNUPLOT: {
  938. X            fprintf(fp,"gnuplot\n");
  939. X            break;
  940. X        }
  941. X        case PRIVATE: {
  942. X            fprintf(fp,"private\n");
  943. X            break;
  944. X        }
  945. X        case CUSTOMD: {
  946. X            fprintf(fp,"customized\n");
  947. X            break;
  948. X        }
  949. X    }
  950. X    fprintf(fp,"set %slogscale\n", log_y ? "" : "no");
  951. X    fprintf(fp,"set offsets %lg, %lg, %lg, %lg\n", loff, roff, toff, boff);
  952. X    fprintf(fp,"set output %s\n", strcmp(outstr,"STDOUT") ? outstr : "");
  953. X    fprintf(fp,"set size %g, %g\n", xsize, ysize);
  954. X    fprintf(fp,"set style ");
  955. X    switch (data_style) {
  956. X        case ABARS:        fprintf(fp,"adj\n"); break;
  957. X        case SBAR:        fprintf(fp,"sta\n"); break;
  958. X        case LAYB:        fprintf(fp,"lay\n"); break;
  959. X        case PIECHART:    fprintf(fp,"pie\n"); break;
  960. X    }
  961. X    fprintf(fp,"set term %s\n", term_tbl[term].name);
  962. X    fprintf(fp,"set title ");
  963. X    if (data_head.fname) fprintf(fp,"\"%s\"\n", data_head.fname);
  964. X    else (void) putc('\n',fp);
  965. X    show_labels(0, fp, TRUE);
  966. X    show_arrow(0, fp, TRUE);
  967. X    fprintf(fp,"set range ");
  968. X    if (xmin != -1) show_segment(xmin,xmax,fp);
  969. X    (void) putc('\n',fp);
  970. X    fprintf(fp,"set zero %lg\n", zero);
  971. X
  972. X    (void) putc('\n',fp);
  973. X    
  974. X    fprintf(fp,"set bar %sautoscale\n", autoscale ? "" : "no");
  975. X    fprintf(fp,"set bar base %lg\n", base);
  976. X    fprintf(fp,"set bar %sclock\n", b_clockwise ? "" : "counter_");
  977. X    fprintf(fp,"set bar grav %s\n", grav_name(gravity));
  978. X    fprintf(fp,"set bar width %lg, %lg, %lg\n", b_wid, b_int, b_spc);
  979. X
  980. X    (void) putc('\n',fp);
  981. X
  982. X    fprintf(fp,"set pie expl %s\n", grav_name(explode));
  983. X    fprintf(fp,"set pie %sclockwise\n", p_clockwise ? "" : "counter_");
  984. X    fprintf(fp,"set pie radius %lg\n", radexp);
  985. X    fprintf(fp,"set pie samples %d\n", samples);
  986. X    fprintf(fp,"set pie threshold %lg \"%s\"\n", treshold, thrname);
  987. X
  988. X    (void) fclose(fp);
  989. X}
  990. X
  991. Xint instring(str, c)
  992. Xchar *str;
  993. Xchar c;
  994. X{
  995. X    int pos = 0;
  996. X    
  997. X    while (str != NULL && *str != '\0' && c != *str) {
  998. X        str++;
  999. X        pos++;
  1000. X    }
  1001. X    return (pos);
  1002. X}
  1003. X
  1004. Xshow_style()
  1005. X{
  1006. X    fprintf(stderr,"\tdata are plotted with ");
  1007. X    switch (data_style) {
  1008. X        case ABARS: fprintf(stderr,"adjacent bars\n"); break;
  1009. X        case LAYB: fprintf(stderr,"layer bars\n"); break;
  1010. X        case SBAR: fprintf(stderr,"stacked bars\n"); break;
  1011. X        case PIECHART: fprintf(stderr,"piechart\n"); break;
  1012. X    }
  1013. X}
  1014. X
  1015. Xshow_range()
  1016. X{
  1017. X    if (xmin==-1)
  1018. X        fprintf(stderr,"\twhole file is processed");
  1019. X    else {
  1020. X        fprintf(stderr,"\tdata range is: ");
  1021. X        show_segment(xmin,xmax,stderr);
  1022. X    }
  1023. X    (void) putc('\n',stderr);
  1024. X}
  1025. X
  1026. Xshow_zero()
  1027. X{
  1028. X    fprintf(stderr,"\tzero/epsilon is %lg\n",zero);
  1029. X}
  1030. X
  1031. Xshow_offsets()
  1032. X{
  1033. X    fprintf(stderr,"\toffsets are %lg, %lg, %lg, %lg\n",loff,roff,toff,boff);
  1034. X}
  1035. X
  1036. Xshow_samples()
  1037. X{
  1038. X    fprintf(stderr,"\tsampling rate for piechart is %d\n",samples);
  1039. X}
  1040. X
  1041. Xshow_output()
  1042. X{
  1043. X    fprintf(stderr,"\toutput is sent to %s\n",outstr);
  1044. X}
  1045. X
  1046. Xshow_term()
  1047. X{
  1048. X    fprintf(stderr,"\tterminal type is %s\n",term_tbl[term].name);
  1049. X}
  1050. X
  1051. Xshow_autoscale()
  1052. X{
  1053. X    fprintf(stderr,"\tbar autoscaling is %s\n",(autoscale)? "ON" : "OFF");
  1054. X}
  1055. X
  1056. Xshow_logscale()
  1057. X{
  1058. X    if (log_y)
  1059. X        fprintf(stderr,"\tlogscaling is ON\n");
  1060. X    else
  1061. X        fprintf(stderr,"\tno logscaling\n");
  1062. X}
  1063. X
  1064. Xshow_version()
  1065. X{
  1066. Xextern char version[];
  1067. Xextern char date[];
  1068. Xstatic char *authors[] = {"Thomas Williams","Colin Kelley"};
  1069. Xextern int patchlevel;
  1070. Xextern char bug_email[];
  1071. Xint x;
  1072. Xlong time();
  1073. X
  1074. X    x = time((long *)NULL) & 1;
  1075. X    fprintf(stderr,"\n\t%s\n\t%sversion %s patchlevel %d\n\tlast modified %s\n",
  1076. X        PROGRAM, OS, version, patchlevel, date);
  1077. X    fprintf(stderr,"\tGnuplot v.1.x Copyright (C) 1986, 1987  %s, %s\n",
  1078. X        authors[x],authors[1-x]);
  1079. X    fprintf(stderr,"\tGnuplot v.2.0 John Campbell, David Kotz, Russell Lang\n");
  1080. X    fprintf(stderr,"\t%s Copyright (C) 1990 Piotr Filip Sawicki\n",PROGRAM);
  1081. X#ifdef __TURBOC__
  1082. X    fprintf(stderr,"\tCreated using Turbo C, Copyright Borland 1987, 1988\n");
  1083. X#endif
  1084. X    fprintf(stderr, "\n\tSend bugs and comments to %s\n\n", bug_email);
  1085. X}
  1086. X
  1087. Xstatic char *grav_name(what)
  1088. Xenum GRAV_DIR what;
  1089. X{
  1090. X    static char buf[20];
  1091. X    switch (what) {
  1092. X        case(SOUTH)   : (void) strcpy(buf,"bottom"); break;
  1093. X        case(NORTH)   : (void) strcpy(buf,"top"); break;
  1094. X        case(EAST)    : (void) strcpy(buf,"right"); break;
  1095. X        case(WEST)    : (void) strcpy(buf,"left"); break;
  1096. X        case(DEFAULT) : buf[0] = '\0'; break;
  1097. X    }
  1098. X    return(buf);
  1099. X}
  1100. X
  1101. Xshow_gravity()
  1102. X{
  1103. X    fprintf(stderr,"\tbar gravitation to the %s\n", grav_name(gravity));
  1104. X}
  1105. X
  1106. Xshow_explode()
  1107. X{
  1108. X    fprintf(stderr,"\thighlited slice explodes %s\n",
  1109. X            explode == DEFAULT
  1110. X                ? "where it should"
  1111. X                : grav_name(explode));
  1112. X}
  1113. X
  1114. Xshow_HLset()
  1115. X{
  1116. X    switch (HLitem) {
  1117. X        case(HL_NON): fprintf(stderr,"\tno item"); break;
  1118. X        case(HL_MIN): fprintf(stderr,"\tminimal item"); break;
  1119. X        case(HL_MAX): fprintf(stderr,"\tmaximal item"); break;
  1120. X        default     : fprintf(stderr,"\titem no. %d",HLitem); break;
  1121. X    }
  1122. X    fprintf(stderr," is highlited\n");
  1123. X}
  1124. X
  1125. Xshow_base()
  1126. X{
  1127. X    fprintf(stderr,"\tbase for bars is %lg\n",base);
  1128. X}    
  1129. X
  1130. Xshow_input()
  1131. X{
  1132. X    switch (inp_style) {
  1133. X        case(GNUPLOT) : fprintf(stderr,"\tgnuplot-compatible"); break;
  1134. X        case(PRIVATE) : fprintf(stderr,"\tstandard"); break;
  1135. X        case(CUSTOMD) : fprintf(stderr,"\tcustomized"); break;
  1136. X    }
  1137. X    fprintf(stderr," data input style\n");
  1138. X}
  1139. X
  1140. Xshow_custom()
  1141. X{
  1142. X    if (data_place.from == -1) 
  1143. X        fprintf(stderr,"\tcustomized input format not given\n");
  1144. X    else {
  1145. X        fprintf(stderr,"\tcustomized input format:\n");
  1146. X        fprintf(stderr,"\t\tvalue: ");
  1147. X        show_segment(data_place.from,data_place.upto,stderr);
  1148. X        if (label_plac.from == -1) fprintf(stderr,"\n\t\tno label position");
  1149. X        else {
  1150. X            fprintf(stderr,"\n\t\tlabel: ");
  1151. X            show_segment(label_plac.from,label_plac.upto,stderr);
  1152. X        }
  1153. X        (void) putc('\n',stderr);
  1154. X    }
  1155. X}
  1156. X
  1157. Xstatic show_segment(l,r,fp)
  1158. Xint l,r;
  1159. XFILE *fp;
  1160. X{
  1161. X    (void) putc('[',fp);
  1162. X    if (l) fprintf(fp,"%d",l);
  1163. X    fprintf(fp," : ");
  1164. X    if (r>-1) fprintf(fp,"%d",r);
  1165. X    (void) putc(']',fp);
  1166. X}
  1167. X
  1168. Xshow_label()
  1169. X{
  1170. X    fprintf(stderr,"\tlabels are%s auto-generated\n",
  1171. X            auto_label ? "" : "n't");
  1172. X}
  1173. X
  1174. Xshow_clock(pie)
  1175. XBOOLEAN pie;
  1176. X{
  1177. X    if (pie)
  1178. X        fprintf(stderr,"\tpies are drawn %sclockwise\n",
  1179. X                p_clockwise ? "" : "counter-");
  1180. X    else
  1181. X        fprintf(stderr,"\tbars are drawn %sclockwise\n",
  1182. X                b_clockwise ? "" : "counter-");
  1183. X}
  1184. X
  1185. Xshow_width()
  1186. X{
  1187. X    fprintf(stderr,"\tbar width params are %lg, %lg, %lg\n",b_wid,b_int,b_spc);
  1188. X}
  1189. X
  1190. Xshow_radius()
  1191. X{
  1192. X    fprintf(stderr,"\texplosion radius ratio is %lg\n",radexp);
  1193. X}
  1194. X
  1195. Xshow_border()
  1196. X{
  1197. X    fprintf(stderr,"\tpicture frame is%s drawn\n",draw_border?"":" not");
  1198. X}
  1199. X
  1200. Xshow_size()
  1201. X{
  1202. X    fprintf(stderr,"\tsize is scaled by %g, %g\n",xsize,ysize);
  1203. X}
  1204. X
  1205. Xshow_title()
  1206. X{
  1207. X    if (!data_head.fname || !*(data_head.fname))
  1208. X        fprintf(stderr,"\tpicture has no title\n");
  1209. X    else
  1210. X        fprintf(stderr,"\ttitle for picture is: \"%s\"\n",data_head.fname);
  1211. X}
  1212. X
  1213. Xshow_tresh()
  1214. X{
  1215. X    fprintf(stderr,"\tslices glue threshold is %lg with name \"%s\"\n", treshold, thrname);
  1216. X}
  1217. X
  1218. Xshow_format()
  1219. X{
  1220. X    fprintf(stderr,"\tformat for numbers is: \"%s\"\n", tic_form);
  1221. X}
  1222. X
  1223. Xshow_font()
  1224. X{
  1225. X    fprintf(stderr,"\tvector font is ");
  1226. X    switch (vect_font) {
  1227. X        case F_NEVER: fprintf(stderr,"never used\n"); break;
  1228. X        case F_WHENN: fprintf(stderr,"used when needed\n"); break;
  1229. X        case F_ROTAT: fprintf(stderr,"for rotated text\n"); break;
  1230. X        case F_ALWYS: fprintf(stderr,"always used\n"); break;
  1231. X    }
  1232. X}
  1233. X
  1234. Xshow_trunc()
  1235. X{
  1236. X    fprintf(stderr,"\tlabels are%s truncated", strunc==-1 ? " not" : "");
  1237. X    if (strunc>0)
  1238. X        fprintf(stderr," at char no. %d", strunc);
  1239. X    fprintf(stderr,"\n");
  1240. X}
  1241. SHAR_EOF
  1242. $TOUCH -am 0604152590 fmisc.c &&
  1243. chmod 0666 fmisc.c ||
  1244. echo "restore of fmisc.c failed"
  1245. set `wc -c fmisc.c`;Wc_c=$1
  1246. if test "$Wc_c" != "12994"; then
  1247.     echo original size 12994, current size $Wc_c
  1248. fi
  1249. # ============= font.c ==============
  1250. echo "x - extracting font.c (Text)"
  1251. sed 's/^X//' << 'SHAR_EOF' > font.c &&
  1252. X/* Fchart - font.c */
  1253. X/*
  1254. X * Copyright (C) 1990 Piotr Filip Sawicki
  1255. X *
  1256. X * Permission to use, copy, and distribute this software and its
  1257. X * documentation for any purpose with or without fee is hereby granted,
  1258. X * provided that the above copyright notice appear in all copies and
  1259. X * that both that copyright notice and this permission notice appear
  1260. X * in supporting documentation.
  1261. X *
  1262. X * Permission to modify the software is granted, but not the right to
  1263. X * distribute the modified code.  Modifications are to be distributed
  1264. X * as patches to released version.
  1265. X *
  1266. X * This software  is provided "as is" without express or implied warranty.
  1267. X *
  1268. X * send your comments or suggestions to fs@uwasa.fi
  1269. X *
  1270. X ***********************************************************************
  1271. X * This file contains two vector fonts:
  1272. X *   - nonstandard my private one
  1273. X *   - public-domain Hershey Roman
  1274. X *       courtesy Joe Felsenstein, joe@genetics.washington.edu
  1275. X * Currently the latter is used, though the former has better digits.
  1276. X * To use my font, add the following line to the "fchart.h":
  1277. X * #define NO_ROMAN_FONT
  1278. X * and rebuild the entire application.
  1279. X ***********************************************************************
  1280. X *
  1281. X */
  1282. X
  1283. X#include <stdio.h>
  1284. X#include <math.h>
  1285. X#include "plot.h"
  1286. X#include "fchart.h"
  1287. X
  1288. X#ifdef NO_ROMAN_FONT
  1289. X
  1290. X/* character height: 256, character width: 20-256 */    
  1291. X
  1292. Xstatic unsigned char I_shape[] = { 10,20 , 10,220 , 0 };
  1293. Xstatic unsigned char P_shape[] = { 10,220 , 150,220 , 200,190 , 200,160 , 150,130 , 10,130 , 0 };
  1294. Xstatic unsigned char B_shape[] = { 150,130 , 200,90 , 200,55 , 150,20 , 10,20 , 0 };
  1295. Xstatic unsigned char R_shape[] = { 150,130 , 200,90 , 200,20 , 0 };
  1296. Xstatic unsigned char D_shape[] = { 10,220 , 150,220 , 200,190 , 200,55 , 150,20 , 10,20 , 0 };
  1297. Xstatic unsigned char t_shape[] = { 150,220 , 10,220 , 0 };
  1298. Xstatic unsigned char m_shape[] = { 10,120 , 150,120 , 0 };
  1299. Xstatic unsigned char l_shape[] = { 150,20 , 10,20 , 0 };
  1300. Xstatic unsigned char L_shape[] = { 10,220 , 10,20 , 150,20 , 0 };
  1301. Xstatic unsigned char i_shape[] = { 150,20 , 150,220 , 0 };
  1302. Xstatic unsigned char b_shape[] = { 10,220 , 150,20 , 0 };
  1303. Xstatic unsigned char s_shape[] = { 10,20 , 150,220 , 0 };
  1304. Xstatic unsigned char u_shape[] = { 5,10 , 105,10 , 0 };
  1305. Xstatic unsigned char T_shape[] = { 80,20 , 80,220 , 0 };
  1306. Xstatic unsigned char d1shape[] = { 80,220 , 10,170 , 0 };
  1307. Xstatic unsigned char J_shape[] = { 80,220 , 80,55 , 50,20 , 20,20 , 10,35 , 0 };
  1308. Xstatic unsigned char V_shape[] = { 80,20 , 10,220 , 0 };
  1309. Xstatic unsigned char d7shape[] = { 80,20 , 150,220 , 0 };
  1310. Xstatic unsigned char d4shape[] = { 10,220 , 10,100 , 100,100 , 0 };
  1311. Xstatic unsigned char M_shape[] = { 10,220 , 125,20 , 240,220 , 240,20 , 0 };
  1312. Xstatic unsigned char W_shape[] = { 10,220 , 80,20 , 130,130 , 180,20 , 250,220 , 0 };
  1313. Xstatic unsigned char K_shape[] = { 200,220 , 10,100 , 200,20 , 0 };        /* wrong !!! */
  1314. Xstatic unsigned char C_shape[] = { 200,190 , 150,220 , 60,220 , 10,190 , 10,55 , 60,20 , 150,20 , 200,55 , 0 };
  1315. Xstatic unsigned char O_shape[] = { 200,55 , 200,190 , 0 };
  1316. Xstatic unsigned char G_shape[] = { 200,20 , 200,120 , 120,120 , 0 };
  1317. Xstatic unsigned char Q_shape[] = { 130,55 , 190,10 , 0 };
  1318. Xstatic unsigned char d0shape[] = { 10,55 , 60,20 , 100,20 , 150,55 , 150,190 , 100,220 , 60,220 , 10,190 , 10,55 , 150,190 , 0 };
  1319. Xstatic unsigned char p_shape[] = { 10,20 , 10,20 , 0 };
  1320. Xstatic unsigned char S_shape[] = { 200,190 , 150,220 , 60,220 , 10,190 , 10,160 , 60,130 , 150,120 , 200,90 , 200,55 , 150,20 , 60,20 , 10,55 , 0 };
  1321. Xstatic unsigned char U_shape[] = { 10,220 , 10,55 , 60,20 , 100,20 , 150,55 , 150,220 , 0 };
  1322. Xstatic unsigned char A_shape[] = { 10,20 , 80,220 , 150,20 , 0 };
  1323. Xstatic unsigned char a_shape[] = { 45,100 , 115,100 , 0 };
  1324. Xstatic unsigned char Y_shape[] = { 150,220 , 80,100 , 80,20 , 0 };
  1325. Xstatic unsigned char y_shape[] = { 10,220 , 80,100 , 0 };
  1326. Xstatic unsigned char d_shape[] = { 150,180 , 100,210 , 60,210 , 10,180 , 10,150, 60,130 , 100,110 , 150,95 , 150,65 , 100,30 , 60,30 , 10,65 , 0 };
  1327. Xstatic unsigned char d2shape[] = { 10,190 , 60,220 , 100,220 , 150,190 , 150,160 , 10,55 , 10,20 , 150,20 , 0 };
  1328. Xstatic unsigned char d3shape[] = { 10,190 , 60,220 , 100,220 , 150,190 , 150,160 , 100,130 , 150,90 , 150,55 , 100,20 , 60,20 , 10,55 , 0 };
  1329. Xstatic unsigned char x_shape[] = { 80,50 , 80,190 , 0 };
  1330. Xstatic unsigned char d5shape[] = { 150,220 , 10,220 , 10,120 , 100,120 , 150,90 , 150,55 , 100,20 , 60,20 , 10,55 , 0 };
  1331. Xstatic unsigned char d6shape[] = { 150,190 , 100,220 , 60,220 , 10,190 , 10,90 , 60,120 , 100,120 , 150,90 , 150,55 , 100,20 , 60,20 , 10,55 , 10,90 , 0 };
  1332. Xstatic unsigned char d9shape[] = { 10,55 , 60,20 , 100,20 , 150,55 , 150,160 , 100,130 , 60,130 , 10,160 , 10,190 , 60,220 , 100,220 , 150,190 , 150,160 , 0 };
  1333. Xstatic unsigned char d8shape[] = { 60,130 , 100,130 , 150,160 , 150,190 , 100,220 , 60,220 , 10,190 , 10,160 , 60,130 , 10,90 , 10,55 , 60,20 , 100,20 , 150,55 , 150,90 , 100,130 , 0 };
  1334. Xstatic unsigned char pLshape[] = { 60,220 , 10,160 , 10,55 , 60,20 , 0 };
  1335. Xstatic unsigned char pRshape[] = { 10,220 , 60,160 , 60,55 , 10,20 , 0 };
  1336. X
  1337. Xstruct Char trt[128] = {
  1338. X/* . */ { 20 , p_shape , NULL , NULL }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
  1339. X        { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
  1340. X        { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
  1341. X        { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
  1342. X/*   */ {  20 , NULL , NULL , NULL }, { 0 }, { 0 }, { 0 }, 
  1343. X/* $ */ { 160 , T_shape , d_shape , NULL }, { 0 }, { 0 }, { 0 },
  1344. X/* ( */ {  70 , pLshape , NULL , NULL },
  1345. X/* ) */ {  70 , pRshape , NULL , NULL },
  1346. X        { 0 },
  1347. X/* + */ { 160 , m_shape , x_shape , NULL },
  1348. X        { 0 }, 
  1349. X/* - */ { 160 , m_shape , NULL , NULL },
  1350. X/* . */ { 20 , p_shape , NULL , NULL }, 
  1351. X/* / */ { 160 , s_shape , NULL , NULL },
  1352. X/* 0 */ { 160 , d0shape , NULL , NULL },
  1353. X/* 1 */ {  90 , T_shape , d1shape , NULL },
  1354. X/* 2 */ { 160 , d2shape , NULL , NULL },
  1355. X/* 3 */ { 160 , d3shape , NULL , NULL },
  1356. X/* 4 */ { 110 , T_shape , d4shape , NULL },
  1357. X/* 5 */ { 160 , d5shape , NULL , NULL },
  1358. X/* 6 */ { 160 , d6shape , NULL , NULL },
  1359. X/* 7 */ { 160 , d7shape , t_shape , NULL },
  1360. X/* 8 */ { 160 , d8shape , NULL , NULL },
  1361. X/* 9 */ { 160 , d9shape , NULL , NULL }, { 0 }, { 0 },
  1362. X        { 0 }, { 0 }, { 0 }, { 0 },
  1363. X        { 0 }, 
  1364. X/* A */ { 160 , A_shape , a_shape , NULL },
  1365. X/* B */ { 210 , I_shape , P_shape , B_shape },
  1366. X/* C */ { 210 , C_shape , NULL , NULL },
  1367. X/* D */ { 210 , I_shape , D_shape , NULL },
  1368. X/* E */ { 160 , t_shape , L_shape , m_shape },
  1369. X/* F */ { 160 , t_shape , I_shape , m_shape },
  1370. X/* G */ { 210 , C_shape , G_shape , NULL },
  1371. X/* H */ { 160 , I_shape , m_shape , i_shape },
  1372. X/* I */ {  20 , I_shape , NULL , NULL },
  1373. X/* J */ {  90 , J_shape , NULL , NULL },
  1374. X/* K */ { 210 , I_shape , K_shape , NULL },
  1375. X/* L */ { 160 , L_shape , NULL , NULL },
  1376. X/* M */ { 250 , I_shape , M_shape , NULL },
  1377. X/* N */ { 160 , I_shape , b_shape , i_shape },
  1378. X/* O */ { 210 , C_shape , O_shape , NULL },
  1379. X/* P */ { 210 , I_shape , P_shape , NULL },
  1380. X/* Q */ { 210 , C_shape , O_shape , Q_shape },
  1381. X/* R */ { 210 , I_shape , P_shape , R_shape },
  1382. X/* S */ { 210 , S_shape , NULL , NULL },
  1383. X/* T */ { 160 , T_shape , t_shape , NULL },
  1384. X/* U */ { 160 , U_shape , NULL , NULL },
  1385. X/* V */ { 160 , V_shape , d7shape , NULL },
  1386. X/* W */ { 260 , W_shape , NULL , NULL },
  1387. X/* X */ { 160 , b_shape , s_shape , NULL },
  1388. X/* Y */ { 160 , Y_shape , y_shape , NULL },
  1389. X/* Z */ { 160 , l_shape , s_shape , t_shape }, { 0 },
  1390. X/* \ */ { 160 , b_shape , NULL , NULL }, { 0 }, { 0 }, /* _ */ { 110 , u_shape , NULL , NULL },
  1391. X        { 0 },
  1392. X/* A */ { 160 , A_shape , a_shape , NULL },
  1393. X/* B */ { 210 , I_shape , P_shape , B_shape },
  1394. X/* C */ { 210 , C_shape , NULL , NULL },
  1395. X/* D */ { 210 , I_shape , D_shape , NULL },
  1396. X/* E */ { 160 , t_shape , L_shape , m_shape },
  1397. X/* F */ { 160 , t_shape , I_shape , m_shape },
  1398. X/* G */ { 210 , C_shape , G_shape , NULL },
  1399. X/* H */ { 160 , I_shape , m_shape , i_shape },
  1400. X/* I */ {  20 , I_shape , NULL , NULL },
  1401. X/* J */ {  90 , J_shape , NULL , NULL },
  1402. X/* K */ { 210 , I_shape , K_shape , NULL },
  1403. X/* L */ { 160 , L_shape , NULL , NULL },
  1404. X/* M */ { 250 , I_shape , M_shape , NULL },
  1405. X/* N */ { 160 , I_shape , b_shape , i_shape },
  1406. X/* O */ { 210 , C_shape , O_shape , NULL },
  1407. X/* P */ { 210 , I_shape , P_shape , NULL },
  1408. X/* Q */ { 210 , C_shape , O_shape , Q_shape },
  1409. X/* R */ { 210 , I_shape , P_shape , R_shape },
  1410. X/* S */ { 210 , S_shape , NULL , NULL },
  1411. X/* T */ { 160 , T_shape , t_shape , NULL },
  1412. X/* U */ { 160 , U_shape , NULL , NULL },
  1413. X/* V */ { 160 , V_shape , d7shape , NULL },
  1414. X/* W */ { 260 , W_shape , NULL , NULL },
  1415. X/* X */ { 160 , b_shape , s_shape , NULL },
  1416. X/* Y */ { 160 , Y_shape , y_shape , NULL },
  1417. X/* Z */ { 160 , l_shape , s_shape , t_shape }, { 0 },
  1418. X/* | */ {  90 , T_shape , NULL , NULL }, { 0 }, { 0 }, { 0 }
  1419. X    } ;
  1420. X
  1421. X#else        /* use roman font */
  1422. X
  1423. X/* character height: 80, character width: ~30 */    
  1424. X
  1425. Xstatic int char_32[2] = { -2600, 0 };
  1426. Xstatic int char_33[9] = { -1531, 1517, -1512, 1411, 1510, 1611, 1512, -2000, 0 };
  1427. Xstatic int char_40[12] = { -2135, 1933, 1730, 1526, 1421, 1417, 1512, 1708, 1905, 2103, -2400, 0 };
  1428. Xstatic int char_41[12] = { -1335, 1533, 1730, 1926, 2021, 2017, 1912, 1708, 1505, 1303, -2400, 0 };
  1429. Xstatic int char_42[8] = { -1825, 1813, -1322, 2316, -2322, 1316, -2600, 0 };
  1430. Xstatic int char_44[10] = { -1611, 1510, 1411, 1512, 1611, 1609, 1507, 1406, -2000, 0 };
  1431. Xstatic int char_45[4] = { -1419, 3219, -3600, 0 };
  1432. Xstatic int char_46[7] = { -1512, 1411, 1510, 1611, 1512, -2000, 0 };
  1433. Xstatic int char_47[4] = { -3035, 1203, -3200, 0 };
  1434. Xstatic int char_0[19] = { -1931, 1630, 1427, 1322, 1319, 1414, 1611, 1910, 2110, 2411, 2614, 2719, 2722, 2627, 2430, 2131, 1931, -3000, 0 };
  1435. Xstatic int char_1[6] = { -1627, 1828, 2131, 2110, -3000, 0 };
  1436. Xstatic int char_2[16] = { -1426, 1427, 1529, 1630, 1831, 2231, 2430, 2529, 2627, 2625, 2523, 2320, 1310, 2710, -3000, 0 };
  1437. Xstatic int char_3[17] = { -1531, 2631, 2023, 2323, 2522, 2621, 2718, 2716, 2613, 2411, 2110, 1810, 1511, 1412, 1314, -3000, 0 };
  1438. Xstatic int char_4[7] = { -2331, 1317, 2817, -2331, 2310, -3000, 0 };
  1439. Xstatic int char_5[19] = { -2531, 1531, 1422, 1523, 1824, 2124, 2423, 2621, 2718, 2716, 2613, 2411, 2110, 1810, 1511, 1412, 1314, -3000, 0 };
  1440. Xstatic int char_6[25] = { -2628, 2530, 2231, 2031, 1730, 1527, 1422, 1417, 1513, 1711, 2010, 2110, 2411, 2613, 2716, 2717, 2620, 2422, 2123, 2023, 1722, 1520, 1417, -3000, 0 };
  1441. Xstatic int char_7[6] = { -2731, 1710, -1331, 2731, -3000, 0 };
  1442. Xstatic int char_8[31] = { -1831, 1530, 1428, 1426, 1524, 1723, 2122, 2421, 2619, 2717, 2714, 2612, 2511, 2210, 1810, 1511, 1412, 1314, 1317, 1419, 1621, 1922, 2323, 2524, 2626, 2628, 2530, 2231, 1831, -3000, 0 };
  1443. Xstatic int char_9[25] = { -2624, 2521, 2319, 2018, 1918, 1619, 1421, 1324, 1325, 1428, 1630, 1931, 2031, 2330, 2528, 2624, 2619, 2514, 2311, 2010, 1810, 1511, 1413, -3000, 0 };
  1444. Xstatic int char_58[12] = { -1524, 1423, 1522, 1623, 1524, -1512, 1411, 1510, 1611, 1512, -2000, 0 };
  1445. Xstatic int char_59[15] = { -1524, 1423, 1522, 1623, 1524, -1611, 1510, 1411, 1512, 1611, 1609, 1507, 1406, -2000, 0 };
  1446. Xstatic int char_63[21] = { -1326, 1327, 1429, 1530, 1731, 2131, 2330, 2429, 2527, 2525, 2423, 2322, 1920, 1917, -1912, 1811, 1910, 2011, 1912, -2800, 0 };
  1447. Xstatic int char_A[8] = { -1931, 1110, -1931, 2710, -1417, 2417, -2800, 0 };
  1448. Xstatic int char_B[23] = { -1431, 1410, -1431, 2331, 2630, 2729, 2827, 2825, 2723, 2622, 2321, -1421, 2321, 2620, 2719, 2817, 2814, 2712, 2611, 2310, 1410, -3100, 0 };
  1449. Xstatic int char_C[20] = { -2826, 2728, 2530, 2331, 1931, 1730, 1528, 1426, 1323, 1318, 1415, 1513, 1711, 1910, 2310, 2511, 2713, 2815, -3100, 0 };
  1450. Xstatic int char_D[16] = { -1431, 1410, -1431, 2131, 2430, 2628, 2726, 2823, 2818, 2715, 2613, 2411, 2110, 1410, -3100, 0 };
  1451. Xstatic int char_E[10] = { -1431, 1410, -1431, 2731, -1421, 2221, -1410, 2710, -2900, 0 };
  1452. Xstatic int char_F[8] = { -1431, 1410, -1431, 2731, -1421, 2221, -2800, 0 };
  1453. Xstatic int char_G[23] = { -2826, 2728, 2530, 2331, 1931, 1730, 1528, 1426, 1323, 1318, 1415, 1513, 1711, 1910, 2310, 2511, 2713, 2815, 2818, -2318, 2818, -3100, 0 };
  1454. Xstatic int char_H[8] = { -1431, 1410, -2831, 2810, -1421, 2821, -3200, 0 };
  1455. Xstatic int char_I[4] = { -1431, 1410, -1800, 0 };
  1456. Xstatic int char_J[12] = { -2231, 2215, 2112, 2011, 1810, 1610, 1411, 1312, 1215, 1217, -2600, 0 };
  1457. Xstatic int char_K[8] = { -1431, 1410, -2831, 1417, -1922, 2810, -3100, 0 };
  1458. Xstatic int char_L[6] = { -1431, 1410, -1410, 2610, -2700, 0 };
  1459. Xstatic int char_M[10] = { -1431, 1410, -1431, 2210, -3031, 2210, -3031, 3010, -3400, 0 };
  1460. Xstatic int char_N[8] = { -1431, 1410, -1431, 2810, -2831, 2810, -3200, 0 };
  1461. Xstatic int char_O[23] = { -1931, 1730, 1528, 1426, 1323, 1318, 1415, 1513, 1711, 1910, 2310, 2511, 2713, 2815, 2918, 2923, 2826, 2728, 2530, 2331, 1931, -3200, 0 };
  1462. Xstatic int char_P[14] = { -1431, 1410, -1431, 2331, 2630, 2729, 2827, 2824, 2722, 2621, 2320, 1420, -3100, 0 };
  1463. Xstatic int char_Q[25] = { -1931, 1730, 1528, 1426, 1323, 1318, 1415, 1513, 1711, 1910, 2310, 2511, 2713, 2815, 2918, 2923, 2826, 2728, 2530, 2331, 1931, -2214, 2808, -3200, 0 };
  1464. Xstatic int char_R[16] = { -1431, 1410, -1431, 2331, 2630, 2729, 2827, 2825, 2723, 2622, 2321, 1421, -2121, 2810, -3100, 0 };
  1465. Xstatic int char_S[22] = { -2728, 2530, 2231, 1831, 1530, 1328, 1326, 1424, 1523, 1722, 2320, 2519, 2618, 2716, 2713, 2511, 2210, 1810, 1511, 1313, -3000, 0 };
  1466. Xstatic int char_T[6] = { -1831, 1810, -1131, 2531, -2600, 0 };
  1467. Xstatic int char_U[12] = { -1431, 1416, 1513, 1711, 2010, 2210, 2511, 2713, 2816, 2831, -3200, 0 };
  1468. Xstatic int char_V[6] = { -1131, 1910, -2731, 1910, -2800, 0 };
  1469. Xstatic int char_W[10] = { -1231, 1710, -2231, 1710, -2231, 2710, -3231, 2710, -3400, 0 };
  1470. Xstatic int char_X[6] = { -1331, 2710, -2731, 1310, -3000, 0 };
  1471. Xstatic int char_Y[7] = { -1131, 1921, 1910, -2731, 1921, -2800, 0 };
  1472. Xstatic int char_Z[8] = { -2731, 1310, -1331, 2731, -1310, 2710, -3000, 0 };
  1473. Xstatic int char_a[18] = { -2524, 2510, -2521, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2900, 0 };
  1474. Xstatic int char_b[18] = { -1431, 1410, -1421, 1623, 1824, 2124, 2323, 2521, 2618, 2616, 2513, 2311, 2110, 1810, 1611, 1413, -2900, 0 };
  1475. Xstatic int char_c[16] = { -2521, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2800, 0 };
  1476. Xstatic int char_d[18] = { -2531, 2510, -2521, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2900, 0 };
  1477. Xstatic int char_e[19] = { -1318, 2518, 2520, 2422, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2800, 0 };
  1478. Xstatic int char_f[9] = { -2031, 1831, 1630, 1527, 1510, -1224, 1924, -2200, 0 };
  1479. Xstatic int char_g[23] = { -2524, 2508, 2405, 2304, 2103, 1803, 1604, -2521, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2900, 0 };
  1480. Xstatic int char_h[11] = { -1431, 1410, -1420, 1723, 1924, 2224, 2423, 2520, 2510, -2900, 0 };
  1481. Xstatic int char_i[9] = { -1331, 1430, 1531, 1432, 1331, -1424, 1410, -1800, 0 };
  1482. Xstatic int char_j[12] = { -1531, 1630, 1731, 1632, 1531, -1624, 1607, 1504, 1303, 1103, -2000, 0 };
  1483. Xstatic int char_k[8] = { -1431, 1410, -2424, 1414, -1818, 2510, -2700, 0 };
  1484. Xstatic int char_l[4] = { -1431, 1410, -1800, 0 };
  1485. Xstatic int char_m[18] = { -1424, 1410, -1420, 1723, 1924, 2224, 2423, 2520, 2510, -2520, 2823, 3024, 3324, 3523, 3620, 3610, -4000, 0 };
  1486. Xstatic int char_n[11] = { -1424, 1410, -1420, 1723, 1924, 2224, 2423, 2520, 2510, -2900, 0 };
  1487. Xstatic int char_o[19] = { -1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, 2616, 2618, 2521, 2323, 2124, 1824, -2900, 0 };
  1488. Xstatic int char_p[18] = { -1424, 1403, -1421, 1623, 1824, 2124, 2323, 2521, 2618, 2616, 2513, 2311, 2110, 1810, 1611, 1413, -2900, 0 };
  1489. Xstatic int char_q[18] = { -2524, 2503, -2521, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2900, 0 };
  1490. Xstatic int char_r[9] = { -1424, 1410, -1418, 1521, 1723, 1924, 2224, -2300, 0 };
  1491. Xstatic int char_s[19] = { -2421, 2323, 2024, 1724, 1423, 1321, 1419, 1618, 2117, 2316, 2414, 2413, 2311, 2010, 1710, 1411, 1313, -2700, 0 };
  1492. Xstatic int char_t[9] = { -1531, 1514, 1611, 1810, 2010, -1224, 1924, -2200, 0 };
  1493. Xstatic int char_u[11] = { -1424, 1414, 1511, 1710, 2010, 2211, 2514, -2524, 2510, -2900, 0 };
  1494. Xstatic int char_v[6] = { -1224, 1810, -2424, 1810, -2600, 0 };
  1495. Xstatic int char_w[10] = { -1324, 1710, -2124, 1710, -2124, 2510, -2924, 2510, -3200, 0 };
  1496. Xstatic int char_x[6] = { -1324, 2410, -2424, 1310, -2700, 0 };
  1497. Xstatic int char_y[10] = { -1224, 1810, -2424, 1810, 1606, 1404, 1203, 1103, -2600, 0 };
  1498. Xstatic int char_z[8] = { -2424, 1310, -1324, 2424, -1310, 2410, -2700, 0 };
  1499. Xstruct Char trt[128] = {
  1500. X/* ^@ */     { 10 , char_46 },
  1501. X/* ^A */     { 10 , char_46 },
  1502. X/* ^B */     { 10 , char_46 },
  1503. X/* ^C */     { 10 , char_46 },
  1504. X/* ^D */     { 10 , char_46 },
  1505. X/* ^E */     { 10 , char_46 },
  1506. X/* ^F */     { 10 , char_46 },
  1507. X/* ^G */     { 10 , char_46 },
  1508. X/* ^H */     { 10 , char_46 },
  1509. X/* ^I */     { 10 , char_46 },
  1510. X/* ^J */     { 10 , char_46 },
  1511. X/* ^K */     { 10 , char_46 },
  1512. X/* ^L */     { 10 , char_46 },
  1513. X/* ^M */     { 10 , char_46 },
  1514. X/* ^N */     { 10 , char_46 },
  1515. X/* ^O */     { 10 , char_46 },
  1516. X/* ^P */     { 10 , char_46 },
  1517. X/* ^Q */     { 10 , char_46 },
  1518. X/* ^R */     { 10 , char_46 },
  1519. X/* ^S */     { 10 , char_46 },
  1520. X/* ^T */     { 10 , char_46 },
  1521. X/* ^U */     { 10 , char_46 },
  1522. X/* ^V */     { 10 , char_46 },
  1523. X/* ^W */     { 10 , char_46 },
  1524. X/* ^X */     { 10 , char_46 },
  1525. X/* ^Y */     { 10 , char_46 },
  1526. X/* ^Z */     { 10 , char_46 },
  1527. X/* ^[ */     { 10 , char_46 },
  1528. X/* ^\ */     { 10 , char_46 },
  1529. X/* ^] */     { 10 , char_46 },
  1530. X/* ^^ */     { 10 , char_46 },
  1531. X/* ^_ */     { 10 , char_46 },
  1532. X/*    */     { 16 , char_32 },
  1533. X/*  ! */     { 10 , char_33 },
  1534. X/*  " */     { 10 , char_46 },
  1535. X/*  # */     { 10 , char_46 },
  1536. X/*  $ */     { 10 , char_46 },
  1537. X/*  % */     { 10 , char_46 },
  1538. X/*  & */     { 10 , char_46 },
  1539. X/*  ' */     { 10 , char_46 },
  1540. X/*  ( */     { 14 , char_40 },
  1541. X/*  ) */     { 14 , char_41 },
  1542. X/*  * */     { 16 , char_42 },
  1543. X/*  + */     { 10 , char_46 },
  1544. X/*  , */     { 10 , char_44 },
  1545. X/*  - */     { 26 , char_45 },
  1546. X/*  . */     { 10 , char_46 },
  1547. X/*  / */     { 22 , char_47 },
  1548. X/*  0 */     { 20 , char_0 },
  1549. X/*  1 */     { 20 , char_1 },
  1550. X/*  2 */     { 20 , char_2 },
  1551. X/*  3 */     { 20 , char_3 },
  1552. X/*  4 */     { 20 , char_4 },
  1553. X/*  5 */     { 20 , char_5 },
  1554. X/*  6 */     { 20 , char_6 },
  1555. X/*  7 */     { 20 , char_7 },
  1556. X/*  8 */     { 20 , char_8 },
  1557. X/*  9 */     { 20 , char_9 },
  1558. X/*  : */     { 10 , char_58 },
  1559. X/*  ; */     { 10 , char_59 },
  1560. X/*  < */     { 10 , char_46 },
  1561. X/*  = */     { 10 , char_46 },
  1562. X/*  > */     { 10 , char_46 },
  1563. X/*  ? */     { 18 , char_63 },
  1564. X/*  @ */     { 10 , char_46 },
  1565. X/*  A */     { 18 , char_A },
  1566. X/*  B */     { 21 , char_B },
  1567. X/*  C */     { 21 , char_C },
  1568. X/*  D */     { 21 , char_D },
  1569. X/*  E */     { 19 , char_E },
  1570. X/*  F */     { 18 , char_F },
  1571. X/*  G */     { 21 , char_G },
  1572. X/*  H */     { 22 , char_H },
  1573. X/*  I */     {  8 , char_I },
  1574. X/*  J */     { 16 , char_J },
  1575. X/*  K */     { 21 , char_K },
  1576. X/*  L */     { 17 , char_L },
  1577. X/*  M */     { 24 , char_M },
  1578. X/*  N */     { 22 , char_N },
  1579. X/*  O */     { 22 , char_O },
  1580. X/*  P */     { 21 , char_P },
  1581. X/*  Q */     { 22 , char_Q },
  1582. X/*  R */     { 21 , char_R },
  1583. X/*  S */     { 20 , char_S },
  1584. X/*  T */     { 16 , char_T },
  1585. X/*  U */     { 22 , char_U },
  1586. X/*  V */     { 18 , char_V },
  1587. X/*  W */     { 24 , char_W },
  1588. X/*  X */     { 20 , char_X },
  1589. X/*  Y */     { 18 , char_Y },
  1590. X/*  Z */     { 20 , char_Z },
  1591. X/*  [ */     { 10 , char_46 },
  1592. X/*  \ */     { 10 , char_46 },
  1593. X/*  ] */     { 10 , char_46 },
  1594. X/*  ^ */     { 10 , char_46 },
  1595. X/*  _ */     { 10 , char_46 },
  1596. X/*  ` */     { 10 , char_46 },
  1597. X/*  a */     { 19 , char_a },
  1598. X/*  b */     { 19 , char_b },
  1599. X/*  c */     { 18 , char_c },
  1600. X/*  d */     { 19 , char_d },
  1601. X/*  e */     { 18 , char_e },
  1602. X/*  f */     { 12 , char_f },
  1603. X/*  g */     { 19 , char_g },
  1604. X/*  h */     { 19 , char_h },
  1605. X/*  i */     {  8 , char_i },
  1606. X/*  j */     { 10 , char_j },
  1607. X/*  k */     { 17 , char_k },
  1608. X/*  l */     {  8 , char_l },
  1609. X/*  m */     { 30 , char_m },
  1610. X/*  n */     { 19 , char_n },
  1611. X/*  o */     { 19 , char_o },
  1612. X/*  p */     { 19 , char_p },
  1613. X/*  q */     { 19 , char_q },
  1614. X/*  r */     { 13 , char_r },
  1615. X/*  s */     { 17 , char_s },
  1616. X/*  t */     { 12 , char_t },
  1617. X/*  u */     { 19 , char_u },
  1618. X/*  v */     { 16 , char_v },
  1619. X/*  w */     { 22 , char_w },
  1620. X/*  x */     { 17 , char_x },
  1621. X/*  y */     { 16 , char_y },
  1622. X/*  z */     { 17 , char_z },
  1623. X/*  { */     { 10 , char_46 },
  1624. X/*  | */     { 10 , char_46 },
  1625. X/*  } */     { 10 , char_46 },
  1626. X/*  ~ */     { 10 , char_46 },
  1627. X/* 46 */     { 10 , char_46 }
  1628. X};
  1629. X
  1630. X#endif         /* NO_ROMAN_FONT */
  1631. X
  1632. X/* procedures for vector fonts */
  1633. X
  1634. Xtransp(tx, ty, A)
  1635. Xint tx, ty;
  1636. XMATRIX A;
  1637. X/* transpose */
  1638. X{
  1639. X    register int i, j;
  1640. X    for (i=0; i<3; i++) {
  1641. X        for (j=0; j<3; j++)
  1642. X            A[i][j] = 0.0;
  1643. X        A[i][i] = 1.0;
  1644. X    }
  1645. X    A[0][2] = -tx;
  1646. X    A[1][2] = -ty;
  1647. X}
  1648. X
  1649. Xscale(sx, sy, A)
  1650. Xdouble sx, sy;
  1651. XMATRIX A;
  1652. X/* scale */
  1653. X{
  1654. X    register int i, j;
  1655. X    for (i=0; i<3; i++)
  1656. X        for (j=0; j<3; j++)
  1657. X            A[i][j] = 0.0;
  1658. X    A[0][0] = sx;
  1659. X    A[1][1] = sy;
  1660. X    A[2][2] = 1.0;
  1661. X}
  1662. X
  1663. Xrotat(al, A)
  1664. Xdouble al;
  1665. XMATRIX A;
  1666. X/* rotate */
  1667. X{
  1668. X    register int i;
  1669. X    double s;
  1670. X    for (i=0; i<2; i++)
  1671. X        A[i][2] = A[2][i] = 0.0;
  1672. X    A[2][2] = 1.0;
  1673. X    s = sin(al);
  1674. X    A[0][0] = A[1][1] = cos(al);
  1675. X    A[0][1] = s;
  1676. X    A[1][0] = -s;
  1677. X}
  1678. X
  1679. Xmulti(A, B, C)
  1680. XMATRIX A, B, C;
  1681. X/* multiply matrices */
  1682. X{
  1683. X    register int i, j, k;
  1684. X    register double db;
  1685. X    for (i=0; i<3; i++) 
  1686. X        for (j=0; j<3; j++) {
  1687. X            for (k=0, db=0.0; k<3; k++)
  1688. X                db += A[i][k] * B[k][j];
  1689. X            C[i][j] = db;
  1690. X        }
  1691. X}
  1692. SHAR_EOF
  1693. $TOUCH -am 0604152590 font.c &&
  1694. chmod 0666 font.c ||
  1695. echo "restore of font.c failed"
  1696. set `wc -c font.c`;Wc_c=$1
  1697. if test "$Wc_c" != "20937"; then
  1698.     echo original size 20937, current size $Wc_c
  1699. fi
  1700. echo "End of part 3, continue with part 4"
  1701. exit 0
  1702.  
  1703.  
  1704.  
  1705.