0022627: Change OCCT memory management defaults
[occt.git] / src / CGM / cgmotext.c
1 /* Standard include files */
2
3 #include "cgmout.h"
4 #include "cgminit.h"
5 /*  Output stream for functions */
6
7 static FILE *cgmot;
8
9 /*  Functions in this Module  */
10
11 # if (defined __STDC__ && __STDC__) || defined __cplusplus
12 /* use function prototypes, they are requred for ANSI C and C++ compilers */
13 void CGMOtext(FILE *stream, Code c, Long *pi, float *pr, char *str);     /* Main Output */
14 static void MOTpoints(Long n, Long *pi, float *pr, Enum set),    /* Output a points list */
15             MOTvdc(int n, Long *pi, Float *pr),       /* Output n VDCs */
16             MOTcol(struct colour *c, Enum type),       /* Output a colour */
17             MOTstring(char *s),    /* Output a text string  */
18             MOTenum(char *s, Enum k),      /* Output an enumerated type */
19             MOTprcode(Code code);    /* Output a metafile element code */
20 #else
21 void CGMOtext();     /* Main Output */
22 static void MOTpoints(),    /* Output a points list */
23             MOTvdc(),       /* Output n VDCs */
24             MOTcol(),       /* Output a colour */
25             MOTstring(),    /* Output a text string  */
26             MOTenum(),      /* Output an enumerated type */
27             MOTprcode();    /* Output a metafile element code */
28 #endif
29 /*  Local macro */
30
31 #define TEXTOUT       (void) fprintf( cgmot,
32
33 /*  Table for element decoding */
34
35 extern const struct commands cgmelement[];
36
37 /*  Local Variables */
38
39 static int vp = 4, rp = 4;   /* decimal places for real numbers */
40 static int indent;         /*  Indent for current element  */
41
42 #include "cgmatt.h"
43
44 /*static char *func = "CGMotext", mess[40];*/
45 static char mess[40];
46
47 /****************************************************** CGMOtext *******/
48 void
49 CGMOtext(FILE *stream, Code c, Long *pi, float *pr, char *str)
50 {
51 /*  Outputs Clear Text for MF element 'c' on Output stream 'stream'  */
52
53    static Logical first = TRUE, first_pic = TRUE;
54    static Prec loc_prec;
55    static Long nx, ny;
56    register Long n, i, j, k, num;
57    Code major;
58    Posint prec;
59 /*   char s[100];*/
60
61    if (c == (Code) EOF)
62    {
63      exit(0);
64    }
65
66    cgmot = stream;
67    major = c>>8;
68    num = *pi++;
69
70    switch (major)
71    {
72       case 0x00:               /* Graphics Primitives  */
73          switch (c)
74          {
75             case NONOP:  /* Ignore Non-Op */
76                break;
77
78             case LINE:         /*  Polyline   */
79                if ( first ) MOTprcode ( LINE );
80                MOTpoints ( num, pi, pr, NOSET);
81                first = ( num >= ZERO );
82                break;
83
84             case DISJTLINE:         /*  Disjoint Polyline  */
85                if ( first ) MOTprcode ( DISJTLINE );
86                MOTpoints ( num, pi, pr, NOSET);
87                first = ( num >= ZERO );
88                break;
89
90             case MARKER:         /*  Polymarker  */
91                if ( first ) MOTprcode ( MARKER );
92                MOTpoints ( num, pi, pr, NOSET);
93                first = ( num >= ZERO );
94                break;
95
96             case TEXT:         /*  Text   */
97                MOTprcode ( TEXT );
98                MOTpoints ((Long)1, pi, pr, NOSET);
99                MOTenum("notfinal/final", (Enum) num);
100                MOTstring ( str );
101                break;
102
103             case RESTRTEXT:         /*  Restricted Text */
104                MOTprcode ( RESTRTEXT );
105                MOTvdc ((Int)2, pi, pr);
106                MOTpoints ((Long)1, pi+2, pr+2, NOSET);
107                MOTenum("notfinal/final", (Enum) num);
108                MOTstring ( str );
109                break;
110
111             case APNDTEXT:         /*  Append Text   */
112                MOTprcode ( APNDTEXT );
113                MOTenum("notfinal/final", (Enum) num);
114                MOTstring ( str );
115                break;
116
117             case POLYGON:         /*  Polygon   */
118                if ( first ) MOTprcode ( POLYGON );
119                MOTpoints ( num, pi, pr, NOSET);
120                first = ( num >= ZERO );
121                break;
122
123             case POLYGONSET:         /*  Polygon Set  */
124                if ( first ) MOTprcode ( POLYGONSET );
125                MOTpoints ( num, pi, pr, SET);
126                first = ( num >= ZERO );
127                break;
128
129             case CELLARRAY:         /*  Cell Array  */
130                if ( first )
131                {
132                   MOTprcode ( CELLARRAY );
133                   MOTpoints ((Long)3, pi, pr, NOSET);
134                   pi += 6;
135                   nx = *pi++;
136                   ny = *pi++;
137                   loc_prec = *pi++;
138                   k = ( loc_prec ? ( 1L<<loc_prec ) - 1 : 0 );
139                   TEXTOUT ", %ld, %ld, %lu\n", nx, ny, k );
140                }
141                first = ( num >= ZERO );
142                if ( ! first ) num = -num;
143
144 /*  set decimal places and number of elements per line 'k' */
145
146                prec = (Prec)((loc_prec ? (Double)loc_prec
147                                       : (Double)cur.col_bits )*LOG2) + 1;
148                if ( prec < 2 ) prec = 2;
149                if ( cur.color_mode == INDEXED ) k = 80L / (prec+1);
150                else                             k = 80L / (3*prec+5);
151                if ( k > nx ) k = nx;
152                n = nx; i = k;
153
154                for ( j = ZERO; j < num ; j++ )
155                {
156                   if ( j ) /*  Check for line skip after first pass */
157                   {
158                      if ( cur.color_mode == DIRECT ) TEXTOUT ",");
159 /*  Line skip if end of row or row count reached */
160                      if ( j == n || j == i )
161                      {
162                         TEXTOUT "\n");
163                         if ( j == n )
164                         {
165                            n += nx; i = j + k;
166 /* Extra line skip if row is Longer than one line */
167                            if ( nx > k ) TEXTOUT "\n");
168                         }
169                         else  i += k;
170                      }
171                      else TEXTOUT " ");
172                   }
173                   if ( cur.color_mode == INDEXED )
174                      TEXTOUT "%*ld", (int)prec, *pi++);
175                   else
176                   {
177                      TEXTOUT "%*ld %*ld %*ld",
178                  (int)prec, *pi, (int)prec, *(pi+1), (int)prec, *(pi+2));
179                      pi += (Long)3;
180                   }
181                }
182                if ( ! first )   /* Not finished yet */
183                {
184                   TEXTOUT "\n");
185                   if ( nx > k ) TEXTOUT "\n");
186                }
187                break;
188
189             case GDP:         /*  Generalised Drawing Primitive  */
190                MOTprcode ( GDP );
191                TEXTOUT " %ld  ", *pi++);
192                MOTpoints (num, pi, pr, ZERO);
193                MOTstring ( str );
194                break;
195
196             case RECT:         /*  Rectangle   */
197                MOTprcode ( RECT );
198                MOTpoints ((Long)2, pi, pr, ZERO);
199                break;
200
201             default:
202                (void) sprintf( mess, "(code: 0x%x)", c);
203               break;
204          }
205          break;
206
207       case 0x30:  /*  Delimiter Elements  */
208          switch (c)
209          {
210             case BEGMF:         /*  Begin Metafile   */
211                MOTprcode ( BEGMF );
212                MOTstring ( str );
213                curtext = textdef;
214                break;
215
216             case ENDMF:         /*  End Metafile   */
217                MOTprcode ( ENDMF );
218                break;
219
220             case BEGPIC:         /*  Begin Picture Descriptor   */
221                TEXTOUT "\n");
222                MOTprcode ( BEGPIC );
223                if ( first_pic )
224                {
225                   first_pic = FALSE;
226                   mftext = curtext;  /* Set MF defaults */
227                }
228                else
229                   curtext = mftext;  /* Set Text picture defaults */
230
231                TEXTOUT "'Picture Number ");
232                TEXTOUT "%ld'",*pi);
233                break;
234
235             case BEGPICBODY:         /*  Begin Picture Body  */
236                MOTprcode ( BEGPICBODY );
237                break;
238
239             case ENDPIC:         /*  End  Picture    */
240                MOTprcode ( ENDPIC );
241                break;
242
243             default:
244                (void) sprintf( mess, "(code: 0x%x)", c);
245                break;
246          }
247
248
249       case 0x31:  /* Metafile Descriptor Elements  */
250          switch (c)
251          {
252             case MFVERSION:         /*  Metafile version   */
253                MOTprcode ( MFVERSION );
254                TEXTOUT " %ld", num);
255                break;
256
257             case MFDESC:         /*  Metafile Description  */
258                MOTprcode ( MFDESC );
259                MOTstring ( str );
260                break;
261
262             case VDCTYPE:         /*  VDC Type   */
263                MOTprcode ( VDCTYPE );
264                MOTenum ("integer/real",cur.vdc_type);
265                break;
266
267             case INTEGERPREC:         /*  Integer Precision  */
268                MOTprcode ( INTEGERPREC );
269                curtext.max_int = (Long) (1L<< (cur.int_bits - 1)) -1;
270                curtext.min_int = - curtext.max_int - 1;
271                TEXTOUT " %ld, %ld", curtext.min_int, curtext.max_int);
272                break;
273
274             case REALPREC:         /*  Real Precision   */
275                MOTprcode ( REALPREC );
276                curtext.max_real = cur.max_real;
277                curtext.min_real = cur.min_real;
278                curtext.real_digits = (long)(1.0 +
279                                   (cur.real_bits - cur.real_places) * LOG2);
280                rp =4;
281                TEXTOUT " %.*f, %.*f,", rp, (Double)curtext.min_real,
282                                        rp,(Double)curtext.max_real);
283                TEXTOUT " %ld", curtext.real_digits);
284                break;
285
286             case INDEXPREC:         /*  Index Precision   */
287                MOTprcode ( INDEXPREC );
288                curtext.max_index = (Long) (1L<<(cur.index_bits - 1)) -1;
289                curtext.min_index = -curtext.max_index - 1;
290                TEXTOUT " %ld, %ld", curtext.min_index, curtext.max_index);
291                break;
292
293             case COLRPREC:         /*  Colour Precision  */
294                MOTprcode ( COLRPREC );
295                curtext.col_prec = (Long) (1L<<cur.col_bits) - 1;
296                TEXTOUT " %lu", curtext.col_prec);
297                break;
298
299             case COLRINDEXPREC:         /*  Colour Index Precision  */
300                MOTprcode ( COLRINDEXPREC );
301                curtext.colind_prec = (Long) (1L<<(cur.colind_bits-1)) - 1;
302                TEXTOUT " %ld", curtext.colind_prec);
303                break;
304
305             case MAXCOLRINDEX:         /*  Maximum Colour Index  */
306                MOTprcode ( MAXCOLRINDEX );
307                TEXTOUT " %ld", cur.max_colind);
308                break;
309
310             case COLRVALUEEXT:         /*  Colour value extent  */
311                MOTprcode ( COLRVALUEEXT );
312                curtext.min_rgb.red   = cur.min_rgb.red;
313                curtext.min_rgb.green = cur.min_rgb.green;
314                curtext.min_rgb.blue  = cur.min_rgb.blue;
315                curtext.max_rgb.red   = cur.max_rgb.red;
316                curtext.max_rgb.green = cur.max_rgb.green;
317                curtext.max_rgb.blue  = cur.max_rgb.blue;
318                TEXTOUT " %ld %ld %ld,", curtext.min_rgb.red,
319                                         curtext.min_rgb.green,
320                                         curtext.min_rgb.blue);
321                TEXTOUT " %ld %ld %ld", curtext.max_rgb.red,
322                                        curtext.max_rgb.green,
323                                        curtext.max_rgb.blue);
324                break;
325
326             case MFELEMLIST:         /*  Metafile element List  */
327             {
328 /*               Logical endmfdef = FALSE;*/
329
330                MOTprcode ( MFELEMLIST );
331                TEXTOUT " '");
332                switch ( (Int) *pi )
333                   {
334                      case ZERO:
335                      case 1:
336                         MOTenum ("DRAWINGSET/DRAWINGPLUS",(Enum) *pi );
337                         break;
338
339                      default:
340                         MOTprcode ( (Code) *pi );
341                         break;
342                   }
343
344                TEXTOUT "'");
345                break;
346             }
347
348             case BEGMFDEFAULTS:     /*  Begin Metafile defaults Replacement */
349             case ENDMFDEFAULTS:    /*  End Metafile defaults Replacement  */
350                MOTprcode ( c );
351                break;
352
353             case FONTLIST:         /*  Font List   */
354                MOTprcode ( FONTLIST );
355                for ( j = k = ZERO ; j < num ; )
356                {
357                   if (j) TEXTOUT ",");
358                   k += strlen ( &str[j] ) + 4;
359                   if ( k > 70 )
360                   {
361                      TEXTOUT "\n%9s", " ");
362                      k = strlen ( &str[j] ) + 4;
363                   }
364                   MOTstring ( &str[j] );
365                   j = *pi++;
366                }
367                break;
368
369             case CHARSETLIST:         /*  Character set list  */
370                MOTprcode ( CHARSETLIST );
371                for ( j = ZERO; j < num ; )
372                {
373                   MOTenum ( "STD94/STD96/STD94MULTIBYTE/STD96MULTIBYTE/COMPLETECODE", (Enum) *pi++);
374                   MOTstring ( &str[j] );
375                   j = *pi++;
376                }
377                break;
378
379             case CHARCODING:         /*  Character coding Announcer  */
380                MOTprcode ( CHARCODING );
381                MOTenum ("BASIC7BIT/BASIC8BIT/EXTD7BIT/EXTD8BIT",
382                                  (Enum) num);
383                break;
384          }
385          break;
386
387       case 0x32:  /* Picture Descriptor Elements  */
388          switch (c)
389          {
390             case SCALEMODE:         /*  Scaling Mode   */
391               MOTprcode ( SCALEMODE );
392               MOTenum ("abstract/metric", cur.scale_mode);
393               TEXTOUT ", %.*f", rp, (Double)cur.scale_factor);
394               break;
395
396             case COLRMODE:         /*  Colour Selection Mode */
397                MOTprcode ( COLRMODE );
398                MOTenum ("indexed/direct", cur.color_mode);
399                break;
400
401             case LINEWIDTHMODE:    /*  Line width Specification  */
402                MOTprcode ( LINEWIDTHMODE );
403                MOTenum ("abs/scaled", cur.linewidth_mode);
404                break;
405
406             case MARKERSIZEMODE:   /*  Marker size Specification  */
407                MOTprcode ( MARKERSIZEMODE );
408                MOTenum ("abs/scaled", cur.markersize_mode);
409                break;
410
411             case EDGEWIDTHMODE:    /*  Edge width Specification  */
412                MOTprcode ( EDGEWIDTHMODE );
413                MOTenum ("abs/scaled", cur.edgewidth_mode);
414                break;
415
416             case VDCEXT:         /*  VDC Extent    */
417                MOTprcode ( VDCEXT );
418                if (cur.vdc_type == REAL)
419                   TEXTOUT  " (%.*f,%.*f) (%.*f,%.*f)",
420                           vp, (double)cur.vdc_extent.a.x.real,
421                           vp, (double)cur.vdc_extent.a.y.real,
422                           vp, (double)cur.vdc_extent.b.x.real,
423                           vp, (double)cur.vdc_extent.b.y.real );
424                else
425                   TEXTOUT  " (%ld,%ld) (%ld,%ld)",
426                           cur.vdc_extent.a.x.intr,
427                           cur.vdc_extent.a.y.intr,
428                           cur.vdc_extent.b.x.intr,
429                           cur.vdc_extent.b.y.intr );
430                break;
431
432             case BACKCOLR:         /*  Background Colour  */
433                MOTprcode ( BACKCOLR );
434                MOTcol(&cur.back, DIRECT);
435                break;
436
437             default:
438                (void) sprintf( mess, "(code: 0x%x)", c);
439                break;
440          }
441          break;
442
443       case 0x33:  /* Control Elements  */
444          switch(c)
445          {
446             case VDCINTEGERPREC:       /* VDC Integer Precision  */
447                MOTprcode ( VDCINTEGERPREC );
448                curtext.max_vdc.intr = (Long) (1L<<(cur.vdcint_bits - 1)) -1;
449                curtext.min_vdc.intr = (long) (- curtext.max_vdc.intr - 1);
450                TEXTOUT " %ld, %ld", (long)curtext.min_vdc.intr,
451                                   (long)curtext.max_vdc.intr);
452                TEXTOUT " %ld", cur.vdcint_bits);
453                break;
454
455             case VDCREALPREC:       /* VDC Real Precision  */
456                MOTprcode ( VDCREALPREC );
457                curtext.max_vdc.real = cur.max_vdc;
458                curtext.min_vdc.real = cur.min_vdc;
459                curtext.vdc_digits = (long)(1.0 + (cur.vdc_bits - cur.vdc_places) * LOG2);
460                vp = (long)( cur.vdc_places < 0 ? 1.0-cur.vdc_places*LOG2 : 0);
461                TEXTOUT " %.*f, %.*f,", vp, (double)curtext.min_vdc.real,
462                                        vp, (double)curtext.max_vdc.real);
463                TEXTOUT " %ld", curtext.vdc_digits);
464                TEXTOUT " %ld", cur.vdc_bits);
465                break;
466
467             case AUXCOLR:       /* Auxiliary Colour  */
468                MOTprcode ( AUXCOLR );
469                MOTcol(&cur.aux, cur.color_mode);
470                break;
471
472             case TRANSPARENCY:       /* Transparency  */
473                MOTprcode ( TRANSPARENCY );
474                MOTenum ("off/on", cur.transparency);
475                break;
476
477             case CLIPRECT:       /* Clip Rectangle  */
478                MOTprcode ( CLIPRECT );
479                if (cur.vdc_type == REAL)
480                   TEXTOUT  " (%.*f,%.*f) (%.*f,%.*f)",
481                            vp, (double)cur.clip_rect.a.x.real,
482                            vp, (double)cur.clip_rect.a.y.real,
483                            vp, (double)cur.clip_rect.b.x.real,
484                            vp, (double)cur.clip_rect.b.y.real );
485                else
486                   TEXTOUT  " (%ld,%ld) (%ld,%ld)",
487                        cur.clip_rect.a.x.intr, cur.clip_rect.a.y.intr,
488                        cur.clip_rect.b.x.intr, cur.clip_rect.b.y.intr );
489                break;
490
491             case CLIP:       /* Clip Indicator  */
492                MOTprcode ( CLIP );
493                MOTenum ("off/on", cur.clip_ind);
494                break;
495
496             default:
497                (void) sprintf( mess, "(code: 0x%x)", c);
498                break;
499          }
500          break;
501
502       case 0x34:  /* Circles and Ellipses  */
503          switch(c)
504          {
505             case CIRCLE:       /* Circle      */
506                MOTprcode ( CIRCLE );
507                MOTpoints ((Long)1, pi, pr, ZERO);
508                MOTvdc ((Int)1, pi+2, pr+2 );
509                break;
510
511             case ARC3PT:       /* Circular Arc  3 point */
512                MOTprcode ( ARC3PT );
513                MOTpoints ((Long)3, pi, pr, ZERO);
514                break;
515
516             case ARC3PTCLOSE:       /* Circular Arc  3 point close */
517                MOTprcode ( ARC3PTCLOSE );
518                MOTpoints ((Long)3, pi, pr, ZERO);
519                MOTenum ("pie/chord", (Enum) *(pi+6) );
520                break;
521
522             case ARCCTR:       /* Circle Arc centre */
523                MOTprcode ( ARCCTR );
524                MOTpoints ((Long)3, pi, pr, ZERO);
525                MOTvdc ((Int)1, pi+6, pr+6);
526                break;
527
528             case ARCCTRCLOSE:       /* Circle Arc centre close */
529                MOTprcode ( ARCCTRCLOSE );
530                MOTpoints ((Long)3, pi, pr, ZERO);
531                MOTvdc((Int)1, pi+6, pr+6);
532                MOTenum ("pie/chord", (Enum) *(pi+7) );
533                break;
534
535             case ELLIPSE:       /* Ellipse    */
536                MOTprcode ( ELLIPSE );
537                MOTpoints ((Long)3, pi, pr, ZERO);
538                break;
539
540             case ELLIPARC:       /* Elliptical Arc */
541                MOTprcode ( ELLIPARC );
542                MOTpoints ((Long)5, pi, pr, ZERO);
543                break;
544
545             case ELLIPARCCLOSE:       /* Elliptical Arc close*/
546                MOTprcode ( ELLIPARCCLOSE );
547                MOTpoints ((Long)5, pi, pr, ZERO);
548                MOTenum ("pie/chord", (Enum) *(pi+10) );
549                break;
550
551             default:
552                (void) sprintf( mess, "(code: 0x%x)", c);
553                break;
554          }
555          break;
556
557       case 0x35:  /* Attributes  */
558          switch(c)
559          {
560             case LINEINDEX:       /*  Line Bundle index  */
561                MOTprcode ( LINEINDEX );
562                TEXTOUT " %ld", curatt.line_ind);
563                break;
564
565             case LINETYPE:       /*  Line Type   */
566                MOTprcode ( LINETYPE );
567                TEXTOUT " %ld", curatt.line_type);
568                break;
569
570             case LINEWIDTH:       /*  Line Width */
571                MOTprcode ( LINEWIDTH );
572                if (cur.linewidth_mode == SCALED || cur.vdc_type == REAL)
573                      TEXTOUT  " %.*f", rp, (double)curatt.line_width.real);
574                else
575                      TEXTOUT  " %ld", curatt.line_width.intr);
576                break;
577
578             case LINECOLR:       /*  Line Colour  */
579                MOTprcode ( LINECOLR );
580                MOTcol(&curatt.line, cur.color_mode);
581                break;
582
583             case MARKERINDEX:       /*  Marker Bundle index  */
584                MOTprcode ( MARKERINDEX );
585                TEXTOUT " %ld", curatt.mark_ind);
586                break;
587
588             case MARKERTYPE:       /*  Marker Type   */
589                MOTprcode ( MARKERTYPE );
590                TEXTOUT " %ld", curatt.mark_type);
591                break;
592
593             case MARKERSIZE:       /*  Marker Size */
594                MOTprcode ( MARKERSIZE );
595                if (cur.markersize_mode == SCALED || cur.vdc_type == REAL)
596                      TEXTOUT  " %.*f", rp, (double)curatt.mark_size.real);
597                else
598                      TEXTOUT  " %ld", curatt.mark_size.intr);
599                break;
600
601             case MARKERCOLR:       /*  Marker Colour  */
602                MOTprcode ( MARKERCOLR );
603                MOTcol(&curatt.marker, cur.color_mode);
604                break;
605
606             case TEXTINDEX:       /*  Text Bundle index  */
607                MOTprcode ( TEXTINDEX );
608                TEXTOUT " %ld", curatt.text_ind);
609                break;
610
611             case TEXTFONTINDEX:       /*  Text Font Index  */
612                MOTprcode ( TEXTFONTINDEX );
613                TEXTOUT " %ld", curatt.text_font);
614                break;
615
616             case TEXTPREC:       /*  Text Precision   */
617                MOTprcode ( TEXTPREC );
618                MOTenum ("string/char/stroke", curatt.text_prec);
619                break;
620
621             case CHAREXPAN:       /*  Character Expansion Factor  */
622                MOTprcode ( CHAREXPAN );
623                TEXTOUT " %.*f", rp, (double)curatt.char_exp);
624                break;
625
626             case CHARSPACE:       /*  Character Spacing  */
627                MOTprcode ( CHARSPACE );
628                TEXTOUT " %.*f", rp, (double)curatt.char_space);
629                break;
630
631             case TEXTCOLR:       /*  Text Colour   */
632                MOTprcode ( TEXTCOLR );
633                MOTcol(&curatt.text, cur.color_mode);
634                break;
635
636             case CHARHEIGHT:       /*  Character Height   */
637                MOTprcode ( CHARHEIGHT );
638                if ( cur.vdc_type == REAL)
639                      TEXTOUT  " %.*f", vp, (double)curatt.char_height.real);
640                else
641                      TEXTOUT  " %ld", curatt.char_height.intr);
642                break;
643
644             case CHARORI:       /*  Character Orientation */
645                MOTprcode ( CHARORI );
646                if (cur.vdc_type == REAL)
647                   TEXTOUT " %.*f %.*f, %.*f %.*f",
648                           vp, (double)curatt.char_up.x.real,
649                           vp, (double)curatt.char_up.y.real,
650                           vp, (double)curatt.char_base.x.real,
651                           vp, (double)curatt.char_base.y.real );
652                else
653                   TEXTOUT " %ld %ld, %ld %ld",
654                           curatt.char_up.x.intr,
655                           curatt.char_up.y.intr,
656                           curatt.char_base.x.intr,
657                           curatt.char_base.y.intr );
658                break;
659
660             case TEXTPATH:       /*  Text Path */
661                MOTprcode ( TEXTPATH );
662                MOTenum ("right/left/up/down", curatt.text_path);
663                break;
664
665             case TEXTALIGN:       /*  Text Alignment */
666                MOTprcode ( TEXTALIGN );
667                MOTenum ("normhoriz/left/ctr/right/conthoriz",
668                                                 curatt.text_halign);
669                TEXTOUT ", ");
670                MOTenum ("normvert/top/cap/half/base/bottom/contvert",
671                                                 curatt.text_valign);
672                TEXTOUT ",  %.*f, %.*f", rp, (double)curatt.text_hcont,
673                                         rp, (double)curatt.text_vcont );
674                break;
675
676             case CHARSETINDEX:       /*  Character Set Index */
677                MOTprcode ( CHARSETINDEX );
678                TEXTOUT " %ld", curatt.char_set);
679                break;
680
681             case ALTCHARSETINDEX:   /*  Alternative Character Set Index */
682                MOTprcode ( ALTCHARSETINDEX );
683                TEXTOUT " %ld", curatt.altchar_set);
684                break;
685
686             default:
687                (void) sprintf( mess, "(code: 0x%x)", c);
688                break;
689          }
690          break;
691
692       case 0x36:  /* More Attributes  */
693          switch(c)
694          {
695             case FILLINDEX:       /*  Fill Bundle index  */
696                MOTprcode ( FILLINDEX );
697                TEXTOUT " %ld", curatt.fill_ind);
698                break;
699
700             case INTSTYLE:       /*  Interior Style  */
701                MOTprcode ( INTSTYLE );
702                MOTenum ("hollow/solid/pat/hatch/empty",curatt.int_style);
703                break;
704
705             case FILLCOLR:       /*  Fill Colour */
706                MOTprcode ( FILLCOLR );
707                MOTcol(&curatt.fill, cur.color_mode);
708                break;
709
710             case HATCHINDEX:       /*  Hatch Index  */
711                MOTprcode ( HATCHINDEX );
712                TEXTOUT " %ld", curatt.hatch_ind);
713                break;
714
715             case PATINDEX:       /*  Pattern Index  */
716                MOTprcode ( PATINDEX );
717                TEXTOUT " %ld", curatt.pat_ind);
718                break;
719
720             case EDGEINDEX:       /*  Edge Bundle index  */
721                MOTprcode ( EDGEINDEX );
722                TEXTOUT " %ld", curatt.edge_ind);
723                break;
724
725             case EDGETYPE:       /*  Edge Type  */
726                MOTprcode ( EDGETYPE );
727                TEXTOUT " %ld", curatt.edge_type);
728                break;
729
730             case EDGEWIDTH:       /*  Edge Width */
731                MOTprcode ( EDGEWIDTH );
732                if (cur.edgewidth_mode == SCALED || cur.vdc_type == REAL)
733                      TEXTOUT  " %.*f", rp, (double)curatt.edge_width.real);
734                else
735                      TEXTOUT  " %ld", curatt.edge_width.intr);
736                break;
737
738             case EDGECOLR:       /*  Edge Colour  */
739                MOTprcode ( EDGECOLR );
740                MOTcol(&curatt.edge, cur.color_mode);
741                break;
742
743             case EDGEVIS:       /*  Edge Visibility  */
744                MOTprcode ( EDGEVIS );
745                MOTenum ("off/on",curatt.edge_vis);
746                break;
747
748             case FILLREFPT:       /*  Fill Reference Point  */
749                MOTprcode ( FILLREFPT );
750                if (cur.vdc_type == REAL)
751                   TEXTOUT  " (%.*f,%.*f)", vp, (double)curatt.fill_ref.x.real,
752                                            vp, (double)curatt.fill_ref.y.real );
753                else
754                   TEXTOUT  " (%ld,%ld)", curatt.fill_ref.x.intr,
755                                        curatt.fill_ref.y.intr );
756                break;
757
758             case PATTABLE:       /*  Pattern Table  */
759                if ( first )
760                {
761                   MOTprcode ( PATTABLE );
762                   TEXTOUT "  %ld,", *pi++);
763                   nx = *pi++;
764                   ny = *pi++;
765                   loc_prec = *pi++;
766                   TEXTOUT " %ld, %ld, %ld\n",
767                              nx, ny, (1L<<(loc_prec-1)) -1);
768                }
769                first = (num >= ZERO );
770                if (num < ZERO ) num = -num;
771                prec = (unsigned long) (loc_prec * LOG2 + 1);
772                if ( prec < 2 ) prec = 2;
773                if ( cur.color_mode == INDEXED ) k = 80 / (prec+1);
774                else                             k = 80 / (3*prec+5);
775                if ( k > nx ) k = nx;
776                n = nx; i = k;
777
778                for (j = ZERO; j < num; j++ )
779                {
780                   if ( j )
781                   {
782                      if ( j == k || j == n )
783                      {
784                           TEXTOUT ",\n");
785                           k += i;
786                           if ( j == n )
787                           {
788                              n += nx; k = j + i;
789                           }
790                      }
791                      else TEXTOUT ", ");
792                   }
793                   if ( cur.color_mode == INDEXED )
794                      TEXTOUT "%*ld", (int)prec, *pi++);
795                   else
796                   {
797                      TEXTOUT "%*ld %*ld %*ld",
798                      (int)prec, *pi, (int)prec, *(pi+1), (int)prec, *(pi+2));
799                      pi += 3;
800                   }
801                }
802                break;
803
804             case PATSIZE:       /*  Pattern Size  */
805                MOTprcode ( PATSIZE );
806                if (cur.vdc_type == REAL)
807                   TEXTOUT  " %.*f %.*f, %.*f %.*f",
808                           vp, (double)curatt.pat_size.a.x.real,
809                           vp, (double)curatt.pat_size.a.y.real,
810                           vp, (double)curatt.pat_size.b.x.real,
811                           vp, (double)curatt.pat_size.b.y.real );
812                else
813                   TEXTOUT  " %ld %ld, %ld %ld",
814                           curatt.pat_size.a.x.intr,
815                           curatt.pat_size.a.y.intr,
816                           curatt.pat_size.b.x.intr,
817                           curatt.pat_size.b.y.intr );
818                break;
819
820             case COLRTABLE:       /*  Colour Table  */
821                MOTprcode ( COLRTABLE );
822                TEXTOUT " %ld ", *pi++);
823                for (j = ZERO; j < num ; j++ )
824                {
825                   if (j) TEXTOUT ",\n%*s", indent+12," ");
826                   TEXTOUT " %ld %ld %ld", *pi, *(pi+1), *(pi+2));
827                   pi += 3;
828                }
829                break;
830
831             case ASF:       /*  Aspect source flags  */
832                MOTprcode ( ASF );
833                for (n = ZERO ; n < num ; n ++ )
834                {
835                   if ( n ) TEXTOUT ",\n%*s", indent+3, " ");
836                   if ( *pi < ASFS )
837                      MOTenum ("linetype/linewidth/linecolr/markertype/markersize/markercolr/textfontindex/textprec/charexp/charspace/textcolr/intstyle/fillcolr/hatchindex/patindex/edgetype/edgewidth/edgecolr", (Enum) *pi++);
838 /*  charexp should be changed to charexpan */
839                   else
840                     MOTenum ("alledge/allfill/alltext/allmarker/allline/all",
841                                (Enum) (*(pi++) - 506) );
842                   MOTenum ("indiv/bundled", (Enum) *pi++);
843                }
844                break;
845
846             default:
847                (void) sprintf( mess, "(code: 0x%x)", c);
848                break;
849            }
850            break;
851
852         case 0x37:  /* Escape And External Elements  */
853           switch (c)
854           {
855             case ESCAPE:         /*  Escape  */
856                MOTprcode ( ESCAPE );
857                TEXTOUT " %ld ", num);
858                MOTstring ( str );
859                break;
860
861             case MESSAGE:         /*  Message  */
862                MOTprcode ( MESSAGE );
863                MOTenum ("noaction /action ", (Enum) num);
864                MOTstring ( str );
865                break;
866
867             case APPLDATA:         /*  Application Data  */
868                MOTprcode ( APPLDATA );
869                TEXTOUT " %ld ", num);
870                MOTstring ( str );
871                break;
872
873             default:
874                (void) sprintf( mess, "(code: 0x%x)", c);
875                break;
876           }
877           break;
878
879        default:
880           (void) sprintf( mess, "(code: 0x%x)", c);
881           break;
882    }
883    if ( first && c != NONOP ) TEXTOUT ";\n");
884    return;
885 }
886
887 /******************************************************* MOTpoints *****/
888 static void
889 MOTpoints (Long n, Long *pi, float *pr, Enum set)
890 {
891 /*  Output 'n' points starting at pi/pr
892     'set' indicates if this is a POLYGONSET   */
893
894     register Long i, k, no;
895     register int prec;
896
897 /*  Set number of points to print on each line  */
898
899     if (cur.vdc_type == REAL)
900     {
901        prec = vp;
902        no = 80 - 2*(prec + 6*set + 5);
903     }
904     else
905     {
906        prec = (int) (cur.vdcint_bits*LOG2 + 1);
907        no = 80 - 2*(prec + 6*set + 3);
908     }
909
910     n = abs(n);
911     for (i = 0, k = 10 ; i < n ; i++ )
912     {
913        if ( k > no )
914        {
915            TEXTOUT "\n");
916            k = 0;
917        }
918        if (cur.vdc_type == REAL)
919        {
920           k += fprintf(cgmot, " (%.*f,%.*f)", prec, (double)*pr,
921                                              prec, (double)*(pr+1));
922           pr += 2;
923        }
924        else
925        {
926           k += fprintf(cgmot,  " (%ld,%ld)", *pi, *(pi+1) );
927           pi += 2;
928        }
929        if (set)
930        {
931           MOTenum("invis/vis/closeinvis/closevis", (Enum) *pi++ );
932           k += 10;
933        }
934     }
935     return;
936 }
937
938 /******************************************************* MOTvdc ********/
939 static void
940 MOTvdc (int n, Long *pi, Float *pr)
941 {
942 /*  Output 'n' VDCs strating at pi/pr  */
943
944     register Long j, k, no;
945     register Prec prec;
946
947     if (cur.vdc_type == REAL)
948     {
949        prec = vp;
950        no = 80 / (prec + 5);
951     }
952     else
953     {
954        prec = (long) (cur.vdcint_bits*LOG2 + 1);
955        no = 80 / (prec + 3);
956     }
957
958     for ( j = 0, k = no ; j < n ; j++ )
959     {
960        if (cur.vdc_type == REAL)
961           TEXTOUT " %.*f ", (int)prec, (double)*pr++ );
962        else
963           TEXTOUT " %ld ", *pi++ );
964        if ( !k-- )
965        {
966           TEXTOUT "\n");
967           k = no;
968        }
969     }
970     return;
971 }
972
973 /******************************************************* MOTcol ********/
974 static void
975 MOTcol (struct colour *c, Enum type)
976 {
977 /*  Output colour 'c' depending on Color_mode 'type'  */
978
979     if (type == DIRECT)
980        TEXTOUT " %ld %ld %ld",  c->red, c->green, c->blue);
981     else
982        TEXTOUT " %ld", c->index);
983
984     return;
985 }
986
987 /******************************************************* MOTstring *****/
988 static void
989 MOTstring( char *s )
990 {
991 /*  Output text string 's'
992     if ' then output ''   */
993
994    register Long i;
995
996    TEXTOUT  " '");
997    for ( i = ZERO; i < (int)strlen(s); i++ )
998    {
999       TEXTOUT  "%c", s[i] );
1000       if ( s[i] == '\'' ) TEXTOUT "'");
1001    }
1002    TEXTOUT  "'");
1003    return;
1004 }
1005
1006 /******************************************************* MOTenum *******/
1007 static void
1008 MOTenum ( char *s, Enum k )
1009 {
1010 /*   Output enumerated type 'k' using string 's'
1011      enumerated values are seperated by '/'    */
1012
1013    register Long i = ZERO, j = ZERO, n = k;
1014
1015    char s1[16];
1016
1017 /*   Find nth '/'   */
1018
1019    while ( n-- )
1020    {
1021       while ( s[i++] != '/' )
1022       {
1023          if ( ! s[i] )  /*  end of string found  */
1024          {
1025             (void) sprintf( mess, "(type: %d)", k);
1026             i = 0;    /* defaults to first value */
1027             n = 0;    /* exit loop */
1028          }
1029       }
1030    }
1031
1032 /*   Extract string into s1 until next '/' or end of string  */
1033
1034    while ( (s[i] != '/') && s[i] ) s1[j++] = s[i++];
1035    s1[j] = '\0';
1036
1037 /*   Print enumerated value  */
1038 TEXTOUT " %s", s1);
1039 return;
1040 }
1041
1042 /******************************************************* MOTprcode *****/
1043 static void
1044 MOTprcode ( Code code )
1045 {
1046 /*   Output Metafile element name 'code ' */
1047
1048    register int i, group, index, upcase = FALSE;
1049    static int pos[16] = { 0, 2, 4, 6, 7, 8, 9, 11, 13, 14, 15,
1050                          -1, -1, -1, -1, -1};
1051    char c[16];
1052    group = code & 0xfff0;
1053    index = code & 0x000f;
1054    switch ( group )
1055    {
1056       case LINE:
1057          index = pos[index];
1058          upcase = TRUE;
1059          break;
1060       case CIRCLE:
1061          index += 16;
1062          upcase = TRUE;
1063          break;
1064       case LINEINDEX:
1065          index += 24;
1066          break;
1067       case TEXTINDEX:
1068          index += 32;
1069          break;
1070       case FILLINDEX:
1071          index += 44;
1072          break;
1073       case COLRTABLE:
1074          index += 57;
1075          break;
1076       case VDCINTEGERPREC:
1077          index += 59;
1078          break;
1079       case BEGMF:
1080          index += 65;
1081          upcase = TRUE;
1082          break;
1083       case MFVERSION:
1084          index += 70;
1085          if ( code == BEGMFDEFAULTS || code == ENDMFDEFAULTS ) upcase = TRUE;
1086          break;
1087       case SCALEMODE:
1088          index += 86;
1089          break;
1090       case ESCAPE:
1091          index += 93;
1092          upcase = TRUE;
1093          break;
1094       default:
1095          index = -1;
1096          break;
1097    }
1098
1099    if ( index >= 0 && code == cgmelement[index].code )
1100    {
1101       if ( indent ) TEXTOUT "%*s", indent, " " );
1102
1103       strcpy(c, cgmelement[index].string);
1104
1105       if ( ! upcase )
1106          for ( i = 0; i < (int)strlen(c); i++) c[i] = tolower( c[i] );
1107
1108       TEXTOUT "%s", c );
1109       return;
1110    }
1111
1112    (void) sprintf(mess, "(code: %x)", code);
1113    return;
1114 }