source: tags/initial/fig2dev/dev/genpictex.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: 24.9 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 *      genpictex.C : PiCTeX driver for fig2dev
26 *
27 *      Author Micah Beck, Cornell University, 4/88
28 *    Color, rotated text and ISO-chars added by Herbert Bauer 11/91
29*/
30#if defined(hpux) || defined(SYSV)
31#include <sys/types.h>
32#endif
33#include <sys/file.h>
34#include <stdio.h>
35#include <math.h>
36#include "pi.h"
37#include "object.h"
38#include "fig2dev.h"
39#include "texfonts.h"
40
41#define UNIT "cm"       /* dip */
42#define CONVUNIT 2.54   /* dip */
43
44#ifndef fabs
45extern double fabs();
46#endif
47#ifndef sin
48extern double sin();
49#endif
50#ifndef cos
51extern double cos();
52#endif
53#ifndef acos
54extern double acos();
55#endif
56extern char *ISOtoTeX[];
57
58void genpictex_ctl_spline(), genpictex_itp_spline();
59
60static int              coord_system;
61static double           dash_length = -1;
62static int              line_style = SOLID_LINE;
63static char             *linethick = "1pt";
64static char             *plotsymbol = "\\makebox(0,0)[l]{\\tencirc\\symbol{'160}}";
65static int              cur_thickness = -1;
66
67static void genpictex_option(opt, optarg)
68char opt, *optarg;
69{
70        int i;
71
72        switch (opt) {
73
74                case 'a':
75                    fprintf(stderr, "warning: pictex option -a obsolete\n");
76                    break;
77
78                case 'f':                       /* set default text font */
79                    for ( i = 1; i <= MAX_FONT; i++ )
80                        if ( !strcmp(optarg, texfontnames[i]) ) break;
81
82                    if ( i > MAX_FONT)
83                        fprintf(stderr,
84                        "warning: non-standard font name %s\n", optarg);
85               
86                    texfontnames[0] = texfontnames[1] = optarg;
87                    break;
88
89                case 'l':                       /* set line thickness */
90                    linethick = optarg;
91                    break;
92
93                case 'p':                       /* set plot symbol */
94                    plotsymbol = optarg;
95                    break;
96
97                case 's':
98                    if (font_size <= 0 || font_size > MAXFONTSIZE) {
99                        fprintf(stderr,
100                                "warning: font size %d out of bounds\n", font_size);
101                    }
102                    break;
103
104                case 'm':
105                case 'L':
106                    break;
107
108        default:
109                put_msg(Err_badarg, opt, "pictex");
110                exit(1);
111                break;
112        }
113}
114
115#define                 TOP     10.5    /* top of page is 10.5 inch */
116static double           ppi;
117static int              CONV = 0;
118
119static double convy(a)
120double  a;
121{
122        return((double)(CONV ? TOP-a : a));
123}
124
125void genpictex_start(objects)
126F_compound      *objects;
127{
128        texfontsizes[0] = texfontsizes[1] = TEXFONTSIZE(font_size);
129
130        coord_system = objects->nwcorner.y;
131        ppi = objects->nwcorner.x;
132        if (coord_system == 2) CONV = 1;
133
134        /* PiCTeX start */
135        fprintf(tfp, "\\font\\thinlinefont=cmr5\n");
136        define_setfigfont(tfp);
137        fprintf(tfp, "\\mbox{\\beginpicture\n");
138        fprintf(tfp, "\\setcoordinatesystem units <%6.3f%s,%6.3f%s>\n",
139                        mag, UNIT, mag, UNIT);
140        fprintf(tfp, "\\unitlength=%6.3f%s\n", mag, UNIT);
141        fprintf(tfp, "\\linethickness=%s\n", linethick);
142        fprintf(tfp, "\\setplotsymbol ({%s})\n", plotsymbol);
143        fprintf(tfp, "\\setshadesymbol ({\\thinlinefont .})\n");
144        fprintf(tfp, "\\setlinear\n");
145}
146
147void genpictex_end()
148{
149        /* PiCTeX ending */
150        fprintf(tfp, "\\linethickness=0pt\n");
151        fprintf(tfp, "\\putrectangle corners at %6.3f %6.3f and %6.3f %6.3f\n",
152                (llx/ppi)*CONVUNIT, (convy(lly/ppi))*CONVUNIT, (urx/ppi)*CONVUNIT, (convy(ury/ppi))*CONVUNIT);
153        fprintf(tfp, "\\endpicture}\n");
154}
155
156static set_linewidth(w)
157int     w;
158{
159/*      static int      cur_thickness = -1;*/
160
161/*      if (w == 0) return;*/
162/*      if (w != cur_thickness) {*/
163            if (!w) {
164                fprintf(tfp, "\\linethickness=0pt\n");
165                cur_thickness = 0;
166                }
167            else {
168                cur_thickness = round(w*mag);
169
170                if (!cur_thickness || cur_thickness == 1) {
171                    cur_thickness = 1;
172                    fprintf(tfp, "\\linethickness=%6.3fpt\n", 0.5*cur_thickness);
173                    }
174                else {
175                    fprintf(tfp, "\\linethickness=%dpt\n", cur_thickness-1);
176                    }
177                }
178            switch (cur_thickness) {
179                    case 0:
180                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\thinlinefont \\ ");
181                            break;
182                    case 1:
183                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\thinlinefont .");
184                            break;
185                    case 2:
186                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'160}}");
187                            break;
188                    case 3:
189                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'161}}");
190                            break;
191                    case 4:
192                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'162}}");
193                            break;
194                    case 5:
195                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'163}}");
196                            break;
197                    case 6:
198                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'164}}");
199                            break;
200                    case 7:
201                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'165}}");
202                            break;
203                    case 8:
204                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'166}}");
205                            break;
206                    case 9:
207                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'167}}");
208                            break;
209                    case 10:
210                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'170}}");
211                            break;
212                    case 11:
213                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'171}}");
214                            break;
215                    case 12:
216                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'172}}");
217                            break;
218                    case 13:
219                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'173}}");
220                            break;
221                    case 14:
222                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'174}}");
223                            break;
224                    case 15:
225                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'175}}");
226                            break;
227                    case 16:
228                        fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'176}}");
229                            break;
230                    default:
231                            fprintf(tfp, "\\setplotsymbol ({%s})\n", "\\makebox(0,0)[l]{\\tencirc\\symbol{'176}}");
232                            break;
233            }
234/* PIC  fprintf(tfp, "\"D't %.3fi'\"\n", 0.7 * cur_thickness);*/
235/*    }*/
236}
237
238void genpictex_line(l)
239F_line  *l;
240{
241        F_point         *p, *q;
242        int             x, y, llx, lly, urx, ury;
243
244        fprintf(tfp, "%%\n%% Fig POLYLINE object\n%%\n");
245
246        if (l->type == T_ARC_BOX) { /* A box with rounded corners */
247          fprintf(stderr, "Arc box not implemented; substituting box.\n");
248          l->type = T_BOX;
249        }
250
251        set_linewidth(l->thickness);
252        set_style(l->style, l->style_val);
253        set_color(l->color);
254
255        p = l->points;
256        q = p->next;
257
258        if (q == NULL) { /* A single point line */
259            fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f /\n",
260                        (p->x/ppi)*CONVUNIT, (convy(p->y/ppi))*CONVUNIT, (p->x/ppi)*CONVUNIT, (convy(p->y/ppi))*CONVUNIT);
261            return;
262            }
263
264        if (l->type == T_BOX || l->type == T_ARC_BOX) /* A (rounded corner) box */
265        {
266            x = p->x; y=p->y;
267            llx =urx = x;
268            lly =ury = y;
269            while ( q!= NULL )
270            {
271                x = q->x; y=q->y;
272                if (x < llx) llx = x;
273                if (y < lly) lly = y;
274                if (x > urx) urx = x;
275                if (y > ury) ury = y;
276                q = q->next;
277            }
278            put_box (llx, lly, urx, ury, l);
279            return; 
280        }
281
282        if (l->back_arrow)
283            draw_arrow_head(q->x/ppi, convy(q->y/ppi), p->x/ppi,
284                convy(p->y/ppi), l->back_arrow->ht/ppi, l->back_arrow->wid/ppi);
285        set_style(l->style, l->style_val);
286
287        while (q->next != NULL) {
288
289            putline(p->x, p->y, (double) q->x, (double) q->y,
290                    (q->next)->x, (q->next)->y, -1, -1, -1, -1);
291            p = q;
292            q = q->next;
293            }
294
295        putline(p->x, p->y, (double) q->x, (double) q->y, -1, -1,
296                l->points->x, l->points->y,
297                l->points->next->x,l->points->next->y);
298        if (l->for_arrow)
299            draw_arrow_head(p->x/ppi, convy(p->y/ppi), q->x/ppi,
300                convy(q->y/ppi), l->for_arrow->ht/ppi, l->for_arrow->wid/ppi);
301
302        if (l->area_fill && (int)l->area_fill != DEFAULT)
303                fprintf(stderr, "Line area fill not implemented\n");
304        reset_color(l->color);
305        }
306
307
308/*
309 * draw box
310 */
311static put_box (llx, lly, urx, ury, l)
312int     llx, lly, urx, ury;
313F_line  *l;
314{
315        int radius;
316
317        set_color(l->color);
318        if (l->type == T_BOX)
319        {
320           if (l->area_fill && l->area_fill == BLACK_FILL)
321           {
322               fprintf(tfp,"\\linethickness=%6.3f%s\n", 
323                    ((convy(lly/ppi))-(convy(ury/ppi)))*CONVUNIT*mag, UNIT);
324               fprintf(tfp,"{\\setsolid"); 
325               fprintf(tfp,"\\putrule from %6.3f %6.3f to %6.3f %6.3f }%%\n",
326                    (llx/ppi)*CONVUNIT,
327                    ((convy(lly/ppi)+convy(ury/ppi))/2)*CONVUNIT,
328                    (urx/ppi)*CONVUNIT,
329                    ((convy(lly/ppi)+convy(ury/ppi))/2)*CONVUNIT);
330               fprintf(tfp,"\\linethickness=%dpt\n", l->thickness);
331           }
332           else if (l->area_fill && l->area_fill > 15)
333           {
334               fprintf(tfp,"\\setshadegrid span <1pt>\n");
335               fprintf(tfp,"\\shaderectangleson\n");
336           }
337           else if (l->area_fill && l->area_fill > 10)
338           {
339               fprintf(tfp,"\\setshadegrid span <2pt>\n");
340               fprintf(tfp,"\\shaderectangleson\n");
341           }
342           else if (l->area_fill && l->area_fill > 5)
343           {
344               fprintf(tfp,"\\setshadegrid span <4pt>\n");
345               fprintf(tfp,"\\shaderectangleson\n");
346           }
347           else if (l->area_fill && l->area_fill == WHITE_FILL)
348           {
349               fprintf(stderr,"WHITE_FILL not implemeted for boxes\n");
350           }
351
352           fprintf(tfp,"\\putrectangle corners at %6.3f %6.3f and %6.3f %6.3f\n",
353                (llx/ppi)*CONVUNIT, (convy(lly/ppi))*CONVUNIT,
354                (urx/ppi)*CONVUNIT, (convy(ury/ppi))*CONVUNIT);
355
356           if (l->area_fill
357                && l->area_fill != WHITE_FILL && l->area_fill != BLACK_FILL)
358           {
359               fprintf(tfp,"\\setshadegrid span <5pt>\n");
360               fprintf(tfp,"\\shaderectanglesoff\n");
361           }
362        }
363        else if (l->type == T_ARC_BOX)
364        {
365           radius = l->radius;
366
367           if (l->area_fill)
368           {
369               fprintf(stderr,"area fill not implemeted for rounded corner boxes\n");
370           }
371
372           fprintf(tfp,"\\putrule from %6.3f %6.3f to %6.3f %6.3f\n",
373                   ((llx+radius)/ppi)*CONVUNIT, (convy(lly/ppi))*CONVUNIT,
374                   ((urx-radius)/ppi)*CONVUNIT, (convy(lly/ppi))*CONVUNIT);
375           fprintf(tfp,"\\putrule from %6.3f %6.3f to %6.3f %6.3f\n",
376                   (urx/ppi)*CONVUNIT, (convy((lly+radius)/ppi))*CONVUNIT,
377                   (urx/ppi)*CONVUNIT, (convy((ury-radius)/ppi))*CONVUNIT);
378           fprintf(tfp,"\\putrule from %6.3f %6.3f to %6.3f %6.3f\n",
379                   ((urx-radius)/ppi)*CONVUNIT, (convy(ury/ppi))*CONVUNIT,
380                   ((llx+radius)/ppi)*CONVUNIT, (convy(ury/ppi))*CONVUNIT);
381           fprintf(tfp,"\\putrule from %6.3f %6.3f to %6.3f %6.3f\n",
382                   (llx/ppi)*CONVUNIT, (convy((ury-radius)/ppi))*CONVUNIT,
383                   (llx/ppi)*CONVUNIT, (convy((lly+radius)/ppi))*CONVUNIT);
384           fprintf(tfp,"\\circulararc -90 degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
385                   ((urx-radius)/ppi)*CONVUNIT, (convy(lly/ppi))*CONVUNIT,
386                   ((urx-radius)/ppi)*CONVUNIT, (convy((lly+radius)/ppi))*CONVUNIT);
387           fprintf(tfp,"\\circulararc -90 degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
388                   (urx/ppi)*CONVUNIT, (convy((ury-radius)/ppi))*CONVUNIT,
389                   ((urx-radius)/ppi)*CONVUNIT, (convy((ury-radius)/ppi))*CONVUNIT);
390           fprintf(tfp,"\\circulararc -90 degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
391                   ((llx+radius)/ppi)*CONVUNIT, (convy(ury/ppi))*CONVUNIT,
392                   ((llx+radius)/ppi)*CONVUNIT, (convy((ury-radius)/ppi))*CONVUNIT);
393           fprintf(tfp,"\\circulararc -90 degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
394                   (llx/ppi)*CONVUNIT, (convy((lly+radius)/ppi))*CONVUNIT,
395                   ((llx+radius)/ppi)*CONVUNIT, (convy((lly+radius)/ppi))*CONVUNIT);
396        }
397        reset_color(l->color);
398}
399
400
401
402
403
404
405
406
407
408/*
409 * set_style - issue style commands as appropriate
410 */
411static set_style(style, dash_len)
412int style;
413double dash_len;
414{
415    switch (style) {
416         case SOLID_LINE:
417            if (line_style == SOLID_LINE) break;
418            fprintf(tfp, "\\setsolid\n");
419            break;
420
421        case DASH_LINE:
422            if (line_style == DASH_LINE && dash_length == dash_len)
423                break;
424            fprintf(tfp, "\\setdashes <%7.4f%s>\n", (0.5*dash_len*(cur_thickness+1)/ppi)*CONVUNIT, UNIT);
425            break;
426
427        case DOTTED_LINE:
428            if (line_style == DOTTED_LINE)
429                break;
430            fprintf(tfp, "\\setdots <%7.4f%s>\n", (0.5*dash_len*(cur_thickness+1)/ppi)*CONVUNIT, UNIT);
431            break;
432            }
433
434        line_style = style;
435        dash_length = dash_len;
436    }
437
438/*
439 * putline - use rules if possible
440 */
441static putline (start_x, start_y, end_x, end_y, next_x, next_y,
442                first_start_x, first_start_y, first_end_x, first_end_y)
443int     start_x, start_y, next_x, next_y;
444int     first_start_x, first_start_y, first_end_x, first_end_y;
445double  end_x, end_y;
446{
447    if (line_style == SOLID_LINE &&
448            ((start_x == end_x) || (start_y == end_y))) {
449        if (next_x != -1) {
450            if (start_x == end_x && end_y == next_y) {
451                if (end_y > start_y)
452                    end_y += 0.5*ppi*(cur_thickness-1)/72/mag;
453                else
454                    end_y -= 0.5*ppi*(cur_thickness-1)/72/mag;
455                }
456            else if (start_y == end_y && end_x == next_x) {
457                if (end_x > start_x)
458                    end_x += 0.5*ppi*(cur_thickness-1)/72/mag;
459                else
460                    end_x -= 0.5*ppi*(cur_thickness-1)/72/mag;
461                }
462            }
463        else if (end_x == first_start_x && end_y == first_start_y) {
464            if (start_x == end_x && first_start_y == first_end_y) {
465                if (end_y > start_y)
466                    end_y += 0.5*ppi*(cur_thickness-1)/72/mag;
467                else
468                    end_y -= 0.5*ppi*(cur_thickness-1)/72/mag;
469                }
470            else if (start_y == end_y && first_start_x == first_end_x) {
471                if (end_x > start_x)
472                    end_x += 0.5*ppi*(cur_thickness-1)/72/mag;
473                else
474                    end_x -= 0.5*ppi*(cur_thickness-1)/72/mag;
475                }
476            }
477
478        fprintf(tfp, "\\putrule from %6.3f %6.3f to %6.3f %6.3f\n",
479                (start_x/ppi)*CONVUNIT, (convy(start_y/ppi))*CONVUNIT, (end_x/ppi)*CONVUNIT, (convy(end_y/ppi))*CONVUNIT);
480        }
481    else {
482        fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f /\n",
483                (start_x/ppi)*CONVUNIT, (convy(start_y/ppi))*CONVUNIT, (end_x/ppi)*CONVUNIT, (convy(end_y/ppi))*CONVUNIT);
484        }
485}
486
487
488void genpictex_spline(s)
489F_spline        *s;
490{
491        set_linewidth(s->thickness);
492        set_style(s->style, s->style_val);
493        set_color(s->color);
494
495        if (int_spline(s))
496            genpictex_itp_spline(s);
497        else
498            genpictex_ctl_spline(s);
499
500        if (s->area_fill && (int)s->area_fill != DEFAULT)
501                fprintf(stderr, "Spline area fill not implemented\n");
502        reset_color(s->color);
503}
504
505#define MAXBLACKDIAM 15 /* pt */
506
507void genpictex_ellipse(e)
508F_ellipse       *e;
509{
510        fprintf(tfp, "%%\n%% Fig ELLIPSE\n%%\n");
511
512        set_linewidth(e->thickness);
513        set_style(e->style, e->style_val);
514        set_color(e->color);
515
516        if ((e->area_fill == BLACK_FILL) && (e->radiuses.x == e->radiuses.y)) {
517                if (mag*e->radiuses.x > 0.5*ppi/72*MAXBLACKDIAM)
518                        fprintf(stderr, "Too big black filled circle substituted by a diameter of %dpt\n", MAXBLACKDIAM);
519                fprintf(tfp, "\\put{\\makebox(0,0)[l]{\\circle*{%6.3f}}} at %6.3f %6.3f\n",
520                    (2*e->radiuses.x/ppi)*CONVUNIT,
521                    ((e->center.x)/ppi)*CONVUNIT, (convy(e->center.y/ppi))*CONVUNIT);
522
523            }
524        else {
525
526                fprintf(tfp, "\\ellipticalarc axes ratio %6.3f:%-6.3f 360 degrees \n",
527                    (e->radiuses.x/ppi)*CONVUNIT, (e->radiuses.y/ppi)*CONVUNIT);
528                fprintf(tfp, "\tfrom %6.3f %6.3f center at %6.3f %6.3f\n",
529                    ((e->center.x+e->radiuses.x)/ppi)*CONVUNIT, (convy(e->center.y/ppi))*CONVUNIT,
530                    (e->center.x/ppi)*CONVUNIT, (convy(e->center.y/ppi))*CONVUNIT);
531                if (e->area_fill && (int)e->area_fill != DEFAULT)
532                        fprintf(stderr, "Ellipse area fill not implemented\n");
533                }
534        reset_color(e->color);
535        }
536
537#define                 HT_OFFSET       (0.2 / 72.0)
538
539void genpictex_text(t)
540F_text  *t;
541{
542        double  x, y;
543        char *tpos;
544        unsigned char *cp;
545
546        fprintf(tfp, "%%\n%% Fig TEXT object\n%%\n");
547
548        x = t->base_x/ppi;
549        y = convy(t->base_y/ppi);
550
551        switch (t->type) {
552
553            case T_LEFT_JUSTIFIED:
554            case DEFAULT:
555                tpos = "[lB]";
556                break;
557
558            case T_CENTER_JUSTIFIED:
559                tpos = "[B]";
560                break;
561
562            case T_RIGHT_JUSTIFIED:
563                tpos = "[rB]";
564                break;
565
566            default:
567                fprintf(stderr, "Text incorrectly positioned\n");
568                return;
569            }
570
571        unpsfont(t);
572        { int texsize;
573          double baselineskip;
574
575          texsize = TEXFONTMAG(t);
576          baselineskip = (texsize * 1.2);
577
578          fprintf(tfp, "\\put{\\SetFigFont{%d}{%.1f}{%s}",
579                texsize, baselineskip, TEXFONT(t->font));
580        }
581
582#ifdef DVIPS
583        if(t->angle && t->type == T_LEFT_JUSTIFIED)
584          fprintf(tfp, "\\special{ps:gsave currentpoint currentpoint translate\n-%.1f rotate neg exch neg exch translate}", t->angle*180/M_PI);
585#endif
586
587        set_color(t->color);
588
589        if (!special_text(t))
590
591                /* this loop escapes characters "$&%#_{}" */
592                /* and deleted characters "~^\" */
593                for(cp = (unsigned char*)t->cstring; *cp; cp++) {
594                    if (strchr("$&%#_{}", *cp)) (void)fputc('\\', tfp);
595                    if (strchr("~^\\", *cp))
596                        fprintf(stderr,
597                                "Bad character in text object '%c'\n" ,*cp);
598                    else
599                        (void)fputc(*cp, tfp);
600                }
601        else 
602                for(cp = (unsigned char*)t->cstring; *cp; cp++) {
603                    if (*cp >= 0xa0)
604                         fprintf(tfp, "%s", ISOtoTeX[(int)*cp-0xa0]);
605                else
606                    fputc(*cp, tfp);
607                }
608
609        reset_color(t->color);
610
611#ifdef DVIPS
612        if(t->angle)
613        {
614          if (t->type == T_LEFT_JUSTIFIED)
615               fprintf(tfp, "\\special{ps:currentpoint grestore moveto}");
616          else
617             fprintf(stderr, "Rotated Text only for left justified text\n");
618        }
619#endif
620        fprintf(tfp, "} %s at %6.3f %6.3f\n",
621            tpos, (x)*CONVUNIT, (y)*CONVUNIT);
622        }
623
624void genpictex_arc(a)
625F_arc   *a;
626{
627        double          x, y;
628        double          cx, cy, sx, sy, ex, ey;
629        double          dx1, dy1, dx2, dy2, r1, r2, th1, th2, theta;
630
631        fprintf(tfp, "%%\n%% Fig CIRCULAR ARC object\n%%\n");
632
633        set_linewidth(a->thickness);
634        set_style(a->style, a->style_val);
635        set_color(a->color);
636
637        cx = a->center.x/ppi; cy = convy(a->center.y/ppi);
638        sx = a->point[0].x/ppi; sy = convy(a->point[0].y/ppi);
639        ex = a->point[2].x/ppi; ey = convy(a->point[2].y/ppi);
640
641        if (a->for_arrow) {
642            arc_tangent(cx, cy, ex, ey, a->direction, &x, &y);
643            draw_arrow_head(x, y, ex, ey,
644                        a->for_arrow->ht/ppi, a->for_arrow->wid/ppi);
645            }
646        if (a->back_arrow) {
647            arc_tangent(cx, cy, sx, sy, !a->direction, &x, &y);
648            draw_arrow_head(x, y, sx, sy,
649                        a->back_arrow->ht/ppi, a->back_arrow->wid/ppi);
650            }
651
652        dx1 = sx - cx;
653        dy1 = sy - cy;
654        dx2 = ex - cx;
655        dy2 = ey - cy;
656           
657        rtop(dx1, dy1, &r1, &th1);
658        rtop(dx2, dy2, &r2, &th2);
659        theta = th2 - th1;
660        if (theta > 0) theta -= 2*M_PI;
661
662/*      set_linewidth(a->thickness); */
663
664        if (a->direction)
665                fprintf(tfp, "\\circulararc %6.3f degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
666                        360+(180/M_PI * theta), (sx)*CONVUNIT, (sy)*CONVUNIT, (cx)*CONVUNIT, (cy)*CONVUNIT);
667        else
668                fprintf(tfp, "\\circulararc %6.3f degrees from %6.3f %6.3f center at %6.3f %6.3f\n",
669                        -180/M_PI * theta, (ex)*CONVUNIT, (ey)*CONVUNIT, (cx)*CONVUNIT, (cy)*CONVUNIT);
670
671        if (a->area_fill && (int)a->area_fill != DEFAULT)
672                fprintf(stderr, "Arc area fill not implemented\n");
673        reset_color(a->color);
674        }
675
676
677
678/*
679 * rtop - rectangular to polar conversion
680 */
681static rtop(x, y, r, th)
682double x, y, *r, *th;
683{
684        *r = sqrt(x*x+y*y);
685        *th = acos(x/(*r));
686
687        if (y < 0) *th = 2*M_PI - *th;
688}
689
690static arc_tangent(x1, y1, x2, y2, direction, x, y)
691double  x1, y1, x2, y2, *x, *y;
692int     direction;
693{
694        if (direction) { /* counter clockwise  */
695            *x = x2 + (y2 - y1);
696            *y = y2 - (x2 - x1);
697            }
698        else {
699            *x = x2 - (y2 - y1);
700            *y = y2 + (x2 - x1);
701            }
702        }
703
704/*      draw arrow heading from (x1, y1) to (x2, y2)    */
705
706static draw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid)
707double  x1, y1, x2, y2, arrowht, arrowwid;
708{
709        double  x, y, xb, yb, dx, dy, l, sina, cosa;
710        double  xc, yc, xd, yd;
711        int style;
712        double dash;
713
714        dx = x2 - x1;  dy = y1 - y2;
715
716        if (!dx && !dy)
717            return ;
718
719        l = sqrt(dx*dx+dy*dy);
720        if (l == 0) {
721             return;
722        }
723        else {
724             sina = dy / l;  cosa = dx / l;
725        }
726        xb = x2*cosa - y2*sina;
727        yb = x2*sina + y2*cosa;
728        x = xb - arrowht;
729        y = yb - arrowwid / 2;
730        xc = x*cosa + y*sina;
731        yc = -x*sina + y*cosa;
732        y = yb + arrowwid / 2;
733        xd = x*cosa + y*sina;
734        yd = -x*sina + y*cosa;
735
736        /* save line style and set to solid */
737        style = line_style;
738        dash = dash_length;
739        set_style(SOLID_LINE, 0.0);
740
741        fprintf(tfp, "%%\n%% arrow head\n%%\n");
742
743        fprintf(tfp, "\\plot %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f /\n%%\n",
744                (xc)*CONVUNIT, (yc)*CONVUNIT, (x2)*CONVUNIT, (y2)*CONVUNIT, (xd)*CONVUNIT, (yd)*CONVUNIT);
745
746        /* restore line style */
747        set_style(style, dash);
748        }
749
750#define         THRESHOLD       .05     /* inch */
751
752static quadratic_spline(a1, b1, a2, b2, a3, b3, a4, b4)
753double  a1, b1, a2, b2, a3, b3, a4, b4;
754{
755        double  x1, y1, x4, y4;
756        double  xmid, ymid;
757
758        x1 = a1; y1 = b1;
759        x4 = a4; y4 = b4;
760        xmid = (a2 + a3) / 2;
761        ymid = (b2 + b3) / 2;
762        if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD)
763            fprintf(tfp, "\t%6.3f %6.3f\n", (xmid)*CONVUNIT, (ymid)*CONVUNIT);
764
765        else {
766            quadratic_spline(x1, y1, ((x1+a2)/2), ((y1+b2)/2),
767                        ((3*a2+a3)/4), ((3*b2+b3)/4), xmid, ymid);
768            }
769
770        if (fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD)
771            fprintf(tfp, "\t%6.3f %6.3f\n", (x4)*CONVUNIT, (y4)*CONVUNIT);
772
773        else {
774            quadratic_spline(xmid, ymid, ((a2+3*a3)/4), ((b2+3*b3)/4),
775                        ((a3+x4)/2), ((b3+y4)/2), x4, y4);
776            }
777        }
778
779static void genpictex_ctl_spline(s)
780F_spline        *s;
781{
782        F_point *p;
783        double  cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
784        double  x1, y1, x2, y2;
785
786        fprintf(tfp, "%%\n%% Fig CONTROL PT SPLINE\n%%\n");
787
788        p = s->points;
789        x1 = p->x/ppi;  y1 = convy(p->y/ppi);
790        p = p->next;
791        x2 = p->x/ppi;  y2 = convy(p->y/ppi);
792        cx1 = (x1 + x2) / 2;      cy1 = (y1 + y2) / 2;
793        cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
794
795        if (closed_spline(s)) {
796            fprintf(tfp, "%% closed spline\n%%\n");
797            fprintf(tfp, "\\plot\t%6.3f %6.3f \n ", (cx1)*CONVUNIT, (cy1)*CONVUNIT);
798            }
799        else {
800            fprintf(tfp, "%% open spline\n%%\n");
801            if (s->back_arrow)
802                draw_arrow_head(cx1, cy1, x1, y1,
803                        s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);
804            fprintf(tfp, "\\plot\t%6.3f %6.3f %6.3f %6.3f\n ",
805                (x1)*CONVUNIT, (y1)*CONVUNIT, (cx1)*CONVUNIT, (cy1)*CONVUNIT);
806            }
807
808        for (p = p->next; p != NULL; p = p->next) {
809            x1 = x2;  y1 = y2;
810            x2 = p->x/ppi;  y2 = convy(p->y/ppi);
811            cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
812            cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
813            quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
814            cx1 = cx4;  cy1 = cy4;
815            cx2 = (x1 + 3 * x2) / 4;  cy2 = (y1 + 3 * y2) / 4;
816            }
817        x1 = x2;  y1 = y2;
818        p = s->points->next;
819        x2 = p->x/ppi;  y2 = convy(p->y/ppi);
820        cx3 = (3 * x1 + x2) / 4;  cy3 = (3 * y1 + y2) / 4;
821        cx4 = (x1 + x2) / 2;      cy4 = (y1 + y2) / 2;
822        if (closed_spline(s)) {
823            quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
824            fprintf(tfp, "\t/\n");
825            }
826        else {
827            fprintf(tfp, "\t /\n\\plot %6.3f %6.3f %6.3f %6.3f /\n",
828                (cx1)*CONVUNIT, (cy1)*CONVUNIT, (x1)*CONVUNIT, (y1)*CONVUNIT);
829            if (s->for_arrow)
830                draw_arrow_head(cx1, cy1, x1, y1,
831                        s->for_arrow->ht/ppi, s->for_arrow->wid/ppi);
832            }
833
834        }
835
836static void genpictex_itp_spline(s)
837F_spline        *s;
838{
839        F_point         *p1, *p2;
840        F_control       *cp1, *cp2;
841        double          x1, x2, y1, y2;
842
843        fprintf(tfp, "%%\n%% Fig INTERPOLATED PT SPLINE\n%%\n");
844
845        p1 = s->points;
846        cp1 = s->controls;
847        x2 = p1->x/ppi; y2 = convy(p1->y/ppi);
848
849        if (s->back_arrow)
850            draw_arrow_head(cp1->rx/ppi, convy(cp1->ry/ppi), x2, y2,
851                s->back_arrow->ht/ppi, s->back_arrow->wid/ppi);
852
853        fprintf(tfp, "\\plot %6.3f %6.3f ", (x2)*CONVUNIT, (y2)*CONVUNIT);
854        for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
855                p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
856            x1 = x2; y1 = y2;
857            x2 = p2->x/ppi; y2 = convy(p2->y/ppi);
858            bezier_spline(x1, y1, (double)cp1->rx/ppi, convy(cp1->ry/ppi),
859                (double)cp2->lx/ppi, convy(cp2->ly/ppi), x2, y2);
860            }
861        fprintf(tfp, "\t/\n");
862
863        if (s->for_arrow)
864            draw_arrow_head(cp1->lx/ppi, convy(cp1->ly/ppi), x2, y2,
865                s->for_arrow->ht/ppi, s->for_arrow->wid/ppi);
866        }
867
868static bezier_spline(a0, b0, a1, b1, a2, b2, a3, b3)
869double  a0, b0, a1, b1, a2, b2, a3, b3;
870{
871        double  x0, y0, x3, y3;
872        double  sx1, sy1, sx2, sy2, tx, ty, tx1, ty1, tx2, ty2, xmid, ymid;
873
874        x0 = a0; y0 = b0;
875        x3 = a3; y3 = b3;
876        if (fabs(x0 - x3) < THRESHOLD && fabs(y0 - y3) < THRESHOLD)
877            fprintf(tfp, "\t%6.3f %6.3f\n", (x3)*CONVUNIT, (y3)*CONVUNIT);
878
879        else {
880            tx = (a1 + a2) / 2;         ty = (b1 + b2) / 2;
881            sx1 = (x0 + a1) / 2;        sy1 = (y0 + b1) / 2;
882            sx2 = (sx1 + tx) / 2;       sy2 = (sy1 + ty) / 2;
883            tx2 = (a2 + x3) / 2;        ty2 = (b2 + y3) / 2;
884            tx1 = (tx2 + tx) / 2;       ty1 = (ty2 + ty) / 2;
885            xmid = (sx2 + tx1) / 2;     ymid = (sy2 + ty1) / 2;
886
887            bezier_spline(x0, y0, sx1, sy1, sx2, sy2, xmid, ymid);
888            bezier_spline(xmid, ymid, tx1, ty1, tx2, ty2, x3, y3);
889            }
890        }
891
892struct driver dev_pictex = {
893        genpictex_option,
894        genpictex_start,
895        genpictex_arc,
896        genpictex_ellipse,
897        genpictex_line,
898        genpictex_spline,
899        genpictex_text,
900        genpictex_end,
901        EXCLUDE_TEXT
902};
903
Note: See TracBrowser for help on using the repository browser.