0023510: Integration of test grid "vis" into the new testing system
[occt.git] / src / CGM / cgmochar.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 #include "cgmout.h"
22
23 /*  File stream name  */
24
25 extern char cgmroot[];
26 static FILE *cgmoc;
27
28 /*  declare void internal functions  */
29
30 # if (defined __STDC__ && __STDC__) || defined __cplusplus
31 /* use function prototypes, they are requred for ANSI C and C++ compilers */
32 /* Main Output driver */
33 void CGMOchar(FILE *stream, Code c, Long *pi, Float *pr, char *pc);
34  /* Check Attributes */
35 static void MOCchkatt(Code type),
36 /* Conditional output of integer */
37             MOCcint(Code code, Int n, Long *var1, Long *var2),
38 /* Conditional output of Enumerated types */
39             MOCcenum(Code code, int n, Enum *var1, Enum *var2),
40 /* Conditional output of a real */
41             MOCcreal(Code code, Float *var1, Float *var2, Enum  r),
42 /* Conditional output of a colour */
43             MOCccol(Code code, int n, struct colour *var1, struct colour *var2),
44 /* Conditional output of a rectangle */
45             MOCrectc(Code code, struct rect *var1, struct rect *var2),
46 /* Output n VDCs */
47             MOCvdc(int n, Long *pi, Float *pr),
48 /* Output a points list */
49             MOCpoints(Long n, Long *pi, Float *pr, Enum set),
50 /* Output an attribute */
51             MOCattrib(Code code),
52 /* Output a real */
53             MOCreal(Double x, Enum type, Prec *ptlist),
54 /* Output an Integer */
55             MOCinteger(Long intval, Logical present, Logical allowed),
56 /* Output a colour list */
57             MOCcells(register Long n, register Long *pi, Enum mode, Prec prec),
58 /* Output a text string */
59             MOCstring(register char *s),
60 /* Output a direct colour */
61             MOCdircol(Posint r, Posint g, Posint b, Prec prec),
62 /* Check if default colour prec & value are used */
63             MOCcoldef(),
64 /* Output a character to the buffer */
65             MOCout(Code hex);
66 #else
67 void CGMOchar();           /* Main Output driver */
68 static void MOCchkatt(),   /* Check Attributes */
69             MOCcint(),     /* Conditional output of integer */
70             MOCcenum(),    /* Conditional output of Enumerated types */
71             MOCcreal(),    /* Conditional output of a real */
72             MOCccol(),     /* Conditional output of a colour */
73             MOCrectc(),    /* Conditional output of a rectangle */
74             MOCvdc(),      /* Output n VDCs */
75             MOCpoints(),   /* Output a points list */
76             MOCattrib(),   /* Output an attribute */
77             MOCreal(),     /* Output a real */
78             MOCinteger(),  /* Output an Integer */
79             MOCcells(),    /* Output a colour list */
80             MOCstring(),   /* Output a text string */
81             MOCdircol(),   /* Output a direct colour */
82             MOCcoldef(),   /* Check if default colour prec & value are used */
83             MOCout();      /* Output a character to the buffer */
84 #endif
85
86 /*  Local Variables */
87
88 static Long subchars=0;
89 static char charsub[CHARSUBNUM];
90
91 /*static char *func="CGMochar", mess[40];*/
92 static char mess[40];
93
94 /*  Macros to do common comparisons  */
95
96 #define RDIFF(x,y)  ( FABS(x-y) > cur.realmin )
97 #define VDIFF(x,y)  ( FABS(x-y) > cur.vdcmin )
98 #define RADIFF(x)   ( FABS(oldatt.x-curatt.x) > cur.realmin )
99 #define VADIFF(x)   ( FABS(oldatt.x-curatt.x) > cur.vdcmin )
100
101 #define ACINT(x,y)    ( MOCcint(x, (Int)1, &oldatt.y, &curatt.y) )
102 #define ACENUM(x,y)   ( MOCcenum(x, (Int)1, &oldatt.y, &curatt.y) )
103 #define ACREAL(x,y,z) ( MOCcreal(x, &oldatt.y, &curatt.y, z) )
104 #define ACCOL(x,y)    ( MOCccol(x, (Int)1, &oldatt.y, &curatt.y) )
105 #define NEWATTRIB(x)  ( oldatt.x = curatt.x )
106 #define ATTDIFF(x)    ( oldatt.x != curatt.x )
107 #define PUTINT(x)     ( MOCinteger( (Long) x, FALSE, FALSE) )
108 #define PUTREAL(x)  ( MOCreal( (Double)(x), REAL, (Prec *) NULL) )
109 #define PUTVDC(x)   ( MOCreal( (Double)(x), VDC, (Prec *) NULL) )
110
111 /***************************************************** CGMOchar ********/
112
113 void
114 CGMOchar(FILE *stream, Code c, Long *pi, Float *pr, char *pc )
115 {
116
117 /*   Character encoding Output. stream is output channel
118                                 c is MF element code  */
119
120    static Logical first = TRUE, first_pic = TRUE;
121    static Prec loc_prec;
122    static Long pic_num = ZERO;
123    register Long n, j, num;
124    Code major;
125    char pcx[STRING_MAX];
126
127    if ( c == (Code) EOF )
128    {
129    exit(0);
130    }
131
132    cgmoc = stream;
133    major = c>>8;
134    num = *pi++;
135
136    switch (major)
137    {
138       case 0x00:               /* Graphics Primitives  */
139
140          switch (c)
141          {
142             case NONOP:        /* Ignore Non-Op */
143                break;
144
145             case LINE:         /*  Polyline   */
146                if ( first )
147                {
148                   MOCchkatt(LINE);
149                   MOCout(c);
150                }
151                first = ( num >= ZERO );
152                MOCpoints ( num, pi, pr, NOSET);
153                break;
154
155             case DISJTLINE:         /*  Disjoint Polyline  */
156                if ( first )
157                {
158                   MOCchkatt(LINE);
159                   MOCout(c);
160                }
161                first = ( num >= ZERO );
162                MOCpoints ( num, pi, pr, NOSET);
163                break;
164
165             case MARKER:         /*  Polymarker  */
166                if ( first )
167                {
168                   MOCchkatt(MARKER);
169                   MOCout(c);
170                }
171                first = ( num >= ZERO );
172                MOCpoints ( num, pi, pr, NOSET);
173                break;
174
175             case TEXT:         /*  Text   */
176                MOCchkatt(TEXT);
177                MOCout(c);
178                MOCvdc ((Int)2, pi, pr);
179                PUTINT (num);
180                MOCstring (pc);
181                break;
182
183             case RESTRTEXT:         /*  Restricted Text */
184                MOCchkatt(TEXT);
185                MOCout(c);
186                MOCvdc( (Int)4, pi, pr);
187                PUTINT (num);
188                MOCstring (pc);
189                break;
190
191             case APNDTEXT:         /*  Append Text   */
192                MOCchkatt(TEXT);
193                MOCout(c);
194                PUTINT (num);
195                MOCstring (pc);
196                break;
197
198             case POLYGON:         /*  Polygon   */
199                if ( first )
200                {
201                   MOCchkatt(POLYGON);
202                   MOCout(c);
203                }
204                first = ( num >= ZERO );
205                MOCpoints ( num, pi, pr, NOSET);
206                break;
207
208             case POLYGONSET:         /*  Polygon Set  */
209                if ( first )
210                {
211                   MOCchkatt(POLYGON);
212                   MOCout(c);
213                }
214                first = ( num >= ZERO );
215                MOCpoints ( num, pi, pr, SET);
216                break;
217
218             case CELLARRAY:         /*  Cell Array  */
219                if ( first )
220                {
221                   MOCout(c);
222                   MOCvdc( (Int)6, pi, pr);
223                   pi +=6;
224                   PUTINT ( *pi++ );
225                   PUTINT ( *pi++ );
226                   loc_prec = *pi++;
227                   if ( num > 0 )
228                   {
229                      register Long max = ZERO, *ppc = pi;
230
231 /*  if within a buffer then find maximum colour  */
232
233                      n = ( cur.color_mode == INDEXED ? num
234                                                      : 3*num );
235                      for ( j = 0; j < n; j++, ppc++ )
236                                  if ( *ppc > max ) max = *ppc;
237                      for ( loc_prec = 0; max ; max >>= 1, loc_prec++ )
238                      ;
239                   }
240                   PUTINT ( loc_prec);
241                }
242                first = ( num >= ZERO );
243                MOCcells ( num, pi, cur.color_mode, loc_prec);
244                break;
245
246             case GDP:         /*  Generalised Drawing Primitive  */
247                if ( *pi == -1 ) MOCchkatt(LINE);  /* RAL-GKS arc */
248                else             MOCchkatt(POLYGON);
249                MOCout(c);
250                PUTINT ( *pi++ );
251                MOCpoints ( num, pi, pr, ZERO);
252                MOCstring (pc);
253                break;
254
255             case RECT:         /*  Rectangle   */
256                MOCchkatt(POLYGON);
257                MOCout(c);
258                MOCvdc( (Int)4, pi, pr);
259                break;
260
261             default:
262                (void) sprintf(mess,"(code: 0x%x)",c);
263                break;
264          }
265          break;
266
267       case 0x30:  /*  Delimiter Elements  */
268
269          switch (c)
270          {
271
272             case BEGMF:         /*  Begin Metafile   */
273                MOCout (c);
274
275 /*  Character Substitution */
276
277                MOCout ( (Code)0x7e3e);      /* Tilde           0x7e */
278
279                MOCout ( (Code)0x7e40);      /* Null            0x00*/
280
281                MOCout ( (Code)0x7e4a);      /* Line feed       0x0a */
282                MOCout ( (Code)0x7e4d);      /* carriage return 0x0d */
283
284                MOCout (st_term);
285
286 /* now set up substitution list ( without NULL ) */
287                charsub[subchars++] = 0x7e;
288                charsub[subchars++] = 0x0a;
289                charsub[subchars++] = 0x0d;
290
291                curchar = chardef;
292
293 /*  Set old values to current defaults */
294
295                old = cur;
296                oldchar = curchar;
297                oldatt = curatt;
298                strcpy(pcx, pc);
299                if ( strcmp (pcx, "") == 0 )
300                   strcpy(pcx,"Generated with CGM DRIVER");
301                MOCstring (pcx);
302                break;
303
304             case ENDMF:         /*  End Metafile   */
305                MOCout (c);
306                MOCout( (Code)0 );   /* Starts a new record  */
307                break;
308
309             case BEGPIC:          /*  Begin Picture Descriptor   */
310                if ( first_pic )
311                {
312                   MOCcoldef ();
313                   mfchar = curchar;
314                }
315                else
316                   curchar = mfchar; /*  set current character defaults */
317
318                first_pic = FALSE;
319                old = cur;    /*  reset old settings to MF defaults  */
320                oldchar = curchar;
321                oldatt = curatt;
322
323                MOCout( (Code)0 );   /*  Start on new record  */
324                MOCout (c);
325
326                if ( strcmp(pc, "\0") )  MOCstring (pc);
327                else
328                {
329                    sprintf(pcx, "Picture %ld", pic_num++);
330                    MOCstring (pcx);
331                }
332                break;
333
334             case BEGPICBODY:         /*  Begin Picture Body  */
335                MOCout (c);
336                break;
337
338             case ENDPIC:         /*  End  Picture    */
339                MOCout (c);
340                break;
341
342             default:
343                (void) sprintf(mess,"(code 0x%x)",c);
344                break;
345          }
346          break;
347
348
349       case 0x31:  /* Metafile Descriptor Elements  */
350          switch (c)
351          {
352             case MFVERSION:         /*  Metafile version   */
353                MOCout(c);
354                PUTINT (num);
355                break;
356
357             case MFDESC:         /*  Metafile Description  */
358                MOCout(c);
359                
360                   MOCstring ( pc );
361                
362                break;
363
364             case VDCTYPE:         /*  VDC Type   */
365                MOCcenum (c, (Int)1, &old.vdc_type, &cur.vdc_type);
366                break;
367
368             case INTEGERPREC:         /*  Integer Precision  */
369                curchar.int_prec = cur.int_bits;
370                MOCcint (c, (Int)1, &oldchar.int_prec, &curchar.int_prec);
371                break;
372
373             case REALPREC:         /*  Real Precision   */
374                curchar.real.prec = cur.real_bits;
375                curchar.real.min = cur.real_places;
376                curchar.real.defexp = cur.real_defexp;
377                if ( curchar.real.defexp > curchar.real.min )
378                   curchar.real.defexp = curchar.real.min;
379                curchar.real.expald = cur.real_expald;
380
381                MOCcint (c, (Int)4, &oldchar.real.prec, &curchar.real.prec);
382                break;
383
384             case INDEXPREC:         /*  Index Precision   */
385                curchar.index_prec = cur.index_bits;
386                MOCcint(c, (Int)1, &oldchar.index_prec, &curchar.index_prec);
387                break;
388
389             case COLRPREC:         /*  Colour Precision  */
390                curchar.col_prec = cur.col_bits;
391                MOCcint(c, (Int)1, &oldchar.col_prec, &curchar.col_prec);
392                break;
393
394             case COLRINDEXPREC:         /*  Colour Index Precision  */
395                curchar.colind_prec = cur.colind_bits;
396                MOCcint(c, (Int)1, &oldchar.colind_prec, &curchar.colind_prec);
397                break;
398
399             case MAXCOLRINDEX:         /*  Maximum Colour Index  */
400                MOCcint(c, (Int)1, &old.max_colind, &cur.max_colind);
401                break;
402
403             case COLRVALUEEXT:         /*  Colour value extent  */
404                MOCcint(COLRPREC, (Int)1, &curchar.col_prec, &cur.col_bits);
405                curchar.min_rgb = cur.min_rgb;
406                curchar.max_rgb = cur.max_rgb;
407                MOCccol ( c, (Int)2, &oldchar.min_rgb, &curchar.min_rgb);
408                break;
409
410             case MFELEMLIST:         /*  Metafile element List  */
411                MOCout(c);
412                MOCout(st_start);
413                for (j = ZERO; j < num ; j++, pi++ )
414                {
415                   switch ( (Int) *pi )
416                   {
417                      case 0:
418                      case 1:
419                         PUTINT ( *pi );
420                         break;
421
422                      default:
423                         MOCout( (Code) *pi );
424                         if ( *pi == BEGMFDEFAULTS )
425                                     MOCout ( ENDMFDEFAULTS );
426                         break;
427                   }
428                }
429                MOCout(st_term);
430                break;
431
432             case BEGMFDEFAULTS: /* Begin Metafile defaults Replacement*/
433                MOCcoldef ();
434
435             case ENDMFDEFAULTS: /* End Metafile defaults Replacement */
436                MOCout(c);
437                break;
438
439             case FONTLIST:         /*  Font List   */
440                MOCout(c);
441                for (j = ZERO ; j < num ; )
442                {
443                   MOCstring ( &pc[j] );
444                   j = *pi++;
445                }
446                break;
447
448             case CHARSETLIST:         /*  Character set list  */
449                MOCout(c);
450                for ( j = ZERO; j < num ; )
451                {
452                   Int b1, b2;
453                   char c1, chr[2];
454
455                   PUTINT ( *pi++ );
456                   sscanf( &pc[j], "%1d%c%d", &b1, &c1, &b2);
457                   sprintf( chr, "%c", (b1<<4) + b2);
458
459                   MOCstring ( chr );
460                   j = *pi++;
461                }
462                break;
463
464             case CHARCODING:         /*  Character coding Announcer  */
465                MOCout(c);
466                PUTINT (num);
467                break;
468
469             default:
470                (void) sprintf(mess,"(code: 0x%x)",c);
471                break;
472          }
473          break;
474
475       case 0x32:  /* Picture Descriptor Elements  */
476          switch (c)
477          {
478             case SCALEMODE:         /*  Scaling Mode   */
479                if (old.scale_mode != cur.scale_mode ||
480                    RDIFF(old.scale_factor, cur.scale_factor) )
481                {
482                   MOCout(c);
483                   old.scale_mode = cur.scale_mode;
484                   old.scale_factor = cur.scale_factor;
485                   PUTINT ( cur.scale_mode );
486                   PUTREAL ( cur.scale_factor );
487                }
488                break;
489
490             case COLRMODE:         /*  Colour Selection Mode */
491                MOCcenum(c, (Int)1, &old.color_mode, &cur.color_mode);
492                break;
493
494             case LINEWIDTHMODE:    /*  Line width Specification  */
495                MOCcenum(c, (Int)1, &old.linewidth_mode, &cur.linewidth_mode);
496                break;
497
498             case MARKERSIZEMODE:   /*  Marker size Specification  */
499                MOCcenum(c, (Int)1, &old.markersize_mode, &cur.markersize_mode);
500                break;
501
502             case EDGEWIDTHMODE:     /*  Edge width Specification  */
503                MOCcenum(c, (Int)1, &old.edgewidth_mode, &cur.edgewidth_mode);
504                break;
505
506             case VDCEXT:         /*  VDC Extent    */
507                MOCrectc(c, &old.vdc_extent, &cur.vdc_extent);
508                break;
509
510             case BACKCOLR:         /*  Background Colour  */
511                MOCout ( c );
512                MOCdircol ( cur.back.red, cur.back.green, cur.back.blue,
513                            curchar.col_prec);
514                break;
515
516             default:
517                (void) sprintf(mess,"(code: 0x%x)",c);
518          }
519          break;
520
521       case 0x33:  /* Control Elements  */
522          switch(c)
523          {
524             case VDCINTEGERPREC:       /* VDC Integer Precision  */
525                MOCcint(c, (Int)1, &oldchar.vdcint_prec, &curchar.vdcint_prec);
526                break;
527
528             case VDCREALPREC:       /* VDC Real Precision  */
529                curchar.vdc.prec = cur.vdc_bits;
530                curchar.vdc.min  = cur.vdc_places;
531                curchar.vdc.defexp = cur.vdc_defexp;
532                if ( curchar.vdc.defexp > curchar.vdc.min )
533                   curchar.vdc.defexp = curchar.vdc.min;
534                curchar.vdc.expald = cur.vdc_expald;
535                MOCcint(c, (Int)4, &oldchar.vdc.prec, &curchar.vdc.prec);
536                break;
537
538             case AUXCOLR:       /* Auxiliary Colour  */
539                if (cur.color_mode == DIRECT)
540                {
541                   MOCccol(c, (Int)1, &old.aux, &cur.aux);
542                }
543                else
544                {
545                   MOCcint(c, (Int)1, &old.aux.index, &cur.aux.index);
546                }
547                break;
548
549             case TRANSPARENCY:       /* Transparency  */
550                MOCcenum(c, (Int)1, &old.transparency, &cur.transparency);
551                break;
552
553             case CLIPRECT:       /* Clip Rectangle  */
554                MOCrectc(c, &old.clip_rect, &cur.clip_rect);
555                break;
556
557             case CLIP:       /* Clip Indicator  */
558                MOCcenum(c, (Int)1, &old.clip_ind, &cur.clip_ind);
559                break;
560
561             default:
562                (void) sprintf(mess,"(code: 0x%x)",c);
563                break;
564          }
565          break;
566
567       case 0x34:  /* Circles and Ellipses  */
568          switch(c)
569          {
570             case CIRCLE:       /* Circle      */
571                MOCchkatt(POLYGON);
572                MOCout(c);
573                MOCvdc( (Int)3, pi, pr);
574                break;
575
576             case ARC3PT:       /* Circular Arc  3 point */
577                MOCchkatt(LINE);
578                MOCout(c);
579                MOCvdc( (Int)6, pi, pr);
580                break;
581
582             case ARC3PTCLOSE:       /* Circular Arc  3 point close */
583                MOCchkatt(POLYGON);
584                MOCout(c);
585                MOCvdc( (Int)6, pi, pr);
586                PUTINT (*(pi+6));
587                break;
588
589             case ARCCTR:       /* Circle Arc centre */
590                MOCchkatt(LINE);
591                MOCout(c);
592                MOCvdc( (Int)7, pi, pr);
593                break;
594
595             case ARCCTRCLOSE:       /* Circle Arc centre close */
596                MOCchkatt(POLYGON);
597                MOCout(c);
598                MOCvdc( (Int)7, pi, pr);
599                PUTINT (*(pi+7));
600                break;
601
602             case ELLIPSE:       /* Ellipse    */
603                MOCchkatt(POLYGON);
604                MOCout(c);
605                MOCvdc( (Int)6, pi, pr);
606                break;
607
608             case ELLIPARC:       /* Elliptical Arc */
609                MOCchkatt(LINE);
610                MOCout(c);
611                MOCvdc( (Int)10, pi, pr);
612                break;
613
614             case ELLIPARCCLOSE:       /* Elliptical Arc close*/
615                MOCchkatt(POLYGON);
616                MOCout(c);
617                MOCvdc( (Int)10, pi, pr);
618                PUTINT (*(pi+10));
619                break;
620
621             default:
622                (void) sprintf(mess,"(code: 0x%x)",c);
623                break;
624          }
625          break;
626
627       case 0x35:  /* Attributes  */
628
629          switch(c)
630          {
631             case LINEINDEX:       /*  Line Bundle index  */
632                att.line_index = TRUE;
633                break;
634
635             case LINETYPE:       /*  Line Type   */
636                att.line_type = TRUE;
637                break;
638
639             case LINEWIDTH:       /*  Line Width */
640                att.line_width = TRUE;
641                break;
642
643             case LINECOLR:       /*  Line Colour  */
644                att.line_color = TRUE;
645                break;
646
647             case MARKERINDEX:       /*  Marker Bundle index  */
648                att.mark_index = TRUE;
649                break;
650
651             case MARKERTYPE:       /*  Marker Type   */
652                att.mark_type = TRUE;
653                break;
654
655             case MARKERSIZE:       /*  Marker Size */
656                att.mark_size = TRUE;
657                break;
658
659             case MARKERCOLR:       /*  Marker Colour  */
660                att.mark_color = TRUE;
661                break;
662
663             case TEXTINDEX:       /*  Text Bundle index  */
664                att.text_index = TRUE;
665                break;
666
667             case TEXTFONTINDEX:       /*  Text Font Index  */
668                att.text_font = TRUE;
669                break;
670
671             case TEXTPREC:       /*  Text Precision   */
672                att.text_prec = TRUE;
673                break;
674
675             case CHAREXPAN:       /*  Character Expansion Factor  */
676                att.char_expan = TRUE;
677                break;
678
679             case CHARSPACE:       /*  Character Spacing  */
680                att.char_space = TRUE;
681                break;
682
683             case TEXTCOLR:       /*  Text Colour   */
684                att.text_color = TRUE;
685                break;
686
687             case CHARHEIGHT:       /*  Character Height   */
688                att.char_height = TRUE;
689                break;
690
691             case CHARORI:       /*  Character Orientation */
692                att.char_orient = TRUE;
693                break;
694
695             case TEXTPATH:       /*  Text Path */
696                att.text_path = TRUE;
697                break;
698
699             case TEXTALIGN:       /*  Text Alignment */
700                att.text_align = TRUE;
701                break;
702
703             case CHARSETINDEX:      /*  Character Set Index */
704                att.char_set = TRUE;
705                break;
706
707             case ALTCHARSETINDEX:   /*  Alt Character Set Index */
708                att.altchar_set = TRUE;
709                break;
710
711             default:
712                (void) sprintf(mess,"(code: 0x%x)",c);
713                return;
714          }
715          if ( cgmstate == MF_DEFAULTS ) MOCattrib ( c );
716          break;
717
718       case 0x36:  /* More Attributes  */
719          switch(c)
720          {
721             case FILLINDEX:       /*  Fill Bundle index  */
722                att.fill_index = TRUE;
723                break;
724
725             case INTSTYLE:       /*  Interior Style  */
726                att.int_style = TRUE;
727                break;
728
729             case FILLCOLR:       /*  Fill Colour */
730                att.fill_color = TRUE;
731                break;
732
733             case HATCHINDEX:       /*  Hatch Index  */
734                att.hatch_ind = TRUE;
735                break;
736
737             case PATINDEX:       /*  Pattern Index  */
738                att.pat_ind = TRUE;
739                break;
740
741             case EDGEINDEX:       /*  Edge Bundle index  */
742                att.edge_index = TRUE;
743                break;
744
745             case EDGETYPE:       /*  Edge Type  */
746                att.edge_type = TRUE;
747                break;
748
749             case EDGEWIDTH:       /*  Edge Width */
750                att.edge_width = TRUE;
751                break;
752
753             case EDGECOLR:       /*  Edge Colour  */
754                att.edge_color = TRUE;
755                break;
756
757             case EDGEVIS:       /*  Edge Visibility  */
758                att.edge_vis = TRUE;
759                break;
760
761             case FILLREFPT:       /*  Fill Reference Point  */
762                att.fill_ref = TRUE;
763                break;
764
765             case PATSIZE:       /*  Pattern Size  */
766                att.pat_size = TRUE;
767                break;
768
769             case PATTABLE:       /*  Pattern Table  */
770                if ( first )
771                {
772                   register Long max = ZERO;
773                   MOCout(c);
774                   PUTINT ( *pi++ );
775                   PUTINT ( *pi++ );
776                   PUTINT ( *pi++ );
777                   loc_prec = *pi++;
778                   if ( num > 0 )
779                   {
780                      long *ppc=pi;
781 /*  if within a buffer then find maximum colour  */
782
783                      n = ( cur.color_mode == INDEXED ? num
784                                                      : 3*num );
785                      for ( j = 0; j < n; j++, ppc++)
786                         if ( *ppc > max ) max = *ppc;
787                      for ( loc_prec = 0; max ; max >>= 1, loc_prec++ )
788                      ;
789                   }
790                   PUTINT ( loc_prec);
791                }
792                first = ( num >= ZERO );
793                MOCcells ( num, pi, cur.color_mode, loc_prec);
794                return;
795
796             case COLRTABLE:       /*  Colour Table  */
797                if ( first )
798                {
799                   MOCout(c);
800                   PUTINT ( *pi++ );
801                }
802                first = ( num >= ZERO );
803                MOCcells ( num, pi, DIRECT, (Prec) 0);
804                return;
805
806             case ASF:       /*  Aspect source flags  */
807             {
808                short diff = FALSE, type, value, k, l;
809
810 /*  First check if any relevant ASF has changed  */
811
812                for ( n = ZERO; n < ASFS ; n++ )
813                {
814                   if ( curatt.asf[n] != oldatt.asf[n] ) diff++;
815                }
816                if ( diff )
817                {
818
819 /* Output ASFs as they were input - ignoring duplicates */
820
821                   MOCout(c);
822                   for ( n = ZERO; n < num ; n++ )
823                   {
824                      type  = (short) (*pi++);
825                      value = (short) (*pi++);
826                      if ( type < ASFS )
827                      {
828                         if ( value != oldatt.asf[type] )
829                         {
830                            PUTINT ( type );
831                            PUTINT ( value );
832                            oldatt.asf[type] = value;
833                         }
834                      }
835                      else
836                      {
837                         PUTINT ( type );
838                         PUTINT ( value );
839                         switch (type)
840                         {
841                            case 506:   /*  all edge  */
842                               k = 15;
843                               l = 17;
844                               break;
845                            case 507:   /*  all fill  */
846                               k = 11;
847                               l = 14;
848                               break;
849                            case 508:   /*  all text  */
850                               k =  6;
851                               l = 10;
852                               break;
853                            case 509:   /*  all marker */
854                               k =  3;
855                               l =  5;
856                               break;
857                            case 510:   /*  all line */
858                               k =  0;
859                               l =  2;
860                               break;
861                            case 511:   /*  all  */
862                               k =  0;
863                               l = 17;
864                               break;
865                            default:   /*  ignore */
866                               k =  1;
867                               l =  0;
868                               break;
869                         }
870                         for ( ; k <= l; k++) oldatt.asf[k] = value;
871                      }
872                   }
873                }
874                return;
875
876             }
877             default:
878                (void) sprintf(mess,"(code: 0x%x)",c);
879                return;
880          }
881          if ( cgmstate == MF_DEFAULTS ) MOCattrib ( c );
882          break;
883
884       case 0x37:  /* Escape And External Elements  */
885          switch (c)
886          {
887             case ESCAPE:         /*  Escape  */
888                MOCout(c);
889                PUTINT (num);
890                MOCstring (pc);
891                break;
892
893             case MESSAGE:         /*  Message  */
894                MOCout(c);
895                PUTINT (num);
896                MOCstring (pc);
897                break;
898
899             case APPLDATA:         /*  Application Data  */
900                MOCout(c);
901                PUTINT (num);
902                MOCstring (pc);
903                break;
904
905             default:
906                (void) sprintf(mess,"(code: 0x%x)",c);
907                break;
908          }
909          break;
910
911       default:
912         (void) sprintf(mess,"(code: 0x%x)",c);
913         break;
914    }
915
916    return;
917 }
918
919 /****************************************************** MOCchkatt ******/
920 static void
921 MOCchkatt ( Code type )
922 {
923 /*   Check 'type' Attributes and send to Output if changed  */
924
925     Logical bundled, indiv;
926
927     switch (type)
928     {
929         case LINE:
930
931           bundled = (curatt.asf[0] == BUNDLED
932                   || curatt.asf[1] == BUNDLED
933                   || curatt.asf[2] == BUNDLED );
934           indiv = (curatt.asf[0] == INDIVIDUAL
935                 || curatt.asf[1] == INDIVIDUAL
936                 || curatt.asf[2] == INDIVIDUAL );
937
938           if ( bundled && att.line_index)
939           {
940              ACINT(LINEINDEX, line_ind);
941              att.line_index = FALSE;
942           }
943
944           if ( indiv && att.line_type)
945           {
946              ACINT(LINETYPE, line_type);
947              att.line_type = FALSE;
948           }
949
950           if ( indiv && att.line_width )
951           {
952              if (cur.linewidth_mode == SCALED)
953              {
954                 ACREAL(LINEWIDTH, line_width.real, REAL);
955              }
956              else if ( cur.vdc_type == REAL)
957              {
958                 ACREAL(LINEWIDTH, line_width.real, VDC);
959              }
960              else
961              {
962                 ACINT(LINEWIDTH, line_width.intr);
963              }
964              att.line_width = FALSE;
965          }
966
967          if ( indiv && att.line_color )
968          {
969             if (cur.color_mode == DIRECT)
970             {
971                ACCOL (LINECOLR, line );
972             }
973             else
974             {
975                ACINT(LINECOLR, line.index);
976             }
977             att.line_color = FALSE;
978           }
979           break;
980
981         case MARKER:
982
983           bundled = (curatt.asf[3] == BUNDLED
984                   || curatt.asf[4] == BUNDLED
985                   || curatt.asf[5] == BUNDLED );
986           indiv = (curatt.asf[3] == INDIVIDUAL
987                 || curatt.asf[4] == INDIVIDUAL
988                 || curatt.asf[5] == INDIVIDUAL );
989
990           if ( bundled && att.mark_index)
991           {
992              ACINT(MARKERINDEX, mark_ind);
993              att.mark_index = FALSE;
994           }
995
996           if ( indiv && att.mark_type)
997           {
998              ACINT(MARKERTYPE, mark_type);
999              att.mark_type = FALSE;
1000           }
1001
1002           if ( indiv && att.mark_size )
1003           {
1004              if (cur.markersize_mode == SCALED)
1005              {
1006                 ACREAL(MARKERSIZE, mark_size.real, REAL );
1007              }
1008              else if ( cur.vdc_type == REAL)
1009              {
1010                 ACREAL(MARKERSIZE, mark_size.real, VDC );
1011              }
1012              else
1013              {
1014                 ACINT(MARKERSIZE, mark_size.intr );
1015              }
1016              att.mark_size = FALSE;
1017          }
1018
1019          if ( indiv && att.mark_color )
1020          {
1021             if (cur.color_mode == DIRECT)
1022             {
1023                ACCOL (MARKERCOLR, marker );
1024             }
1025             else
1026             {
1027                ACINT(MARKERCOLR, marker.index );
1028             }
1029             att.mark_color = FALSE;
1030           }
1031           break;
1032
1033         case TEXT:
1034
1035           bundled = (curatt.asf[6] == BUNDLED
1036                   || curatt.asf[7] == BUNDLED
1037                   || curatt.asf[8] == BUNDLED
1038                   || curatt.asf[9] == BUNDLED
1039                   || curatt.asf[10] == BUNDLED );
1040           indiv = (curatt.asf[6] == INDIVIDUAL
1041                 || curatt.asf[7] == INDIVIDUAL
1042                 || curatt.asf[8] == INDIVIDUAL
1043                 || curatt.asf[9] == INDIVIDUAL
1044                 || curatt.asf[10] == INDIVIDUAL );
1045
1046           if ( bundled && att.text_index)
1047           {
1048              ACINT(TEXTINDEX, text_ind);
1049              att.text_index = FALSE;
1050           }
1051
1052           if ( indiv && att.text_font)
1053           {
1054              ACINT(TEXTFONTINDEX, text_font);
1055              att.text_font = FALSE;
1056           }
1057
1058           if ( indiv && att.text_prec)
1059           {
1060              ACENUM(TEXTPREC, text_prec);
1061              att.text_prec = FALSE;
1062           }
1063
1064           if ( indiv && att.char_expan)
1065           {
1066              ACREAL(CHAREXPAN, char_exp, REAL );
1067              att.char_expan = FALSE;
1068           }
1069
1070           if ( indiv && att.char_space)
1071           {
1072              ACREAL(CHARSPACE, char_space, REAL );
1073              att.char_space = FALSE;
1074           }
1075
1076           if ( indiv && att.text_color )
1077           {
1078             if (cur.color_mode == DIRECT)
1079             {
1080                ACCOL (TEXTCOLR, text );
1081             }
1082             else
1083             {
1084                ACINT(TEXTCOLR, text.index );
1085             }
1086             att.text_color = FALSE;
1087           }
1088
1089           if ( att.char_height)
1090           {
1091             if (cur.vdc_type == REAL)
1092             {
1093                ACREAL(CHARHEIGHT, char_height.real, VDC );
1094             }
1095             else
1096             {
1097                ACINT(CHARHEIGHT, char_height.intr );
1098             }
1099             att.char_height = FALSE;
1100           }
1101
1102           if ( att.char_orient)
1103           {
1104             if (cur.vdc_type == REAL)
1105             {
1106                if ( VADIFF(char_up.x.real) || VADIFF(char_up.y.real) ||
1107                     VADIFF(char_base.x.real) || VADIFF(char_base.y.real) )
1108                {
1109                   MOCout(CHARORI);
1110                   NEWATTRIB (char_up.x.real);
1111                   NEWATTRIB (char_up.y.real);
1112                   NEWATTRIB (char_base.x.real);
1113                   NEWATTRIB (char_base.y.real);
1114                   PUTVDC (curatt.char_up.x.real);
1115                   PUTVDC (curatt.char_up.y.real);
1116                   PUTVDC (curatt.char_base.x.real);
1117                   PUTVDC (curatt.char_base.y.real);
1118                }
1119             }
1120             else
1121             {
1122                if ( ATTDIFF(char_up.x.intr)
1123                   || ATTDIFF(char_up.y.intr)
1124                   || ATTDIFF(char_base.x.intr)
1125                   || ATTDIFF(char_base.y.intr) )
1126                {
1127                   MOCout(CHARORI);
1128                   NEWATTRIB (char_up.x.intr);
1129                   NEWATTRIB (char_up.y.intr);
1130                   NEWATTRIB (char_base.x.intr);
1131                   NEWATTRIB (char_base.y.intr);
1132                   PUTINT (curatt.char_up.x.intr);
1133                   PUTINT (curatt.char_up.y.intr);
1134                   PUTINT (curatt.char_base.x.intr);
1135                   PUTINT (curatt.char_base.y.intr);
1136                }
1137             }
1138             att.char_orient = FALSE;
1139           }
1140
1141           if ( att.char_set)
1142           {
1143              ACINT(CHARSETINDEX, char_set );
1144              att.char_set = FALSE;
1145           }
1146
1147           if ( att.altchar_set)
1148           {
1149              ACINT(ALTCHARSETINDEX, altchar_set );
1150              att.altchar_set = FALSE;
1151           }
1152
1153           if ( att.text_path )
1154           {
1155              ACENUM(TEXTPATH, text_path );
1156              att.text_path = FALSE;
1157           }
1158
1159           if ( att.text_align )
1160           {
1161              if ( ATTDIFF(text_halign) ||  ATTDIFF(text_valign) ||
1162                   RADIFF(text_hcont) || RADIFF(text_vcont) )
1163              {
1164                 MOCout(TEXTALIGN);
1165                 NEWATTRIB (text_halign);
1166                 NEWATTRIB (text_valign);
1167                 PUTINT ( curatt.text_halign);
1168                 PUTINT ( curatt.text_valign);
1169                 NEWATTRIB (text_hcont);
1170                 NEWATTRIB (text_vcont);
1171                 PUTREAL( curatt.text_hcont );
1172                 PUTREAL( curatt.text_vcont );
1173              }
1174              att.text_align = FALSE;
1175           }
1176           break;
1177
1178         case POLYGON:  /*  Fill and edge attributes  */
1179
1180           bundled = (curatt.asf[11] == BUNDLED
1181                   || curatt.asf[12] == BUNDLED
1182                   || curatt.asf[13] == BUNDLED
1183                   || curatt.asf[14] == BUNDLED );
1184           indiv = (curatt.asf[11] == INDIVIDUAL
1185                 || curatt.asf[12] == INDIVIDUAL
1186                 || curatt.asf[13] == INDIVIDUAL
1187                 || curatt.asf[14] == INDIVIDUAL );
1188
1189          if ( bundled && att.fill_index)
1190          {
1191             ACINT(FILLINDEX, fill_ind);
1192             att.fill_index = FALSE;
1193          }
1194
1195          if ( indiv && att.int_style)
1196          {
1197             ACENUM(INTSTYLE, int_style);
1198             att.int_style = FALSE;
1199          }
1200
1201          if ( indiv && att.hatch_ind )
1202          {
1203             ACINT(HATCHINDEX, hatch_ind);
1204             att.hatch_ind = FALSE;
1205          }
1206
1207          if ( indiv && att.pat_ind )
1208          {
1209             ACINT(PATINDEX, pat_ind);
1210             att.pat_ind = FALSE;
1211          }
1212
1213          if ( indiv && att.fill_color )
1214          {
1215             if (cur.color_mode == DIRECT)
1216             {
1217               ACCOL (FILLCOLR, fill );
1218             }
1219             else
1220             {
1221               ACINT(FILLCOLR, fill.index );
1222             }
1223             att.fill_color = FALSE;
1224          }
1225
1226          if ( att.pat_size)
1227          {
1228            if (cur.vdc_type == REAL)
1229            {
1230               if ( VADIFF(pat_size.a.x.real) || VADIFF(pat_size.a.y.real) ||
1231                    VADIFF(pat_size.b.x.real) || VADIFF(pat_size.b.y.real) )
1232               {
1233                  MOCout(PATSIZE);
1234                  NEWATTRIB (pat_size.a.x.real);
1235                  NEWATTRIB (pat_size.a.y.real);
1236                  NEWATTRIB (pat_size.b.x.real);
1237                  NEWATTRIB (pat_size.b.y.real);
1238                  PUTVDC (curatt.pat_size.a.x.real);
1239                  PUTVDC (curatt.pat_size.a.y.real);
1240                  PUTVDC (curatt.pat_size.b.x.real);
1241                  PUTVDC (curatt.pat_size.b.y.real);
1242               }
1243            }
1244            else
1245            {
1246               if ( ATTDIFF(pat_size.a.x.intr) ||
1247                    ATTDIFF(pat_size.a.y.intr) ||
1248                    ATTDIFF(pat_size.b.x.intr) ||
1249                    ATTDIFF(pat_size.b.y.intr) )
1250               {
1251                  MOCout(PATSIZE);
1252                  NEWATTRIB (pat_size.a.x.intr);
1253                  NEWATTRIB (pat_size.a.y.intr);
1254                  NEWATTRIB (pat_size.b.x.intr);
1255                  NEWATTRIB (pat_size.b.y.intr);
1256                  PUTINT (curatt.pat_size.a.x.intr);
1257                  PUTINT (curatt.pat_size.a.y.intr);
1258                  PUTINT (curatt.pat_size.b.x.intr);
1259                  PUTINT (curatt.pat_size.b.y.intr);
1260               }
1261            }
1262            att.pat_size = FALSE;
1263          }
1264
1265         /*   Edge characteristics   */
1266
1267          bundled = (curatt.asf[15] == BUNDLED
1268                   || curatt.asf[16] == BUNDLED
1269                   || curatt.asf[17] == BUNDLED );
1270          indiv = (curatt.asf[15] == INDIVIDUAL
1271                 || curatt.asf[16] == INDIVIDUAL
1272                 || curatt.asf[17] == INDIVIDUAL );
1273
1274          if ( bundled && att.edge_index)
1275          {
1276             ACINT(EDGEINDEX, edge_ind);
1277             att.edge_index = FALSE;
1278          }
1279
1280          if ( indiv && att.edge_type)
1281          {
1282             ACINT(EDGETYPE, edge_type);
1283             att.edge_type = FALSE;
1284          }
1285
1286          if ( indiv && att.edge_width )
1287          {
1288             if (cur.edgewidth_mode == SCALED)
1289             {
1290                ACREAL(EDGEWIDTH, edge_width.real, REAL );
1291             }
1292             else if ( cur.vdc_type == REAL)
1293             {
1294                ACREAL(EDGEWIDTH, edge_width.real, VDC );
1295             }
1296             else
1297             {
1298                ACINT(EDGEWIDTH, edge_width.intr );
1299             }
1300             att.edge_width = FALSE;
1301          }
1302
1303          if ( indiv && att.edge_color )
1304          {
1305             if (cur.color_mode == DIRECT)
1306             {
1307               ACCOL (EDGECOLR, edge );
1308             }
1309             else
1310             {
1311               ACINT(EDGECOLR, edge.index );
1312             }
1313             att.edge_color = FALSE;
1314          }
1315
1316          if ( att.edge_vis)
1317          {
1318             ACENUM(EDGEVIS, edge_vis);
1319             att.edge_vis = FALSE;
1320          }
1321
1322          break;
1323
1324      default:
1325         (void) sprintf(mess,"(type: 0x%x)", type);
1326         break;
1327    }
1328
1329    return;
1330 }
1331
1332 /****************************************************** MOCattrib ******/
1333 static void
1334 MOCattrib ( Code code )
1335 {
1336 /*  Outputs attribute code 'code'  */
1337
1338    MOCout( code );
1339
1340    switch ( code )
1341    {
1342       case LINEINDEX:       /*  Line Bundle index  */
1343          PUTINT ( curatt.line_ind );
1344          break;
1345
1346       case LINETYPE:       /*  Line Type   */
1347          PUTINT ( curatt.line_type );
1348          break;
1349
1350       case LINEWIDTH:       /*  Line Width */
1351          if ( cur.linewidth_mode == SCALED )
1352             PUTREAL ( curatt.line_width.real );
1353          else if ( cur.vdc_type == REAL )
1354             PUTVDC ( curatt.line_width.real );
1355          else
1356             PUTINT ( curatt.line_width.intr );
1357          break;
1358
1359       case LINECOLR:       /*  Line Colour  */
1360          if ( cur.color_mode == DIRECT )
1361             MOCdircol ( curatt.line.red, curatt.line.green,
1362                         curatt.line.blue, curchar.col_prec );
1363          else
1364             PUTINT ( curatt.line.index );
1365          break;
1366
1367       case MARKERINDEX:       /*  Marker Bundle index  */
1368          PUTINT ( curatt.mark_ind );
1369          break;
1370
1371       case MARKERTYPE:       /*  Marker Type   */
1372          PUTINT ( curatt.mark_type );
1373          break;
1374
1375       case MARKERSIZE:       /*  Marker Size */
1376          if ( cur.markersize_mode == SCALED )
1377             PUTREAL ( curatt.mark_size.real );
1378          else if ( cur.vdc_type == REAL )
1379             PUTVDC ( curatt.mark_size.real );
1380          else
1381             PUTINT ( curatt.mark_size.intr );
1382          break;
1383
1384       case MARKERCOLR:       /*  Marker Colour  */
1385          if ( cur.color_mode == DIRECT )
1386             MOCdircol ( curatt.marker.red, curatt.marker.green,
1387                         curatt.marker.blue, curchar.col_prec );
1388          else
1389             PUTINT ( curatt.marker.index );
1390          break;
1391
1392       case TEXTINDEX:       /*  Text Bundle index  */
1393          PUTINT ( curatt.text_ind );
1394          break;
1395
1396       case TEXTFONTINDEX:       /*  Text Font Index  */
1397          PUTINT ( curatt.text_font );
1398          break;
1399
1400       case TEXTPREC:       /*  Text Precision   */
1401          PUTINT ( curatt.text_prec );
1402          break;
1403
1404       case CHAREXPAN:       /*  Character Expansion Factor  */
1405          PUTREAL ( curatt.char_exp );
1406          break;
1407
1408       case CHARSPACE:       /*  Character Spacing  */
1409          PUTREAL ( curatt.char_space );
1410          break;
1411
1412       case TEXTCOLR:       /*  Text Colour   */
1413          if ( cur.color_mode == DIRECT )
1414             MOCdircol ( curatt.text.red, curatt.text.green,
1415                         curatt.text.blue, curchar.col_prec );
1416          else
1417             PUTINT ( curatt.text.index );
1418          break;
1419
1420       case CHARHEIGHT:       /*  Character Height   */
1421          if ( cur.vdc_type == REAL )
1422             PUTVDC ( curatt.char_height.real );
1423          else
1424             PUTINT ( curatt.char_height.intr );
1425          break;
1426
1427       case CHARORI:       /*  Character Orientation */
1428          if ( cur.vdc_type == REAL )
1429          {
1430             PUTREAL ( curatt.char_up.x.real );
1431             PUTREAL ( curatt.char_up.y.real );
1432             PUTREAL ( curatt.char_base.x.real );
1433             PUTREAL ( curatt.char_base.y.real );
1434          }
1435          else
1436          {
1437             PUTINT ( curatt.char_up.x.intr );
1438             PUTINT ( curatt.char_up.y.intr );
1439             PUTINT ( curatt.char_base.x.intr );
1440             PUTINT ( curatt.char_base.y.intr );
1441          }
1442          break;
1443
1444       case TEXTPATH:       /*  Text Path */
1445          PUTINT ( curatt.text_path );
1446          break;
1447
1448       case TEXTALIGN:       /*  Text Alignment */
1449          PUTINT ( curatt.text_halign );
1450          PUTINT ( curatt.text_valign );
1451          PUTREAL ( curatt.text_hcont );
1452          PUTREAL ( curatt.text_vcont );
1453          break;
1454
1455       case CHARSETINDEX:      /*  Character Set Index */
1456          PUTINT ( curatt.char_set );
1457          break;
1458
1459       case ALTCHARSETINDEX:   /*  Alt Character Set Index */
1460          PUTINT ( curatt.altchar_set );
1461          break;
1462
1463       case FILLINDEX:       /*  Fill Bundle index  */
1464          PUTINT ( curatt.fill_ind );
1465          break;
1466
1467       case INTSTYLE:       /*  Interior Style  */
1468          PUTINT ( curatt.int_style );
1469          break;
1470
1471       case FILLCOLR:       /*  Fill Colour */
1472          if ( cur.color_mode == DIRECT )
1473             MOCdircol ( curatt.fill.red, curatt.fill.green,
1474                         curatt.fill.blue, curchar.col_prec );
1475          else
1476             PUTINT ( curatt.fill.index );
1477          break;
1478
1479       case HATCHINDEX:       /*  Hatch Index  */
1480          PUTINT ( curatt.hatch_ind );
1481          break;
1482
1483       case PATINDEX:       /*  Pattern Index  */
1484          PUTINT ( curatt.pat_ind );
1485          break;
1486
1487       case EDGEINDEX:       /*  Edge Bundle index  */
1488          PUTINT ( curatt.edge_ind );
1489          break;
1490
1491       case EDGETYPE:       /*  Edge Type  */
1492          PUTINT ( curatt.edge_type );
1493          break;
1494
1495       case EDGEWIDTH:       /*  Edge Width */
1496          if ( cur.edgewidth_mode == SCALED )
1497             PUTREAL ( curatt.edge_width.real );
1498          else if ( cur.vdc_type == REAL )
1499             PUTVDC ( curatt.edge_width.real );
1500          else
1501             PUTINT ( curatt.edge_width.intr );
1502          break;
1503
1504       case EDGECOLR:       /*  Edge Colour  */
1505          if ( cur.color_mode == DIRECT )
1506             MOCdircol ( curatt.edge.red, curatt.edge.green,
1507                         curatt.edge.blue, curchar.col_prec );
1508          else
1509             PUTINT ( curatt.edge.index );
1510          break;
1511
1512       case EDGEVIS:       /*  Edge Visibility  */
1513          PUTINT ( curatt.edge_vis );
1514          break;
1515
1516       case FILLREFPT:       /*  Fill Reference Point  */
1517          if ( cur.vdc_type == REAL )
1518          {
1519             PUTVDC ( curatt.fill_ref.x.real );
1520             PUTVDC ( curatt.fill_ref.y.real );
1521          }
1522          else
1523          {
1524             PUTINT ( curatt.fill_ref.x.intr );
1525             PUTINT ( curatt.fill_ref.y.intr );
1526          }
1527          break;
1528
1529       case PATSIZE:       /*  Pattern Size  */
1530          if ( cur.vdc_type == REAL )
1531          {
1532             PUTVDC ( curatt.pat_size.a.x.real );
1533             PUTVDC ( curatt.pat_size.a.y.real );
1534             PUTVDC ( curatt.pat_size.b.x.real );
1535             PUTVDC ( curatt.pat_size.b.y.real );
1536          }
1537          else
1538          {
1539             PUTINT ( curatt.pat_size.a.x.intr );
1540             PUTINT ( curatt.pat_size.a.y.intr );
1541             PUTINT ( curatt.pat_size.b.x.intr );
1542             PUTINT ( curatt.pat_size.b.y.intr );
1543          }
1544          break;
1545
1546       default:
1547          (void) sprintf(mess,"(type: 0x%x)", code);
1548          break;
1549    }
1550
1551    return;
1552 }
1553
1554 /****************************************************** MOCcint ********/
1555 static void
1556 MOCcint ( Code code, Int n, Long *var1, Long *var2)
1557 {
1558 /*  Conditionally outputs 'code' and 'n' integers starting at *var2
1559     only if at least one is different      */
1560
1561     register Long i;
1562     register Logical diff = FALSE;
1563
1564     for (i = ZERO; i < n; i++)
1565        if (var1[i] != var2[i]) diff = TRUE;
1566     if (diff)
1567     {
1568         MOCout(code);
1569         for (i = ZERO ; i < n ; i++)
1570         {
1571            PUTINT ( *var2 );
1572            *var1++ = *var2++;
1573         }
1574     }
1575     return;
1576 }
1577
1578 /****************************************************** MOCcenum *******/
1579 static void
1580 MOCcenum (Code code, int n, Enum *var1, Enum *var2 )
1581 {
1582 /*  Conditionally outputs 'code' and 'n' short integers starting at *var2
1583     only if at least one is different      */
1584
1585     register Long i;
1586     register Logical diff = FALSE;
1587
1588     for (i = ZERO; i < n; i++)
1589        if (var1[i] != var2[i]) diff = TRUE;
1590     if (diff)
1591     {
1592         MOCout(code);
1593         for (i = ZERO ; i < n ; i++)
1594         {
1595            PUTINT ( *var2 );
1596            *var1++ = *var2++;
1597         }
1598     }
1599     return;
1600 }
1601
1602 /****************************************************** MOCcreal *******/
1603 static void
1604 MOCcreal (Code code, Float *var1, Float *var2, Enum  r)
1605 {
1606 /*  Conditionally outputs 'code' and real *var2 if different from *var1
1607     using precision specified by r      */
1608
1609     if ( FABS(*var1-*var2) > (r == REAL ? cur.realmin : cur.vdcmin) )
1610     {
1611         MOCout(code);
1612         MOCreal ((Double)*var2, r, null);
1613         *var1 = *var2;
1614     }
1615     return;
1616 }
1617
1618 /****************************************************** MOCrectc *******/
1619 static void
1620 MOCrectc( Code code, struct rect *var1, struct rect *var2 )
1621 {
1622 /*  Conditionally outputs 'code' and 4 VDCs indicated by *var2
1623     if different from *var1 using vdc precision   */
1624
1625    if (cur.vdc_type == INTEGER)
1626    {
1627       if ( (*var1).a.x.intr != (*var2).a.x.intr ||
1628            (*var1).a.y.intr != (*var2).a.y.intr ||
1629            (*var1).b.x.intr != (*var2).b.x.intr ||
1630            (*var1).b.y.intr != (*var2).b.y.intr  )
1631       {
1632           MOCout(code);
1633           (*var1).a.x.intr = (*var2).a.x.intr;
1634           PUTINT ( (*var1).a.x.intr );
1635           (*var1).a.y.intr = (*var2).a.y.intr;
1636           PUTINT ( (*var1).a.y.intr );
1637           (*var1).b.x.intr = (*var2).b.x.intr;
1638           PUTINT ( (*var1).b.x.intr );
1639           (*var1).b.y.intr = (*var2).b.y.intr;
1640           PUTINT ( (*var1).b.y.intr );
1641       }
1642    }
1643    else
1644    {
1645       if ( VDIFF( (*var1).a.x.real, (*var2).a.x.real ) ||
1646            VDIFF( (*var1).a.y.real, (*var2).a.y.real ) ||
1647            VDIFF( (*var1).b.x.real, (*var2).b.x.real ) ||
1648            VDIFF( (*var1).b.y.real, (*var2).b.y.real ) )
1649       {
1650           MOCout(code);
1651           (*var1).a.x.real = (*var2).a.x.real;
1652           PUTVDC ( (*var2).a.x.real );
1653           (*var1).a.y.real = (*var2).a.y.real;
1654           PUTVDC ( (*var2).a.y.real );
1655           (*var1).b.x.real = (*var2).b.x.real;
1656           PUTVDC ( (*var2).b.x.real );
1657           (*var1).b.y.real = (*var2).b.y.real;
1658           PUTVDC ( (*var2).b.y.real );
1659       }
1660    }
1661    return;
1662 }
1663
1664 /****************************************************** MOCccol ********/
1665 static void
1666 MOCccol (Code code, int n, struct colour *var1, struct colour *var2)
1667 {
1668 /*  Conditional output 'code' and colour indicated by *var2
1669     if different from colour *var1  */
1670
1671     register int i, j;
1672     register Logical diff = FALSE;
1673
1674     for (i = j = ZERO; i < n; i++, j++ )
1675     {
1676        if ( (var1[j].red != var2[j].red) ||
1677             (var1[j].green != var2[j].green) ||
1678             (var1[j].blue != var2[j].blue) ) diff = TRUE;
1679     }
1680
1681     if (diff)
1682     {
1683        MOCout(code);
1684        for (i = j = ZERO; i < n; i++, j++)
1685        {
1686           var1[j].red = var2[j].red;
1687           var1[j].green = var2[j].green;
1688           var1[j].blue = var2[j].blue;
1689           MOCdircol (var1[j].red, var1[j].green, var1[j].blue,
1690                      curchar.col_prec);
1691        }
1692     }
1693     return;
1694 }
1695
1696 /****************************************************** MOCvdc *********/
1697 static void
1698 MOCvdc (int n, Long *pi, Float *pr )
1699 {
1700 /*  Outputs n VDCs starting at pi/pr  */
1701
1702    register Long j;
1703
1704    if (cur.vdc_type == REAL)
1705       for ( j = ZERO; j < n; j++)
1706          PUTVDC( *pr++ );
1707    else
1708       for ( j = ZERO; j < n; j++)
1709          PUTINT ( *pi++ );
1710
1711    return;
1712 }
1713
1714 /****************************************************** MOCpoints ******/
1715 static void
1716 MOCpoints(Long n, Long *pi, Float *pr, Enum set )
1717 {
1718 /*  Outputs n points starting at pi/pr
1719     'set' indicates if this is a Polygon set */
1720
1721    static Logical first = TRUE;
1722    static Long ix, iy;
1723    static Long exp_x, exp_y;
1724    static Float xx, yy;
1725    register Long i;
1726
1727    if ( first )
1728    {
1729       exp_x = exp_y = curchar.vdc.defexp;
1730       xx = yy = 0.0F;
1731       ix = iy = ZERO;
1732    }
1733    if ( n >= ZERO ) first = TRUE;
1734    else
1735    {
1736       first = FALSE;
1737       n = -n;
1738    }
1739
1740    if (cur.vdc_type == REAL)
1741    {
1742       for ( i=0; i < n; i++ )
1743       {
1744         xx += *pr -= xx;
1745         MOCreal ( (Double)*pr++, VDC, &exp_x);
1746         yy += *pr -= yy;
1747         MOCreal ( (Double)*pr++, VDC, &exp_y);
1748         if (set) PUTINT ( *pi++ );
1749       }
1750    }
1751    else
1752    {
1753       for ( i=0; i < n; i++ )
1754       {
1755         ix += *pi -= ix;
1756         PUTINT ( *pi++ );
1757         iy += *pi -= iy;
1758         PUTINT ( *pi++ );
1759         if ( set)  PUTINT ( *pi++ );
1760       }
1761    }
1762    return;
1763 }
1764
1765 /****************************************************** MOCreal ********/
1766 static void
1767 MOCreal ( Double x, Enum type, Prec *ptlist )
1768 {
1769 /*  Outputs real value 'x', using type 'type'
1770     pointlist indicates if this is part of a pointslist  */
1771
1772    register Long def_exp, mantissa, expnt;
1773    register Double y, realmin, prec;
1774    register Logical present = ZERO, expald;
1775
1776    if ( type == REAL )
1777    {
1778       def_exp = curchar.real.defexp;
1779       realmin = (Double) cur.realmin;
1780       prec = (Double) ( (1L<<curchar.real.prec) - 1);
1781       prec = (Double)( curchar.real.prec > 0 ? (1L<<curchar.real.prec) - 1
1782                                           : 1.0/((1L<<-curchar.real.prec)-1) );
1783       expald = ( curchar.real.expald == ALLOWED );
1784    }
1785    else
1786    {
1787       def_exp = curchar.vdc.defexp;
1788       realmin = (Double) cur.vdcmin;
1789       prec = (Double)( curchar.vdc.prec > 0 ? (1L<<curchar.vdc.prec) - 1
1790                                             : 1.0/((1L<<-curchar.vdc.prec)-1) );
1791       expald = ( curchar.vdc.expald == ALLOWED );
1792    }
1793
1794    if (ptlist != NULL) def_exp = *ptlist;
1795
1796    y = (Double) ( x>0 ? x : -x );
1797    expnt = ZERO;
1798
1799    if ( y < realmin )
1800    {
1801       mantissa = ZERO;
1802    }
1803    else
1804    {
1805       if ( expald ) /* if Exponent allowed */
1806       {
1807          while (y >= prec)
1808          {
1809             y /= (Double) 2.0;
1810             expnt++;
1811          }
1812          while (y < prec)
1813          {
1814             y *= (Double) 2.0;
1815             expnt--;
1816          }
1817          mantissa = (long)y;
1818
1819  /*  Strip off trailing zeros   */
1820
1821          while ( mantissa && !(mantissa & 0x01) )
1822          {
1823             mantissa >>= 1;
1824             expnt++;
1825          }
1826          present = (expnt != def_exp);
1827       }
1828       else
1829       {
1830          while (expnt < def_exp)
1831          {
1832             y /= (Double) 2.0;
1833             expnt++;
1834          }
1835          while (expnt > def_exp)
1836          {
1837             y *= (Double) 2.0;
1838             expnt--;
1839          }
1840          mantissa = (long) y;
1841       }
1842
1843       if ( x < 0.0 )  mantissa = -mantissa;
1844    }
1845
1846    MOCinteger ( (Long) mantissa, present, expald);
1847    if (present) PUTINT ( expnt );
1848
1849    if ( mantissa && (ptlist != NULL) ) *ptlist = expnt;
1850
1851    return;
1852 }
1853
1854 /****************************************************** MOCinteger *****/
1855 static void
1856 MOCinteger (Long intval, Logical present, Logical allowed)
1857 {
1858 /*  Output an integer 'intval', 'present' indicates if exponent present
1859     and 'allowed' if allowed */
1860
1861    register Long ival;
1862    register Long i, j;
1863    Code hex[16];
1864
1865    ival = abs(intval);
1866
1867  /*  Strip of bits in 5 bit chunks  */
1868
1869    for (j = -1; ival > ZERO && j < curchar.int_prec; ival >>= 5)
1870               hex[++j] = 0x60 | (ival & 0x1F);
1871
1872  /* if zero or top bit set or Exponent follows and bit set
1873     then add another byte  */
1874
1875    if ( (j < ZERO) | ( hex[j] & (1L<<(4-present)) ) |
1876       ( allowed && (hex[j] & 0x18) ) )     hex[++j] = 0x60;
1877
1878    if (allowed) hex[j] |= present << 3;   /*  set exponent present bit */
1879    hex[j] |= (intval++ < ZERO) << 4;      /*  set sign on first byte  */
1880    hex[0] &= 0x5F;                        /*  set continuation bit off */
1881
1882  /*  Reverse bits to buffer  */
1883    for (i = j; i >= ZERO; i--)  MOCout( hex [i] );
1884
1885    return;
1886 }
1887
1888 /****************************************************** MOCstring ******/
1889 static void
1890 MOCstring (register char *s)
1891 {
1892 /*  Output a text string 'string'
1893     if CMS translate from EBCDIC to ASCII  */
1894
1895    register short c;
1896
1897    MOCout(st_start);
1898
1899    while ( (c = *s++) != '\0')
1900      MOCout (c);
1901
1902    MOCout(st_term);
1903
1904    return;
1905 }
1906
1907 /****************************************************** MOCcells *******/
1908 static void
1909 MOCcells (register Long n, register Long *pi, Enum mode, Prec prec)
1910 {
1911 /*  Output a Colour list of 'n' cells, starting at pi
1912     using local precision 'prec' (if zero use current precision)
1913     and colour mode 'mode'  */
1914
1915    register Long i, j, k, num;
1916    static Logical first = TRUE;
1917    static Long normal_list, bit_stream, run_length, run_bits, colbytes;
1918    Posint red, green, blue, lastred, lastgreen, lastblue;
1919    Logical more;
1920    Long col, last, run, *pi0 = pi;
1921
1922    more = (n < 0);
1923    num = ( more ? -n : n);
1924
1925    if ( first )
1926    {
1927       Long bytes, cols;
1928
1929 /* if Prec = 0 the use Current precision */
1930       if ( !prec ) prec = ( mode == INDEXED ? curchar.colind_prec
1931                                             : curchar.col_prec );
1932       colbytes = ( mode == INDEXED ? (prec+5)/6
1933                                    : (3*prec+5)/6 );
1934
1935       normal_list = bit_stream = ZERO;
1936       run_bits = run_length = ZERO;
1937
1938 /*  Work out shortest method of coding list  */
1939
1940       if ( mode == INDEXED )
1941       {
1942          cols = 1;
1943          for ( i = ZERO, last = *pi, run = 1 ; i < num; )
1944          {
1945 /*  make sure last value forces an end */
1946
1947             col = ( ++i == num ? -1 : *pi++ );
1948
1949             if (col == last) run++;
1950             else
1951             {
1952
1953 /*  Work out bytes for run count  */
1954
1955                for ( j=run, bytes=1; j > 0x0f; bytes++, j>>=5);
1956                run_length += bytes;
1957                run_bits += bytes;
1958
1959 /*  Work out bytes for normal colour value  */
1960
1961                for ( j=last, bytes=1; j > 0x0f; bytes++, j>>=5);
1962                run_length += bytes;
1963                run_bits += colbytes;
1964                normal_list += run*bytes;
1965
1966                run = 1;
1967                last = col;
1968             }
1969          }
1970       }
1971       else  /*  Direct Colour */
1972       {
1973          cols = 3;
1974          lastred = *pi++; lastgreen = *pi++; lastblue = *pi++;
1975          for ( i = ZERO, run = 1 ; i < num ; )
1976          {
1977             red = *pi++ ; green = *pi++ ; blue = *pi++;
1978
1979             if ( ++i != num && red == lastred && green == lastgreen
1980                                           && blue == lastblue )
1981                run++;
1982             else
1983             {
1984                for ( j=run , bytes=1; j > 0x0f; bytes++, j>>=5);
1985                normal_list += run*colbytes;
1986                run_length += bytes + colbytes;
1987                run_bits += colbytes;
1988
1989                run = 1;
1990                lastred = red; lastgreen = green; lastblue = blue;
1991             }
1992          }
1993       }
1994
1995 /* work out list lengths */
1996       bit_stream = (cols * num * prec + 5) / 6;
1997
1998 /*   Work out best coding method   */
1999      if ( mode == INDEXED && run_bits < run_length ) run_length = run_bits;
2000      else run_bits = 0;
2001
2002      if ( run_length < normal_list && run_length < bit_stream )
2003      {
2004          run_length = TRUE;  normal_list = FALSE; bit_stream = FALSE;
2005          i = ( run_bits ? 0x43 : 0x42 );
2006      }
2007      else if ( bit_stream < normal_list)
2008      {
2009          run_length = FALSE;  normal_list = FALSE; bit_stream = TRUE;
2010          i = 0x41;
2011      }
2012      else
2013      {
2014          run_length = FALSE;  normal_list = TRUE; bit_stream = FALSE;
2015          i = 0x40;
2016      }
2017    }
2018
2019 /*  Reset continuation marker */
2020
2021    if ( first ) MOCout( (Code) i);
2022    first = ( n >= ZERO );
2023    pi = pi0;
2024
2025 /*   Now send points to Metafile  */
2026
2027    if ( run_length )
2028    {
2029      if ( mode == INDEXED )
2030       {
2031          for ( i = ZERO, last = *pi, run = 1 ; i < num ; )
2032          {
2033             pi++;
2034             col = ( ++i == num ? -1 : *pi );
2035
2036             if (col == last)  run++;
2037             else
2038             {
2039              if ( run_bits )
2040                {
2041                   Code byte;
2042
2043 /*  Run length bitstream */
2044                   for ( j = 0, k = prec-6; j < colbytes; j++, k-=6 )
2045                   {
2046                      byte = ( k >= 0 ? (last>>k & 0x3f) | 0x40
2047                                      : (last<<(-k) & 0x3f) | 0x40 );
2048                      MOCout( byte );
2049                   }
2050                }
2051                else  PUTINT ( last );
2052
2053                PUTINT ( run );
2054                run = 1;
2055                last = col;
2056             }
2057          }
2058       }
2059       else  /*  DIRECT Colour (Run length) */
2060       {
2061          lastred = *pi++; lastgreen = *pi++; lastblue = *pi++;
2062          for ( i = ZERO, run = 1 ; i < num ; i++ )
2063          {
2064             last = TRUE;
2065             red = *pi++; green = *pi++; blue = *pi++;
2066             if ( i != num && red == lastred && green == lastgreen
2067                                           && blue == lastblue )
2068             {
2069                last = FALSE;
2070                run++;
2071             }
2072
2073             if ( last )
2074             {
2075                MOCdircol(lastred, lastgreen, lastblue, prec);
2076                PUTINT ( run );
2077                run = 1;
2078                lastred = red; lastgreen = green; lastblue = blue;
2079             }
2080          }
2081       }
2082    }
2083    else if ( normal_list )
2084    {
2085       if ( mode == INDEXED )
2086       {
2087          for ( i = ZERO ; i < num ; i++ )
2088          {
2089              PUTINT ( *pi++ );
2090          }
2091       }
2092       else
2093          for (i = ZERO; i < num ; i++ )
2094          {
2095             red = *pi++; green = *pi++; blue = *pi++;
2096             MOCdircol ( red, green, blue, prec );
2097          }
2098    }
2099    else
2100    {
2101       Code byte;
2102       int bits;
2103
2104       if ( mode == DIRECT ) num *= 3;
2105
2106       for (i = ZERO, bits = 6, byte = 0x40 ; i < num ; i++ )
2107       {
2108          col = *pi++;
2109          for ( j = prec - 1 ; j >= ZERO ; j--)
2110          {
2111             byte |= ((col>>j) & 1) <<--bits;
2112             if ( !bits )
2113             {
2114                MOCout (byte);
2115                bits = 6;
2116                byte = 0x40;
2117             }
2118          }
2119       }
2120       if ( bits < 6 ) MOCout(byte);
2121    }
2122    return;
2123 }
2124
2125 /****************************************************** MOCdircol ******/
2126 static void
2127 MOCdircol ( Posint r, Posint g, Posint b, Prec prec )
2128 {
2129 /*  Output a direct colour (r, g, b) using precision 'prec'  */
2130
2131    register Long i;
2132    register Code c;
2133
2134    if (prec & 0x01)
2135    {
2136       /*   odd number of bits  */
2137
2138       r <<= 1; g <<= 1; b <<= 1;
2139    }
2140    else prec--;
2141
2142 /* if default colour precision convert to 8 bits */
2143    if ( ! cur.colprec_flag )
2144    {
2145       r >>= 2; g >>= 2; b >>= 2;
2146    }
2147    for (i = prec; i > ZERO ; i-- )
2148    {
2149       c = (short) (0x40 | (((r>>i)&1)<<5) | (((g>>i)&1)<<4) | (((b>>i)&1)<<3));
2150       i--;
2151       c = (short) (c    | (((r>>i)&1)<<2) | (((g>>i)&1)<<1) | ((b>>i)&1));
2152       MOCout( c );
2153    }
2154    return;
2155 }
2156
2157 /****************************************************** MOCcoldef ******/
2158 static void
2159 MOCcoldef ()
2160 {
2161 /*  Check if colour precision or Value extent are not set use defaults */
2162
2163    if ( ! cur.colprec_flag && cur.col_bits != curchar.col_prec )
2164    {
2165       curchar.col_prec = cur.col_bits;
2166       MOCout ( COLRPREC );
2167       PUTINT ( curchar.col_prec );
2168    }
2169    if ( ! cur.colval_flag && ( cur.min_rgb.red != curchar.min_rgb.red
2170                           ||  cur.min_rgb.green != curchar.min_rgb.green
2171                           ||  cur.min_rgb.blue != curchar.min_rgb.blue
2172                           ||  cur.max_rgb.red != curchar.max_rgb.red
2173                           ||  cur.max_rgb.green != curchar.max_rgb.green
2174                           ||  cur.max_rgb.blue != curchar.max_rgb.blue ))
2175    {
2176       curchar.min_rgb = cur.min_rgb;
2177       curchar.max_rgb = cur.max_rgb;
2178       MOCout ( COLRVALUEEXT );
2179       MOCdircol ( curchar.min_rgb.red,
2180                   curchar.min_rgb.green,
2181                   curchar.min_rgb.blue,
2182                   curchar.col_prec );
2183       MOCdircol ( curchar.max_rgb.red,
2184                   curchar.max_rgb.green,
2185                   curchar.max_rgb.blue,
2186                   curchar.col_prec );
2187    }
2188    return;
2189 }
2190
2191 /****************************************************** MOCout *********/
2192 static void
2193 MOCout ( Code hex )
2194 {
2195 /*   Add character to buffer and Output if buffer is full */
2196
2197    register Int bits, j;
2198    register unsigned char c;
2199    static size_t index = ZERO;
2200    static unsigned char buffer[BUFF_LEN+1];
2201
2202    bits = ( (hex & 0xff00) > 0 )*8;
2203
2204    for (; bits >= 0 ; bits -= 8)
2205    {
2206       c = (hex>>bits) & 0xff;
2207
2208       if ( c <= 0x20 || c >= 0x7e )
2209          for ( j = 0; j < subchars; j++)
2210          {
2211             if ( c == charsub[j] )
2212             {
2213                hex ^= c<<bits;
2214
2215                c = (c > 0x20 ? c - 0x40 : c + 0x40);
2216                hex |= c<<bits;
2217                c = 0x7e;
2218                bits += 8;
2219                break;
2220             }
2221          }
2222       buffer[index++] = c;
2223
2224       if( ! hex ) for ( ; index < BUFF_LEN; buffer[index++] = '\0');
2225
2226       fwrite (buffer, index, (size_t)1, cgmoc);
2227       fflush (cgmoc);
2228       index = ZERO;
2229    }
2230 /*
2231    register Int bits, j;
2232    register unsigned char c;
2233    static size_t index = ZERO;
2234    static unsigned char buffer[BUFF_LEN+1];
2235
2236    bits = ( (hex & 0xff00) > 0 )*8;
2237
2238    for (; bits >= 0 ; bits -= 8)
2239    {
2240       c = (hex>>bits) & 0xff;
2241
2242       if ( c <= 0x20 || c >= 0x7e )
2243          for ( j = 0; j < subchars; j++)
2244          {
2245             if ( c == charsub[j] )
2246             {
2247                hex ^= c<<bits;
2248
2249                c = (c > 0x20 ? c - 0x40 : c + 0x40);
2250                hex |= c<<bits;
2251                c = 0x7e;
2252                bits += 8;
2253                break;
2254             }
2255          }
2256      buffer[index++] = c;
2257
2258       if( ! hex ) for ( ; index < BUFF_LEN; buffer[index++] = '\0');
2259
2260       if (index == BUFF_LEN)
2261       {
2262          fwrite (buffer, BUFF_LEN, (size_t)1, cgmoc);
2263          fflush (cgmoc);
2264          index = ZERO;
2265       }
2266    }
2267 */
2268    return;
2269 }