source: tags/initial/fig2dev/dev/genibmgl.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: 25.5 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 *      genibmgl.c :    IBMGL driver for fig2dev
26 *                      IBM 6180 Color Plotter with
27 *                      IBM Graphics Enhancement Cartridge
28 *      Author E. Robert Tisdale, University of California, 1/92
29 *      (edwin@cs.ucla.edu)
30 *
31 *              adapted from:
32 *
33 *      genpictex.c :   PiCTeX driver for fig2dev
34 *
35 *      Author Micah Beck, Cornell University, 4/88
36 *      Color, rotated text and ISO-chars added by Herbert Bauer 11/91
37*/
38
39#if defined(hpux) || defined(SYSV)
40#include <sys/types.h>
41#endif
42#include <sys/file.h>
43#ifdef SYSV
44#include <string.h>
45#else
46#include <strings.h>
47#endif
48#include <stdio.h>
49#include <math.h>
50#include "object.h"
51#include "fig2dev.h"
52#include "pi.h"
53
54#define         FALSE                   0
55#define         TRUE                    1
56#define         FONTS                   35
57#define         COLORS                  8
58#define         PATTERNS                21
59#define         DPR             180.0/M_PI      /*       degrees/radian */
60#define         DELTA           M_PI/36.0       /* radians              */
61#define         DEFAULT_FONT_SIZE       11      /* points               */
62#define         POINT_PER_INCH          72.27   /*        points/inch   */
63#define         CMPP            254.0/7227.0    /*   centimeters/point  */
64#define         UNITS_PER_INCH           1016.0 /* plotter units/inch   */
65#define         HEIGHT                   7650.0 /* plotter units        */
66#define         ISO_A4                  10900.0 /* plotter units        */
67#define         ANSI_A                  10300.0 /* plotter units        */
68#define         SPEED_LIMIT             128.0   /* centimeters/second   */
69
70#ifdef IBMGEC
71static  int     ibmgec           = TRUE;
72#else
73static  int     ibmgec           = FALSE;
74#endif
75static  int     portrait         = FALSE;
76static  int     reflected        = FALSE;
77static  int     fonts            = FONTS;
78static  int     colors           = COLORS;
79static  int     patterns         = PATTERNS;
80static  int     line_color       = DEFAULT;
81static  int     line_style       = SOLID_LINE;
82static  int     fill_pattern     = DEFAULT;
83static  double  dash_length      = DEFAULT;     /* in pixels            */
84#ifdef A4
85static  double  pagelength       = ISO_A4/UNITS_PER_INCH;
86#else
87static  double  pagelength       = ANSI_A/UNITS_PER_INCH;
88#endif
89static  double  pageheight       = HEIGHT/UNITS_PER_INCH;
90static  double  pen_speed        = SPEED_LIMIT;
91static  double  xz               =  0.0;        /* inches               */
92static  double  yz               =  0.0;        /* inches               */
93static  double  xl               =  0.0;        /* inches               */
94static  double  yl               =  0.0;        /* inches               */
95static  double  xu               = 32.25;       /* inches               */
96static  double  yu               = 32.25;       /* inches               */
97
98static  int     pen_number[]     = { 1, 2, 3, 4, 5, 6, 7, 8, 1};
99static  double  pen_thickness[]  = {.3,.3,.3,.3,.3,.3,.3,.3,.3};
100
101static  int     line_type[]      =
102           {-1, 1, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6,-1,-1,-1,-1,-1,-1,-1,-1};
103static  double  line_space[]     =
104           {.3,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,.3,.3};
105static  int     fill_type[]      =
106           { 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 1, 2};
107static  double  fill_space[]     =
108           {.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1,.1};
109static  double  fill_angle[]     =
110           { 0, 0,-45,0,45,90,-45,0,45,90,-45,0,45,90,-45,0,45,90, 0, 0, 0, 0};
111
112static  int     standard[]       = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
114static  int     alternate[]      = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
115             1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
116static  double  slant[]          = { 0,10, 0,10, 0,10, 0,10, 0,10, 0,10, 0,10,
117             0,10, 0,10, 0,10, 0,10, 0,10, 0,10, 0,10, 0,10, 0,10, 0,10, 0, 0};
118static  double  wide[]           = {.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,
119            .6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6,.6};
120static  double  high[]           = {.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,
121            .8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8,.8};
122
123static void genibmgl_option(opt, optarg)
124char opt, *optarg;
125{
126        switch (opt) {
127
128            case 'a':                           /* paper size           */
129#ifdef A4
130                pagelength       = ANSI_A/UNITS_PER_INCH;
131#else
132                pagelength       = ISO_A4/UNITS_PER_INCH;
133#endif
134                break;
135
136            case 'c':                           /* Graphics Enhancement */
137                ibmgec           = !ibmgec;     /* Cartridge emulation  */
138                break;
139
140            case 'd':                           /* position and window  */
141                sscanf(optarg, "%lf,%lf,%lf,%lf", &xl,&yl,&xu,&yu);
142                                                /* inches               */
143                break;
144
145            case 'f':                           /* user's characters    */
146                {
147                    FILE        *ffp;
148                    int         font;
149                    if ((ffp = fopen(optarg, "r")) == NULL)
150                        fprintf(stderr, "Couldn't open %s\n", optarg);
151                    else
152                        for (font = 0; font <= fonts; font++)
153                            fscanf(ffp, "%d%d%lf%lf%lf",
154                                &standard[font],        /* 0-4 6-9 30-39*/
155                                &alternate[font],       /* 0-4 6-9 30-39*/
156                                &slant[font],           /*   degrees    */
157                                &wide[font],            /*      ~1.0    */
158                                &high[font]);           /*      ~1.0    */
159                    fclose(ffp);
160                }
161                break;
162
163            case 'l':                           /* user's fill patterns */
164                {
165                    FILE        *ffp;
166                    int         pattern;
167                    if ((ffp = fopen(optarg, "r")) == NULL)
168                        fprintf(stderr, "Couldn't open %s\n", optarg);
169                    else
170                        for (pattern = 1; pattern <= patterns; pattern++)
171                            fscanf(ffp, "%d%lf%d%lf%lf",
172                                &line_type[pattern],    /*    -1-6      */
173                                &line_space[pattern],   /*   inches     */
174                                &fill_type[pattern],    /*     1-5      */
175                                &fill_space[pattern],   /*   inches     */
176                                &fill_angle[pattern]);  /*   degrees    */
177                    fclose(ffp);
178                }
179                break;
180
181            case 'L':                           /* language             */
182                break;
183
184            case 'm':                           /* magnify and offset   */
185                sscanf(optarg, "%lf,%lf,%lf", &mag,&xz,&yz);
186                                                /* inches               */
187                break;
188
189            case 'p':                           /* user's colors        */
190                {
191                    FILE        *ffp;
192                    int         color;
193                    if ((ffp = fopen(optarg, "r")) == NULL)
194                        fprintf(stderr, "Couldn't open %s\n", optarg);
195                    else
196                        for (color = 0; color <= colors; color++)
197                            fscanf(ffp, "%d%lf",
198                                &pen_number[color],     /*     1-8      */
199                                &pen_thickness[color]); /* millimeters  */
200                    fclose(ffp);
201                }
202                break;
203
204            case 'P':                           /* portrait mode        */
205                portrait         = TRUE;
206                break;
207
208            case 's':                           /* set default font size */
209                font_size        = atoi(optarg) ?
210                        atoi(optarg): DEFAULT_FONT_SIZE;
211                break;
212
213            case 'S':                           /* select pen velocity  */
214                pen_speed        = atof(optarg);
215                break;
216
217            case 'v':
218                reflected        = TRUE;        /* mirror image         */
219                break;
220
221            default:
222                put_msg(Err_badarg, opt, "ibmgl");
223                exit(1);
224                break;
225        }
226}
227
228static double           ppi;                    /*     pixels/inch      */
229static double           cpi;                    /*       cent/inch      */
230static double           cpp;                    /*       cent/pixel     */
231static double           wcmpp    = CMPP;        /* centimeter/point     */
232static double           hcmpp    = CMPP;        /* centimeter/point     */
233static int              flipped  = FALSE;       /* flip Y coordinate    */
234
235void genibmgl_start(objects)
236F_compound      *objects;
237{
238        int      P1x, P1y, P2x, P2y;
239        int      Xll, Yll, Xur, Yur;
240        double  Xmin,Xmax,Ymin,Ymax;
241        double  height, length;
242
243        if (fabs(mag) < 1.0/2048.0){
244            fprintf(stderr, "|mag| < 1/2048\n");
245            exit(1);
246            }
247
248        if (xl < xu)
249            if (0.0 < xu)
250                if (xl < pagelength) {
251                    xl   = (0.0 < xl) ? xl: 0.0;
252                    xu   = (xu < pagelength) ? xu: pagelength;
253                    }
254                else {
255                    fprintf(stderr, "xll >= %.2f\n", pagelength);
256                    exit(1);
257                    }
258            else {
259                fprintf(stderr, "xur <= 0.0\n");
260                exit(1);
261                }
262        else {
263            fprintf(stderr, "xur <= xll\n");
264            exit(1);
265            }
266
267        if (yl < yu)
268            if (0.0 < yu)
269                if (yl < pageheight) {
270                    yl   = (0.0 < yl) ? yl: 0.0;
271                    yu   = (yu < pageheight) ? yu: pageheight;
272                    }
273                else {
274                    fprintf(stderr, "yll >= %.2f\n", pageheight);
275                    exit(1);
276                    }
277            else {
278                fprintf(stderr, "yur <= 0.0\n");
279                exit(1);
280                }
281        else {
282            fprintf(stderr, "yur <= yll\n");
283            exit(1);
284            }
285
286        ppi      = objects->nwcorner.x;
287        cpi      = mag*100.0/sqrt((xu-xl)*(xu-xl) + (yu-yl)*(yu-yl));
288        cpp      = cpi/ppi;
289        if (objects->nwcorner.y == 2)
290            flipped      = TRUE;
291
292        /* IBMGL start */
293        fprintf(tfp, "IN;\n");                  /* initialize plotter   */
294
295        if (portrait) {                         /* portrait mode        */
296            fprintf(tfp, "RO90;\n");            /* rotate 90 degrees    */
297            Xll  = yl*UNITS_PER_INCH;
298            Xur  = yu*UNITS_PER_INCH;
299            Yll  = (pagelength - xu)*UNITS_PER_INCH;
300            Yur  = (pagelength - xl)*UNITS_PER_INCH;
301            length       = yu - yl;
302            height       = xu - xl;
303            P1x          = Xll;
304            P2x          = Xur;
305            if (reflected)                      /* upside-down text     */
306                hcmpp    = -hcmpp;
307            if (reflected^flipped) {            /* reflected or flipped */
308                P1y      = Yur;                 /* but not both         */
309                P2y      = Yll;
310                }
311            else {                              /* normal               */
312                P1y      = Yll;
313                P2y      = Yur;
314                }
315            Xmin         =  xz;
316            Xmax         =  xz + (yu - yl)/mag;
317            Ymin         =  yz;
318            Ymax         =  yz + (xu - xl)/mag;
319            }
320        else {                                  /* landscape mode       */
321            Xll  = xl*UNITS_PER_INCH;
322            Yll  = yl*UNITS_PER_INCH;
323            Yur  = yu*UNITS_PER_INCH;
324            Xur  = xu*UNITS_PER_INCH;
325            length       = xu - xl;
326            height       = yu - yl;
327            if (reflected) {                    /* flipped   or not     */
328                wcmpp    = -wcmpp;              /* backward text        */
329                P1x      = Xur;
330                P2x      = Xll;
331                }
332            else {                              /* normal               */
333                P1x      = Xll;
334                P2x      = Xur;
335                }
336            if (flipped) {                      /* reflected or not     */
337                P1y      = Yur;
338                P2y      = Yll;
339                }
340            else {
341                P1y      = Yll;
342                P2y      = Yur;
343                }
344            }
345
346        Xmin     = xz;
347        Ymin     = yz;
348        Xmax     = xz + length/mag;
349        Ymax     = yz + height/mag;
350
351        fprintf(tfp, "IP%d,%d,%d,%d;\n",
352                P1x, P1y, P2x, P2y);
353        fprintf(tfp, "IW%d,%d,%d,%d;\n",
354                Xll, Yll, Xur, Yur);
355        fprintf(tfp, "SC%.4f,%.4f,%.4f,%.4f;\n",
356                Xmin,Xmax,Ymin,Ymax);
357        if (0.0 < pen_speed && pen_speed < SPEED_LIMIT)
358            fprintf(tfp, "VS%.2f;\n", pen_speed);
359}
360
361static arc_tangent(x1, y1, x2, y2, direction, x, y)
362double  x1, y1, x2, y2, *x, *y;
363int     direction;
364{
365        if (direction) { /* counter clockwise  */
366            *x = x2 - (y2 - y1);
367            *y = y2 + (x2 - x1);
368            }
369        else {
370            *x = x2 + (y2 - y1);
371            *y = y2 - (x2 - x1);
372            }
373        }
374
375/*      draw arrow heading from (x1, y1) to (x2, y2)    */
376
377static draw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid)
378double  x1, y1, x2, y2, arrowht, arrowwid;
379{
380        double  x, y, xb, yb, dx, dy, l, sina, cosa;
381        double  xc, yc, xd, yd;
382        int style;
383        double length;
384
385        dx       = x2 - x1;
386        dy       = y1 - y2;
387        l        = sqrt(dx*dx+dy*dy);
388        sina     = dy/l;
389        cosa     = dx/l;
390        xb       = x2*cosa - y2*sina;
391        yb       = x2*sina + y2*cosa;
392        x        = xb - arrowht;
393        y        = yb - arrowwid/2.0;
394        xc       =  x*cosa + y*sina;
395        yc       = -x*sina + y*cosa;
396        y        = yb + arrowwid/2.0;
397        xd       =  x*cosa + y*sina;
398        yd       = -x*sina + y*cosa;
399
400        /* save line style and set to solid */
401        style    = line_style;
402        length   = dash_length;
403        set_style(SOLID_LINE, 0.0);
404
405        fprintf(tfp, "PA%.4f,%.4f;PD%.4f,%.4f,%.4f,%.4f;PU\n",
406                xc, yc, x2, y2, xd, yd);
407
408        /* restore line style */
409        set_style(style, length);
410        }
411
412/*
413 * set_style - issue line style commands as appropriate
414 */
415static set_style(style, length)
416int     style;
417double  length;
418{
419        if (style == line_style)
420            switch (line_style) {
421                case SOLID_LINE:
422                    break;
423
424                case DASH_LINE:
425                    if (dash_length != length && length > 0.0) {
426                        dash_length  = length;
427                        fprintf(tfp, "LT2,%.4f;\n", dash_length*2.0*cpp);
428                        }
429                    break;
430
431                case DOTTED_LINE:
432                    if (dash_length != length && length > 0.0) {
433                        dash_length  = length;
434                        fprintf(tfp, "LT1,%.4f;\n", dash_length*2.0*cpp);
435                        }
436                    break;
437                }
438        else {
439            line_style = style;
440            switch (line_style) {
441                case SOLID_LINE:
442                    fprintf(tfp, "LT;\n");
443                    break;
444
445                case DASH_LINE:
446                    if (dash_length != length && length > 0.0)
447                        dash_length  = length;
448                    if (dash_length > 0.0)
449                        fprintf(tfp, "LT2,%.4f;\n", dash_length*2.0*cpp);
450                    else
451                        fprintf(tfp, "LT2,-1.0;\n");
452                    break;
453
454                case DOTTED_LINE:
455                    if (dash_length != length && length > 0.0)
456                        dash_length  = length;
457                    if (dash_length > 0.0)
458                        fprintf(tfp, "LT1,%.4f;\n", dash_length*2.0*cpp);
459                    else
460                        fprintf(tfp, "LT1,-1.0;\n");
461                    break;
462                }
463            }
464    }
465
466/*
467 * set_width - issue line width commands as appropriate
468 */
469static set_width(w)
470int     w;
471{
472static  int     line_width       = DEFAULT;     /* in pixels             */
473        line_width  = w;
474        }
475
476/*
477 * set_color - issue line color commands as appropriate
478 */
479static set_color(color)
480int     color;
481{
482static  int     number           = 0;   /* 1 <= number <= 8             */
483static  double  thickness        = 0.3; /* pen thickness in millimeters */
484        if (line_color != color) {
485            line_color  = color;
486            color       = (colors + color)%colors;
487            if (number != pen_number[color]) {
488                number  = pen_number[color];
489                fprintf(tfp, "SP%d;\n", pen_number[color]);
490                }
491            if (thickness != pen_thickness[color]) {
492                thickness  = pen_thickness[color];
493                fprintf(tfp, "PT%.4f;\n", pen_thickness[color]);
494                }
495            }
496        }
497
498static fill_polygon(pattern)
499int     pattern;
500{
501        if (1 < pattern && pattern <= patterns) {
502            int         style;
503            double      length;
504            if (fill_pattern != pattern) {
505                fill_pattern  = pattern;
506                fprintf(tfp, "FT%d,%.4f,%.4f;", fill_type[pattern],
507                        fill_space[pattern],
508                        reflected ? -fill_angle[pattern]: fill_angle[pattern]);
509                }
510            /*    save line style */
511            style        = line_style;
512            length       = dash_length;
513            fprintf(tfp, "LT%d,%.4f;FP;\n",
514                    line_type[pattern], line_space[pattern]*cpi);
515            /* restore line style */
516            line_style   = DEFAULT;
517            dash_length  = DEFAULT;
518            set_style(style, length);
519            }
520        }
521       
522void arc(sx, sy, cx, cy, theta, delta)
523double  sx, sy, cx, cy, theta, delta;
524{
525        if (ibmgec)
526            if (delta == M_PI/36.0)             /* 5 degrees            */
527                fprintf(tfp, "AA%.4f,%.4f,%.4f;",
528                        cx, cy, theta*DPR);
529            else
530                fprintf(tfp, "AA%.4f,%.4f,%.4f,%.4f;",
531                        cx, cy, theta*DPR, delta*DPR);
532        else {
533            double      alpha;
534            if (theta < 0.0)
535                delta = -fabs(delta);
536            else
537                delta = fabs(delta);
538            for (alpha = delta; fabs(alpha) < fabs(theta); alpha += delta) {
539                fprintf(tfp, "PA%.4f,%.4f;\n",
540                        cx + (sx - cx)*cos(alpha) - (sy - cy)*sin(alpha),
541                        cy + (sy - cy)*cos(alpha) + (sx - cx)*sin(alpha));
542                }
543            fprintf(tfp, "PA%.4f,%.4f;\n",
544                    cx + (sx - cx)*cos(theta) - (sy - cy)*sin(theta),
545                    cy + (sy - cy)*cos(theta) + (sx - cx)*sin(theta));
546            }
547        }
548
549void genibmgl_arc(a)
550F_arc   *a;
551{
552        if (a->thickness != 0 ||
553                ibmgec && 1 <= a->area_fill && a->area_fill <= patterns) {
554            double      x, y;
555            double      cx, cy, sx, sy, ex, ey;
556            double      dx1, dy1, dx2, dy2, theta;
557
558            set_style(a->style, a->style_val);
559            set_width(a->thickness);
560            set_color(a->color);
561
562            cx           = a->center.x/ppi;
563            cy           = a->center.y/ppi;
564            sx           = a->point[0].x/ppi;
565            sy           = a->point[0].y/ppi;
566            ex           = a->point[2].x/ppi;
567            ey           = a->point[2].y/ppi;
568
569            dx1          = sx - cx;
570            dy1          = sy - cy;
571            dx2          = ex - cx;
572            dy2          = ey - cy;
573           
574            theta        = atan2(dy2, dx2) - atan2(dy1, dx1);
575            if (a->direction^flipped) {
576                if (theta < 0.0)
577                    theta       += 2.0*M_PI;
578                }
579            else {
580                if (theta > 0.0)
581                    theta       -= 2.0*M_PI;
582                }
583
584            if (a->thickness != 0 && a->back_arrow) {
585                arc_tangent(cx, cy, sx, sy, a->direction^flipped, &x, &y);
586                draw_arrow_head(x, y, sx, sy,
587                a->back_arrow->ht/ppi, a->back_arrow->wid/ppi);
588                }
589
590            fprintf(tfp, "PA%.4f,%.4f;PM;PD;", sx, sy);
591            arc(sx, sy, cx, cy, theta, DELTA);
592            fprintf(tfp, "PU;PM2;\n");
593
594            if (a->thickness != 0)
595                fprintf(tfp, "EP;\n");
596
597            if (a->thickness != 0 && a->for_arrow) {
598                arc_tangent(cx, cy, ex, ey, !a->direction^flipped, &x, &y);
599                draw_arrow_head(x, y, ex, ey,
600                        a->for_arrow->ht/ppi, a->for_arrow->wid/ppi);
601                }
602
603            if (1 < a->area_fill && a->area_fill <= patterns)
604                fill_polygon(a->area_fill);
605            }
606        }
607
608void genibmgl_ellipse(e)
609F_ellipse       *e;
610{
611        if (e->thickness != 0 ||
612                ibmgec && 1 <= e->area_fill && e->area_fill <= patterns) {
613            int         j;
614            double      alpha    = 0.0;
615            double      angle;
616            double      delta;
617            double      x0, y0;
618            double      a,  b;
619            double      x,  y;
620
621            set_style(e->style, e->style_val);
622            set_width(e->thickness);
623            set_color(e->color);
624
625            a            = e->radiuses.x/ppi;
626            b            = e->radiuses.y/ppi;
627            x0           = e->center.x/ppi;
628            y0           = e->center.y/ppi;
629            angle        = (flipped ? -e->angle: e->angle);
630            delta        = (flipped ? -DELTA: DELTA);
631
632            x            = x0 + cos(angle)*a;
633            y            = y0 + sin(angle)*a;
634            fprintf(tfp, "PA%.4f,%.4f;PM;PD;\n", x, y);
635            for (j = 1; j <= 72; j++) { alpha    = j*delta;
636                x        = x0 + cos(angle)*a*cos(alpha)
637                         - sin(angle)*b*sin(alpha);
638                y        = y0 + sin(angle)*a*cos(alpha)
639                         + cos(angle)*b*sin(alpha);
640                fprintf(tfp, "PA%.4f,%.4f;\n", x, y);
641                }
642            fprintf(tfp, "PU;PM2;\n");
643
644            if (e->thickness != 0)
645                fprintf(tfp, "EP;\n");
646
647            if (1 < e->area_fill && e->area_fill <= patterns)
648                fill_polygon((int)e->area_fill);
649            }
650        }
651
652void swap(i, j)
653int     *i, *j;
654{       int     t; t = *i; *i = *j; *j = t; }
655
656void genibmgl_line(l)
657F_line  *l;
658{
659        if (l->thickness != 0 ||
660                ibmgec && 1 <= l->area_fill && l->area_fill <= patterns) {
661            F_point     *p, *q;
662
663            set_style(l->style, l->style_val);
664            set_width(l->thickness);
665            set_color(l->color);
666
667            p    = l->points;
668            q    = p->next;
669
670            switch (l->type) {
671                case    T_POLYLINE:
672                case    T_BOX:
673                case    T_POLYGON:
674                    if (q == NULL)              /* A single point line */
675                        fprintf(tfp, "PA%.4f,%.4f;PD;PU;\n",
676                                p->x/ppi, p->y/ppi);
677                    else {
678                        if (l->thickness != 0 && l->back_arrow)
679                            draw_arrow_head(q->x/ppi, q->y/ppi,
680                                    p->x/ppi, p->y/ppi,
681                                    l->back_arrow->ht/ppi,
682                                    l->back_arrow->wid/ppi);
683
684                        fprintf(tfp, "PA%.4f,%.4f;PM;PD%.4f,%.4f;\n",
685                                p->x/ppi, p->y/ppi,
686                                q->x/ppi, q->y/ppi);
687                        while (q->next != NULL) {
688                            p    = q;
689                            q    = q->next;
690                            fprintf(tfp, "PA%.4f,%.4f;\n",
691                                    q->x/ppi, q->y/ppi);
692                            }
693                        fprintf(tfp, "PU;PM2;\n");
694
695                        if (l->thickness != 0)
696                            fprintf(tfp, "EP;\n");
697
698                        if (l->thickness != 0 && l->for_arrow)
699                            draw_arrow_head(p->x/ppi, p->y/ppi,
700                                    q->x/ppi, q->y/ppi,
701                                    l->for_arrow->ht/ppi,
702                                    l->for_arrow->wid/ppi);
703
704                        if (1 < l->area_fill && l->area_fill <= patterns)
705                            fill_polygon((int)l->area_fill);
706                        }
707                    break;
708
709                case    T_ARC_BOX: {
710                    int         llx, lly, urx, ury;
711                    double       x0,  y0,  x1,  y1;
712                    double      dx, dy, angle;
713
714                    llx  = urx  = p->x;
715                    lly  = ury  = p->y;
716                    while ((p = p->next) != NULL) {
717                        if (llx > p->x)
718                            llx = p->x;
719                        if (urx < p->x)
720                            urx = p->x;
721                        if (lly > p->y)
722                            lly = p->y;
723                        if (ury < p->y)
724                            ury = p->y;
725                        }
726
727                    x0   = llx/ppi;
728                    x1   = urx/ppi;
729                    dx   = l->radius/ppi;
730                    if (flipped) {
731                        y0       = ury/ppi;
732                        y1       = lly/ppi;
733                        dy       = -dx;
734                        angle    = -M_PI/2.0;
735                        }
736                    else {
737                        y0       = lly/ppi;
738                        y1       = ury/ppi;
739                        dy       =  dx;
740                        angle    =  M_PI/2.0;
741                        }
742
743                    fprintf(tfp, "PA%.4f,%.4f;PM;PD;\n",  x0, y0 + dy);
744                    arc(x0, y0 + dy, x0 + dx, y0 + dy, angle, DELTA);
745                    fprintf(tfp, "PA%.4f,%.4f;\n", x1 - dx, y0);
746                    arc(x1 - dx, y0, x1 - dx, y0 + dy, angle, DELTA);
747                    fprintf(tfp, "PA%.4f,%.4f;\n", x1, y1 - dy);
748                    arc(x1, y1 - dy, x1 - dx, y1 - dy, angle, DELTA);
749                    fprintf(tfp, "PA%.4f,%.4f;\n", x0 + dx, y1);
750                    arc(x0 + dx, y1, x0 + dx, y1 - dy, angle, DELTA);
751                    fprintf(tfp, "PA%.4f,%.4f;PU;PM2;\n", x0, y0 + dy);
752
753                    if (l->thickness != 0)
754                        fprintf(tfp, "EP;\n");
755
756                    if (1 < l->area_fill && l->area_fill <= patterns)
757                        fill_polygon((int)l->area_fill);
758                    }
759                    break;
760
761                case    T_EPS_BOX:
762                    break;
763                }
764            }
765        }
766
767#define         THRESHOLD       .05     /* inch */
768
769static bezier_spline(a0, b0, a1, b1, a2, b2, a3, b3)
770double  a0, b0, a1, b1, a2, b2, a3, b3;
771{
772        double  x0, y0, x3, y3;
773        double  sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid;
774
775        x0 = a0; y0 = b0;
776        x3 = a3; y3 = b3;
777        if (fabs(x0 - x3) < THRESHOLD && fabs(y0 - y3) < THRESHOLD)
778            fprintf(tfp, "PA%.4f,%.4f;\n", x3, y3);
779
780        else {
781            tx   = (a1  + a2 )/2.0;     ty   = (b1  + b2 )/2.0;
782            sx1  = (x0  + a1 )/2.0;     sy1  = (y0  + b1 )/2.0;
783            sx2  = (sx1 + tx )/2.0;     sy2  = (sy1 + ty )/2.0;
784            tx2  = (a2  + x3 )/2.0;     ty2  = (b2  + y3 )/2.0;
785            tx1  = (tx2 + tx )/2.0;     ty1  = (ty2 + ty )/2.0;
786            xmid = (sx2 + tx1)/2.0;     ymid = (sy2 + ty1)/2.0;
787
788            bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid);
789            bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3);
790            }
791        }
792
793static void genibmgl_itp_spline(s)
794F_spline        *s;
795{
796        F_point         *p1, *p2;
797        F_control       *cp1, *cp2;
798        double          x1, x2, y1, y2;
799
800        p1 = s->points;
801        cp1 = s->controls;
802        x2 = p1->x/ppi; y2 = p1->y/ppi;
803
804        if (s->thickness != 0 && s->back_arrow)
805            draw_arrow_head(cp1->rx/ppi, cp1->ry/ppi, x2, y2,
806                    s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);
807
808        fprintf(tfp, "PA%.4f,%.4f;PD;\n", x2, y2);
809        for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
810                p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
811            x1   = x2;
812            y1   = y2;
813            x2   = p2->x/ppi;
814            y2   = p2->y/ppi;
815            bezier_spline(x1, y1, (double)cp1->rx/ppi, cp1->ry/ppi,
816                (double)cp2->lx/ppi, cp2->ly/ppi, x2, y2);
817            }
818        fprintf(tfp, "PU;\n");
819
820        if (s->thickness != 0 && s->for_arrow)
821            draw_arrow_head(cp1->lx/ppi, cp1->ly/ppi, x2, y2,
822                    s->for_arrow->ht/ppi, s->for_arrow->wid/ppi);
823        }
824
825static quadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4)
826double  a1, b1, a2, b2, a3, b3, a4, b4;
827{
828        double  x1, y1, x4, y4;
829        double  xmid, ymid;
830
831        x1       = a1; y1 = b1;
832        x4       = a4; y4 = b4;
833        xmid     = (a2 + a3)/2.0;
834        ymid     = (b2 + b3)/2.0;
835        if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD)
836            fprintf(tfp, "PA%.4f,%.4f;\n", xmid, ymid);
837        else {
838            quadratic_spline(x1, y1, ((x1+a2)/2.0), ((y1+b2)/2.0),
839                ((3.0*a2+a3)/4.0), ((3.0*b2+b3)/4.0), xmid, ymid);
840            }
841
842        if (fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD)
843            fprintf(tfp, "PA%.4f,%.4f;\n", x4, y4);
844        else {
845            quadratic_spline(xmid, ymid, ((a2+3.0*a3)/4.0), ((b2+3.0*b3)/4.0),
846                        ((a3+x4)/2.0), ((b3+y4)/2.0), x4, y4);
847            }
848        }
849
850static void genibmgl_ctl_spline(s)
851F_spline        *s;
852{
853        F_point *p;
854        double  cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
855        double  x1, y1, x2, y2;
856
857        p        = s->points;
858        x1       = p->x/ppi;
859        y1       = p->y/ppi;
860        p        = p->next;
861        x2       = p->x/ppi;
862        y2       = p->y/ppi;
863        cx1      = (x1 + x2)/2.0;
864        cy1      = (y1 + y2)/2.0;
865        cx2      = (x1 + 3.0*x2)/4.0;
866        cy2      = (y1 + 3.0*y2)/4.0;
867
868        if (closed_spline(s))
869            fprintf(tfp, "PA%.4f,%.4f;PD;\n ", cx1, cy1);
870        else {
871            if (s->thickness != 0 && s->back_arrow)
872                draw_arrow_head(cx1, cy1, x1, y1,
873                        s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);
874            fprintf(tfp, "PA%.4f,%.4f;PD%.4f,%.4f;\n",
875                    x1, y1, cx1, cy1);
876            }
877
878        for (p = p->next; p != NULL; p = p->next) {
879            x1   = x2;
880            y1   = y2;
881            x2   = p->x/ppi;
882            y2   = p->y/ppi;
883            cx3  = (3.0*x1 + x2)/4.0;
884            cy3  = (3.0*y1 + y2)/4.0;
885            cx4  = (x1 + x2)/2.0;
886            cy4  = (y1 + y2)/2.0;
887            quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
888            cx1  = cx4;
889            cy1  = cy4;
890            cx2  = (x1 + 3.0*x2)/4.0;
891            cy2  = (y1 + 3.0*y2)/4.0;
892            }
893        x1       = x2; 
894        y1       = y2;
895        p        = s->points->next;
896        x2       = p->x/ppi;
897        y2       = p->y/ppi;
898        cx3      = (3.0*x1 + x2)/4.0;
899        cy3      = (3.0*y1 + y2)/4.0;
900        cx4      = (x1 + x2)/2.0;
901        cy4      = (y1 + y2)/2.0;
902        if (closed_spline(s)) {
903            quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
904            fprintf(tfp, "PU;\n");
905            }
906        else {
907            fprintf(tfp, "PA%.4f,%.4f;PU;\n", x1, y1);
908            if (s->thickness != 0 && s->for_arrow)
909                draw_arrow_head(cx1, cy1, x1, y1,
910                        s->for_arrow->ht/ppi, s->for_arrow->wid/ppi);
911            }
912        }
913
914void genibmgl_spline(s)
915F_spline        *s;
916{
917        if (s->thickness != 0) {
918            set_style(s->style, s->style_val);
919            set_width(s->thickness);
920            set_color(s->color);
921
922            if (int_spline(s))
923                genibmgl_itp_spline(s);
924            else
925                genibmgl_ctl_spline(s);
926
927            }
928        if (1 < s->area_fill && s->area_fill <= patterns)
929            fprintf(stderr, "Spline area fill not implemented\n");
930}
931
932#define FONT(T) ((-1 < (T) && (T) < fonts) ? (T): fonts)
933void genibmgl_text(t)
934F_text  *t;
935{
936static  int     font     = DEFAULT;     /* font                         */
937static  int     size     = DEFAULT;     /* font size        in points   */
938static  int     rigid    = 0;           /* rigid text                   */
939static  int     cs       = 0;           /* standard  character set      */
940static  int     ca       = 0;           /* alternate character set      */
941static  double  theta    = 0.0;         /* character slant  in degrees  */
942static  double  angle    = 0.0;         /* label direction  in radians  */
943        double  width;                  /* character width  in centimeters */
944        double  height;                 /* character height in centimeters */
945
946        if (font != FONT(t->font)) {
947            font  = FONT(t->font);
948            if (cs != standard[font]) {
949                cs  = standard[font];
950                fprintf(tfp, "CS%d;", cs);
951                }
952            if (ca != alternate[font]) {
953                ca  = alternate[font];
954                fprintf(tfp, "CA%d;", ca);
955                }
956            if (theta != slant[font]) {
957                theta  = slant[font];
958                fprintf(tfp, "SL%.4f;", tan(theta*M_PI/180.0));
959                }
960            }
961        if (size != t->size || rigid != t->flags&RIGID_TEXT) {
962            size  = t->size ? t->size: font_size;
963            rigid  = (t->flags&RIGID_TEXT);
964            width        = size*wcmpp*wide[font];
965            height       = size*hcmpp*high[font];
966            rigid        = (t->flags&RIGID_TEXT);
967            if (rigid)
968                fprintf(tfp, "SI%.4f,%.4f;", width, height);
969            else
970                fprintf(tfp, "SI%.4f,%.4f;", width*mag, height*mag);
971            }
972        if (angle != t->angle) {
973            angle  = t->angle;
974            fprintf(tfp, "DI%.4f,%.4f;",
975                    cos(angle), sin(reflected ? -angle: angle));
976            }
977        set_color(t->color);
978
979        fprintf(tfp, "PA%.4f,%.4f;\n",
980                t->base_x/ppi, t->base_y/ppi);
981
982        switch (t->type) {
983            case DEFAULT:
984            case T_LEFT_JUSTIFIED:
985                break;
986            case T_CENTER_JUSTIFIED:
987                fprintf(tfp, "CP%.4f,0.0;", -(double)(strlen(t->cstring)/2.0));
988                break;
989            case T_RIGHT_JUSTIFIED:
990                fprintf(tfp, "CP%.4f,0.0;", -(double)(strlen(t->cstring)));
991                break;
992            default:
993                fprintf(stderr, "unknown text position type\n");
994                exit(1);
995            }   
996
997        fprintf(tfp, "LB%s\003\n", t->cstring);
998        }
999
1000void genibmgl_end()
1001{
1002        /* IBMGL ending */
1003        fprintf(tfp, "PU;SP;IN;\n");
1004}
1005
1006struct driver dev_ibmgl = {
1007        genibmgl_option,
1008        genibmgl_start,
1009        genibmgl_arc,
1010        genibmgl_ellipse,
1011        genibmgl_line,
1012        genibmgl_spline,
1013        genibmgl_text,
1014        genibmgl_end,
1015        EXCLUDE_TEXT
1016        };
Note: See TracBrowser for help on using the repository browser.