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.
24 /* File stream name */
28 /* declare internal functions */
29 # if (defined __STDC__ && __STDC__) || defined __cplusplus
30 /* use function prototypes, they are requred for ANSI C and C++ compilers */
31 void CGMObin(FILE *stream, Code c, Long *pi, Float *pr, char *str);
32 /* Main Output Routine */
33 static void MOBopcode(Code c, Long len), /* Output an Op code */
34 MOBint(Long n, Prec prec, Enum sign), /* Output an Integer */
35 MOBreal(Double x, Enum real_type, Enum real_or_vdc), /* Output a real number */
36 MOBcolour(struct colour *col, Enum type), /* Output a colour */
37 MOBvdc(Int n, Long *pi, Float *pr), /* Output a number of VDCs */
38 MOBpointlist(Long n, Long *pi, Float *pr, Enum set), /* Output a Points List */
39 MOBclist(register Long num, register Long *col,
40 Prec mode, Enum type, Prec prec), /* Output a colour list */
41 MOBbits(Posint value, Prec prec, Long *bit), /* Output a value to a bit stream */
42 MOBstring(char *s), /* Output a string */
43 MOBout(Posint hex, Prec bytes), /* Output values to the output buffer */
44 MOBcharci(Code c, Int *class, Int *id); /* Convert Op code value to Class and Id */
46 void CGMObin(); /* Main Output Routine */
47 static void MOBopcode(), /* Output an Op code */
48 MOBint(), /* Output an Integer */
49 MOBreal(), /* Output a real number */
50 MOBcolour(), /* Output a colour */
51 MOBvdc(), /* Output a number of VDCs */
52 MOBpointlist(), /* Output a Points List */
53 MOBclist(), /* Output a colour list */
54 MOBbits(), /* Output a value to a bit stream */
55 MOBstring(), /* Output a string */
56 MOBout(), /* Output values to the output buffer */
57 MOBcharci(); /* Convert Op code value to Class and Id */
59 /* Local Parameters */
61 #define ENUMERATED (Prec) 16
63 #define PARTITION (Code) 0xff
65 #define UNSIGNED (Enum) 0
66 #define SIGNED (Enum) 1
68 #define FLOATING (Enum) 0
69 #define FIXED (Enum) 1
71 #define RUNLENGTH (Enum) 0
72 #define PACKED (Enum) 1
76 #define LONGINT (Prec) 4
80 #define ENUMSIZE ( (Long) 2 )
81 #define INDEXSIZE ( (Long) curbin.index_prec>>3 )
82 #define COLINDEXSIZE ( (Long) curbin.colind_prec>>3 )
83 #define INTSIZE ( (Long) curbin.int_prec>>3 )
84 #define REALSIZE ( (Long) (curbin.real_whole + curbin.real_fraction)>>3 )
85 #define VDCSIZE ( (Long) (cur.vdc_type == REAL\
86 ? (curbin.vdc_whole + curbin.vdc_fraction)>>3 \
87 : curbin.vdcint_prec>>3 ) )
88 #define COLOURSIZE ( (Long) (cur.color_mode == DIRECT\
89 ? 3*curbin.col_prec>>3 : curbin.colind_prec>>3 ) )
90 #define STRINGSIZE(x) ( (Long) (256 * strlen(x) / 255 + 1) )
92 /* Basic Common Output functions */
94 #define PUTBYTE(x) MOBout( (Posint) x, (Prec) 1 )
95 #define PUTWORD(x) MOBout( (Posint) x, (Prec) 2 )
96 #define PUTINT(x) MOBint( (Long) x, curbin.int_prec, SIGNED )
97 #define PUTREAL(x) MOBreal ( (Double)x, curbin.real_type, REAL )
98 #define PUTINDEX(x) MOBint( (Long) x, curbin.index_prec, SIGNED )
99 #define PUTENUM(x) MOBint( (Long) x, ENUMERATED, SIGNED )
100 #define PUTINTVDC(x) MOBint( (Long) x, curbin.vdcint_prec, SIGNED )
101 #define PUTREALVDC(x) MOBreal( (Double)x, curbin.vdc_type, VDC )
103 /* Local Variables */
105 static size_t mobblen = BUFF_LEN, /* Normal Output Buffer length */
106 mobparmlen, /* Parameter length in bytes */
107 mobremainder, /* Bytes left after partition */
108 mobdeflen, /* MF Defaults replacement length */
109 mobindex = 0; /* Output buffer pointer */
110 static char mobstdbuff[BUFF_LEN], /* Normal Output buffer */
111 *mobbuff = mobstdbuff, /* Buffer origin */
112 *mobdefbuff; /* MF Defaults replacement buffer */
114 /*static char *func="CGMobin", mess[40];*/
115 static char mess[40];
117 /********************************************************* CGMObin *****/
119 CGMObin(FILE *stream, Code c, Long *pi, Float *pr, char *str)
121 register Long j, n, num;
124 static Long defindex, saveparmlen;
125 static Logical first = TRUE, first_pic = TRUE;
128 if ( c == (Code) EOF )
130 MOBout ( (Posint) 0, (Prec) 0); /* flush output buffer */
139 case 0x00: /* Graphics Primitives */
143 case NONOP: /* Ignore Non-Op */
146 case LINE: /* Polyline */
147 case DISJTLINE: /* Disjoint Polyline */
148 case MARKER: /* Polymarker */
149 parmlen = 2*num*VDCSIZE;
150 if ( first ) MOBopcode(c, parmlen);
151 else MOBopcode(PARTITION, parmlen);
152 first = ( parmlen >= ZERO );
153 MOBpointlist(num, pi, pr, NOSET);
156 case TEXT: /* Text */
157 parmlen = 2*VDCSIZE + ENUMSIZE + STRINGSIZE(str);
158 MOBopcode(c, parmlen);
159 MOBvdc( (Int)2, pi, pr);
164 case RESTRTEXT: /* Restricted Text */
165 parmlen = 4*VDCSIZE + ENUMSIZE + STRINGSIZE(str);
166 MOBopcode(c, parmlen);
167 MOBvdc( (Int)4, pi, pr);
172 case APNDTEXT: /* Append Text */
173 parmlen = ENUMSIZE + STRINGSIZE(str);
174 MOBopcode(c, parmlen);
179 case POLYGON: /* Polygon */
180 parmlen = 2*num*VDCSIZE;
181 if ( first ) MOBopcode(c, parmlen);
182 else MOBopcode(PARTITION, parmlen);
183 first = ( parmlen >= ZERO );
184 MOBpointlist(num, pi, pr, NOSET);
187 case POLYGONSET: /* Polygon Set */
188 parmlen = num * ( 2*VDCSIZE + ENUMSIZE );
189 if ( first ) MOBopcode(c, parmlen);
190 else MOBopcode(PARTITION, parmlen);
191 first = ( parmlen >= ZERO );
192 MOBpointlist(num, pi, pr, SET);
195 case CELLARRAY: /* Cell Array */
197 register Long *pt = pi, i, k;
198 Long red, green, blue, nc, ncol;
200 Long last, lastred, lastgreen, lastblue;
203 static Enum runlength;
205 /* Number of colour cells */
208 ncol = abs(cur.color_mode == DIRECT ? 3*num : num );
213 /* set up basic parameter length */
214 parmlen = 6*VDCSIZE + 3*INTSIZE + ENUMSIZE;
215 pt += 6; /* skip 3 points */
216 nx = *pt++; /* Number of columns */
217 ny = *pt++; /* Number of rows */
218 j = *pt++; /* Local precision */
220 if ( j == ZERO || num > 0 )
223 /* Find largest colour value if cell within buffer */
225 for ( i = 0, k = 0; i < ncol; i++, pt++ )
227 if ( *pt > k ) k = *pt;
245 /* Find number of bytes for both coding methods */
248 for ( j = 0; j < nc; j += nx )
251 /* Make sure row starts on a word boundary */
253 if ( packed & 1 ) packed++;
254 if ( run & 1 ) run++;
256 /* Calculate length of packed list in bytes per row */
258 packed += ( (cur.color_mode == DIRECT ? 3*nx : nx)
261 /* Calculate length of run length in bits */
264 if ( cur.color_mode == INDEXED )
267 for ( i = 0; i < nx; i++, pt++ )
271 k += curbin.int_prec + lprec;
278 lastred = -1; lastgreen = -1; lastblue = -1;
279 for ( i = 0; i < nx; i++ )
281 red = *pt++; green = *pt++; blue = *pt++;
282 if ( red != lastred || green != lastgreen
283 || blue != lastblue )
285 k += curbin.int_prec + 3*lprec;
293 /* Convert runlength to bytes */
300 /* Decide which encoding is smallest */
304 runlength = RUNLENGTH;
313 if ( num < 0 ) parmlen = - parmlen;
314 MOBopcode(c, parmlen);
316 MOBvdc ( (Int)6, pi, pr );
322 PUTENUM ( runlength );
326 parmlen = ( runlength = RUNLENGTH ? run : packed );
327 if ( num < 0 ) parmlen = - parmlen;
328 MOBopcode(PARTITION, parmlen);
331 first = ( num >= ZERO );
333 /* Output cell array a row at a time */
335 for ( j = 0; j < nc; j += nx )
337 MOBclist (nx, pi, cur.color_mode, runlength, lprec);
338 pi += ( cur.color_mode == DIRECT ? 3*nx : nx );
343 case GDP: /* Generalised Drawing Primitive */
344 parmlen = 2*INTSIZE + 2*num*VDCSIZE + STRINGSIZE(str);
345 if ( first ) MOBopcode(c, parmlen);
346 else MOBopcode(PARTITION, parmlen);
347 first = ( parmlen >= ZERO );
350 MOBpointlist(num, pi, pr, NOSET);
354 case RECT: /* Rectangle */
356 MOBopcode(c, parmlen);
357 MOBvdc( (Int)4, pi, pr);
361 (void) sprintf( mess, "(code: 0x%x)", c);
366 case 0x30: /* Delimiter Elements */
371 case BEGMF: /* Begin Metafile */
374 parmlen = STRINGSIZE(str);
375 MOBopcode(c, parmlen);
379 case ENDMF: /* End Metafile */
380 MOBopcode(c, (Long)0 );
383 case BEGPIC: /* Begin Picture Descriptor */
384 parmlen = STRINGSIZE(str);
385 MOBopcode(c, parmlen);
396 case BEGPICBODY: /* Begin Picture Body */
397 MOBopcode(c, (Long)0 );
400 case ENDPIC: /* End Picture */
401 MOBopcode(c, (Long)0 );
405 (void) sprintf( mess, "(code: 0x%x)", c);
411 case 0x31: /* Metafile Descriptor Elements */
414 case MFVERSION: /* Metafile version */
416 MOBopcode(c, parmlen);
420 case MFDESC: /* Metafile Description */
421 parmlen = STRINGSIZE(str);
422 MOBopcode(c, parmlen);
426 case VDCTYPE: /* VDC Type */
428 MOBopcode(c, parmlen);
429 PUTENUM ( cur.vdc_type );
432 case INTEGERPREC: /* Integer Precision */
434 MOBopcode(c, parmlen);
435 j = ( cur.int_bits <= 8 ? 8
436 : cur.int_bits <= 16 ? 16
437 : cur.int_bits <= 24 ? 24
443 case REALPREC: /* Real Precision */
444 parmlen = ENUMSIZE + 2*INTSIZE;
445 MOBopcode(c, parmlen);
446 PUTENUM ( curbin.real_type );
447 if ( curbin.real_type == FIXED )
448 { /* NB: only 16,16 and 32,32 are permitted */
450 (cur.real_bits > 16 || -cur.real_places > 16 ? 32 : 16);
451 curbin.real_fraction = curbin.real_whole;
453 PUTINT ( curbin.real_whole );
454 PUTINT ( curbin.real_fraction );
457 case INDEXPREC: /* Index Precision */
459 MOBopcode(c, parmlen);
460 curbin.index_prec = ( cur.index_bits <= 8 ? 8
461 : cur.index_bits <= 16 ? 16
462 : cur.index_bits <= 24 ? 24
464 PUTINT ( curbin.index_prec );
467 case COLRPREC: /* Colour Precision */
469 MOBopcode(c, parmlen);
470 curbin.col_prec = ( cur.col_bits <= 8 ? 8
471 : cur.col_bits <= 16 ? 16
472 : cur.col_bits <= 24 ? 24
474 PUTINT ( curbin.col_prec );
477 case COLRINDEXPREC: /* Colour Index Precision */
479 MOBopcode(c, parmlen);
480 curbin.colind_prec = ( cur.colind_bits <= 8 ? 8
481 : cur.colind_bits <= 16 ? 16
482 : cur.colind_bits <= 24 ? 24
484 PUTINT ( curbin.colind_prec );
487 case MAXCOLRINDEX: /* Maximum Colour Index */
488 parmlen = COLINDEXSIZE;
489 MOBopcode(c, parmlen);
490 MOBint (cur.max_colind, curbin.colind_prec, UNSIGNED);
493 case COLRVALUEEXT: /* Colour value extent */
494 parmlen = 6 * curbin.col_prec >>3;
495 MOBopcode(c, parmlen);
496 curbin.min_rgb.red = cur.min_rgb.red;
497 curbin.min_rgb.green = cur.min_rgb.green;
498 curbin.min_rgb.blue = cur.min_rgb.blue;
499 MOBcolour ( &curbin.min_rgb, DIRECT );
500 curbin.max_rgb.red = cur.max_rgb.red;
501 curbin.max_rgb.green = cur.max_rgb.green;
502 curbin.max_rgb.blue = cur.max_rgb.blue;
503 MOBcolour ( &curbin.max_rgb, DIRECT );
506 case MFELEMLIST: /* Metafile element List */
507 parmlen = INTSIZE + 2*num*INDEXSIZE;
508 MOBopcode(c, parmlen);
510 for(n = 0; n < num; n++, pi++)
516 class = -1; id = (Int)*pi;
519 MOBcharci( (Code)*pi, &class, &id);
527 case BEGMFDEFAULTS: /* Begin Metafile defaults Replacement */
528 /* Save current index value */
530 saveparmlen = mobparmlen;
532 /* Create new buffer */
534 mobbuff = mobdefbuff = (char *) malloc( (size_t)mobblen );
538 case ENDMFDEFAULTS: /* End Metafile defaults Replacement */
539 /* reset buffer and index */
540 mobbuff = mobstdbuff;
541 mobdeflen = mobindex;
544 mobparmlen = saveparmlen;
545 MOBopcode(BEGMFDEFAULTS, mobdeflen);
547 /* copy defaults buffer to output */
548 for ( n = 0; n < (int)mobdeflen; n++ )
549 PUTBYTE( mobdefbuff[n] );
553 case FONTLIST: /* Font List */
555 register Long *pt = pi;
557 for ( j=0, parmlen=0; j < num; j = *pt++ )
558 parmlen += STRINGSIZE( &str[j] );
559 MOBopcode(c, parmlen);
560 for ( j=0, pt = pi; j < num; j = *pt++ )
561 MOBstring( &str[j] );
565 case CHARSETLIST: /* Character set list */
567 register Long *pt = pi;
569 for ( j=0, parmlen=0; j < num; j = *pt++ )
571 parmlen += ENUMSIZE + STRINGSIZE(&str[j]);
574 MOBopcode(c, parmlen);
575 for ( j=0, pt = pi; j < num; j = *pt++ )
578 MOBstring( &str[j] );
583 case CHARCODING: /* Character coding Announcer */
585 MOBopcode(c, parmlen);
590 (void) sprintf( mess, "(code: 0x%x)", c);
595 case 0x32: /* Picture Descriptor Elements */
598 case SCALEMODE: /* Scaling Mode */
599 parmlen = ENUMSIZE + REALSIZE;
600 MOBopcode(c, parmlen);
601 PUTENUM ( cur.scale_mode );
602 MOBreal ( (Double)cur.scale_factor, FLOATING, REAL );
605 case COLRMODE: /* Colour Selection Mode */
607 MOBopcode(c, parmlen);
608 PUTENUM ( cur.color_mode );
611 case LINEWIDTHMODE: /* Line width Specification */
613 MOBopcode(c, parmlen);
614 PUTENUM ( cur.linewidth_mode );
617 case MARKERSIZEMODE: /* Marker size Specification */
619 MOBopcode(c, parmlen);
620 PUTENUM ( cur.markersize_mode );
623 case EDGEWIDTHMODE: /* Edge width Specification */
625 MOBopcode(c, parmlen);
626 PUTENUM ( cur.edgewidth_mode );
629 case VDCEXT: /* VDC Extent */
631 MOBopcode(c, parmlen);
632 if (cur.vdc_type == REAL)
634 PUTREALVDC ( cur.vdc_extent.a.x.real );
635 PUTREALVDC ( cur.vdc_extent.a.y.real );
636 PUTREALVDC ( cur.vdc_extent.b.x.real );
637 PUTREALVDC ( cur.vdc_extent.b.y.real );
641 PUTINTVDC ( cur.vdc_extent.a.x.intr );
642 PUTINTVDC ( cur.vdc_extent.a.y.intr );
643 PUTINTVDC ( cur.vdc_extent.b.x.intr );
644 PUTINTVDC ( cur.vdc_extent.b.y.intr );
648 case BACKCOLR: /* Background Colour */
649 parmlen = 3 * curbin.col_prec >>3;
650 MOBopcode(c, parmlen);
651 MOBcolour( &cur.back, DIRECT );
655 (void) sprintf( mess, "(code: 0x%x)", c);
659 case 0x33: /* Control Elements */
662 case VDCINTEGERPREC: /* VDC Integer Precision */
664 MOBopcode(c, parmlen);
665 curbin.vdcint_prec = ( cur.vdcint_bits <= 8 ? 8
666 : cur.int_bits <= 16 ? 16
667 : cur.int_bits <= 24 ? 24
669 PUTINT ( curbin.vdcint_prec );
672 case VDCREALPREC: /* VDC Real Precision */
673 parmlen = ENUMSIZE + 2*INTSIZE;
674 MOBopcode(c, parmlen);
675 PUTENUM ( curbin.vdc_type );
676 if ( curbin.real_type == FIXED )
677 { /* NB: only 16,16 or 32,32 permitted */
679 (cur.vdc_bits > 16 || -cur.vdc_places > 16 ? 32 : 16);
680 curbin.vdc_fraction = curbin.vdc_whole;
682 PUTINT ( curbin.vdc_whole );
683 PUTINT ( curbin.vdc_fraction );
686 case AUXCOLR: /* Auxiliary Colour */
687 parmlen = COLOURSIZE;
688 MOBopcode(c, parmlen);
689 MOBcolour( &cur.aux, cur.color_mode );
692 case TRANSPARENCY: /* Transparency */
694 MOBopcode(c, parmlen);
695 PUTENUM ( cur.transparency );
698 case CLIPRECT: /* Clip Rectangle */
700 MOBopcode(c, parmlen);
701 if ( cur.vdc_type == REAL )
703 PUTREALVDC ( cur.clip_rect.a.x.real );
704 PUTREALVDC ( cur.clip_rect.a.y.real );
705 PUTREALVDC ( cur.clip_rect.b.x.real );
706 PUTREALVDC ( cur.clip_rect.b.y.real );
710 PUTINTVDC ( cur.clip_rect.a.x.intr );
711 PUTINTVDC ( cur.clip_rect.a.y.intr );
712 PUTINTVDC ( cur.clip_rect.b.x.intr );
713 PUTINTVDC ( cur.clip_rect.b.y.intr );
717 case CLIP: /* Clip Indicator */
719 MOBopcode(c, parmlen);
720 PUTENUM ( cur.clip_ind );
724 (void) sprintf( mess, "(code: 0x%x)", c);
729 case 0x34: /* Circles and Ellipses */
732 case CIRCLE: /* Circle */
734 MOBopcode(c, parmlen);
735 MOBvdc( (Int)3, pi, pr );
738 case ARC3PT: /* Circular Arc 3 point */
740 MOBopcode(c, parmlen);
741 MOBvdc( (Int)6, pi, pr );
744 case ARC3PTCLOSE: /* Circular Arc 3 point close */
745 parmlen = 6*VDCSIZE + ENUMSIZE;
746 MOBopcode(c, parmlen);
747 MOBvdc( (Int)6, pi, pr );
751 case ARCCTR: /* Circle Arc centre */
753 MOBopcode(c, parmlen);
754 MOBvdc( (Int)7, pi, pr );
757 case ARCCTRCLOSE: /* Circle Arc centre close */
758 parmlen = 7*VDCSIZE + ENUMSIZE;
759 MOBopcode(c, parmlen);
760 MOBvdc( (Int)7, pi, pr );
764 case ELLIPSE: /* Ellipse */
766 MOBopcode(c, parmlen);
767 MOBvdc( (Int)6, pi, pr );
770 case ELLIPARC: /* Elliptical Arc */
771 parmlen = 10*VDCSIZE;
772 MOBopcode(c, parmlen);
773 MOBvdc( (Int)10, pi, pr );
776 case ELLIPARCCLOSE: /* Elliptical Arc close */
777 parmlen = 10*VDCSIZE + ENUMSIZE;
778 MOBopcode(c, parmlen);
779 MOBvdc( (Int)10, pi, pr );
780 PUTENUM ( *(pi+10) );
784 (void) sprintf( mess, "(code: 0x%x)", c);
789 case 0x35: /* Attributes */
793 case LINEINDEX: /* Line Bundle index */
795 MOBopcode(c, parmlen);
796 PUTINDEX ( curatt.line_ind );
799 case LINETYPE: /* Line Type */
801 MOBopcode(c, parmlen);
802 PUTINDEX ( curatt.line_type );
805 case LINEWIDTH: /* Line Width */
806 if(cur.linewidth_mode == SCALED)
809 MOBopcode(c, parmlen);
810 PUTREAL ( curatt.line_width.real );
815 MOBopcode(c, parmlen);
816 if ( cur.vdc_type == REAL )
817 PUTREALVDC ( curatt.line_width.real );
818 else PUTINTVDC ( curatt.line_width.intr );
822 case LINECOLR: /* Line Colour */
823 parmlen = COLOURSIZE;
824 MOBopcode(c, parmlen);
825 MOBcolour( &curatt.line, cur.color_mode);
828 case MARKERINDEX: /* Marker Bundle index */
830 MOBopcode(c, parmlen);
831 PUTINDEX ( curatt.mark_ind );
834 case MARKERTYPE: /* Marker Type */
836 MOBopcode(c, parmlen);
837 PUTINDEX ( curatt.mark_type );
840 case MARKERSIZE: /* Marker Size */
841 if(cur.markersize_mode == SCALED)
844 MOBopcode(c, parmlen);
845 PUTREAL ( curatt.mark_size.real );
850 MOBopcode(c, parmlen);
851 if ( cur.vdc_type == REAL )
852 PUTREALVDC ( curatt.mark_size.real );
853 else PUTINTVDC ( curatt.mark_size.intr );
857 case MARKERCOLR: /* Marker Colour */
858 parmlen = COLOURSIZE;
859 MOBopcode(c, parmlen);
860 MOBcolour( &curatt.marker, cur.color_mode);
863 case TEXTINDEX: /* Text Bundle index */
865 MOBopcode(c, parmlen);
866 PUTINDEX ( curatt.text_ind );
869 case TEXTFONTINDEX: /* Text Font Index */
871 MOBopcode(c, parmlen);
872 PUTINDEX ( curatt.text_font );
875 case TEXTPREC: /* Text Precision */
877 MOBopcode(c, parmlen);
878 PUTENUM ( curatt.text_prec );
881 case CHAREXPAN: /* Character Expansion Factor */
883 MOBopcode(c, parmlen);
884 PUTREAL ( curatt.char_exp );
887 case CHARSPACE: /* Character Spacing */
889 MOBopcode(c, parmlen);
890 PUTREAL ( curatt.char_space );
893 case TEXTCOLR: /* Text Colour */
894 parmlen = COLOURSIZE;
895 MOBopcode(c, parmlen);
896 MOBcolour( &curatt.text, cur.color_mode);
899 case CHARHEIGHT: /* Character Height */
901 MOBopcode(c, parmlen);
902 if ( cur.vdc_type == REAL )
903 PUTREALVDC ( curatt.char_height.real );
904 else PUTINTVDC ( curatt.char_height.intr );
907 case CHARORI: /* Character Orientation */
909 MOBopcode(c, parmlen);
910 if ( cur.vdc_type == REAL )
912 PUTREALVDC ( curatt.char_up.x.real );
913 PUTREALVDC ( curatt.char_up.y.real );
914 PUTREALVDC ( curatt.char_base.x.real );
915 PUTREALVDC ( curatt.char_base.y.real );
919 PUTINTVDC (curatt.char_up.x.intr );
920 PUTINTVDC (curatt.char_up.y.intr );
921 PUTINTVDC (curatt.char_base.x.intr );
922 PUTINTVDC (curatt.char_base.y.intr );
926 case TEXTPATH: /* Text Path */
928 MOBopcode(c, parmlen);
929 PUTENUM ( curatt.text_path );
932 case TEXTALIGN: /* Text Alignment */
933 parmlen = 2*ENUMSIZE + 2*REALSIZE;
934 MOBopcode(c, parmlen);
935 PUTENUM ( curatt.text_halign );
936 PUTENUM ( curatt.text_valign );
937 PUTREAL ( curatt.text_hcont );
938 PUTREAL ( curatt.text_vcont );
941 case CHARSETINDEX: /* Character Set Index */
943 MOBopcode(c, parmlen);
944 PUTINDEX ( curatt.char_set );
947 case ALTCHARSETINDEX: /* Alt Character Set Index */
949 MOBopcode(c, parmlen);
950 PUTINDEX ( curatt.altchar_set );
954 (void) sprintf( mess, "(code: 0x%x)", c);
959 case 0x36: /* More Attributes */
962 case FILLINDEX: /* Fill Bundle index */
964 MOBopcode(c, parmlen);
965 PUTINDEX ( curatt.fill_ind );
968 case INTSTYLE: /* Interior Style */
970 MOBopcode(c, parmlen);
971 PUTENUM ( curatt.int_style );
974 case FILLCOLR: /* Fill Colour */
975 parmlen = COLOURSIZE;
976 MOBopcode(c, parmlen);
977 MOBcolour( &curatt.fill, cur.color_mode);
980 case HATCHINDEX: /* Hatch Index */
982 MOBopcode(c, parmlen);
983 PUTINDEX(curatt.hatch_ind );
986 case PATINDEX: /* Pattern Index */
988 MOBopcode(c, parmlen);
989 PUTINDEX(curatt.pat_ind );
992 case EDGEINDEX: /* Edge Bundle index */
994 MOBopcode(c, parmlen);
995 PUTINDEX(curatt.edge_ind );
998 case EDGETYPE: /* Edge Type */
1000 MOBopcode(c, parmlen);
1001 PUTINDEX(curatt.edge_type );
1004 case EDGEWIDTH: /* Edge Width */
1005 if(cur.edgewidth_mode == SCALED)
1008 MOBopcode(c, parmlen);
1009 PUTREAL ( curatt.edge_width.real );
1014 MOBopcode(c, parmlen);
1015 if ( cur.vdc_type == REAL )
1016 PUTREALVDC ( curatt.edge_width.real );
1017 else PUTINTVDC ( curatt.edge_width.intr );
1021 case EDGECOLR: /* Edge Colour */
1022 parmlen = COLOURSIZE;
1023 MOBopcode(c, parmlen);
1024 MOBcolour( &curatt.edge, cur.color_mode);
1027 case EDGEVIS: /* Edge Visibility */
1029 MOBopcode(c, parmlen);
1030 PUTENUM ( curatt.edge_vis );
1033 case FILLREFPT: /* Fill Reference Point */
1034 parmlen = 2*VDCSIZE;
1035 MOBopcode(c, parmlen);
1036 if ( cur.vdc_type == REAL )
1038 PUTREALVDC ( curatt.fill_ref.x.real );
1039 PUTREALVDC ( curatt.fill_ref.y.real );
1043 PUTINTVDC ( curatt.fill_ref.x.intr );
1044 PUTINTVDC ( curatt.fill_ref.y.intr );
1048 case PATTABLE: /* Pattern Table */
1050 register Long *pt = pi, patind, i, k;
1054 parmlen = INDEXSIZE + 3*INTSIZE;
1058 pt++; /* ignore previous local precision */
1060 /* Find local precision */
1062 n = (cur.color_mode == DIRECT ? 3*num : num );
1063 for ( i = 0, k = 0; i < n; i++, pt++ )
1065 if ( *pt > k ) k = *pt;
1072 lprec = ( j <= 1 ? 1
1080 /* Work out parameter length in bytes */
1082 parmlen += ( lprec * (cur.color_mode == DIRECT ? 3*num : num )
1085 MOBopcode(c, parmlen);
1087 PUTINDEX ( patind );
1092 /* Output whole cell array */
1094 MOBclist ( num, pi + 4, cur.color_mode, PACKED, lprec);
1098 case PATSIZE: /* Pattern Size */
1099 parmlen = 4*VDCSIZE;
1100 MOBopcode(c, parmlen);
1101 if ( cur.vdc_type == REAL )
1103 PUTREALVDC ( curatt.pat_size.a.x.real );
1104 PUTREALVDC ( curatt.pat_size.a.y.real );
1105 PUTREALVDC ( curatt.pat_size.b.x.real );
1106 PUTREALVDC ( curatt.pat_size.b.y.real );
1110 PUTINTVDC ( curatt.pat_size.a.x.intr );
1111 PUTINTVDC ( curatt.pat_size.a.y.intr );
1112 PUTINTVDC ( curatt.pat_size.b.x.intr );
1113 PUTINTVDC ( curatt.pat_size.b.y.intr );
1117 case COLRTABLE: /* Colour Table */
1118 parmlen = COLINDEXSIZE + ((3*num*curbin.col_prec)>>3);
1119 MOBopcode(c, parmlen);
1120 MOBint(*pi++, curbin.colind_prec, UNSIGNED);
1121 for ( j=0; j < num; j++)
1123 MOBint(*pi++, curbin.col_prec, UNSIGNED);
1124 MOBint(*pi++, curbin.col_prec, UNSIGNED);
1125 MOBint(*pi++, curbin.col_prec, UNSIGNED);
1129 case ASF: /* Aspect source flags */
1133 Logical asflag[ASFS];
1135 for ( j=0; j < ASFS; j++) asflag[j] = FALSE;
1136 for ( j=0; j < num; j++ )
1138 type = *pt++; value = (*pt++) + 1;
1139 if ( type < ASFS ) asflag[type] = value;
1144 case 506: /* all edge */
1145 k = 15; l = 17; break;
1146 case 507: /* all fill */
1147 k = 11; l = 14; break;
1148 case 508: /* all text */
1149 k = 6; l = 10; break;
1150 case 509: /* all marker */
1151 k = 3; l = 5; break;
1152 case 510: /* all line */
1153 k = 0; l = 2; break;
1155 k = 0; l = 17; break;
1156 default: /* ignore */
1157 k = 1; l = 0; break;
1159 for ( n = k; n < l; n++ ) asflag[n] = value;
1162 for ( j=0; j < ASFS; j++)
1163 if ( asflag[j] ) parmlen += 2*ENUMSIZE;
1164 MOBopcode(c, parmlen);
1165 for ( j=0; j < ASFS; j++)
1169 PUTENUM ( curatt.asf[j] );
1175 (void) sprintf( mess, "(code: 0x%x)", c);
1180 case 0x37: /* Escape And External Elements */
1183 case ESCAPE: /* Escape */
1184 parmlen = INTSIZE + STRINGSIZE(str);
1185 MOBopcode(c, parmlen);
1190 case MESSAGE: /* Message */
1191 parmlen = ENUMSIZE + STRINGSIZE(str);
1192 MOBopcode(c, parmlen);
1197 case APPLDATA: /* Application Data */
1198 parmlen = INTSIZE + STRINGSIZE(str);
1199 MOBopcode(c, parmlen);
1205 (void) sprintf( mess, "(code: 0x%x)", c);
1211 (void) sprintf( mess, "(code: 0x%x)", c);
1217 /******************************************************** MOBopcode ****/
1220 MOBopcode( Code c, Long len )
1223 unsigned Long oneword, plen, remainder;
1226 /* Pad out last element if necessary */
1227 while ( mobparmlen && mobparmlen < 0x8000 ) PUTBYTE( ZERO );
1232 /* check for parameter length > 32766 */
1234 if ( plen > 0x7ffe )
1236 remainder = plen - 0x7ffe;
1242 if ( c != PARTITION )
1244 MOBcharci(c, &class, &id);
1245 oneword = (class<<12) + (id<<5) + ( part || (plen > 0x1e) ? 0x1f : plen );
1246 PUTWORD ( oneword );
1249 /* Put out parameter length as integer */
1251 if ( c == PARTITION || plen > 0x1e )
1253 oneword = ( part ? plen | 0x8000 : plen );
1254 PUTWORD ( oneword );
1258 mobremainder = remainder;
1259 if (mobparmlen & 1) mobparmlen++;
1263 /******************************************************** MOBcharci ****/
1265 MOBcharci( Code c, Int *class, Int *id )
1267 /* Converts Code c to class and Id */
1269 Code major = c>>8, minor = c & 0xff;
1271 *class = -1; *id = 0;
1274 case 0x00: /* Graphics Primitives */
1275 if ( minor >= 0x20 && minor <= 0x2A )
1277 *class = 4; *id = minor - 0x20 + 1;
1279 else if ( minor == 0 ) *class = ZERO; /* Non-Op */
1282 case 0x30: /* Metafile delimiters */
1283 if ( minor >= 0x20 && minor <= 0x24 )
1285 *class = 0; *id = minor - 0x20 + 1;
1289 case 0x31: /* Metafile Descriptor Elements */
1290 if ( minor >= 0x20 && minor <= 0x2b )
1292 *class = 1; *id = minor - 0x20 + 1;
1294 else if ( minor > 0x2c && minor <= 0x2f )
1296 *class = 1; *id = minor - 0x20;
1300 case 0x32: /* Picture Descriptor Elements */
1301 if ( minor >= 0x20 && minor <= 0x26 )
1303 *class = 2; *id = minor - 0x20 + 1;
1307 case 0x33: /* Control Elements */
1308 if ( minor >= 0x20 && minor <= 0x25 )
1310 *class = 3; *id = minor - 0x20 + 1;
1314 case 0x34: /* More Graphics Primitives */
1315 if ( minor >= 0x20 && minor <= 0x27 )
1317 *class = 4; *id = minor - 0x20 + 12;
1321 case 0x35: /* Attributes */
1322 if ( minor >= 0x20 && minor <= 0x27 )
1324 *class = 5; *id = minor - 0x20 + 1;
1326 else if ( minor >= 0x30 && minor <= 0x3b )
1328 *class = 5; *id = minor - 0x30 + 9;
1332 case 0x36: /* More Attributes */
1333 if ( minor >= 0x20 && minor <= 0x2c )
1335 *class = 5; *id = minor - 0x20 + 21;
1337 else if ( minor >= 0x30 && minor <= 0x31 )
1339 *class = 5; *id = minor - 0x30 + 34;
1343 case 0x37: /* External elements */
1344 if ( minor == 0x20 )
1346 *class = 6; *id = 1;
1348 else if ( minor >= 0x21 && minor <= 0x22 )
1350 *class = 7; *id = minor - 0x20;
1360 (void) sprintf( mess, "(code: 0x%x)", c);
1367 /******************************************************** MOBint *******/
1369 MOBint( Long n, Prec prec, Enum sign )
1372 if ( sign == SIGNED && n < 0 )
1373 n = (-n | (Posint) 1L<<(prec-1));
1375 MOBout( (Posint) n, prec>>3 );
1379 /******************************************************** MOBcolour ****/
1381 MOBcolour( struct colour *col, Enum type )
1384 if ( type == DIRECT )
1386 MOBint( (Long) col->red, curbin.col_prec, UNSIGNED );
1387 MOBint( (Long) col->green, curbin.col_prec, UNSIGNED );
1388 MOBint( (Long) col->blue, curbin.col_prec, UNSIGNED );
1392 MOBint( (Long) col->index, curbin.colind_prec, UNSIGNED );
1398 /******************************************************** MOBvdc *******/
1400 MOBvdc( Int n, Long *pi, Float *pr)
1403 for ( i = 0; i < n; i++)
1405 if ( cur.vdc_type == INTEGER )
1407 PUTINTVDC ( *pi++ );
1411 PUTREALVDC ( *pr++ );
1418 /******************************************************** MOBpointlist */
1420 MOBpointlist(Long n, Long *pi, Float *pr, Enum set)
1423 for ( i = 0; i < n; i++)
1425 if ( cur.vdc_type == INTEGER )
1427 PUTINTVDC ( *pi++ );
1428 PUTINTVDC ( *pi++ );
1432 PUTREALVDC ( *pr++ );
1433 PUTREALVDC ( *pr++ );
1435 if ( set ) PUTENUM ( *pi++ );
1441 /******************************************************** MOBreal ******/
1443 MOBreal(Double x, Enum real_type, Enum real_or_vdc )
1445 Posint whole, exponent, fract, neg;
1448 neg = ( x < 0.0 ) << 15;
1450 if ( real_type == FIXED )
1452 prec = (real_or_vdc == VDC ? curbin.vdc_whole
1453 : curbin.real_whole);
1454 whole = (Posint)( neg ? -((floor(x))) : x );
1455 fract = (Posint)( ( neg ? x + (Double)whole : x - (Double)whole )
1456 * ( 1L<<(prec-2) ) * 4.0 );
1460 PUTWORD( whole>>16 | neg );
1461 PUTWORD( whole & (Posint)0xffff );
1462 PUTWORD( fract>>16 );
1463 PUTWORD( fract & (Posint)0xffff );
1467 PUTWORD( whole | neg );
1473 /* IEEE Floating point reals */
1475 prec = (real_or_vdc == VDC ? curbin.vdc_whole + curbin.vdc_fraction
1476 : curbin.real_whole + curbin.real_fraction);
1477 prec = (prec == 64 ? 12 : 9);
1478 f = ( neg ? -x : x );
1480 if ( f < (Double)(real_or_vdc == VDC ? cur.vdcmin : cur.realmin) )
1488 /* check if greater than smallest exponent */
1490 exponent = ( prec == 12 ? 1023 : 127 );
1492 if ( f <= 1.0 / (Double) (prec-1) )
1509 fract = (Long) ( (f - 1.0) * (Double)(1L<<(prec == 12 ? 52 : 23)) );
1515 PUTWORD( (exponent<<4) | neg | (fract>>48) );
1516 PUTWORD( (fract >> 32) & (Posint)0xffff );
1517 PUTWORD( (fract >> 16) & (Posint)0xffff );
1518 PUTWORD( fract & (Posint)0xffff );
1523 PUTWORD( (exponent<<7) | neg | (fract>>16) );
1524 PUTWORD( fract & (Posint)0xffff );
1530 /******************************************************** MOBstring ****/
1532 MOBstring( char *s )
1534 /* Output a text string if CMS translate from EBCDIC to ASCII */
1536 register Int i, len, slen = strlen(s);
1541 PUTBYTE ( len >= 0xff ? 0xff : len );
1543 } while ( len >= 0 );
1545 for (i = 0; i < slen; i++)
1553 /******************************************************** MOBclist *****/
1555 MOBclist( register Long num, register Long *col,
1556 Prec mode, Enum type, Prec prec )
1558 /* Output a colour list */
1560 register Long j, k, n;
1561 Long bits, bytes = 0;
1562 if ( type == RUNLENGTH )
1564 Long run = 1, bit = 0;
1566 if ( mode == DIRECT )
1568 Posint red, green, blue, lastred, lastgreen, lastblue;
1571 lastgreen = (*col++);
1572 lastblue = (*col++);
1573 for ( j = 1; j <= num; j++ )
1575 red = (*col++); green = (*col++); blue = (*col++);
1577 red != lastred || green != lastgreen || blue != lastblue )
1579 MOBbits ( run, curbin.int_prec, &bit );
1580 MOBbits ( lastred, prec, &bit );
1581 MOBbits ( lastgreen, prec, &bit );
1582 MOBbits ( lastblue, prec, &bit );
1583 if ( j == num ) break;
1584 lastred = red; lastgreen = green; lastblue = blue;
1590 else /* Indexed runlength */
1595 for ( j = 1; j <= num; j++, col++ )
1597 if ( j == num || *col != lastcol )
1599 MOBbits ( run, curbin.int_prec, &bit );
1600 MOBbits ( lastcol, prec, &bit );
1601 if ( j == num ) break;
1609 /* make sure list ends on a word boundary */
1611 if ( bit ) MOBbits ( (Posint) 0 , (Prec) 16, &bit );
1614 else /* Packed mode */
1616 n = ( mode == DIRECT ? 3*num : num );
1617 bytes = ( n*prec + 7 ) >>3;
1619 for ( j = 0, bits = 0, k = 0; j < n; j++)
1621 if ( bits ) k <<= prec;
1629 PUTBYTE ( (k>>bits) & 0xff );
1632 if ( bits > 0 ) PUTBYTE ( k<<(8-bits) );
1634 /* Pad buffer if necessary */
1635 if ( bytes & 1 ) PUTBYTE ( 0 );
1640 /******************************************************** MOBbits ******/
1642 MOBbits ( Posint value, Prec prec, Long *bit )
1644 /* Output 'value' as 'prec' bits
1645 using 'word' to hold current value
1646 returns number of bits left in 'bits' */
1648 static Posint oneword = 0;
1649 Posint mask = (Posint)0xffffffff;
1653 oneword |= value<<(16 - *bit);
1660 /* k = prec + *bit - 16; */
1661 oneword |= value>>*bit;
1662 value &= mask>>(32 - *bit);
1663 MOBout ( oneword, WORD );
1664 oneword = value<<16;
1666 oneword = value<<(16 - *bit);
1671 /******************************************************** MOBout *******/
1673 MOBout( Posint hex, Prec bytes )
1675 /* Output 'hex' as 'bytes' bytes to output file 'cgmob'
1676 which is either the file or MF defaults buffer */
1678 register Int /*i,*/ b_len;
1681 if ( bytes > 0 ) for( ; bytes ; mobindex++ )
1684 mobbuff[mobindex] = (char)((hex >> (8*bytes) ) & 0xff);
1687 fwrite(mobbuff,b_len,(size_t)1,cgmob);
1690 if ( bytes > 0 ) for( ; bytes ; mobindex++ )
1692 if ( mobindex == mobblen )
1694 if ( cgmstate != MF_DEFAULTS )
1696 fwrite(mobbuff,mobblen,(size_t)1,cgmob);
1701 mobblen += BUFF_LEN;
1702 mobbuff = (char *)realloc (mobbuff, (size_t)mobblen);
1705 if ( mobindex == ZERO )
1707 for(i = ZERO; i < mobblen ; i++) mobbuff[i] = '\0';
1710 mobbuff[mobindex] = ( hex>>(8*bytes) ) & 0xff;
1715 fwrite(mobbuff,BUFF_LEN,(size_t)1,cgmob);
1719 if ( mobremainder && mobparmlen == 0 )
1721 if ( mobremainder > 0x7ffe )
1724 mobremainder -= 0x7ffe;
1731 mobparmlen = hex & 0x7fff;