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