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