source: tags/initial/fig2dev/dev/gentpic.c

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.0 KB
Line 
1/*
2 * TransFig: Facility for Translating Fig code
3 * Copyright (c) 1985 Supoj Sutantavibul
4 * Copyright (c) 1991 Micah Beck
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation. The authors make no representations about the suitability
11 * of this software for any purpose.  It is provided "as is" without express
12 * or implied warranty.
13 *
14 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 */
23
24/*
25 *      gentpic : TPIC driver for fig2dev
26 *
27 *      Author: Conrad Kwok, UC Davis, 12/88
28 *      Modified: Richard Auletta, George Mason Univ., 6/21/89
29 *              Added code comments are marked with "rja".
30 *              Added: Support for native pic arrowheads.
31 *              Added: Support for arrowheads at both ends of lines, arc, splines.
32 *      Modified: Modified from pic to tpic. Baron Grey, UCLA. 10/2/90.
33 *
34 *              This driver supports TeX's virtual font mechanism. Any Fig
35 *              font whose ordinal number is greater than 6 is treated as
36 *              a TeX virtual PostScript font. Virtual PostScript font
37 *              names are defined in tpicfonts.h (you should define
38 *              corresponding names in Fig in file change.c). Customize to
39 *              suit your virtual font availability or your name preferences.
40 *
41 *              There are no restrictions on font sizes in this driver, but
42 *              keep in mind that TeX only supports fonts up to 2048 points!
43 *              Since PostScript fonts are scaleable, virtual PS fonts can have
44 *              any point size within the limits imposed by TeX or by your
45 *              PostScript interpreter. If you are using
46 *              standard predefined LaTeX fonts (assumed to be the first
47 *              6 positions in Fig's ordinal font numbering scheme), font
48 *              sizes are mapped into the nearest valid normally-available
49 *              LaTeX font sizes -- look at tpicfonts.h to see how this is
50 *              done; you can modify it for fonts at your site.
51 *
52 *              Additional features of this driver are:
53 *              1) Support for all Fig features except text at nonzero
54 *                 angles.  (In fact, any limitations of this driver are
55 *                 actually tpic limitations.)
56 *              2) Boxes with rounded corners are supported in two ways.
57 *                 If (when) tpic is extended to use the "radius" attribute
58 *                 with a "box" specification, the driver will generate the
59 *                 appropriate box specification. Otherwise, it creates
60 *                 rounded-corner boxes from line and arc segments using
61 *                 existing tpic primitives. In the former case, rounded-
62 *                 corner boxes can be shaded; in the latter, they can't.
63 *                 Define TPIC_ARC_BOX for the first case (the default);
64 *                 undefine it otherwise.
65 *              3) Supports Fig's ability to texture (shade) objects.
66 *                 Bitmapped PostScript texture patterns are supported;
67 *                 they are defined in "tpicfonts.h". The tpic ".tx"
68 *                 primitive is used for this. Your dvi-to-PostScript
69 *                 driver must be adapted to support them.
70 *              4) If an object's line "thickness" is 0, it is given tpic's
71 *                 `invis' attribute. That is, tpic will treat it as an
72 *                 invisible object in the normal tpic sense.
73 *              5) This driver supports tpic 2.0. It will work with tpic 1.0,
74 *                 but some object attributes will not be available.
75 *              6) The default line thickness is 8 milli inches (in tpic
76 *                 units). This corresponds to 1 pixel width in Fig. The
77 *                 formula is: line_thickness = Fig_line_thickness *
78 *                 default_tpic_line_thickness.
79 *              7) The default font size is (assumed to be) 10 points!
80 */
81
82#include <stdio.h>
83#include <math.h>
84#include "object.h"
85#include "fig2dev.h"
86#include "tpicfonts.h"
87
88/*
89 * Define TPIC_ARC_BOX if your tpic supports rounded-corner boxes
90 * via a "radius" attribute of a box specification.
91 */
92#define TPIC_ARC_BOX
93
94#define                 TOP     10.5    /* top of page is 10.5 inch */
95static double           ppi;
96static int              CONV = 0;
97static int              line_width = 8; /* milli-inches */
98static int              vfont = 0; /* true if using a virtual TeX font */
99
100void gentpic_ctl_spline(), gentpic_itp_spline();
101void gentpic_open_spline(), gentpic_closed_spline();
102void gentpic_spline(), gentpic_ellipse(), gentpic_text();
103void gentpic_arc(), gentpic_line(), newline();
104
105void gentpic_option(opt, optarg)
106char opt, *optarg;
107{
108        switch (opt) {
109
110        case 'f':               /* set default text font */
111                {   int i;
112
113                    for ( i = 1; i <= MAX_TPICFONT; i++ )
114                        if ( !strcmp(optarg, texfontnames[i]) ) break;
115
116                    if ( i > MAX_FONT)
117                            vfont = 1; /* assume a virtual font */
118                }
119               
120                texfontnames[0] = optarg;
121                break;
122
123        case 's':
124        case 'm':
125        case 'L':
126                break;
127
128        default:
129                put_msg(Err_badarg, opt, "tpic");
130                exit(1);
131        }
132}
133
134static double convy(a)
135double  a;
136{
137        return((double)(CONV ? TOP-a : a));
138}
139
140void gentpic_start(objects)
141F_compound      *objects;
142{
143        int             coord_system;
144
145        ppi = objects->nwcorner.x/mag;
146        coord_system = objects->nwcorner.y;
147        if (coord_system == 2) CONV = 1;
148
149        fprintf(tfp, ".PS\n");  /* PIC preamble */
150
151}
152
153void gentpic_end()
154{
155        fprintf(tfp, ".PE\n");                          /* PIC ending */
156}
157
158/*
159 * tpic's line thickness is given in milli-inches with a default of 8
160 * milli-inches. We simply multiply this default with the Fig pixel width.
161 */
162static set_linewidth(w)
163int     w;
164{
165        static int      cur_thickness = -1;
166
167        if (w == 0) return;
168        if (w != cur_thickness) {
169            cur_thickness = w;
170            fprintf(tfp, ".ps %d\n", cur_thickness * line_width);
171            }
172        }
173
174static set_style(s, v)
175int     s;
176float   v;
177{
178        static float    style_val = -1;
179
180        if (s == DASH_LINE || s == DOTTED_LINE) {
181            if (v == style_val || v == 0.0) return;
182            style_val = v;
183            fprintf(tfp, "dashwid = %.3fi\n", style_val/ppi);
184            }
185        }
186
187static set_baseline(b)
188int     b;
189{
190        static int      cur_baseline = -1;
191
192        if (b != cur_baseline) {
193                fprintf(tfp, ".baseline %d\n", b);
194                cur_baseline = b;
195        }
196}
197
198static set_texture(cur_texture)
199int     cur_texture;
200{
201        /*
202         * This applies only to bitmapped texture patterns defined in
203         * tpicfonts.h. See set_fill() below for normal shading.
204         */
205        if (cur_texture <= BLACK_FILL || cur_texture > MAXPATTERNS + BLACK_FILL)
206                return;
207        fprintf(tfp, ".tx 16 %s\n",
208                texture_patterns[cur_texture - BLACK_FILL - 1]);
209}
210
211/*
212 * Set the shade for filling an object. Your dvi-to-postscript driver must
213 * distinguish between a "shaded" attribute with or without a parameter.
214 * If there is no parameter, then it should do a bitmap texture fill;
215 * otherwise, it should do a normal gray-scale fill. Note that the gray-
216 * scale fill parameter is wired for fig2.X (the constant 0.05).
217 */
218static set_fill(cur_fill)
219int     cur_fill;
220{
221        if(cur_fill < WHITE_FILL ||
222           cur_fill > BLACK_FILL + MAXPATTERNS)
223                return;
224        switch(cur_fill) {
225        case BLACK_FILL:
226                fprintf(tfp, " black");
227                break;
228        case WHITE_FILL:
229                fprintf(tfp, " white");
230                break;
231        default:
232                if (cur_fill > BLACK_FILL)
233                        fprintf (tfp, " shaded");
234                else
235                        fprintf(tfp, " shaded %0.3f", (cur_fill-1)*0.05);
236                break;
237        }
238}
239
240#ifdef TPIC_ARC_BOX
241void gentpic_line(l)
242F_line  *l;
243{
244        F_point         *p, *q;
245        int     llx, lly, urx, ury;
246
247        set_linewidth(l->thickness);
248        set_style(l->style, l->style_val);
249        set_texture(l->area_fill);
250        p = l->points;
251        q = p->next;
252        if (q == NULL) { /* A single point line */
253            fprintf(tfp, "line from %.3f,%.3f to %.3f,%.3f",
254                        p->x/ppi, convy(p->y/ppi), p->x/ppi, convy(p->y/ppi));
255            newline();
256            return;
257            }
258
259        if (l->type == T_BOX || l->type == T_ARC_BOX) {
260                llx = urx = p->x;
261                lly = ury = p->y;
262                while (q != NULL) {
263                        p = q;
264                        if (p->x < llx) {
265                                llx = p->x;
266                        } else if (p->x > urx) {
267                                urx = p->x;
268                        }
269                        if (p->y < lly) {
270                                lly = p->y;
271                        } else if (p->y > ury) {
272                                ury = p->y;
273                        }
274                        q = q->next;
275                }
276                fprintf(tfp, "box height %.3f width %.3f", (ury-lly)/ppi,
277                        (urx-llx)/ppi);
278                switch(l->style) {
279                case SOLID_LINE:
280                        break;
281                case DASH_LINE:
282                        fprintf(tfp, " dashed");
283                        break;
284                case DOTTED_LINE:
285                        fprintf(tfp, " dotted");
286                        break;
287                default:
288                        put_msg("Program error! No other line styles allowed.\n");
289                        return;
290                }
291                if (l->thickness == 0)
292                        fprintf(tfp, " invis");
293                fprintf(tfp, " radius %.3f", l->radius/ppi);
294                set_fill(l->area_fill);
295                fprintf(tfp, " with .nw at %.3f,%.3f", llx/ppi, convy(lly/ppi));
296                newline();
297                return;
298        }
299
300        if (l->style == DASH_LINE && l->style_val > 0.0)
301            fprintf(tfp, "line dashed");
302        else if (l->style == DOTTED_LINE && l->style_val > 0.0)
303            fprintf(tfp, "line dotted");
304        else
305            fprintf(tfp, "line");
306
307        /*rja: Place arrowheads or lack there of on the line*/
308        if ((l->for_arrow) && (l->back_arrow))
309            fprintf(tfp, " <-> from");
310        else if (l->back_arrow)
311            fprintf(tfp, " <- from");
312        else if (l->for_arrow)
313            fprintf(tfp, " -> from");
314        else
315            fprintf(tfp, " from ");
316
317        fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
318        while (q->next != NULL) {
319            p = q;
320            q = q->next;
321            fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
322            }
323        fprintf(tfp, " %.3f,%.3f", q->x/ppi, convy(q->y/ppi));
324        if (l->thickness == 0)
325                fprintf(tfp, " invis");
326        if (l->type == T_POLYGON)
327                set_fill(l->area_fill);
328        newline();
329        }
330
331#else
332void gentpic_line(l)
333F_line  *l;
334{
335        F_point         *p, *q;
336        int             radius = l->radius;
337        char            attr[80];
338
339        attr[0] = '\0';
340        set_linewidth(l->thickness);
341        set_style(l->style, l->style_val);
342        set_texture(l->area_fill);
343        p = l->points;
344        q = p->next;
345        if (q == NULL) { /* A single point line */
346            fprintf(tfp, "line from %.3f,%.3f to %.3f,%.3f",
347                        p->x/ppi, convy(p->y/ppi), p->x/ppi, convy(p->y/ppi));
348            newline();
349            return;
350            }
351
352        if (l->style == DASH_LINE && l->style_val > 0.0)
353                strcat(attr, "dashed");
354        else if (l->style == DOTTED_LINE && l->style_val > 0.0)
355                strcat(attr, "dotted");
356        if (l->thickness == 0)
357                strcat(attr, " invis");
358
359        if (radius > 0) {       /* T_ARC_BOX */
360                register int xmin,xmax,ymin,ymax;
361
362                xmin = xmax = p->x;
363                ymin = ymax = p->y;
364                while (p->next != NULL) { /* find lower left and upper right corners */
365                        p=p->next;
366                        if (xmin > p->x)
367                                xmin = p->x;
368                        else if (xmax < p->x)
369                                xmax = p->x;
370                        if (ymin > p->y)
371                                ymin = p->y;
372                        else if (ymax < p->y)
373                                ymax = p->y;
374                }
375                fprintf(tfp, "line %s from  %.3f,%.3f to %.3f, %.3f\n", attr,
376                        (xmin+radius)/ppi, convy(ymin/ppi),
377                        (xmax-radius)/ppi, convy(ymin/ppi));
378                fprintf(tfp, "arc cw %s from %.3f, %.3f to %.3f,%.3f radius %.3f\n",
379                        attr, (xmax-radius)/ppi, convy(ymin/ppi),
380                        (xmax/ppi), convy((ymin+radius)/ppi), radius/ppi);
381                fprintf(tfp, "line %s from  %.3f,%.3f to %.3f, %.3f\n", attr,
382                        xmax/ppi, convy((ymin+radius)/ppi),
383                        xmax/ppi, convy((ymax-radius)/ppi));
384                fprintf(tfp, "arc cw %s from %.3f, %.3f to %.3f,%.3f radius %.3f\n",
385                        attr, xmax/ppi, convy((ymax-radius)/ppi),
386                        (xmax-radius)/ppi, convy(ymax/ppi), radius/ppi);
387                fprintf(tfp, "line %s from  %.3f,%.3f to %.3f, %.3f\n", attr,
388                        (xmax-radius)/ppi, convy(ymax/ppi),
389                        (xmin+radius)/ppi, convy(ymax/ppi));
390                fprintf(tfp, "arc cw %s from %.3f, %.3f to %.3f,%.3f radius %.3f\n",
391                        attr, (xmin+radius)/ppi, convy(ymax/ppi),
392                        xmin/ppi, convy((ymax-radius)/ppi), radius/ppi);
393                fprintf(tfp, "line %s from  %.3f,%.3f to %.3f, %.3f\n", attr,
394                        xmin/ppi, convy((ymax-radius)/ppi),
395                        xmin/ppi, convy((ymin+radius)/ppi));
396                fprintf(tfp, "arc cw %s from %.3f, %.3f to %.3f,%.3f radius %.3f",
397                        attr, xmin/ppi, convy((ymin+radius)/ppi),
398                        (xmin+radius)/ppi, convy(ymin/ppi), radius/ppi);
399        } else {
400                /*rja: Place arrowheads or lack there of on the line*/
401                fprintf(tfp, "line %s", attr);
402                if ((l->for_arrow) && (l->back_arrow))
403                        fprintf(tfp, " <-> from");
404                else if (l->back_arrow)
405                        fprintf(tfp, " <- from");
406                else if (l->for_arrow)
407                        fprintf(tfp, " -> from");
408                else
409                        fprintf(tfp, " from ");
410
411                fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
412                while (q->next != NULL) {
413                        p = q;
414                        q = q->next;
415                        fprintf(tfp, " %.3f,%.3f to", p->x/ppi, convy(p->y/ppi));
416                }
417                fprintf(tfp, " %.3f,%.3f", q->x/ppi, convy(q->y/ppi));
418        }
419        if (l->type != T_POLYLINE)
420                set_fill(l->area_fill);
421        newline();
422        }
423#endif
424
425void gentpic_spline(s)
426F_spline        *s;
427{
428        if (int_spline(s))
429            gentpic_itp_spline(s);
430        else
431            gentpic_ctl_spline(s);
432        }
433
434void gentpic_ctl_spline(s)
435F_spline        *s;
436{
437        if (closed_spline(s))
438            gentpic_closed_spline(s);
439        else
440            gentpic_open_spline(s);
441        }
442
443void gentpic_open_spline(s)
444F_spline        *s;
445{
446        double          x1, y1, x2, y2;
447        F_point         *p, *q;
448
449        p = s->points;
450        x1 = p->x/ppi; y1 = convy(p->y/ppi);
451        p = p->next;
452        x2 = p->x/ppi; y2 = convy(p->y/ppi);
453
454        set_style(s->style, s->style_val);
455        set_linewidth(s->thickness);
456
457        if (p->next == NULL) {
458            fprintf(tfp, "line");
459            if (s->style == DASH_LINE && s->style_val > 0.0)
460                    fprintf(tfp, " dashed");
461            else if (s->style == DOTTED_LINE && s->style_val > 0.0)
462                    fprintf(tfp, " dotted");
463
464
465           /*rja: Attach arrowhead as required */
466            if ((s->for_arrow) && (s->back_arrow))
467               fprintf(tfp, " <->");
468            else if (s->back_arrow)
469               fprintf(tfp, " <-");
470            else if (s->for_arrow)
471               fprintf(tfp, " ->");
472
473            fprintf(tfp, " from %.3f,%.3f to %.3f,%.3f", x1, y1, x2, y2);
474            newline();
475            return;
476            }
477
478        fprintf(tfp, "spline"); 
479        if (s->style == DASH_LINE && s->style_val > 0.0)
480            fprintf(tfp, " dashed");
481        else if (s->style == DOTTED_LINE && s->style_val > 0.0)
482            fprintf(tfp, " dotted");
483
484
485           /*rja: Attach arrowhead as required */
486            if ((s->for_arrow) && (s->back_arrow))
487               fprintf(tfp, " <->");
488            else if (s->back_arrow)
489               fprintf(tfp, " <-");
490            else if (s->for_arrow)
491               fprintf(tfp, " ->");
492
493        fprintf(tfp, " from %.3f,%.3f to %.3f,%.3f", x1, y1, x2, y2);
494
495        for (q = p->next; q->next != NULL; p = q, q = q->next)
496            fprintf(tfp, " to %.3f,%.3f", q->x/ppi, convy(q->y/ppi));
497        fprintf(tfp, " to %.3f,%.3f", (x2=q->x/ppi), (y2=convy(q->y/ppi)));
498
499        newline();
500        }
501
502void gentpic_ellipse(e)
503F_ellipse       *e;
504{
505        set_linewidth(e->thickness);
506        set_texture(e->area_fill);
507        set_style(e->style, e->style_val);
508
509        fprintf(tfp, "ellipse");
510
511        if (e->style == DASH_LINE && e->style_val > 0.0)
512                fprintf(tfp, " dashed");
513        else if (e->style == DOTTED_LINE && e->style_val > 0.0)
514                fprintf(tfp, " dotted");
515
516        fprintf(tfp, " at %.3f,%.3f wid %.3f ht %.3f",
517                e->center.x/ppi, convy(e->center.y/ppi),
518                2 * e->radiuses.x/ppi, 2 * e->radiuses.y/ppi);
519        if (e->thickness == 0)
520                fprintf(tfp, " invis");
521        set_fill(e->area_fill);
522        newline();
523        }
524
525/*
526Text is displayed on the screen with the base line starting at
527(base_x, base_y); some characters extend below this line.
528Pic displays the center of the height of text at the given
529coordinate. HT_OFFSET is used to compensate all the above factors
530so text position in fig should be at the same position on
531the screen as on the hard copy.
532
533THIS IS A HACK. tpic should be modified to put text with its
534baseline at the given coordinates as does fig -- Baron.
535*/
536#define                 HT_OFFSET       (0.25 / 72.0)
537
538void gentpic_text(t)
539F_text  *t;
540{
541        float   y;
542        char    *tpos;
543        int     virtual_font = 0;
544
545        /*
546         * If a font size is specified and the current text font size
547         * is the default, then use the specified font size.
548         */
549        if (t->size == 0 && font_size)
550                t->size = font_size;
551
552        /*
553         * tpic is informed of the baseline spacing here. Not particularly
554         * useful in this version of the driver.
555         */
556        set_baseline((int)t->size);
557
558        unpsfont(t);
559
560        if (t->font > MAX_FONT || vfont)
561                virtual_font = 1;       /* must be a virtual font */
562
563        if (virtual_font)
564                /*
565                 * NOTE. Virtual fonts are defined dynamically using
566                 * TeX's font definition machinery.
567                 */
568                fprintf(tfp, "\"\\font\\fig%s=%s at %dpt \\fig%s ",
569                        TEXFONT(t->font), TEXFONT(t->font), t->size,
570                        TEXFONT(t->font));
571        else
572#ifdef FST
573                fprintf(tfp, "\"\\%spt\\%s ", TEXFONTMAG(t), TEXFONT(t->font));
574#else
575                fprintf(tfp, "\"\\%s%s ", TEXFONTMAG(t), TEXFONT(t->font));
576#endif
577
578        switch (t->type) {
579        case T_LEFT_JUSTIFIED:
580        case DEFAULT:
581            tpos = "ljust";
582            break;
583        case T_CENTER_JUSTIFIED:
584            tpos = "";
585            break;
586        case T_RIGHT_JUSTIFIED:
587            tpos = "rjust";
588            break;
589        default:
590            fprintf(stderr, "unknown text position type\n");
591            exit(1);
592        }   
593        y = convy(t->base_y/ppi) + (TEXFONTMAGINT(t)
594                * HT_OFFSET);
595
596        fprintf(tfp, "%s\" at %.3f,%.3f %s",
597                t->cstring, t->base_x/ppi, y, tpos);
598        newline();
599}
600
601void gentpic_arc(a)
602F_arc   *a;
603{
604        double          x, y;
605        double          cx, cy, sx, sy, ex, ey;
606
607        cx = a->center.x/ppi; cy = convy(a->center.y/ppi);
608        sx = a->point[0].x/ppi; sy = convy(a->point[0].y/ppi);
609        ex = a->point[2].x/ppi; ey = convy(a->point[2].y/ppi);
610
611        set_texture(a->area_fill);
612        set_linewidth(a->thickness);
613        set_style(a->style, a->style_val);
614
615        fprintf(tfp, "arc");
616
617        if (a->style == DASH_LINE && a->style_val > 0.0)
618                fprintf(tfp, " dashed");
619        else if (a->style == DOTTED_LINE && a->style_val > 0.0)
620                fprintf(tfp, " dotted");
621
622        /*rja: Attach arrowhead as required */
623        if ((a->for_arrow) && (a->back_arrow))
624                fprintf(tfp, " <->");
625        else if (a->back_arrow)
626                fprintf(tfp, " <-");
627        else if (a->for_arrow)
628                fprintf(tfp, " ->");
629
630
631        if (a->direction)
632            fprintf(tfp, " at %.3f,%.3f from %.3f,%.3f to %.3f,%.3f",
633                        cx, cy, sx, sy, ex, ey);
634        else
635            fprintf(tfp, " at %.3f,%.3f from %.3f,%.3f to %.3f,%.3f cw",
636                        cx, cy, sx, sy, ex, ey);
637        if (a->thickness == 0)
638                fprintf(tfp, " invis");
639        set_fill(a->area_fill);
640        newline();
641
642        }
643
644static arc_tangent(x1, y1, x2, y2, direction, x, y)
645double  x1, y1, x2, y2, *x, *y;
646int     direction;
647{
648        if (direction) { /* counter clockwise  */
649            *x = x2 + (y2 - y1);
650            *y = y2 - (x2 - x1);
651            }
652        else {
653            *x = x2 - (y2 - y1);
654            *y = y2 + (x2 - x1);
655            }
656        }
657
658#define         THRESHOLD       .05     /* inch */
659
660static quadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4)
661double  a1, b1, a2, b2, a3, b3, a4, b4;
662{
663        double  x1, y1, x4, y4;
664        double  xmid, ymid;
665
666        x1 = a1; y1 = b1;
667        x4 = a4; y4 = b4;
668
669        xmid = (a2 + a3) / 2;
670        ymid = (b2 + b3) / 2;
671        if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD) {
672            fprintf(tfp, "\tto %.3f,%.3f\\\n", xmid, ymid);
673            }
674        else {
675            quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2),
676                        ((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid);
677            }
678
679        if (fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) {
680            fprintf(tfp, "\tto %.3f,%.3f\\\n", x4, y4);
681            }
682        else {
683            quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4),
684                        ((a3+x4)/2), ((b3+y4)/2), x4, y4);
685            }
686        }
687
688void gentpic_closed_spline(s)
689F_spline        *s;
690{
691        F_point *p;
692        double  cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
693        double  x1, y1, x2, y2;
694
695        p = s->points;
696        x1 = p->x/ppi;  y1 = convy(p->y/ppi);
697        p = p->next;
698        x2 = p->x/ppi;  y2 = convy(p->y/ppi);
699        cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
700        cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
701
702        set_linewidth(s->thickness);
703        set_texture(s->area_fill); /* probably won't work! */
704        set_style(s->style, s->style_val);
705
706        for (p = p->next; p != NULL; p = p->next) {
707            fprintf(tfp, "line from %.3f,%.3f ", cx1, cy1);
708            x1 = x2;  y1 = y2;
709            x2 = p->x/ppi;  y2 = convy(p->y/ppi);
710            cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
711            cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
712            quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
713            newline();
714            /* fprintf(tfp, "\n"); */
715            cx1 = cx4;  cy1 = cy4;
716            cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
717            }
718        x1 = x2;  y1 = y2;
719        p = s->points->next;
720        x2 = p->x/ppi;  y2 = convy(p->y/ppi);
721        cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
722        cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
723        fprintf(tfp, "line from %.3f,%.3f ", cx1, cy1);
724        quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
725        if (s->thickness == 0)
726                fprintf(tfp, " invis");
727        set_fill(s->area_fill);
728        newline();
729        /* fprintf(tfp, "\n"); */
730        }
731
732void gentpic_itp_spline(s)
733F_spline        *s;
734{
735        F_point         *p1, *p2, *pfirst;
736        F_control       *cp1, *cp2;
737        double          x1, x2, y1, y2;
738
739        set_style(s->style, s->style_val);
740        set_texture(s->area_fill); /* probably won't work! */
741        set_linewidth(s->thickness);
742
743        p1 = s->points;
744        cp1 = s->controls;
745        cp2 = cp1->next;
746        x2 = p1->x/ppi; y2 = convy(p1->y/ppi);
747
748         pfirst = p1->next;/*save first to test in loop*/
749        for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
750                p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
751
752            fprintf(tfp, "line ");
753
754           /*rja: Attach arrowhead as required */
755
756            if ((s->back_arrow) && (p2 == pfirst))
757               fprintf(tfp, " <- ");
758            else if ((s->for_arrow) && (p2->next == NULL))
759               fprintf(tfp, " -> ");
760
761            fprintf(tfp, " from %.3f,%.3f ", x2, y2);
762
763            x1 = x2; y1 = y2;
764            x2 = p2->x/ppi; y2 = convy(p2->y/ppi);
765            bezier_spline(x1, y1, (double)cp1->rx/ppi, convy(cp1->ry/ppi),
766                (double)cp2->lx/ppi, convy(cp2->ly/ppi), x2, y2);
767            /* fprintf(tfp, "\n"); */
768            newline();
769            }
770
771        }
772
773static bezier_spline(a0, b0, a1, b1, a2, b2, a3, b3)
774double  a0, b0, a1, b1, a2, b2, a3, b3;
775{
776        double  x0, y0, x3, y3;
777        double  sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid;
778
779        x0 = a0; y0 = b0;
780        x3 = a3; y3 = b3;
781        if (fabs(x0 - x3) < THRESHOLD && fabs(y0 - y3) < THRESHOLD) {
782            fprintf(tfp, "\tto %.3f,%.3f\\\n", x3, y3);
783            }
784        else {
785            tx = (a1 + a2) / 2;         ty = (b1 + b2) / 2;
786            sx1 = (x0 + a1) / 2;        sy1 = (y0 + b1) / 2;
787            sx2 = (sx1 + tx) / 2;       sy2 = (sy1 + ty) / 2;
788            tx2 = (a2 + x3) / 2;        ty2 = (b2 + y3) / 2;
789            tx1 = (tx2 + tx) / 2;       ty1 = (ty2 + ty) / 2;
790            xmid = (sx2 + tx1) / 2;     ymid = (sy2 + ty1) / 2;
791
792            bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid);
793            bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3);
794            }
795        }
796
797static void
798newline()
799{
800        /*
801         * A vestige from another version of this driver.
802         */
803        fprintf(tfp, "\n");
804}
805
806struct driver dev_tpic = {
807        gentpic_option,
808        gentpic_start,
809        gentpic_arc,
810        gentpic_ellipse,
811        gentpic_line,
812        gentpic_spline,
813        gentpic_text,
814        gentpic_end,
815        INCLUDE_TEXT
816};
817
Note: See TracBrowser for help on using the repository browser.