2 Copyright (c) 1999-2012 OPEN CASCADE SAS
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.
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.
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.
23 /* File stream name */
25 extern char cgmroot[];
28 /* declare void internal functions */
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),
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 */
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 */
64 /* Output a character to the buffer */
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 */
88 static Long subchars=0;
89 static char charsub[CHARSUBNUM];
91 /*static char *func="CGMochar", mess[40];*/
94 /* Macros to do common comparisons */
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 )
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) )
111 /***************************************************** CGMOchar ********/
114 CGMOchar(FILE *stream, Code c, Long *pi, Float *pr, char *pc )
117 /* Character encoding Output. stream is output channel
118 c is MF element code */
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;
125 char pcx[STRING_MAX];
127 if ( c == (Code) EOF )
138 case 0x00: /* Graphics Primitives */
142 case NONOP: /* Ignore Non-Op */
145 case LINE: /* Polyline */
151 first = ( num >= ZERO );
152 MOCpoints ( num, pi, pr, NOSET);
155 case DISJTLINE: /* Disjoint Polyline */
161 first = ( num >= ZERO );
162 MOCpoints ( num, pi, pr, NOSET);
165 case MARKER: /* Polymarker */
171 first = ( num >= ZERO );
172 MOCpoints ( num, pi, pr, NOSET);
175 case TEXT: /* Text */
178 MOCvdc ((Int)2, pi, pr);
183 case RESTRTEXT: /* Restricted Text */
186 MOCvdc( (Int)4, pi, pr);
191 case APNDTEXT: /* Append Text */
198 case POLYGON: /* Polygon */
204 first = ( num >= ZERO );
205 MOCpoints ( num, pi, pr, NOSET);
208 case POLYGONSET: /* Polygon Set */
214 first = ( num >= ZERO );
215 MOCpoints ( num, pi, pr, SET);
218 case CELLARRAY: /* Cell Array */
222 MOCvdc( (Int)6, pi, pr);
229 register Long max = ZERO, *ppc = pi;
231 /* if within a buffer then find maximum colour */
233 n = ( cur.color_mode == INDEXED ? 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++ )
242 first = ( num >= ZERO );
243 MOCcells ( num, pi, cur.color_mode, loc_prec);
246 case GDP: /* Generalised Drawing Primitive */
247 if ( *pi == -1 ) MOCchkatt(LINE); /* RAL-GKS arc */
248 else MOCchkatt(POLYGON);
251 MOCpoints ( num, pi, pr, ZERO);
255 case RECT: /* Rectangle */
258 MOCvdc( (Int)4, pi, pr);
262 (void) sprintf(mess,"(code: 0x%x)",c);
267 case 0x30: /* Delimiter Elements */
272 case BEGMF: /* Begin Metafile */
275 /* Character Substitution */
277 MOCout ( (Code)0x7e3e); /* Tilde 0x7e */
279 MOCout ( (Code)0x7e40); /* Null 0x00*/
281 MOCout ( (Code)0x7e4a); /* Line feed 0x0a */
282 MOCout ( (Code)0x7e4d); /* carriage return 0x0d */
286 /* now set up substitution list ( without NULL ) */
287 charsub[subchars++] = 0x7e;
288 charsub[subchars++] = 0x0a;
289 charsub[subchars++] = 0x0d;
293 /* Set old values to current defaults */
299 if ( strcmp (pcx, "") == 0 )
300 strcpy(pcx,"Generated with CGM DRIVER");
304 case ENDMF: /* End Metafile */
306 MOCout( (Code)0 ); /* Starts a new record */
309 case BEGPIC: /* Begin Picture Descriptor */
316 curchar = mfchar; /* set current character defaults */
319 old = cur; /* reset old settings to MF defaults */
323 MOCout( (Code)0 ); /* Start on new record */
326 if ( strcmp(pc, "\0") ) MOCstring (pc);
329 sprintf(pcx, "Picture %ld", pic_num++);
334 case BEGPICBODY: /* Begin Picture Body */
338 case ENDPIC: /* End Picture */
343 (void) sprintf(mess,"(code 0x%x)",c);
349 case 0x31: /* Metafile Descriptor Elements */
352 case MFVERSION: /* Metafile version */
357 case MFDESC: /* Metafile Description */
364 case VDCTYPE: /* VDC Type */
365 MOCcenum (c, (Int)1, &old.vdc_type, &cur.vdc_type);
368 case INTEGERPREC: /* Integer Precision */
369 curchar.int_prec = cur.int_bits;
370 MOCcint (c, (Int)1, &oldchar.int_prec, &curchar.int_prec);
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;
381 MOCcint (c, (Int)4, &oldchar.real.prec, &curchar.real.prec);
384 case INDEXPREC: /* Index Precision */
385 curchar.index_prec = cur.index_bits;
386 MOCcint(c, (Int)1, &oldchar.index_prec, &curchar.index_prec);
389 case COLRPREC: /* Colour Precision */
390 curchar.col_prec = cur.col_bits;
391 MOCcint(c, (Int)1, &oldchar.col_prec, &curchar.col_prec);
394 case COLRINDEXPREC: /* Colour Index Precision */
395 curchar.colind_prec = cur.colind_bits;
396 MOCcint(c, (Int)1, &oldchar.colind_prec, &curchar.colind_prec);
399 case MAXCOLRINDEX: /* Maximum Colour Index */
400 MOCcint(c, (Int)1, &old.max_colind, &cur.max_colind);
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);
410 case MFELEMLIST: /* Metafile element List */
413 for (j = ZERO; j < num ; j++, pi++ )
423 MOCout( (Code) *pi );
424 if ( *pi == BEGMFDEFAULTS )
425 MOCout ( ENDMFDEFAULTS );
432 case BEGMFDEFAULTS: /* Begin Metafile defaults Replacement*/
435 case ENDMFDEFAULTS: /* End Metafile defaults Replacement */
439 case FONTLIST: /* Font List */
441 for (j = ZERO ; j < num ; )
443 MOCstring ( &pc[j] );
448 case CHARSETLIST: /* Character set list */
450 for ( j = ZERO; j < num ; )
456 sscanf( &pc[j], "%1d%c%d", &b1, &c1, &b2);
457 sprintf( chr, "%c", (b1<<4) + b2);
464 case CHARCODING: /* Character coding Announcer */
470 (void) sprintf(mess,"(code: 0x%x)",c);
475 case 0x32: /* Picture Descriptor Elements */
478 case SCALEMODE: /* Scaling Mode */
479 if (old.scale_mode != cur.scale_mode ||
480 RDIFF(old.scale_factor, cur.scale_factor) )
483 old.scale_mode = cur.scale_mode;
484 old.scale_factor = cur.scale_factor;
485 PUTINT ( cur.scale_mode );
486 PUTREAL ( cur.scale_factor );
490 case COLRMODE: /* Colour Selection Mode */
491 MOCcenum(c, (Int)1, &old.color_mode, &cur.color_mode);
494 case LINEWIDTHMODE: /* Line width Specification */
495 MOCcenum(c, (Int)1, &old.linewidth_mode, &cur.linewidth_mode);
498 case MARKERSIZEMODE: /* Marker size Specification */
499 MOCcenum(c, (Int)1, &old.markersize_mode, &cur.markersize_mode);
502 case EDGEWIDTHMODE: /* Edge width Specification */
503 MOCcenum(c, (Int)1, &old.edgewidth_mode, &cur.edgewidth_mode);
506 case VDCEXT: /* VDC Extent */
507 MOCrectc(c, &old.vdc_extent, &cur.vdc_extent);
510 case BACKCOLR: /* Background Colour */
512 MOCdircol ( cur.back.red, cur.back.green, cur.back.blue,
517 (void) sprintf(mess,"(code: 0x%x)",c);
521 case 0x33: /* Control Elements */
524 case VDCINTEGERPREC: /* VDC Integer Precision */
525 MOCcint(c, (Int)1, &oldchar.vdcint_prec, &curchar.vdcint_prec);
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);
538 case AUXCOLR: /* Auxiliary Colour */
539 if (cur.color_mode == DIRECT)
541 MOCccol(c, (Int)1, &old.aux, &cur.aux);
545 MOCcint(c, (Int)1, &old.aux.index, &cur.aux.index);
549 case TRANSPARENCY: /* Transparency */
550 MOCcenum(c, (Int)1, &old.transparency, &cur.transparency);
553 case CLIPRECT: /* Clip Rectangle */
554 MOCrectc(c, &old.clip_rect, &cur.clip_rect);
557 case CLIP: /* Clip Indicator */
558 MOCcenum(c, (Int)1, &old.clip_ind, &cur.clip_ind);
562 (void) sprintf(mess,"(code: 0x%x)",c);
567 case 0x34: /* Circles and Ellipses */
570 case CIRCLE: /* Circle */
573 MOCvdc( (Int)3, pi, pr);
576 case ARC3PT: /* Circular Arc 3 point */
579 MOCvdc( (Int)6, pi, pr);
582 case ARC3PTCLOSE: /* Circular Arc 3 point close */
585 MOCvdc( (Int)6, pi, pr);
589 case ARCCTR: /* Circle Arc centre */
592 MOCvdc( (Int)7, pi, pr);
595 case ARCCTRCLOSE: /* Circle Arc centre close */
598 MOCvdc( (Int)7, pi, pr);
602 case ELLIPSE: /* Ellipse */
605 MOCvdc( (Int)6, pi, pr);
608 case ELLIPARC: /* Elliptical Arc */
611 MOCvdc( (Int)10, pi, pr);
614 case ELLIPARCCLOSE: /* Elliptical Arc close*/
617 MOCvdc( (Int)10, pi, pr);
622 (void) sprintf(mess,"(code: 0x%x)",c);
627 case 0x35: /* Attributes */
631 case LINEINDEX: /* Line Bundle index */
632 att.line_index = TRUE;
635 case LINETYPE: /* Line Type */
636 att.line_type = TRUE;
639 case LINEWIDTH: /* Line Width */
640 att.line_width = TRUE;
643 case LINECOLR: /* Line Colour */
644 att.line_color = TRUE;
647 case MARKERINDEX: /* Marker Bundle index */
648 att.mark_index = TRUE;
651 case MARKERTYPE: /* Marker Type */
652 att.mark_type = TRUE;
655 case MARKERSIZE: /* Marker Size */
656 att.mark_size = TRUE;
659 case MARKERCOLR: /* Marker Colour */
660 att.mark_color = TRUE;
663 case TEXTINDEX: /* Text Bundle index */
664 att.text_index = TRUE;
667 case TEXTFONTINDEX: /* Text Font Index */
668 att.text_font = TRUE;
671 case TEXTPREC: /* Text Precision */
672 att.text_prec = TRUE;
675 case CHAREXPAN: /* Character Expansion Factor */
676 att.char_expan = TRUE;
679 case CHARSPACE: /* Character Spacing */
680 att.char_space = TRUE;
683 case TEXTCOLR: /* Text Colour */
684 att.text_color = TRUE;
687 case CHARHEIGHT: /* Character Height */
688 att.char_height = TRUE;
691 case CHARORI: /* Character Orientation */
692 att.char_orient = TRUE;
695 case TEXTPATH: /* Text Path */
696 att.text_path = TRUE;
699 case TEXTALIGN: /* Text Alignment */
700 att.text_align = TRUE;
703 case CHARSETINDEX: /* Character Set Index */
707 case ALTCHARSETINDEX: /* Alt Character Set Index */
708 att.altchar_set = TRUE;
712 (void) sprintf(mess,"(code: 0x%x)",c);
715 if ( cgmstate == MF_DEFAULTS ) MOCattrib ( c );
718 case 0x36: /* More Attributes */
721 case FILLINDEX: /* Fill Bundle index */
722 att.fill_index = TRUE;
725 case INTSTYLE: /* Interior Style */
726 att.int_style = TRUE;
729 case FILLCOLR: /* Fill Colour */
730 att.fill_color = TRUE;
733 case HATCHINDEX: /* Hatch Index */
734 att.hatch_ind = TRUE;
737 case PATINDEX: /* Pattern Index */
741 case EDGEINDEX: /* Edge Bundle index */
742 att.edge_index = TRUE;
745 case EDGETYPE: /* Edge Type */
746 att.edge_type = TRUE;
749 case EDGEWIDTH: /* Edge Width */
750 att.edge_width = TRUE;
753 case EDGECOLR: /* Edge Colour */
754 att.edge_color = TRUE;
757 case EDGEVIS: /* Edge Visibility */
761 case FILLREFPT: /* Fill Reference Point */
765 case PATSIZE: /* Pattern Size */
769 case PATTABLE: /* Pattern Table */
772 register Long max = ZERO;
781 /* if within a buffer then find maximum colour */
783 n = ( cur.color_mode == INDEXED ? 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++ )
792 first = ( num >= ZERO );
793 MOCcells ( num, pi, cur.color_mode, loc_prec);
796 case COLRTABLE: /* Colour Table */
802 first = ( num >= ZERO );
803 MOCcells ( num, pi, DIRECT, (Prec) 0);
806 case ASF: /* Aspect source flags */
808 short diff = FALSE, type, value, k, l;
810 /* First check if any relevant ASF has changed */
812 for ( n = ZERO; n < ASFS ; n++ )
814 if ( curatt.asf[n] != oldatt.asf[n] ) diff++;
819 /* Output ASFs as they were input - ignoring duplicates */
822 for ( n = ZERO; n < num ; n++ )
824 type = (short) (*pi++);
825 value = (short) (*pi++);
828 if ( value != oldatt.asf[type] )
832 oldatt.asf[type] = value;
841 case 506: /* all edge */
845 case 507: /* all fill */
849 case 508: /* all text */
853 case 509: /* all marker */
857 case 510: /* all line */
865 default: /* ignore */
870 for ( ; k <= l; k++) oldatt.asf[k] = value;
878 (void) sprintf(mess,"(code: 0x%x)",c);
881 if ( cgmstate == MF_DEFAULTS ) MOCattrib ( c );
884 case 0x37: /* Escape And External Elements */
887 case ESCAPE: /* Escape */
893 case MESSAGE: /* Message */
899 case APPLDATA: /* Application Data */
906 (void) sprintf(mess,"(code: 0x%x)",c);
912 (void) sprintf(mess,"(code: 0x%x)",c);
919 /****************************************************** MOCchkatt ******/
921 MOCchkatt ( Code type )
923 /* Check 'type' Attributes and send to Output if changed */
925 Logical bundled, indiv;
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 );
938 if ( bundled && att.line_index)
940 ACINT(LINEINDEX, line_ind);
941 att.line_index = FALSE;
944 if ( indiv && att.line_type)
946 ACINT(LINETYPE, line_type);
947 att.line_type = FALSE;
950 if ( indiv && att.line_width )
952 if (cur.linewidth_mode == SCALED)
954 ACREAL(LINEWIDTH, line_width.real, REAL);
956 else if ( cur.vdc_type == REAL)
958 ACREAL(LINEWIDTH, line_width.real, VDC);
962 ACINT(LINEWIDTH, line_width.intr);
964 att.line_width = FALSE;
967 if ( indiv && att.line_color )
969 if (cur.color_mode == DIRECT)
971 ACCOL (LINECOLR, line );
975 ACINT(LINECOLR, line.index);
977 att.line_color = FALSE;
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 );
990 if ( bundled && att.mark_index)
992 ACINT(MARKERINDEX, mark_ind);
993 att.mark_index = FALSE;
996 if ( indiv && att.mark_type)
998 ACINT(MARKERTYPE, mark_type);
999 att.mark_type = FALSE;
1002 if ( indiv && att.mark_size )
1004 if (cur.markersize_mode == SCALED)
1006 ACREAL(MARKERSIZE, mark_size.real, REAL );
1008 else if ( cur.vdc_type == REAL)
1010 ACREAL(MARKERSIZE, mark_size.real, VDC );
1014 ACINT(MARKERSIZE, mark_size.intr );
1016 att.mark_size = FALSE;
1019 if ( indiv && att.mark_color )
1021 if (cur.color_mode == DIRECT)
1023 ACCOL (MARKERCOLR, marker );
1027 ACINT(MARKERCOLR, marker.index );
1029 att.mark_color = FALSE;
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 );
1046 if ( bundled && att.text_index)
1048 ACINT(TEXTINDEX, text_ind);
1049 att.text_index = FALSE;
1052 if ( indiv && att.text_font)
1054 ACINT(TEXTFONTINDEX, text_font);
1055 att.text_font = FALSE;
1058 if ( indiv && att.text_prec)
1060 ACENUM(TEXTPREC, text_prec);
1061 att.text_prec = FALSE;
1064 if ( indiv && att.char_expan)
1066 ACREAL(CHAREXPAN, char_exp, REAL );
1067 att.char_expan = FALSE;
1070 if ( indiv && att.char_space)
1072 ACREAL(CHARSPACE, char_space, REAL );
1073 att.char_space = FALSE;
1076 if ( indiv && att.text_color )
1078 if (cur.color_mode == DIRECT)
1080 ACCOL (TEXTCOLR, text );
1084 ACINT(TEXTCOLR, text.index );
1086 att.text_color = FALSE;
1089 if ( att.char_height)
1091 if (cur.vdc_type == REAL)
1093 ACREAL(CHARHEIGHT, char_height.real, VDC );
1097 ACINT(CHARHEIGHT, char_height.intr );
1099 att.char_height = FALSE;
1102 if ( att.char_orient)
1104 if (cur.vdc_type == REAL)
1106 if ( VADIFF(char_up.x.real) || VADIFF(char_up.y.real) ||
1107 VADIFF(char_base.x.real) || VADIFF(char_base.y.real) )
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);
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) )
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);
1138 att.char_orient = FALSE;
1143 ACINT(CHARSETINDEX, char_set );
1144 att.char_set = FALSE;
1147 if ( att.altchar_set)
1149 ACINT(ALTCHARSETINDEX, altchar_set );
1150 att.altchar_set = FALSE;
1153 if ( att.text_path )
1155 ACENUM(TEXTPATH, text_path );
1156 att.text_path = FALSE;
1159 if ( att.text_align )
1161 if ( ATTDIFF(text_halign) || ATTDIFF(text_valign) ||
1162 RADIFF(text_hcont) || RADIFF(text_vcont) )
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 );
1174 att.text_align = FALSE;
1178 case POLYGON: /* Fill and edge attributes */
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 );
1189 if ( bundled && att.fill_index)
1191 ACINT(FILLINDEX, fill_ind);
1192 att.fill_index = FALSE;
1195 if ( indiv && att.int_style)
1197 ACENUM(INTSTYLE, int_style);
1198 att.int_style = FALSE;
1201 if ( indiv && att.hatch_ind )
1203 ACINT(HATCHINDEX, hatch_ind);
1204 att.hatch_ind = FALSE;
1207 if ( indiv && att.pat_ind )
1209 ACINT(PATINDEX, pat_ind);
1210 att.pat_ind = FALSE;
1213 if ( indiv && att.fill_color )
1215 if (cur.color_mode == DIRECT)
1217 ACCOL (FILLCOLR, fill );
1221 ACINT(FILLCOLR, fill.index );
1223 att.fill_color = FALSE;
1228 if (cur.vdc_type == REAL)
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) )
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);
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) )
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);
1262 att.pat_size = FALSE;
1265 /* Edge characteristics */
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 );
1274 if ( bundled && att.edge_index)
1276 ACINT(EDGEINDEX, edge_ind);
1277 att.edge_index = FALSE;
1280 if ( indiv && att.edge_type)
1282 ACINT(EDGETYPE, edge_type);
1283 att.edge_type = FALSE;
1286 if ( indiv && att.edge_width )
1288 if (cur.edgewidth_mode == SCALED)
1290 ACREAL(EDGEWIDTH, edge_width.real, REAL );
1292 else if ( cur.vdc_type == REAL)
1294 ACREAL(EDGEWIDTH, edge_width.real, VDC );
1298 ACINT(EDGEWIDTH, edge_width.intr );
1300 att.edge_width = FALSE;
1303 if ( indiv && att.edge_color )
1305 if (cur.color_mode == DIRECT)
1307 ACCOL (EDGECOLR, edge );
1311 ACINT(EDGECOLR, edge.index );
1313 att.edge_color = FALSE;
1318 ACENUM(EDGEVIS, edge_vis);
1319 att.edge_vis = FALSE;
1325 (void) sprintf(mess,"(type: 0x%x)", type);
1332 /****************************************************** MOCattrib ******/
1334 MOCattrib ( Code code )
1336 /* Outputs attribute code 'code' */
1342 case LINEINDEX: /* Line Bundle index */
1343 PUTINT ( curatt.line_ind );
1346 case LINETYPE: /* Line Type */
1347 PUTINT ( curatt.line_type );
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 );
1356 PUTINT ( curatt.line_width.intr );
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 );
1364 PUTINT ( curatt.line.index );
1367 case MARKERINDEX: /* Marker Bundle index */
1368 PUTINT ( curatt.mark_ind );
1371 case MARKERTYPE: /* Marker Type */
1372 PUTINT ( curatt.mark_type );
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 );
1381 PUTINT ( curatt.mark_size.intr );
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 );
1389 PUTINT ( curatt.marker.index );
1392 case TEXTINDEX: /* Text Bundle index */
1393 PUTINT ( curatt.text_ind );
1396 case TEXTFONTINDEX: /* Text Font Index */
1397 PUTINT ( curatt.text_font );
1400 case TEXTPREC: /* Text Precision */
1401 PUTINT ( curatt.text_prec );
1404 case CHAREXPAN: /* Character Expansion Factor */
1405 PUTREAL ( curatt.char_exp );
1408 case CHARSPACE: /* Character Spacing */
1409 PUTREAL ( curatt.char_space );
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 );
1417 PUTINT ( curatt.text.index );
1420 case CHARHEIGHT: /* Character Height */
1421 if ( cur.vdc_type == REAL )
1422 PUTVDC ( curatt.char_height.real );
1424 PUTINT ( curatt.char_height.intr );
1427 case CHARORI: /* Character Orientation */
1428 if ( cur.vdc_type == REAL )
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 );
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 );
1444 case TEXTPATH: /* Text Path */
1445 PUTINT ( curatt.text_path );
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 );
1455 case CHARSETINDEX: /* Character Set Index */
1456 PUTINT ( curatt.char_set );
1459 case ALTCHARSETINDEX: /* Alt Character Set Index */
1460 PUTINT ( curatt.altchar_set );
1463 case FILLINDEX: /* Fill Bundle index */
1464 PUTINT ( curatt.fill_ind );
1467 case INTSTYLE: /* Interior Style */
1468 PUTINT ( curatt.int_style );
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 );
1476 PUTINT ( curatt.fill.index );
1479 case HATCHINDEX: /* Hatch Index */
1480 PUTINT ( curatt.hatch_ind );
1483 case PATINDEX: /* Pattern Index */
1484 PUTINT ( curatt.pat_ind );
1487 case EDGEINDEX: /* Edge Bundle index */
1488 PUTINT ( curatt.edge_ind );
1491 case EDGETYPE: /* Edge Type */
1492 PUTINT ( curatt.edge_type );
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 );
1501 PUTINT ( curatt.edge_width.intr );
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 );
1509 PUTINT ( curatt.edge.index );
1512 case EDGEVIS: /* Edge Visibility */
1513 PUTINT ( curatt.edge_vis );
1516 case FILLREFPT: /* Fill Reference Point */
1517 if ( cur.vdc_type == REAL )
1519 PUTVDC ( curatt.fill_ref.x.real );
1520 PUTVDC ( curatt.fill_ref.y.real );
1524 PUTINT ( curatt.fill_ref.x.intr );
1525 PUTINT ( curatt.fill_ref.y.intr );
1529 case PATSIZE: /* Pattern Size */
1530 if ( cur.vdc_type == REAL )
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 );
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 );
1547 (void) sprintf(mess,"(type: 0x%x)", code);
1554 /****************************************************** MOCcint ********/
1556 MOCcint ( Code code, Int n, Long *var1, Long *var2)
1558 /* Conditionally outputs 'code' and 'n' integers starting at *var2
1559 only if at least one is different */
1562 register Logical diff = FALSE;
1564 for (i = ZERO; i < n; i++)
1565 if (var1[i] != var2[i]) diff = TRUE;
1569 for (i = ZERO ; i < n ; i++)
1578 /****************************************************** MOCcenum *******/
1580 MOCcenum (Code code, int n, Enum *var1, Enum *var2 )
1582 /* Conditionally outputs 'code' and 'n' short integers starting at *var2
1583 only if at least one is different */
1586 register Logical diff = FALSE;
1588 for (i = ZERO; i < n; i++)
1589 if (var1[i] != var2[i]) diff = TRUE;
1593 for (i = ZERO ; i < n ; i++)
1602 /****************************************************** MOCcreal *******/
1604 MOCcreal (Code code, Float *var1, Float *var2, Enum r)
1606 /* Conditionally outputs 'code' and real *var2 if different from *var1
1607 using precision specified by r */
1609 if ( FABS(*var1-*var2) > (r == REAL ? cur.realmin : cur.vdcmin) )
1612 MOCreal ((Double)*var2, r, null);
1618 /****************************************************** MOCrectc *******/
1620 MOCrectc( Code code, struct rect *var1, struct rect *var2 )
1622 /* Conditionally outputs 'code' and 4 VDCs indicated by *var2
1623 if different from *var1 using vdc precision */
1625 if (cur.vdc_type == INTEGER)
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 )
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 );
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 ) )
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 );
1664 /****************************************************** MOCccol ********/
1666 MOCccol (Code code, int n, struct colour *var1, struct colour *var2)
1668 /* Conditional output 'code' and colour indicated by *var2
1669 if different from colour *var1 */
1672 register Logical diff = FALSE;
1674 for (i = j = ZERO; i < n; i++, j++ )
1676 if ( (var1[j].red != var2[j].red) ||
1677 (var1[j].green != var2[j].green) ||
1678 (var1[j].blue != var2[j].blue) ) diff = TRUE;
1684 for (i = j = ZERO; i < n; i++, j++)
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,
1696 /****************************************************** MOCvdc *********/
1698 MOCvdc (int n, Long *pi, Float *pr )
1700 /* Outputs n VDCs starting at pi/pr */
1704 if (cur.vdc_type == REAL)
1705 for ( j = ZERO; j < n; j++)
1708 for ( j = ZERO; j < n; j++)
1714 /****************************************************** MOCpoints ******/
1716 MOCpoints(Long n, Long *pi, Float *pr, Enum set )
1718 /* Outputs n points starting at pi/pr
1719 'set' indicates if this is a Polygon set */
1721 static Logical first = TRUE;
1723 static Long exp_x, exp_y;
1724 static Float xx, yy;
1729 exp_x = exp_y = curchar.vdc.defexp;
1733 if ( n >= ZERO ) first = TRUE;
1740 if (cur.vdc_type == REAL)
1742 for ( i=0; i < n; i++ )
1745 MOCreal ( (Double)*pr++, VDC, &exp_x);
1747 MOCreal ( (Double)*pr++, VDC, &exp_y);
1748 if (set) PUTINT ( *pi++ );
1753 for ( i=0; i < n; i++ )
1759 if ( set) PUTINT ( *pi++ );
1765 /****************************************************** MOCreal ********/
1767 MOCreal ( Double x, Enum type, Prec *ptlist )
1769 /* Outputs real value 'x', using type 'type'
1770 pointlist indicates if this is part of a pointslist */
1772 register Long def_exp, mantissa, expnt;
1773 register Double y, realmin, prec;
1774 register Logical present = ZERO, expald;
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 );
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 );
1794 if (ptlist != NULL) def_exp = *ptlist;
1796 y = (Double) ( x>0 ? x : -x );
1805 if ( expald ) /* if Exponent allowed */
1819 /* Strip off trailing zeros */
1821 while ( mantissa && !(mantissa & 0x01) )
1826 present = (expnt != def_exp);
1830 while (expnt < def_exp)
1835 while (expnt > def_exp)
1840 mantissa = (long) y;
1843 if ( x < 0.0 ) mantissa = -mantissa;
1846 MOCinteger ( (Long) mantissa, present, expald);
1847 if (present) PUTINT ( expnt );
1849 if ( mantissa && (ptlist != NULL) ) *ptlist = expnt;
1854 /****************************************************** MOCinteger *****/
1856 MOCinteger (Long intval, Logical present, Logical allowed)
1858 /* Output an integer 'intval', 'present' indicates if exponent present
1859 and 'allowed' if allowed */
1867 /* Strip of bits in 5 bit chunks */
1869 for (j = -1; ival > ZERO && j < curchar.int_prec; ival >>= 5)
1870 hex[++j] = 0x60 | (ival & 0x1F);
1872 /* if zero or top bit set or Exponent follows and bit set
1873 then add another byte */
1875 if ( (j < ZERO) | ( hex[j] & (1L<<(4-present)) ) |
1876 ( allowed && (hex[j] & 0x18) ) ) hex[++j] = 0x60;
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 */
1882 /* Reverse bits to buffer */
1883 for (i = j; i >= ZERO; i--) MOCout( hex [i] );
1888 /****************************************************** MOCstring ******/
1890 MOCstring (register char *s)
1892 /* Output a text string 'string'
1893 if CMS translate from EBCDIC to ASCII */
1899 while ( (c = *s++) != '\0')
1907 /****************************************************** MOCcells *******/
1909 MOCcells (register Long n, register Long *pi, Enum mode, Prec prec)
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' */
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;
1920 Long col, last, run, *pi0 = pi;
1923 num = ( more ? -n : n);
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
1935 normal_list = bit_stream = ZERO;
1936 run_bits = run_length = ZERO;
1938 /* Work out shortest method of coding list */
1940 if ( mode == INDEXED )
1943 for ( i = ZERO, last = *pi, run = 1 ; i < num; )
1945 /* make sure last value forces an end */
1947 col = ( ++i == num ? -1 : *pi++ );
1949 if (col == last) run++;
1953 /* Work out bytes for run count */
1955 for ( j=run, bytes=1; j > 0x0f; bytes++, j>>=5);
1956 run_length += bytes;
1959 /* Work out bytes for normal colour value */
1961 for ( j=last, bytes=1; j > 0x0f; bytes++, j>>=5);
1962 run_length += bytes;
1963 run_bits += colbytes;
1964 normal_list += run*bytes;
1971 else /* Direct Colour */
1974 lastred = *pi++; lastgreen = *pi++; lastblue = *pi++;
1975 for ( i = ZERO, run = 1 ; i < num ; )
1977 red = *pi++ ; green = *pi++ ; blue = *pi++;
1979 if ( ++i != num && red == lastred && green == lastgreen
1980 && blue == lastblue )
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;
1990 lastred = red; lastgreen = green; lastblue = blue;
1995 /* work out list lengths */
1996 bit_stream = (cols * num * prec + 5) / 6;
1998 /* Work out best coding method */
1999 if ( mode == INDEXED && run_bits < run_length ) run_length = run_bits;
2002 if ( run_length < normal_list && run_length < bit_stream )
2004 run_length = TRUE; normal_list = FALSE; bit_stream = FALSE;
2005 i = ( run_bits ? 0x43 : 0x42 );
2007 else if ( bit_stream < normal_list)
2009 run_length = FALSE; normal_list = FALSE; bit_stream = TRUE;
2014 run_length = FALSE; normal_list = TRUE; bit_stream = FALSE;
2019 /* Reset continuation marker */
2021 if ( first ) MOCout( (Code) i);
2022 first = ( n >= ZERO );
2025 /* Now send points to Metafile */
2029 if ( mode == INDEXED )
2031 for ( i = ZERO, last = *pi, run = 1 ; i < num ; )
2034 col = ( ++i == num ? -1 : *pi );
2036 if (col == last) run++;
2043 /* Run length bitstream */
2044 for ( j = 0, k = prec-6; j < colbytes; j++, k-=6 )
2046 byte = ( k >= 0 ? (last>>k & 0x3f) | 0x40
2047 : (last<<(-k) & 0x3f) | 0x40 );
2051 else PUTINT ( last );
2059 else /* DIRECT Colour (Run length) */
2061 lastred = *pi++; lastgreen = *pi++; lastblue = *pi++;
2062 for ( i = ZERO, run = 1 ; i < num ; i++ )
2065 red = *pi++; green = *pi++; blue = *pi++;
2066 if ( i != num && red == lastred && green == lastgreen
2067 && blue == lastblue )
2075 MOCdircol(lastred, lastgreen, lastblue, prec);
2078 lastred = red; lastgreen = green; lastblue = blue;
2083 else if ( normal_list )
2085 if ( mode == INDEXED )
2087 for ( i = ZERO ; i < num ; i++ )
2093 for (i = ZERO; i < num ; i++ )
2095 red = *pi++; green = *pi++; blue = *pi++;
2096 MOCdircol ( red, green, blue, prec );
2104 if ( mode == DIRECT ) num *= 3;
2106 for (i = ZERO, bits = 6, byte = 0x40 ; i < num ; i++ )
2109 for ( j = prec - 1 ; j >= ZERO ; j--)
2111 byte |= ((col>>j) & 1) <<--bits;
2120 if ( bits < 6 ) MOCout(byte);
2125 /****************************************************** MOCdircol ******/
2127 MOCdircol ( Posint r, Posint g, Posint b, Prec prec )
2129 /* Output a direct colour (r, g, b) using precision 'prec' */
2136 /* odd number of bits */
2138 r <<= 1; g <<= 1; b <<= 1;
2142 /* if default colour precision convert to 8 bits */
2143 if ( ! cur.colprec_flag )
2145 r >>= 2; g >>= 2; b >>= 2;
2147 for (i = prec; i > ZERO ; i-- )
2149 c = (short) (0x40 | (((r>>i)&1)<<5) | (((g>>i)&1)<<4) | (((b>>i)&1)<<3));
2151 c = (short) (c | (((r>>i)&1)<<2) | (((g>>i)&1)<<1) | ((b>>i)&1));
2157 /****************************************************** MOCcoldef ******/
2161 /* Check if colour precision or Value extent are not set use defaults */
2163 if ( ! cur.colprec_flag && cur.col_bits != curchar.col_prec )
2165 curchar.col_prec = cur.col_bits;
2166 MOCout ( COLRPREC );
2167 PUTINT ( curchar.col_prec );
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 ))
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,
2183 MOCdircol ( curchar.max_rgb.red,
2184 curchar.max_rgb.green,
2185 curchar.max_rgb.blue,
2191 /****************************************************** MOCout *********/
2195 /* Add character to buffer and Output if buffer is full */
2197 register Int bits, j;
2198 register unsigned char c;
2199 static size_t index = ZERO;
2200 static unsigned char buffer[BUFF_LEN+1];
2202 bits = ( (hex & 0xff00) > 0 )*8;
2204 for (; bits >= 0 ; bits -= 8)
2206 c = (hex>>bits) & 0xff;
2208 if ( c <= 0x20 || c >= 0x7e )
2209 for ( j = 0; j < subchars; j++)
2211 if ( c == charsub[j] )
2215 c = (c > 0x20 ? c - 0x40 : c + 0x40);
2222 buffer[index++] = c;
2224 if( ! hex ) for ( ; index < BUFF_LEN; buffer[index++] = '\0');
2226 fwrite (buffer, index, (size_t)1, cgmoc);
2231 register Int bits, j;
2232 register unsigned char c;
2233 static size_t index = ZERO;
2234 static unsigned char buffer[BUFF_LEN+1];
2236 bits = ( (hex & 0xff00) > 0 )*8;
2238 for (; bits >= 0 ; bits -= 8)
2240 c = (hex>>bits) & 0xff;
2242 if ( c <= 0x20 || c >= 0x7e )
2243 for ( j = 0; j < subchars; j++)
2245 if ( c == charsub[j] )
2249 c = (c > 0x20 ? c - 0x40 : c + 0x40);
2256 buffer[index++] = c;
2258 if( ! hex ) for ( ; index < BUFF_LEN; buffer[index++] = '\0');
2260 if (index == BUFF_LEN)
2262 fwrite (buffer, BUFF_LEN, (size_t)1, cgmoc);