7fd59977 |
1 | #include "cgmout.h" |
2 | |
3 | /* File stream name */ |
4 | |
5 | extern char cgmroot[]; |
6 | static 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 */ |
13 | void CGMOchar(FILE *stream, Code c, Long *pi, Float *pr, char *pc); |
14 | /* Check Attributes */ |
15 | static 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 |
47 | void CGMOchar(); /* Main Output driver */ |
48 | static 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 | |
68 | static Long subchars=0; |
69 | static char charsub[CHARSUBNUM]; |
70 | |
71 | /*static char *func="CGMochar", mess[40];*/ |
72 | static 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 | |
93 | void |
94 | CGMOchar(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 ******/ |
900 | static void |
901 | MOCchkatt ( 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 ******/ |
1313 | static void |
1314 | MOCattrib ( 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 ********/ |
1535 | static void |
1536 | MOCcint ( 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 *******/ |
1559 | static void |
1560 | MOCcenum (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 *******/ |
1583 | static void |
1584 | MOCcreal (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 *******/ |
1599 | static void |
1600 | MOCrectc( 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 ********/ |
1645 | static void |
1646 | MOCccol (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 *********/ |
1677 | static void |
1678 | MOCvdc (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 ******/ |
1695 | static void |
1696 | MOCpoints(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 ********/ |
1746 | static void |
1747 | MOCreal ( 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 *****/ |
1835 | static void |
1836 | MOCinteger (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 ******/ |
1869 | static void |
1870 | MOCstring (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 *******/ |
1888 | static void |
1889 | MOCcells (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 ******/ |
2106 | static void |
2107 | MOCdircol ( 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 ******/ |
2138 | static void |
2139 | MOCcoldef () |
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 *********/ |
2172 | static void |
2173 | MOCout ( 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 | } |