PLplot 5.15.0
Loading...
Searching...
No Matches
cd.c
Go to the documentation of this file.
1
2// cd.c main file for cgmdraw module.
3//
4// Written by G. Edward Johnson <mailto:lorax@nist.gov>
5// Date: April 1996
6// Copyright: cd software produced by NIST, an agency of the
7// U.S. government, is by statute not subject to copyright
8// in the United States. Recipients of this software assume all
9// responsibilities associated with its operation, modification
10// and maintenance.
11//
12// Portions of this package are from the gd package written by
13// Thomas Boutell and are copyright 1994, 1995, Quest Protein
14// Database Center, Cold Spring Harbor Labs. They are marked in the
15// source code.
16//
17
18#ifndef NOMALLOCH
19#include <malloc.h>
20#endif
21#include <stdio.h>
22#include <math.h>
23#include <string.h>
24#include <stdlib.h>
25#include "defines.h"
26#include "cd.h"
27
28
29static int cdImageAddColor( cdImagePtr im, int si, int ei );
30
31cdImagePtr cdImageCreate( int sx, int sy )
32// Creates a new image of size (sx,sy). Most people should always
33// start by calling this function
34{
35 cdImagePtr im;
36
37 im = cdImageStartCgm();
38 if ( !im )
39 return 0; // memory allocation failed
40 if ( !cdImageSetSize( im, sx, sy ) )
41 {
42 free( im ); return 0;
43 }
44
45 if ( !cdCgmHeader( im ) )
46 {
47 free( im ); return 0;
48 }
49
50 if ( cdCgmPic( im, 0 ) )
51 {
52 return im;
53 }
54 else
55 {
56 free( im );
57 return 0;
58 }
59}
60
61static int cdAppNull( unsigned char *es, int x )
62{
63// put x nulls in the string.
64// return value is number of octets added (1)
65 int y;
66
67 for ( y = 0; y < x; y++ )
68 {
69 *es = '\0';
70 es++;
71 }
72 return x;
73}
74
75static int cdAppByte( unsigned char *es, short int addme )
76{
77// Append an octet to the end of es
78// Return value is number of octets added
79// for internal cd functions only, do not call
80//
81 *es = (unsigned char) addme & 0377;
82 return 1;
83}
84
85static int cdAppShort( unsigned char *es, short int addme )
86{
87// Append a short to the end of es
88// return value is number of octets added
89// For internal cd functions only, do not call!
90//
91 short int temp;
92
93 temp = addme >> 8;
94 *es = (unsigned char) temp & 0377;
95 es++;
96 *es = (unsigned char) addme & 0377;
97 return 2;
98}
99
100// static int cdAppWord(unsigned char *es, int addme){
101// Append an word to es
102// Return value is number of octets added
103// For internal cd functions only, do not call!
104//
105//
106// int temp;
107// temp = addme >> 24;
108//es = (unsigned char) temp & 0377;
109// es++;
110// temp = addme >> 16;
111//es = (unsigned char) temp & 0377;
112// es++;
113// temp = addme >> 8;
114//es = (unsigned char) temp & 0377;
115// es++;
116//es = (unsigned char) addme & 0377;
117// es++;
118// return 4;
119// }
120//
121
122static int cdcomhead( unsigned char *es, int elemclass, int id, int len )
123{
124// sets the command header in the first two bytes of string es
125// element class is in bits 15-12
126// element id is in bits 11-5
127// parameter list length is in bits 4-0
128//
129 int temp;
130
131 if ( !es )
132 return 0; // the string must be allocated first
133
134 // set the element class
135 *es = (unsigned char) elemclass << 4;
136 // set the element id
137 temp = 0177 & id;
138 temp = temp >> 3;
139 *es = *es | temp;
140 es++;
141 id = id << 5;
142 *es = (unsigned char) id;
143 *es = *es | (unsigned char) ( 037 & len );
144
145 return 1;
146}
147
148static int cdcomheadlong( unsigned char *es, int elemclass, int id, int len )
149{
150// sets the command header for the long form.
151// first 16 bits:
152// element class is in bits 15-12
153// element id is in bits 11-5
154// parameter list length is in bits 4-0 = 31
155// second 16 bits:
156// bit 15 = 0 (for last partition)
157// bit 14-0 param list len
158//
159
160 // I'm lazy, call cdcomhead to set the first two bytes
161 if ( !cdcomhead( es, elemclass, id, 31 ) )
162 return 0;
163 es += 2;
164
165 // now set the second two bytes
166 cdAppShort( es, (short int) len );
167 *es = *es & 0177; // make bit 15 = 0
168 es += 2;
169
170 return 1;
171}
172
173static int cdAddElem( cdImagePtr im, unsigned char *es, int octet_count )
174// adds a string, which is a CGM element to the elemlist.
175// This function is called by other functions in this library and
176// should NOT be called by users of the library
177// For internal cd functions only, do not call!
178//
179{
180 unsigned char *newlist; // in case memory allocation fails
181 int x; // counter
182
183 while ( ( octet_count + 1 ) >= im->bytestoend )
184 {
185 // not enough space, must grow elemlist
186 im->listlen = im->listlen + CDGROWLISTSIZE;
187 newlist = (unsigned char *) realloc( im->elemlist, SIZEOF( unsigned char ) * im->listlen );
188 if ( newlist )
189 {
190 // successfully allocated memory
191 im->elemlist = newlist;
192 im->bytestoend = im->bytestoend + CDGROWLISTSIZE;
193 im->curelemlist = im->elemlist + ( im->listlen - im->bytestoend );
194 }
195 else
196 {
197 // memory allocation failed, save yurself
198 im->listlen = im->listlen - CDGROWLISTSIZE;
199 return 0;
200 }
201 }
202
203 // ok, if we get to here, there is enough space, so add it.
204 for ( x = 0; x < octet_count; x++ )
205 {
206 *im->curelemlist = (unsigned char) *es;
207 im->curelemlist++;
208 es++;
209 }
210 im->bytestoend = im->bytestoend - octet_count;
211 return 1;
212}
213
215{
216// add the cgm header to the imagepointer's element list
217// do it all in a string than call cdAddElem on it
218// For internal cd functions only, do not call!
219//
220 unsigned char *headerp;
221 unsigned char *head;
222 const unsigned char *buf, *buf2;
223 int octet_count = 0;
224 int blen; // length of buf
225 int curly;
226 int fontlistlen; // each font in the font list is stored as a string,
227 // with a single octet in front of the string
228 // giving its length, fontlistlen is the sum of
229 // the lengths of all the font strings + the
230 // length octets.
231
232 if ( im->state != 0 )
233 return 0;
234 headerp = (unsigned char *) calloc( 1024, SIZEOF( unsigned char ) );
235 if ( !headerp )
236 return 0; // memory allocation failed
237 head = headerp;
238
239 //** Attribute: BegMF; Elem Class 0; Elem ID 1
240 buf = (const unsigned char *) "cd: CgmDraw Library";
241 blen = strlen( (const char *) buf );
242 cdcomhead( head, 0, 1, blen + 1 );
243 head += 2;
244 head += cdAppByte( head, (short int) blen );
245 buf2 = buf;
246 while ( *buf2 )
247 {
248 *head++ = *buf2++;
249 }
250 octet_count += ( blen + 3 );
251 curly = 4 - ( octet_count % 4 );
252 if ( curly % 4 )
253 {
254 octet_count += curly;
255 head += cdAppNull( head, curly );
256 }
257
258 //** Attribute: MFVersion; Elem Class 1; Elem ID 1
259 cdcomhead( head, 1, 1, 2 );
260 head += 2;
261 head += cdAppShort( head, (short int) 1 );
262 octet_count += 4;
263
264 //** Attribute: MFDesc; Elem Class 1; Elem ID 2
265 blen = strlen( (char *) im->desc );
266 cdcomheadlong( head, 1, 2, blen + 1 );
267 head += 4;
268 head += cdAppByte( head, (short int) blen );
269 buf2 = im->desc;
270 while ( *buf2 )
271 {
272 *head++ = *buf2++;
273 }
274 octet_count += ( blen + 5 );
275 curly = 4 - ( octet_count % 4 );
276 if ( curly % 4 )
277 {
278 octet_count += curly;
279 head += cdAppNull( head, curly );
280 }
281
282 //** Attribute: ColrPrec; Elem Class 1; Elem ID 7
283 cdcomhead( head, 1, 7, 2 );
284 head += 2;
285 head += cdAppShort( head, (short int) 8 );
286 octet_count += 4;
287
288 //** Attribute: ColrIndexPrec; Elem Class 1; Elem ID 8
289 cdcomhead( head, 1, 8, 2 );
290 head += 2;
291 head += cdAppShort( head, (short int) 8 );
292 octet_count += 4;
293
294 //** Attribute: MaxColrIndex; Elem Class 1; Elem ID 9
295 cdcomhead( head, 1, 9, 1 );
296 head += 2;
297 head += cdAppByte( head, (short int) 255 );
298 octet_count += 4; head++;
299
300 //** Attribute: MFElemList; Elem Class 1; Elem ID 11
301 // shorthand here. 1 means 1 element specified, (-1,1)
302 // means drawing-plus-control set
303 cdcomhead( head, 1, 11, 6 );
304 head += 2;
305 head += cdAppShort( head, (short int) 1 );
306 head += cdAppShort( head, (short int) -1 );
307 head += cdAppShort( head, (short int) 1 );
308 octet_count += 8;
309
310 //** Attribute: FontList; Elem Class 1; Elem ID 13
311 // im->fontlist contains a comma separated list of font names
312 // since we don't need the commas, and every font except one has
313 // a comma, and we do need a length octet, that means that
314 // taking the string length will give us one less than the
315 // correct length.
316 buf = im->fontlist;
317 if ( buf ) // don't do this if there aren't any fonts
318 {
319 fontlistlen = strlen( (const char *) buf ) + 1;
320 cdcomheadlong( head, 1, 13, fontlistlen );
321 head += 4;
322
323 while ( *buf )
324 {
325 blen = 0;
326 buf2 = buf;
327 while ( ( *buf ) && ( *buf != ',' ) )
328 {
329 buf++;
330 blen++;
331 }
332 head += cdAppByte( head, (short int) blen );
333 while ( buf2 < buf )
334 {
335 *head++ = *buf2++;
336 }
337 if ( *buf )
338 {
339 buf++;
340 }
341 }
342 octet_count += ( 4 + fontlistlen );
343 curly = 4 - ( octet_count % 4 );
344 if ( curly % 4 )
345 {
346 octet_count += curly;
347 head += cdAppNull( head, curly );
348 }
349 } // end of check to see if any fonts
350
351 if ( cdAddElem( im, headerp, octet_count ) )
352 {
353 free( headerp );
354 headerp = 0;
355 return 1;
356 }
357 else
358 {
359 free( headerp );
360 return 0;
361 }
362}
363
364
365int cdCgmPic( cdImagePtr im, int sticky )
366{
367// Start the picture. if the sticky bit is set, set and use the defaults
368// of the previous picture. Otherwise, reset all defaults.
369// Gej: sticky = 0 reset defaults, 1 dont reset anything, 2 only
370// reset the color table
371//
372 unsigned char *headerp;
373 unsigned char *head;
374 unsigned char *buf, *buf2;
375 char *tb;
376 int octet_count = 0;
377 int blen; // length of buf
378 int x1, x2, x3, x4; // needed for setting defaults
379
380 if ( ( im->state != 0 ) && ( im->state != 2 ) )
381 return 0;
382 if ( ( sticky > 2 ) || ( sticky < 0 ) )
383 return 0; // invalid sticky bit
384 // increment the picture number
385 im->picnum++;
386 tb = (char *) calloc( 4 * 4, SIZEOF( char ) );
387 if ( !tb )
388 return 0; // memory allocation failed
389 headerp = (unsigned char *) calloc( 1024, SIZEOF( unsigned char ) );
390 if ( !headerp )
391 { // memory allocation failed
392 free( tb );
393 return 0;
394 }
395 head = headerp;
396
397 //** Attribute: BegPic; Elem Class 0; Elem ID 3
398 sprintf( tb, "picture %d", im->picnum );
399 buf = (unsigned char *) tb;
400 // buf = (unsigned char *) "picture 1";
401 blen = strlen( (char *) buf );
402 cdcomhead( head, 0, 3, blen + 1 );
403 head += 2;
404 head += cdAppByte( head, (short int) blen );
405 buf2 = buf;
406 while ( *buf2 )
407 {
408 *head++ = *buf2++;
409 }
410 free( tb );
411 octet_count += ( blen + 3 );
412 if ( !( blen % 2 ) )
413 {
414 octet_count++;
415 head += cdAppNull( head, 1 );
416 }
417 if ( octet_count % 4 )
418 {
419 octet_count += 2;
420 head += cdAppNull( head, 2 );
421 }
422
423 //** Attribute: ColrMode; Elem Class 2; Elem ID 2
424 cdcomhead( head, 2, 2, 2 );
425 head += 2;
426 head += cdAppShort( head, (short int) 0 );
427 octet_count += 4;
428 // Picture Descriptor: Line Width Specification Mode;
429 // Elem Class 2; Elem ID 3
430 if ( sticky && ( im->linespec != CDLINESPEC ) )
431 {
432 cdcomhead( head, 2, 3, 2 );
433 head += 2;
434 head += cdAppShort( head, (short int) im->linespec );
435 octet_count += 4;
436 }
437 // Picture Descriptor: Marker Size Specification Mode;
438 // Elem Class 2; Elem ID 4
439 if ( sticky && ( im->markerspec != CDMARKERSPEC ) )
440 {
441 cdcomhead( head, 2, 4, 2 );
442 head += 2;
443 head += cdAppShort( head, (short int) im->markerspec );
444 octet_count += 4;
445 }
446 // Picture Descriptor: Edge Width Specification Mode;
447 // Elem Class 2; Elem ID 5
448 if ( sticky && ( im->edgespec != CDEDGESPEC ) )
449 {
450 cdcomhead( head, 2, 5, 2 );
451 head += 2;
452 head += cdAppShort( head, (short int) im->edgespec );
453 octet_count += 4;
454 }
455
456 //** Attribute: VDCExt; Elem Class 2; Elem ID 6
457 cdcomhead( head, 2, 6, 8 );
458 head += 2;
459 head += cdAppShort( head, (short int) 0 );
460 head += cdAppShort( head, (short int) 0 );
461 head += cdAppShort( head, (short int) im->sx );
462 head += cdAppShort( head, (short int) im->sy );
463 octet_count += 10;
464
465 //** Attribute: Begin Picture Body; Elem Class 0; Elem ID 4
466 cdcomhead( head, 0, 4, 0 );
467 head += 2;
468 octet_count += 2;
469
470 if ( cdAddElem( im, headerp, octet_count ) )
471 {
472 free( headerp );
473 }
474 else
475 {
476 free( headerp );
477 return 0;
478 }
479
480 if ( sticky )
481 {
482 // keep defaults the way they are
483 if ( sticky == 1 )
484 {
485 // keep the color table
486 if ( cdImageAddColor( im, 0, im->colorsTotal - 1 ) == -1 )
487 {
488 // no colortable
489 return 1;
490 }
491 }
492 else
493 {
494 // Nuke the color table if there is one
495 cdImageColorClear( im );
496 }
497 im->state = 1;
498 x1 = im->ltype; x2 = im->lwidth; x3 = im->lcolor;
499 im->ltype = CDLTYPE; im->lwidth = CDLWIDTH; im->lcolor = CDLCOLOR;
500 if ( !cdSetLineAttrib( im, x1, x2, x3 ) )
501 return 0;
502
503 x1 = im->shapestyle; x2 = im->shapecolor; x3 = im->shapehatch;
504 im->shapestyle = CDSHAPESTYLE; im->shapecolor = CDSHAPECOLOR;
505 im->shapehatch = CDSHAPEHATCH;
506 if ( !cdSetShapeFillAttrib( im, x1, x2, x3 ) )
507 return 0;
508
509 x1 = im->edgetype; x2 = im->edgewidth;
510 x3 = im->edgecolor; x4 = im->edgevis;
511 im->edgetype = CDEDGETYPE; im->edgewidth = CDEDGEWIDTH;
512 im->edgecolor = CDEDGECOLOR; im->edgevis = CDEDGEVIS;
513 if ( !cdSetShapeEdgeAttrib( im, x1, x2, x3, x4 ) )
514 return 0;
515
516 x1 = im->textfont; x2 = im->textcolor; x3 = im->textheight;
517 im->textfont = CDTEXTFONT; im->textcolor = CDTEXTCOLOR;
518 im->textheight = CDTEXTHEIGHT;
519 if ( !cdSetTextAttrib( im, x1, x2, x3 ) )
520 return 0;
521
522 x1 = im->textpath; im->textpath = CDTEXTPATH;
523 if ( !cdSetTextPath( im, x1 ) )
524 return 0;
525
526 x1 = im->mtype; x2 = im->msize; x3 = im->mcolor;
527 im->ltype = CDMTYPE; im->lwidth = CDMSIZE; im->lcolor = CDMCOLOR;
528 if ( !cdSetMarkerAttrib( im, x1, x2, x3 ) )
529 return 0;
530 }
531 else
532 {
533 // reset all the defaults
534 cdImageSetDefaults( im );
535 // Nuke the color table if there is one
536 cdImageColorClear( im );
537 im->state = 1; // now we are officially in the picture
538 }
539 return 1;
540}
541
542int cdCgmNewPic( cdImagePtr im, int sticky )
543// The CGM standard allows multiple images in a single file. This function
544// will close the current picture, then open a new one.
545// if sticky is 0 then all attributes will be reset to the defaults
546// if sticky is 1 then all attributes will be inherited from the prevous
547// picture.
548// if sticky is 2 all attributes except the color table will be inherited
549// from the previous picture
550//
551{
552 // close the current picture
553 if ( !cdImageEndPic( im ) )
554 return 0;
555
556 // now start the new picture
557 return ( cdCgmPic( im, sticky ) );
558}
559
560int cdImageCgm( cdImagePtr im, FILE *out )
561// Gej: Write the image to file *out, which must be open already
562// does not close the file
563{
564//
565// if (out) {
566// im->outfile = out;
567// }
568//
569 cdImageSetOutput( im, out );
570 return cdImageEndCgm( im );
571}
572
573
574int cdSetLineType( cdImagePtr im, int lntype )
575{
576// Attribute: Line Type; Elem Class 5; Elem ID 2
577// Set the line type. Possible values are:
578// 1=solid, 2=dash, 3=dot, 4=dash-dot, 5=dash-dot-dot
579// Even though new ones can be defined, I am limiting lntype to these values
580// If you really need more, you can make the proper changes.
581//
582 unsigned char *es, *esp;
583 int octet_count;
584
585 // First check and see if the user doesn't want any changes,
586 // if so, just return success
587 if ( lntype == -1 )
588 return 1;
589
590 // Check and see if the value it is being set to is the current
591 // value, if so, don't make any changes, just return 1
592 if ( lntype == im->ltype )
593 return 1;
594
595 // Make sure that lntype is between 1 and 5
596 if ( ( lntype < 1 ) || ( lntype > 5 ) )
597 return 0;
598
599 // allocate sufficent space. should be 32 bits * 4 to be safe
600 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
601 if ( !es )
602 return 0; // memory allocation failed
603 esp = es;
604
605 if ( !cdcomhead( es, 5, 2, 2 ) )
606 {
607 free( esp ); return 0;
608 }
609 es += 2;
610 // set Param_List_Len to 2 (signed int at index precision)
611
612 // add in the value of lntype
613 es += cdAppShort( es, (short int) lntype );
614
615 octet_count = 4; // we just know this
616
617 // add it to the buffer
618 if ( cdAddElem( im, esp, octet_count ) )
619 {
620 im->ltype = (short int) lntype;
621 free( esp );
622 return 1;
623 }
624 else
625 {
626 free( esp );
627 return 0;
628 }
629}
630
631int cdSetLineWidth( cdImagePtr im, int lnwidth )
632{
633// Attribute: Line Width; Elem Class 5; Elem ID 3
634// sets the line width. with an image of height X with line width 1
635// the displayed width will be 1/X%. as an example, if you image is
636// x=5, y=10, and you set line width = 1, and draw a vertical line, the
637// resulting line will cover 20% of horizontal area.
638//
639 unsigned char *es, *esp;
640 int octet_count;
641
642 // First check and see if the user doesn't want any changes,
643 // if so, just return success
644 if ( lnwidth == -1 )
645 return 1;
646
647 // Check and see if the value it is being set to is the current
648 // value, if so, don't make any changes, just return 1
649 if ( lnwidth == im->lwidth )
650 return 1;
651
652 // allocate sufficent space. should be 32 bits * 4 to be safe
653 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
654 if ( !es )
655 return 0; // memory allocation failed
656 esp = es;
657
658
659 //gej: line width is 32 bit floating point number, 16 bits before the
660 // decimal, 16 bits after if Line Spec is default (1, scaled)
661 // if Line Spec is 0 (0, absolute) then it is 16 bit SI
662 if ( im->linespec )
663 {
664 if ( !cdcomhead( es, 5, 3, 4 ) )
665 {
666 free( esp ); return 0;
667 }
668 es += 2;
669 octet_count = 2;
670 es += cdAppShort( es, (short int) lnwidth );
671 octet_count += 2;
672 // the next two (after decimal point) will always be zero
673 es += cdAppNull( es, 2 );
674 octet_count += 2;
675 }
676 else
677 {
678 if ( !cdcomhead( es, 5, 3, 2 ) )
679 {
680 free( esp ); return 0;
681 }
682 octet_count = 2;
683 es += 2;
684 es += cdAppShort( es, (short int) lnwidth );
685 octet_count += 2;
686 }
687
688
689 // add it to the buffer
690 if ( cdAddElem( im, esp, octet_count ) )
691 {
692 im->lwidth = lnwidth;
693 free( esp );
694 return 1;
695 }
696 else
697 {
698 free( esp );
699 return 0;
700 }
701}
702
703int cdSetLineColor( cdImagePtr im, int lncolor )
704{
705// Attribute: Line Colour; Elem Class 5; Elem ID 4
706// Sets the line color. lncolor should be an index into the color
707// table that you have previously allocated.
708//
709 unsigned char *es, *esp;
710 int octet_count;
711 // First check and see if the user doesn't want any changes,
712 // if so, just return success
713 if ( lncolor == -1 )
714 return 1;
715
716 // Check and see if the value it is being set to is the current
717 // value, if so, don't make any changes, just return 1
718 if ( lncolor == im->lcolor )
719 return 1;
720
721 // Make sure the color they want to use has been allocated.
722 // also, that color must be non-negative
723 if ( ( lncolor >= im->colorsTotal ) || ( lncolor < 0 ) )
724 return 0; // you must allocate a color before you use it
725
726 // allocate sufficent space. should be 32 bits * 4 to be safe
727 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
728 if ( !es )
729 return 0; // memory allocation failed
730 esp = es;
731
732
733 if ( !cdcomhead( es, 5, 4, 1 ) )
734 {
735 free( esp ); return 0;
736 }
737 es += 2;
738
739 *es = 0377 & lncolor; // mask off last 8 bits and put in es
740 es++;
741
742 es += cdAppNull( es, 1 );
743
744 octet_count = 4; // we just know this; 2 octets of header,
745 // 1 octet of data, 1 octet of null data
746
747 // add it to the buffer
748 if ( cdAddElem( im, esp, octet_count ) )
749 {
750 im->lcolor = (short int) lncolor;
751 free( esp );
752 return 1;
753 }
754 else
755 {
756 free( esp );
757 return 0;
758 }
759}
760
761int cdSetFillStyle( cdImagePtr im, int instyle )
762{
763// set the style of the interior of filled area elements.
764// Attribute: Interior Style; Elem Class 5; Elem ID 22
765// These attributes stay in effect until changed, so you don't have to output
766// them every time.
767// Interior Style: (integers 0-6, corresponding to: hollow, solid,
768// [not pattern], hatch, empty, [not geometric pattern],
769// interpolated.)
770// attribute is 16 bit signed int
771//
772 unsigned char *es, *esp;
773 int octet_count;
774
775 // First check and see if the user doesn't want any changes,
776 // if so, just return success
777 if ( instyle == -1 )
778 return 1;
779
780 // Check and see if the value it is being set to is the current
781 // value, if so, don't make any changes, just return 1
782 if ( instyle == im->shapestyle )
783 return 1;
784
785 // Make sure that lnhatch is between 0 and 6, but not
786 // 2, 5, or 6
787 if ( ( instyle < 0 ) || ( instyle > 4 ) || ( instyle == 2 ) )
788 return 0;
789
790 // allocate sufficent space. should be 32 bits * 4 to be safe
791 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
792 if ( !es )
793 return 0; // memory allocation failed
794 esp = es;
795
796 // set the header to Class 5, ID 22, Length 2
797 if ( !cdcomhead( es, 5, 22, 2 ) )
798 {
799 free( esp ); return 0;
800 }
801 es += 2;
802
803 // add in the value of inhatch
804 es += cdAppShort( es, (short int) instyle );
805
806 octet_count = 4; // we just know this
807
808 // add it to the buffer
809 if ( cdAddElem( im, esp, octet_count ) )
810 {
811 im->shapestyle = (short int) instyle;
812 free( esp );
813 return 1;
814 }
815 else
816 {
817 free( esp );
818 return 0;
819 }
820}
821
822int cdSetFillColor( cdImagePtr im, int incolor )
823{
824// set the color of the interior of filled area elements
825// Attribute: Fill Colour; Elem Class 5; Elem ID 23
826// These attributes stay in effect until changed, so you don't have to output
827// them every time.
828// Fill Colour: (index into the color table)
829//
830 unsigned char *es, *esp;
831 int octet_count;
832 // First check and see if the user doesn't want any changes,
833 // if so, just return success
834 if ( incolor == -1 )
835 return 1;
836
837 // Check and see if the value it is being set to is the current
838 // value, if so, don't make any changes, just return 1
839 if ( incolor == im->shapecolor )
840 return 1;
841
842 // Make sure the color they want to use has been allocated.
843 // also, that color must be non-negative
844 if ( ( incolor >= im->colorsTotal ) || ( incolor < 0 ) )
845 return 0; // you must allocate a color before you use it
846
847 // allocate sufficent space. should be 32 bits * 4 to be safe
848 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
849 if ( !es )
850 return 0; // memory allocation failed
851 esp = es;
852
853 if ( !cdcomhead( es, 5, 23, 1 ) )
854 {
855 free( esp ); return 0;
856 }
857 es += 2;
858
859 *es = 0377 & incolor; // mask off last 8 bits and put in es
860 es++;
861 es += cdAppNull( es, 1 );
862
863 octet_count = 4; // we just know this; 2 octets of header,
864 // 1 octet of data, 1 octet of null data
865
866 // add it to the buffer
867 if ( cdAddElem( im, esp, octet_count ) )
868 {
869 im->shapecolor = (short int) incolor;
870 free( esp );
871 return 1;
872 }
873 else
874 {
875 free( esp );
876 return 0;
877 }
878}
879
880int cdSetFillHatch( cdImagePtr im, int inhatch )
881{
882// Set the hatch pattern for the interior of filled-area elements
883// the fill style must be set to hatch for this to have an effect.
884// Attribute: Hatch Index; Elem Class 5; Elem ID 24
885// These attributes stay in effect until changed, so you don't have to output
886// them every time.
887// Hatch Index: (integers 1-6, corresponding to: horizontal lines,
888// vertical lines, pos. slope parallel lines,
889// neg. slope parallel lines, horizontal/vertical
890// crosshatch, positive/negative slope crosshatch)
891//
892
893 unsigned char *es, *esp;
894 int octet_count, temp;
895
896
897 // First check and see if the user doesn't want any changes,
898 // if so, just return success
899 if ( inhatch == -1 )
900 return 1;
901
902 // Check and see if the value it is being set to is the current
903 // value, if so, don't make any changes, just return 1
904 if ( inhatch == im->shapehatch )
905 return 1;
906
907 // Make sure that lnhatch is between 1 and 6
908 if ( ( inhatch < 1 ) || ( inhatch > 6 ) )
909 return 0;
910
911 // allocate sufficent space. should be 32 bits * 4 to be safe
912 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
913 if ( !es )
914 return 0; // memory allocation failed
915 esp = es;
916
917 // set the command header to class 5, id 24, length 2
918 if ( !cdcomhead( es, 5, 24, 2 ) )
919 {
920 free( esp ); return 0;
921 }
922 es += 2;
923
924 // add in the value of inhatch
925 temp = inhatch >> 8;
926 *es = *es | ( temp & 0377 );
927 es++;
928 *es = *es | ( inhatch & 0377 );
929 es++;
930
931 octet_count = 4; // we just know this
932
933 // add it to the buffer
934 if ( cdAddElem( im, esp, octet_count ) )
935 {
936 im->shapehatch = (short int) inhatch;
937 free( esp );
938 return 1;
939 }
940 else
941 {
942 free( esp );
943 return 0;
944 }
945}
946
947int cdSetEdgeType( cdImagePtr im, int edtype )
948{
949// set the type of the edge of filled-area elements.
950// Attribute: Edge Type; Elem Class 5; Elem ID 27
951// These attributes stay in effect until changed, so you don't have to output
952// them every time.
953// Edge Type (integers 1-5, corresponding to: solid, dash, dot,
954// dash-dot, dash-dot-dot. These are the same as those used
955// for line type.)
956// In Part 3 of the standard (Binary Encoding) on page 47 it says that
957// edge type is integer. This is incorrect. Edge type is Index, just
958// like line type.
959// Even though new ones can be defined, I am limiting lntype to these values
960// If you really need more, you can make the proper changes.
961//
962 unsigned char *es, *esp;
963 int octet_count;
964
965 // First check and see if the user doesn't want any changes,
966 // if so, just return success
967 if ( edtype == -1 )
968 return 1;
969
970 // Check and see if the value it is being set to is the current
971 // value, if so, don't make any changes, just return 1
972 if ( edtype == im->edgetype )
973 return 1;
974
975 // Make sure that lntype is between 1 and 5
976 if ( ( edtype < 1 ) || ( edtype > 5 ) )
977 return 0;
978
979 // allocate sufficent space. should be 32 bits * 4 to be safe
980 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
981 if ( !es )
982 return 0; // memory allocation failed
983 esp = es;
984
985 if ( !cdcomhead( es, 5, 27, 2 ) )
986 {
987 free( esp ); return 0;
988 }
989 es += 2;
990
991 // add in the value of edtype
992 es += cdAppShort( es, (short int) edtype );
993
994 octet_count = 4; // we just know this
995
996 // add it to the buffer
997 if ( cdAddElem( im, esp, octet_count ) )
998 {
999 im->edgetype = (short int) edtype;
1000 free( esp );
1001 return 1;
1002 }
1003 else
1004 {
1005 free( esp );
1006 return 0;
1007 }
1008}
1009
1010int cdSetEdgeWidth( cdImagePtr im, int edwidth )
1011{
1012// Set the width of the edge of filled-area elements.
1013// Attribute: Edge Width; Elem Class 5; Elem ID 28
1014// These attributes stay in effect until changed, so you don't have to output
1015// them every time.
1016// Edge Width (should be the same as line width)
1017//
1018 unsigned char *es, *esp;
1019 int octet_count;
1020
1021 // First check and see if the user doesn't want any changes,
1022 // if so, just return success
1023 if ( edwidth == -1 )
1024 return 1;
1025
1026 // Check and see if the value it is being set to is the current
1027 // value, if so, don't make any changes, just return 1
1028 if ( edwidth == im->edgewidth )
1029 return 1;
1030
1031 // allocate sufficent space. should be 32 bits * 4 to be safe
1032 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
1033 if ( !es )
1034 return 0; // memory allocation failed
1035 esp = es;
1036
1037 //gej: edge width is 32 bit floating point number, 16 bits before the
1038 // decimal, 16 bits after for default edge spec (1, scaled) if
1039 // edge spec is absolute (0) then just 16 bit SI
1040 if ( im->edgespec )
1041 {
1042 if ( !cdcomhead( es, 5, 28, 4 ) )
1043 {
1044 free( esp ); return 0;
1045 }
1046 es += 2;
1047 octet_count = 2;
1048 es += cdAppShort( es, edwidth );
1049 octet_count += 2;
1050 // the next two (after decimal point) will always be zero
1051 es += cdAppNull( es, 2 );
1052 octet_count += 2;
1053 }
1054 else
1055 {
1056 if ( !cdcomhead( es, 5, 28, 2 ) )
1057 {
1058 free( esp ); return 0;
1059 }
1060 es += 2;
1061 octet_count = 2;
1062 es += cdAppShort( es, edwidth );
1063 octet_count += 2;
1064 }
1065
1066 // add it to the buffer
1067 if ( cdAddElem( im, esp, octet_count ) )
1068 {
1069 im->edgewidth = edwidth;
1070 free( esp );
1071 return 1;
1072 }
1073 else
1074 {
1075 free( esp );
1076 return 0;
1077 }
1078}
1079
1080int cdSetEdgeColor( cdImagePtr im, int edcolor )
1081{
1082// Set the color of the edge of filled-area elements.
1083// Attribute: Edge Color; Elem Class 5; Elem ID 29
1084// These attributes stay in effect until changed, so you don't have to output
1085// them every time.
1086// Edge Colour (index into the color table)
1087//
1088 unsigned char *es, *esp;
1089 int octet_count;
1090 // First check and see if the user doesn't want any changes,
1091 // if so, just return success
1092 if ( edcolor == -1 )
1093 return 1;
1094
1095 // Check and see if the value it is being set to is the current
1096 // value, if so, don't make any changes, just return 1
1097 if ( edcolor == im->edgecolor )
1098 return 1;
1099
1100 // Make sure the color they want to use has been allocated.
1101 // also, that color must be non-negative
1102 if ( ( edcolor >= im->colorsTotal ) || ( edcolor < 0 ) )
1103 return 0; // you must allocate a color before you use it
1104
1105 // allocate sufficent space. should be 32 bits * 4 to be safe
1106 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
1107 if ( !es )
1108 return 0; // memory allocation failed
1109 esp = es;
1110 if ( !cdcomhead( es, 5, 29, 1 ) )
1111 {
1112 free( esp ); return 0;
1113 }
1114 es += 2;
1115
1116 *es = 0377 & edcolor; // mask off last 8 bits and put in es
1117 es++;
1118 es += cdAppNull( es, 1 );
1119
1120 octet_count = 4; // we just know this; 2 octets of header,
1121 // 1 octet of data, 1 octet of null data
1122
1123 // add it to the buffer
1124 if ( cdAddElem( im, esp, octet_count ) )
1125 {
1126 im->edgecolor = (short int) edcolor;
1127 free( esp );
1128 return 1;
1129 }
1130 else
1131 {
1132 free( esp );
1133 return 0;
1134 }
1135}
1136
1137int cdSetEdgeVis( cdImagePtr im, int edvis )
1138{
1139// Set the visibility of the edge of filled-area elements.
1140// Attribute: Edge Visibility; Elem Class 5; Elem ID 30
1141// These attributes stay in effect until changed, so you don't have to output
1142// them every time.
1143// Edge Visibility (integer 0 or 1, corresponding to: Off, On)
1144// Attribute is 16 bit signed int.
1145//
1146 unsigned char *es, *esp;
1147 int octet_count, temp;
1148
1149 // First check and see if the user doesn't want any changes,
1150 // if so, just return success
1151 if ( edvis == -1 )
1152 return 1;
1153
1154 // Check and see if the value it is being set to is the current
1155 // value, if so, don't make any changes, just return 1
1156 if ( edvis == im->edgevis )
1157 return 1;
1158
1159 // allocate sufficent space. should be 32 bits * 4 to be safe
1160 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
1161 if ( !es )
1162 return 0; // memory allocation failed
1163 esp = es;
1164
1165 if ( !cdcomhead( es, 5, 30, 2 ) )
1166 {
1167 free( esp ); return 0;
1168 }
1169 es += 2; octet_count = 2;
1170 temp = edvis >> 8;
1171 *es = *es | ( temp & 0377 );
1172 es++;
1173 *es = *es | ( edvis & 0377 );
1174 es++;
1175 octet_count += 2;
1176
1177
1178 // add it to the buffer
1179 if ( cdAddElem( im, esp, octet_count ) )
1180 {
1181 im->edgevis = (short int) edvis;
1182 free( esp );
1183 return 1;
1184 }
1185 else
1186 {
1187 free( esp );
1188 return 0;
1189 }
1190}
1191
1192int cdSetTextFont( cdImagePtr im, int font )
1193{
1194// Attribute: Text Font Index; Elem Class 5; Elem ID 10
1195// font is an index into the font table. it can have one of the following
1196// values:
1197// 1 Times Roman
1198// 2 Times Bold
1199// 3 Times Italic
1200// 4 Times Bold Italic
1201// 5 Helvetica
1202// 6 Helvetica Bold
1203// 7 Helvetica Italic
1204// 8 Helvetica Bold Italic
1205// 9 Courier
1206// 10 Courier Bold
1207// 11 Courier Italic
1208// 12 Courier Bold Italic
1209//
1210 unsigned char *es, *esp;
1211 int octet_count;
1212
1213 // First check and see if the user doesn't want any changes,
1214 // if so, just return success
1215 if ( font == -1 )
1216 return 1;
1217
1218 // Check and see if the value it is being set to is the current
1219 // value, if so, don't make any changes, just return 1
1220 if ( font == im->textfont )
1221 return 1;
1222
1223 // Make sure that font is between 1 and the number of fonts
1224 if ( ( font < 1 ) || ( font > im->numfonts ) )
1225 return 0;
1226
1227 // allocate sufficent space. should be 32 bits * 4 to be safe
1228 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
1229 if ( !es )
1230 return 0; // memory allocation failed
1231 esp = es;
1232
1233 if ( !cdcomhead( es, 5, 10, 2 ) )
1234 {
1235 free( esp ); return 0;
1236 }
1237 es += 2;
1238
1239 es += cdAppShort( es, (short int) font );
1240
1241 octet_count = 4; // we just know this
1242
1243 // add it to the buffer
1244 if ( cdAddElem( im, esp, octet_count ) )
1245 {
1246 im->textfont = (short int) font;
1247 free( esp );
1248 return 1;
1249 }
1250 else
1251 {
1252 free( esp );
1253 return 0;
1254 }
1255}
1256
1258{
1259// Attribute: Text Colour ; Elem Class 5; Elem ID 14
1260// set the forground color of text
1261//
1262 unsigned char *es, *esp;
1263 int octet_count;
1264 // First check and see if the user doesn't want any changes,
1265 // if so, just return success
1266 if ( color == -1 )
1267 return 1;
1268
1269 // Check and see if the value it is being set to is the current
1270 // value, if so, don't make any changes, just return 1
1271 if ( color == im->textcolor )
1272 return 1;
1273
1274 // Make sure the color they want to use has been allocated.
1275 // also, that color must be non-negative
1276 if ( ( color >= im->colorsTotal ) || ( color < 0 ) )
1277 return 0; // you must allocate a color before you use it
1278
1279 // allocate sufficent space. should be 32 bits * 4 to be safe
1280 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
1281 if ( !es )
1282 return 0; // memory allocation failed
1283 esp = es;
1284
1285 if ( !cdcomhead( es, 5, 14, 1 ) )
1286 {
1287 free( esp ); return 0;
1288 }
1289 es += 2;
1290
1291 *es = 0377 & color; // mask off last 8 bits and put in es
1292 es++;
1293
1294 octet_count = 4; // we just know this; 2 octets of header,
1295 // 1 octet of data, 1 octet of null data
1296
1297 // add it to the buffer
1298 if ( cdAddElem( im, esp, octet_count ) )
1299 {
1300 im->textcolor = (short int) color;
1301 free( esp );
1302 return 1;
1303 }
1304 else
1305 {
1306 free( esp );
1307 return 0;
1308 }
1309}
1310
1311int cdSetTextHeight( cdImagePtr im, int height )
1312{
1313// Attribute: Character Height; Elem Class 5; Elem ID 15
1314// the height is in the same units as line width
1315//
1316 unsigned char *es, *esp;
1317 int octet_count;
1318 // First check and see if the user doesn't want any changes,
1319 // if so, just return success
1320 if ( height == -1 )
1321 return 1;
1322
1323 // Check and see if the value it is being set to is the current
1324 // value, if so, don't make any changes, just return 1
1325 if ( height == im->textheight )
1326 return 1;
1327
1328 // allocate sufficent space. should be 32 bits * 4 to be safe
1329 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
1330 if ( !es )
1331 return 0; // memory allocation failed
1332 esp = es;
1333
1334 if ( !cdcomhead( es, 5, 15, 2 ) )
1335 {
1336 free( esp ); return 0;
1337 }
1338 octet_count = 2; es += 2;
1339
1340 es += cdAppShort( es, height );
1341 octet_count += 2;
1342
1343 // add it to the buffer
1344 if ( cdAddElem( im, esp, octet_count ) )
1345 {
1346 im->textheight = height;
1347 free( esp );
1348 return 1;
1349 }
1350 else
1351 {
1352 free( esp );
1353 return 0;
1354 }
1355}
1356
1357int cdSetTextPath( cdImagePtr im, int tpath )
1358{
1359// Attribute: Text Path; Elem Class 5; Elem ID 17
1360// Is one of:
1361// 0 right -- Means the direction of the character base vector
1362// 1 left -- means 180 degrees from the character base vector
1363// 2 up -- means the direction of the character up vector
1364// 3 down -- means 180 degrees from the character up vector
1365//
1366 unsigned char *es, *esp;
1367 int octet_count;
1368
1369 // First check and see if the user doesn't want any changes,
1370 // if so, just return success
1371 if ( tpath == -1 )
1372 return 1;
1373
1374 // Check and see if the value it is being set to is the current
1375 // value, if so, don't make any changes, just return 1
1376 if ( tpath == im->textpath )
1377 return 1;
1378
1379 // allocate sufficent space. should be 32 bits * 4 to be safe
1380 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
1381 if ( !es )
1382 return 0; // memory allocation failed
1383 esp = es;
1384 octet_count = 0;
1385
1386 if ( !cdcomhead( es, 5, 17, 2 ) )
1387 {
1388 free( esp ); return 0;
1389 }
1390 es += 2; octet_count = 2;
1391
1392 es += cdAppShort( es, (short int) tpath );
1393 octet_count += 2;
1394
1395 // add it to the buffer
1396 if ( cdAddElem( im, esp, octet_count ) )
1397 {
1398 im->textpath = (short int) tpath;
1399 free( esp );
1400 return 1;
1401 }
1402 else
1403 {
1404 free( esp );
1405 return 0;
1406 }
1407}
1408
1409int cdSetTextOrient( cdImagePtr im, int xup, int yup, int xbase, int ybase )
1410{
1411// Attribute: Character Orientation; Elem Class 5; Elem ID 16
1412// (xbase,ybase) is the run and the rise of the line that the text is
1413// written along. For regular text at an angle, set xup = -ybase
1414// and yup = xbase. Setting it to something different will result in
1415// skewed text (which may be what you want.) Text written from bottom to
1416// top at a 90 degree angle would have the following parameters
1417// xup=-1, yup=0, xbase=0, ybase=1
1418//
1419// This function adds the Orientation to the metafile every time.
1420// It does not follow the normal -1 for no change, although if you
1421// put in the same numbers it won't re-add it to the meta file.
1422//
1423 unsigned char *es, *esp;
1424 int octet_count;
1425
1426
1427 // allocate sufficent space. should be 32 bits * 4 to be safe
1428 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
1429 if ( !es )
1430 return 0; // memory allocation failed
1431 esp = es;
1432 octet_count = 0;
1433
1434 if ( !cdcomhead( es, 5, 16, 8 ) )
1435 {
1436 free( esp ); return 0;
1437 }
1438 es += 2; octet_count += 2;
1439
1440 // In the metafile it is a 16 bit signed integer
1441 // add xup
1442 es += cdAppShort( es, (short int) xup );
1443 octet_count += 2;
1444 // add the rest
1445 es += cdAppShort( es, (short int) yup );
1446 octet_count += 2;
1447 es += cdAppShort( es, (short int) xbase );
1448 octet_count += 2;
1449 es += cdAppShort( es, (short int) ybase );
1450 octet_count += 2;
1451
1452 // add it to the buffer
1453 if ( cdAddElem( im, esp, octet_count ) )
1454 {
1455 free( esp );
1456 return 1;
1457 }
1458 else
1459 {
1460 free( esp );
1461 return 0;
1462 }
1463}
1464
1465int cdSetMarkerType( cdImagePtr im, int mtype )
1466{
1467// Attribute: Marker Type; Elem Class 5; Elem ID 6
1468// Set the Marker type. Possible values are:
1469// 1=dot, 2=plus, 3=asterisk, 4=circle, 5=cross
1470// Even though new ones can be defined, I am limiting lntype to these values
1471// If you really need more, you can make the proper changes.
1472//
1473 unsigned char *es, *esp;
1474 int octet_count;
1475
1476 // First check and see if the user doesn't want any changes,
1477 // if so, just return success
1478 if ( mtype == -1 )
1479 return 1;
1480
1481 // Check and see if the value it is being set to is the current
1482 // value, if so, don't make any changes, just return 1
1483 if ( mtype == im->mtype )
1484 return 1;
1485
1486 // Make sure that mtype is between 1 and 5
1487 if ( ( mtype < 1 ) || ( mtype > 5 ) )
1488 return 0;
1489
1490 // allocate sufficent space. should be 32 bits * 4 to be safe
1491 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
1492 if ( !es )
1493 return 0; // memory allocation failed
1494 esp = es;
1495
1496 if ( !cdcomhead( es, 5, 6, 2 ) )
1497 {
1498 free( esp ); return 0;
1499 }
1500 es += 2;
1501 // set Param_List_Len to 2 (signed int at index precision)
1502
1503 // add in the value of mtype
1504 es += cdAppShort( es, (short int) mtype );
1505
1506 octet_count = 4; // we just know this
1507
1508 // add it to the buffer
1509 if ( cdAddElem( im, esp, octet_count ) )
1510 {
1511 im->mtype = (short int) mtype;
1512 free( esp );
1513 return 1;
1514 }
1515 else
1516 {
1517 free( esp );
1518 return 0;
1519 }
1520}
1521
1522int cdSetMarkerSize( cdImagePtr im, int msize )
1523{
1524// Attribute: Marker Size; Elem Class 5; Elem ID 7
1525// sets the marker size. with an image of height X with marker size 1
1526// the displayed size will be 1/X%. as an example, if you image is
1527// x=5, y=10, and you set marker size = 1, and draw a marker, the
1528// resulting marker will cover 20% of horizontal area.
1529//
1530 unsigned char *es, *esp;
1531 int octet_count;
1532
1533 // First check and see if the user doesn't want any changes,
1534 // if so, just return success
1535 if ( msize == -1 )
1536 return 1;
1537
1538 // Check and see if the value it is being set to is the current
1539 // value, if so, don't make any changes, just return 1
1540 if ( msize == im->msize )
1541 return 1;
1542
1543 // allocate sufficent space. should be 32 bits * 4 to be safe
1544 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
1545 if ( !es )
1546 return 0; // memory allocation failed
1547 esp = es;
1548
1549
1550 //gej: marker size is 32 bit floating point number, 16 bits before the
1551 // decimal, 16 bits after if marker spec is default (1, scaled)
1552 // for absolute mode (0, absolute) it is 16 bit SI
1553 if ( im->markerspec )
1554 {
1555 if ( !cdcomhead( es, 5, 7, 4 ) )
1556 {
1557 free( esp ); return 0;
1558 }
1559 octet_count = 2;
1560 es += 2;
1561 es += cdAppShort( es, (short int) msize );
1562 octet_count += 2;
1563 // the next two (after decimal point) will always be zero
1564 es += cdAppNull( es, 2 );
1565 octet_count += 2;
1566 }
1567 else
1568 {
1569 if ( !cdcomhead( es, 5, 7, 4 ) )
1570 {
1571 free( esp ); return 0;
1572 }
1573 octet_count = 2;
1574 es += 2;
1575 es += cdAppShort( es, (short int) msize );
1576 octet_count += 2;
1577 }
1578
1579
1580 // add it to the buffer
1581 if ( cdAddElem( im, esp, octet_count ) )
1582 {
1583 im->msize = msize;
1584 free( esp );
1585 return 1;
1586 }
1587 else
1588 {
1589 free( esp );
1590 return 0;
1591 }
1592}
1593
1594int cdSetMarkerColor( cdImagePtr im, int mcolor )
1595{
1596// Attribute: Marker Colour; Elem Class 5; Elem ID 8
1597// Sets the marker color. mcolor should be an index into the color
1598// table that you have previously allocated.
1599//
1600 unsigned char *es, *esp;
1601 int octet_count;
1602 // First check and see if the user doesn't want any changes,
1603 // if so, just return success
1604 if ( mcolor == -1 )
1605 return 1;
1606
1607 // Check and see if the value it is being set to is the current
1608 // value, if so, don't make any changes, just return 1
1609 if ( mcolor == im->mcolor )
1610 return 1;
1611
1612 // Make sure the color they want to use has been allocated.
1613 // also, that color must be non-negative
1614 if ( ( mcolor >= im->colorsTotal ) || ( mcolor < 0 ) )
1615 return 0; // you must allocate a color before you use it
1616
1617 // allocate sufficent space. should be 32 bits * 4 to be safe
1618 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
1619 if ( !es )
1620 return 0; // memory allocation failed
1621 esp = es;
1622
1623
1624 if ( !cdcomhead( es, 5, 8, 1 ) )
1625 {
1626 free( esp ); return 0;
1627 }
1628 es += 2;
1629
1630 *es = 0377 & mcolor; // mask off last 8 bits and put in es
1631 es++;
1632
1633 es += cdAppNull( es, 1 );
1634
1635 octet_count = 4; // we just know this; 2 octets of header,
1636 // 1 octet of data, 1 octet of null data
1637
1638 // add it to the buffer
1639 if ( cdAddElem( im, esp, octet_count ) )
1640 {
1641 im->mcolor = (short int) mcolor;
1642 free( esp );
1643 return 1;
1644 }
1645 else
1646 {
1647 free( esp );
1648 return 0;
1649 }
1650}
1651
1652int cdSetLineAttrib( cdImagePtr im, int lntype, int lnwidth, int lncolor )
1653{
1654// Spits out the attributes of lines. These attributes stay in effect
1655// until changed, so you don't have to output them every time.
1656//
1657
1658 if ( !cdSetLineType( im, lntype ) )
1659 return 0;
1660 if ( !cdSetLineWidth( im, lnwidth ) )
1661 return 0;
1662 if ( !cdSetLineColor( im, lncolor ) )
1663 return 0;
1664
1665 return 1;
1666}
1667
1668int cdSetShapeFillAttrib( cdImagePtr im, int instyle, int incolor, int inhatch )
1669{
1670// Spits out the attributes for the interior of filled-area elements.
1671// These attributes stay in effect until changed, so you don't have to output
1672// them every time.
1673// Set the following attributes:
1674// Interior Style: (integers 0-6, corresponding to: hollow, solid,
1675// [not pattern], hatch, empty, [not geometric pattern],
1676// interpolated.)
1677// Fill Colour: (index into the color table)
1678// Hatch Index: (integers 1-6, corresponding to: horizontal lines,
1679// vertical lines, pos. slope parallel lines,
1680// neg. slope parallel lines, horizontal/vertical
1681// crosshatch, positive/negative slope crosshatch)
1682//
1683 if ( !cdSetFillStyle( im, instyle ) )
1684 return 0;
1685 if ( !cdSetFillColor( im, incolor ) )
1686 return 0;
1687 if ( !cdSetFillHatch( im, inhatch ) )
1688 return 0;
1689
1690 return 1;
1691}
1692
1693int cdSetShapeEdgeAttrib( cdImagePtr im, int edtype, int edwidth, int edcolor, int edvis )
1694{
1695// Spits out the attributes for the edges of filled-area elements. It may
1696// seem logical that these would be the same as the corresponding line
1697// attributes, but this is not the case.
1698// These attributes stay in effect until changed, so you don't have to output
1699// them every time.
1700// Set the following attributes:
1701// Edge Type (integers 1-5, corresponding to: solid, dash, dot,
1702// dash-dot, dash-dot-dot. These are the same as those used
1703// for line type.)
1704// Edge Width (should be the same as line width)
1705// Edge Colour (index into the color table)
1706// Edge Visibility (integer 0 or 1, corresponding to: Off, On)
1707//
1708 if ( !cdSetEdgeType( im, edtype ) )
1709 return 0;
1710 if ( !cdSetEdgeWidth( im, edwidth ) )
1711 return 0;
1712 if ( !cdSetEdgeColor( im, edcolor ) )
1713 return 0;
1714 if ( !cdSetEdgeVis( im, edvis ) )
1715 return 0;
1716
1717 return 1;
1718}
1719
1720int cdSetTextAttrib( cdImagePtr im, int font, int color, int height )
1721{
1722// Set the attributes of text. the font is an integer pointer into the
1723// font list where:
1724// 1 Times
1725// 2 Times Bold
1726// 3 Times Italic
1727// 4 Times Bold Italic
1728// 5 Helvetica
1729// 6 Helvetica Bold
1730// 7 Helvetica Italic
1731// 8 Helvetica Bold Italic
1732// 9 Courier
1733// 10 Courier Bold
1734// 11 Courier Italic
1735// 12 Courier Bold Italic
1736// color is an index into the colortable which is the color of the text
1737// size is the approximate size you want the text written in.
1738//
1739
1740 if ( !cdSetTextFont( im, font ) )
1741 return 0;
1742 if ( !cdSetTextColor( im, color ) )
1743 return 0;
1744 if ( !cdSetTextHeight( im, height ) )
1745 return 0;
1746
1747 return 1;
1748}
1749
1750int cdSetMarkerAttrib( cdImagePtr im, int mtype, int msize, int mcolor )
1751{
1752// Spits out the attributes of Markers. These attributes stay in effect
1753// until changed, so you don't have to output them every time.
1754//
1755
1756 if ( !cdSetMarkerType( im, mtype ) )
1757 return 0;
1758 if ( !cdSetMarkerSize( im, msize ) )
1759 return 0;
1760 if ( !cdSetMarkerColor( im, mcolor ) )
1761 return 0;
1762
1763 return 1;
1764}
1765
1767// gej: should work, unless I make changes to cdImage Struct
1768{
1769 if ( im->elemlist )
1770 {
1771 free( im->elemlist );
1772 }
1773 if ( im->desc )
1774 {
1775 free( im->desc );
1776 }
1777 if ( im->fontlist )
1778 {
1779 free( im->fontlist );
1780 }
1781 free( im );
1782
1783 return 1;
1784}
1785
1786int cdImageColorClosest( cdImagePtr im, int r, int g, int b )
1787// From gd library, see README file for copyright information
1788// gej: should work unchanged
1789// gej: 5/96, changed the colors to use short int
1790{
1791 short int i;
1792 long rd, gd, bd;
1793 int ct = ( -1 );
1794 long mindist = 0;
1795 for ( i = 0; ( i < ( im->colorsTotal ) ); i++ )
1796 {
1797 long dist;
1798 if ( im->open[i] )
1799 {
1800 continue;
1801 }
1802 rd = ( im->red[i] - r );
1803 gd = ( im->green[i] - g );
1804 bd = ( im->blue[i] - b );
1805 dist = rd * rd + gd * gd + bd * bd;
1806 if ( ( i == 0 ) || ( dist < mindist ) )
1807 {
1808 mindist = dist;
1809 ct = i;
1810 }
1811 }
1812 return ct;
1813}
1814
1816{
1817// mark all entries in the color table as open
1818 short int i;
1819 for ( i = 0; ( i < ( cdMaxColors ) ); i++ )
1820 {
1821 im->open[i] = 1;
1822 }
1823 return 1;
1824}
1825
1826int cdImageColorExact( cdImagePtr im, int r, int g, int b )
1827// From gd library, see README file for copyright information
1828// gej: should work unchanged
1829// gej: 5/96, changed colors to work with short ints
1830{
1831 short int i;
1832 for ( i = 0; ( i < ( im->colorsTotal ) ); i++ )
1833 {
1834 if ( im->open[i] )
1835 {
1836 continue;
1837 }
1838 if ( ( im->red[i] == r ) &&
1839 ( im->green[i] == g ) &&
1840 ( im->blue[i] == b ) )
1841 {
1842 return i;
1843 }
1844 }
1845 return -1;
1846}
1847
1848static int cdImageAddColorIndex( cdImagePtr im, int r, int g, int b )
1849// adds the specified color to the colortable in the cdImagePtr.
1850// does not add it to the cgm file, cdImageAddColor does.
1851// do not use either of these two functions, use cdImageColorAllocate.
1852//
1853{
1854 short int i;
1855 short int ct = ( -1 );
1856 for ( i = 0; ( i < ( im->colorsTotal ) ); i++ )
1857 {
1858 if ( im->open[i] )
1859 {
1860 ct = i;
1861 break;
1862 }
1863 }
1864 if ( ct == ( -1 ) )
1865 {
1866 ct = im->colorsTotal;
1867 if ( ct == cdMaxColors )
1868 {
1869 return -1;
1870 }
1871 im->colorsTotal++;
1872 }
1873 im->red[ct] = (short int) r;
1874 im->green[ct] = (short int) g;
1875 im->blue[ct] = (short int) b;
1876 im->open[ct] = (short int) 0;
1877
1878 return ct;
1879}
1880
1881static int cdImageAddColor( cdImagePtr im, int si, int ei )
1882// adds colors to the cgm file, gets values from the color table.
1883// adds all colors from si to ei inclusive.
1884// Use cdImageColorAllocate, not this one.
1885//
1886{
1887 unsigned char *cts, *ctsp; // GEJ: color table attribute
1888 int octet_count; // GEJ: octet count
1889 int numco, curly;
1890 octet_count = 0;
1891 //
1892 // Attribute: Colour Table; Elem Class 5; Elem ID 34
1893 // two parameters P1: Starting colour table index (1 octet, UI)
1894 // P2: list of direct colour values 3-tuples (3 one-octet values)
1895 //
1896 // G E J: find out how many values are being added
1897 if ( ei < 0 )
1898 return -1; // no colors being added
1899 numco = ei - si + 1;
1900
1901 if ( ( numco > 0 ) && ( numco < 10 ) )
1902 {
1903 // we can use the short form of the command
1904 // allocate sufficent space. Should be 32 bits * 10 to be safe
1905 cts = (unsigned char *) calloc( 4 * 10, SIZEOF( unsigned char ) );
1906 if ( !cts )
1907 return -1; // memory allocation failed
1908 ctsp = cts;
1909 if ( !cdcomhead( ctsp, 5, 34, ( numco * 3 ) + 1 ) )
1910 {
1911 free( cts ); return -1;
1912 }
1913 ctsp += 2; octet_count += 2;
1914 }
1915 else if ( ( numco > 9 ) && ( numco < 256 ) )
1916 {
1917 // we must use the long form of the command
1918 // allocate sufficent space. Should be 32 bits*256 to be safe
1919 cts = (unsigned char *) calloc( 256 * 4, SIZEOF( unsigned char ) );
1920 if ( !cts )
1921 return -1; // memory allocation failed
1922 ctsp = cts;
1923 if ( !cdcomheadlong( ctsp, 5, 34, ( numco * 3 ) + 1 ) )
1924 {
1925 free( cts ); return -1;
1926 }
1927 ctsp += 4; octet_count += 4;
1928 }
1929 else
1930 {
1931 return -1;
1932 }
1933
1934 //ctsp += cdAppByte(ctsp, (short int) si);
1935 cdAppByte( ctsp, (short int) si );
1936 ctsp++;
1937 octet_count++;
1938 for ( numco = si; numco <= ei; numco++ )
1939 {
1940 ctsp += cdAppByte( ctsp, im->red[numco] );
1941 ctsp += cdAppByte( ctsp, im->green[numco] );
1942 ctsp += cdAppByte( ctsp, im->blue[numco] );
1943 octet_count += 3;
1944 }
1945
1946
1947 curly = 4 - ( octet_count % 4 );
1948 if ( curly % 4 )
1949 {
1950 octet_count += curly;
1951 ctsp += cdAppNull( ctsp, curly );
1952 }
1953 // add it to the buffer
1954 if ( cdAddElem( im, cts, octet_count ) )
1955 {
1956 free( cts );
1957 return 1;
1958 }
1959 else
1960 {
1961 free( cts );
1962 return -1;
1963 }
1964}
1965
1966int cdImageColorAllocate( cdImagePtr im, int r, int g, int b )
1967// From gd library, see README file for copyright information
1968// gej: modified to allocate the color in the CGM buffer as well
1969// as the color table
1970// gej: 5/96, modified to use short ints for colors
1971{
1972 short int ct;
1973 ct = cdImageAddColorIndex( im, r, g, b );
1974 if ( ct == -1 )
1975 return -1;
1976 // GEJ: w we have successfully alocated it in the color table
1977 // so let's put it in the CGM as well.
1978 //
1979 if ( cdImageAddColor( im, ct, ct ) == -1 )
1980 {
1981 return -1;
1982 }
1983 else
1984 {
1985 return ct;
1986 }
1987}
1988
1990{
1991// allocate the 16 basic colors in the windows pallete
1992//
1993// cdImageColorAllocate(im, 0, 0, 0);
1994// cdImageColorAllocate(im, 0, 0, 0);
1995// cdImageColorAllocate(im, 0, 0, 0);
1996// cdImageColorAllocate(im, 0, 0, 0);
1997// cdImageColorAllocate(im, 0, 0, 0);
1998// cdImageColorAllocate(im, 0, 0, 0);
1999// cdImageColorAllocate(im, 0, 0, 0);
2000// cdImageColorAllocate(im, 0, 0, 0);
2001// cdImageColorAllocate(im, 0, 0, 0);
2002// cdImageColorAllocate(im, 0, 0, 0);
2003// cdImageColorAllocate(im, 0, 0, 0);
2004// cdImageColorAllocate(im, 0, 0, 0);
2005// cdImageColorAllocate(im, 0, 0, 0);
2006// cdImageColorAllocate(im, 0, 0, 0);
2007// cdImageColorAllocate(im, 0, 0, 0);
2008// cdImageColorAllocate(im, 0, 0, 0);
2009//
2010 int si, ei, li;
2011 si = cdImageAddColorIndex( im, 255, 255, 255 );
2012 if ( si == -1 )
2013 return 0;
2014 li = -1; ei = si;
2015 ei = cdImageAddColorIndex( im, 0, 0, 0 );
2016 if ( ei != -1 )
2017 {
2018 li = ei;
2019 }
2020 ei = cdImageAddColorIndex( im, 128, 0, 0 );
2021 if ( ei != -1 )
2022 {
2023 li = ei;
2024 }
2025 ei = cdImageAddColorIndex( im, 0, 128, 0 );
2026 if ( ei != -1 )
2027 {
2028 li = ei;
2029 }
2030 ei = cdImageAddColorIndex( im, 128, 128, 0 );
2031 if ( ei != -1 )
2032 {
2033 li = ei;
2034 }
2035 ei = cdImageAddColorIndex( im, 0, 0, 128 );
2036 if ( ei != -1 )
2037 {
2038 li = ei;
2039 }
2040 ei = cdImageAddColorIndex( im, 128, 0, 128 );
2041 if ( ei != -1 )
2042 {
2043 li = ei;
2044 }
2045 ei = cdImageAddColorIndex( im, 0, 128, 128 );
2046 if ( ei != -1 )
2047 {
2048 li = ei;
2049 }
2050 ei = cdImageAddColorIndex( im, 128, 128, 128 );
2051 if ( ei != -1 )
2052 {
2053 li = ei;
2054 }
2055 ei = cdImageAddColorIndex( im, 192, 192, 192 );
2056 if ( ei != -1 )
2057 {
2058 li = ei;
2059 }
2060 ei = cdImageAddColorIndex( im, 255, 0, 0 );
2061 if ( ei != -1 )
2062 {
2063 li = ei;
2064 }
2065 ei = cdImageAddColorIndex( im, 0, 255, 0 );
2066 if ( ei != -1 )
2067 {
2068 li = ei;
2069 }
2070 ei = cdImageAddColorIndex( im, 255, 255, 0 );
2071 if ( ei != -1 )
2072 {
2073 li = ei;
2074 }
2075 ei = cdImageAddColorIndex( im, 0, 0, 255 );
2076 if ( ei != -1 )
2077 {
2078 li = ei;
2079 }
2080 ei = cdImageAddColorIndex( im, 255, 0, 255 );
2081 if ( ei != -1 )
2082 {
2083 li = ei;
2084 }
2085 ei = cdImageAddColorIndex( im, 0, 255, 255 );
2086 if ( ei != -1 )
2087 {
2088 li = ei;
2089 }
2090
2091 if ( ei == -1 )
2092 {
2093 ei = li;
2094 }
2095 if ( cdImageAddColor( im, si, ei ) == -1 )
2096 {
2097 return -1;
2098 }
2099 else
2100 {
2101 return ei;
2102 }
2103}
2105// wogl: the parameter names are commented to avoid compiler warnings
2106// From gd library, see README file for copyright information
2107// gej: should work unchanged
2108{
2109 // Mark it open.
2110 //im->open[color] = 1;
2111 // gej: really can't work, we are not allowing redefinition
2112 // of color table entries
2113 return 0;
2114}
2115
2116int cdLine( cdImagePtr im, int x1, int y1, int x2, int y2 )
2117// Graphic Primitive: Polyline; Elem Class 4; Elem ID 1
2118// Actually generate the line, if you are writing a program to use this
2119// library, use this function, not cdImageLine or cdImageDashedLine,
2120// those are just in for compatiblilty with gd
2121//
2122// This function will draw a line using the current line type, width, and color
2123//
2124{
2125 unsigned char *es, *esp;
2126 int octet_count;
2127 short int sweet;
2128 short int sour;
2129
2130 // check to make sure the line is withing the scope of the picture
2131 // ie. the values you give for drawing the line are within
2132 // the values you created the picture with
2133 if ( !( cdImageBoundsSafe( im, x1, y1 ) ) || !( cdImageBoundsSafe( im, x2, y2 ) ) )
2134 return 0;
2135
2136 // allocate sufficent space. should be 32 bits * 4 to be safe
2137 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
2138 if ( !es )
2139 return 0; // memory allocation failed
2140 esp = es;
2141
2142 if ( !cdcomhead( es, 4, 1, 8 ) )
2143 {
2144 free( esp ); return 0;
2145 }
2146 es += 2;
2147 octet_count = 2;
2148
2149 // now we are ready for the parameter data
2150 sweet = (short int) x1;
2151 sour = sweet >> 8;
2152 *es = *es | ( sour & 0377 );
2153 es++; octet_count++;
2154 *es = (unsigned char) sweet;
2155 es++; octet_count++;
2156 sweet = (short int) y1;
2157 sour = sweet >> 8;
2158 *es = *es | ( sour & 0377 );
2159 es++; octet_count++;
2160 *es = (unsigned char) sweet;
2161 es++; octet_count++;
2162 sweet = (short int) x2;
2163 sour = sweet >> 8;
2164 *es = *es | ( sour & 0377 );
2165 es++; octet_count++;
2166 *es = (unsigned char) sweet;
2167 es++; octet_count++;
2168 sweet = (short int) y2;
2169 sour = sweet >> 8;
2170 *es = *es | ( sour & 0377 );
2171 es++; octet_count++;
2172 *es = (unsigned char) sweet;
2173 octet_count++;
2174
2175 // add it to the buffer
2176 if ( cdAddElem( im, esp, octet_count ) )
2177 {
2178 free( esp );
2179 return 1;
2180 }
2181 else
2182 {
2183 free( esp );
2184 return 0;
2185 }
2186}
2187
2188int cdMarker( cdImagePtr im, int x, int y )
2189// Graphic Primitive: PolyMarker; Elem Class 4; Elem ID 3
2190// puts a marker in the file, it will have characteristics set by
2191// cdSetMarkerAttrib
2192//
2193{
2194 unsigned char *es, *esp;
2195 int octet_count;
2196
2197 // check to make sure the line is withing the scope of the picture
2198 // ie. the values you give for drawing the line are within
2199 // the values you created the picture with
2200 if ( !cdImageBoundsSafe( im, x, y ) )
2201 return 0;
2202
2203 // allocate sufficent space. should be 32 bits * 4 to be safe
2204 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
2205 if ( !es )
2206 return 0; // memory allocation failed
2207 esp = es;
2208
2209 if ( !cdcomhead( es, 4, 3, 4 ) )
2210 {
2211 free( esp ); return 0;
2212 }
2213 es += 2;
2214 octet_count = 2;
2215
2216 octet_count += cdAppShort( es, (short int) x );
2217 es += 2;
2218 octet_count += cdAppShort( es, (short int) y );
2219 es += 2;
2220
2221 // add it to the buffer
2222 if ( cdAddElem( im, esp, octet_count ) )
2223 {
2224 free( esp );
2225 return 1;
2226 }
2227 else
2228 {
2229 free( esp );
2230 return 0;
2231 }
2232}
2233
2234
2235int cdRectangle( cdImagePtr im, int x1, int y1, int x2, int y2 )
2236{
2237// Graphic Primitive: rectangle; Elem Class 4; Elem ID 11
2238// Actually generate the rectangle, if you are writing a program to use this
2239// library, use this function, not cdImageRectangle,
2240// those are just in for compatiblilty with gd
2241//
2242// This function will draw a Rectangle using the current
2243// edge type, width, color, and visibility, and the current
2244// fill style, color, and hatch
2245//
2246 unsigned char *es, *esp;
2247 int octet_count;
2248 short int sweet;
2249 short int sour;
2250
2251 // check to make sure the line is withing the scope of the picture
2252 // ie. the values you give for drawing the line are within
2253 // the values you created the picture with
2254 if ( !( cdImageBoundsSafe( im, x1, y1 ) ) || !( cdImageBoundsSafe( im, x2, y2 ) ) )
2255 return 0;
2256
2257 // allocate sufficent space. should be 32 bits * 4 to be safe
2258 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
2259 if ( !es )
2260 return 0; // memory allocation failed
2261 esp = es;
2262
2263 // their are four 16 bit signed integers as attributes
2264 if ( !cdcomhead( es, 4, 11, 8 ) )
2265 {
2266 free( esp ); return 0;
2267 }
2268 es += 2; octet_count = 2;
2269
2270 // now we are ready for the parameter data
2271 sweet = (short int) x1;
2272 sour = sweet >> 8;
2273 *es = *es | ( sour & 0377 );
2274 es++; octet_count++;
2275 *es = (unsigned char) sweet;
2276 es++; octet_count++;
2277 sweet = (short int) y1;
2278 sour = sweet >> 8;
2279 *es = *es | ( sour & 0377 );
2280 es++; octet_count++;
2281 *es = (unsigned char) sweet;
2282 es++; octet_count++;
2283 sweet = (short int) x2;
2284 sour = sweet >> 8;
2285 *es = *es | ( sour & 0377 );
2286 es++; octet_count++;
2287 *es = (unsigned char) sweet;
2288 es++; octet_count++;
2289 sweet = (short int) y2;
2290 sour = sweet >> 8;
2291 *es = *es | ( sour & 0377 );
2292 es++; octet_count++;
2293 *es = (unsigned char) sweet;
2294 octet_count++;
2295
2296 // add it to the buffer
2297 if ( cdAddElem( im, esp, octet_count ) )
2298 {
2299 free( esp );
2300 return 1;
2301 }
2302 else
2303 {
2304 free( esp );
2305 return 0;
2306 }
2307}
2308
2309int cdCircle( cdImagePtr im, int cx, int cy, int r )
2310{
2311// Graphic Primitive: circle; Elem Class 4; Elem ID 12
2312// cx,cy is the center of the circle, r is the radius
2313//
2314// This function will draw a Circle using the current
2315// edge type, width, color, and visibility, and the current
2316// fill style, color, and hatch
2317//
2318 unsigned char *es, *esp;
2319 int octet_count;
2320 short int sweet;
2321 short int sour;
2322
2323 // check to make sure the circle is withing the scope of the picture
2324 // ie. the values you give for drawing the circle are within
2325 // the values you created the picture with
2326 if ( !( cdImageBoundsSafe( im, cx, cy ) ) )
2327 return 0;
2328
2329 // allocate sufficent space. should be 32 bits * 4 to be safe
2330 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
2331 if ( !es )
2332 return 0; // memory allocation failed
2333 esp = es;
2334
2335 // their are three 16 bit signed integers as attributes
2336 if ( !cdcomhead( es, 4, 12, 6 ) )
2337 {
2338 free( esp ); return 0;
2339 }
2340 es += 2; octet_count = 2;
2341
2342 // now we are ready for the parameter data
2343 sweet = (short int) cx;
2344 sour = sweet >> 8;
2345 *es = *es | ( sour & 0377 );
2346 es++; octet_count++;
2347 *es = (unsigned char) sweet;
2348 es++; octet_count++;
2349 sweet = (short int) cy;
2350 sour = sweet >> 8;
2351 *es = *es | ( sour & 0377 );
2352 es++; octet_count++;
2353 *es = (unsigned char) sweet;
2354 es++; octet_count++;
2355 sweet = (short int) r;
2356 sour = sweet >> 8;
2357 *es = *es | ( sour & 0377 );
2358 es++; octet_count++;
2359 *es = (unsigned char) sweet;
2360 octet_count++;
2361
2362
2363 // add it to the buffer
2364 if ( cdAddElem( im, esp, octet_count ) )
2365 {
2366 free( esp );
2367 return 1;
2368 }
2369 else
2370 {
2371 free( esp );
2372 return 0;
2373 }
2374}
2375
2376int cdArc3Pt( cdImagePtr im, int sx, int sy, int ix, int iy, int ex, int ey )
2377{
2378// Graphic Primitive: Cicular Arc 3 Point; Elem Class 4; Elem ID 13
2379//
2380// This function will draw a Circular Arc using the current
2381// Line type, width, and color,
2382//
2383 unsigned char *es, *esp;
2384 int octet_count;
2385 short int sweet;
2386 short int sour;
2387
2388 // check to make sure the line is withing the scope of the picture
2389 // ie. the values you give for drawing the line are within
2390 // the values you created the picture with
2391 if ( !( cdImageBoundsSafe( im, sx, sy ) ) || !( cdImageBoundsSafe( im, ix, iy ) ) || !( cdImageBoundsSafe( im, ex, ey ) ) )
2392 return 0;
2393
2394 // allocate sufficent space. should be 32 bits * 4 to be safe
2395 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
2396 if ( !es )
2397 return 0; // memory allocation failed
2398 esp = es;
2399
2400 // their are six 16 bit signed integers as attributes
2401 if ( !cdcomhead( es, 4, 13, 12 ) )
2402 {
2403 free( esp ); return 0;
2404 }
2405 es += 2; octet_count = 2;
2406
2407 // now we are ready for the parameter data
2408 sweet = (short int) sx;
2409 sour = sweet >> 8;
2410 *es = *es | ( sour & 0377 );
2411 es++; octet_count++;
2412 *es = (unsigned char) sweet;
2413 es++; octet_count++;
2414 sweet = (short int) sy;
2415 sour = sweet >> 8;
2416 *es = *es | ( sour & 0377 );
2417 es++; octet_count++;
2418 *es = (unsigned char) sweet;
2419 es++; octet_count++;
2420 sweet = (short int) ix;
2421 sour = sweet >> 8;
2422 *es = *es | ( sour & 0377 );
2423 es++; octet_count++;
2424 *es = (unsigned char) sweet;
2425 es++; octet_count++;
2426 sweet = (short int) iy;
2427 sour = sweet >> 8;
2428 *es = *es | ( sour & 0377 );
2429 es++; octet_count++;
2430 *es = (unsigned char) sweet;
2431 es++; octet_count++;
2432 sweet = (short int) ex;
2433 sour = sweet >> 8;
2434 *es = *es | ( sour & 0377 );
2435 es++; octet_count++;
2436 *es = (unsigned char) sweet;
2437 es++; octet_count++;
2438 sweet = (short int) ey;
2439 sour = sweet >> 8;
2440 *es = *es | ( sour & 0377 );
2441 es++; octet_count++;
2442 *es = (unsigned char) sweet;
2443 octet_count++;
2444
2445 // add it to the buffer
2446 if ( cdAddElem( im, esp, octet_count ) )
2447 {
2448 free( esp );
2449 return 1;
2450 }
2451 else
2452 {
2453 free( esp );
2454 return 0;
2455 }
2456}
2457
2458int cdArc3PtClose( cdImagePtr im, int sx, int sy, int ix, int iy, int ex, int ey, int cl )
2459{
2460// Graphic Primitive: Cicular Arc 3 Point Close; Elem Class 4; Elem ID 14
2461//
2462// This function will draw a Circle using the current
2463// edge type, width, color, and visibility, and the current
2464// fill style, color, and hatch
2465//
2466// cd is the closure type. It can be either 0 for pie closure or
2467// 1 for chord closure.
2468//
2469 unsigned char *es, *esp;
2470 int octet_count;
2471
2472 // check to make sure the line is withing the scope of the picture
2473 // ie. the values you give for drawing the line are within
2474 // the values you created the picture with
2475 if ( !( cdImageBoundsSafe( im, sx, sy ) ) || !( cdImageBoundsSafe( im, ix, iy ) ) || !( cdImageBoundsSafe( im, ex, ey ) ) )
2476 return 0;
2477
2478 // make sure that they close the arc either with pie (0) or chord (1)
2479 if ( ( cl != 0 ) && ( cl != 1 ) )
2480 return 0;
2481
2482 // allocate sufficent space. should be 32 bits * 6 to be safe
2483 es = (unsigned char *) calloc( 4 * 6, SIZEOF( unsigned char ) );
2484 if ( !es )
2485 return 0; // memory allocation failed
2486 esp = es;
2487
2488 // their are seven 16 bit signed integers as attributes
2489 if ( !cdcomhead( es, 4, 14, 14 ) )
2490 {
2491 free( esp ); return 0;
2492 }
2493 es += 2; octet_count = 2;
2494
2495 // now we are ready for the parameter data
2496 octet_count += cdAppShort( es, (short int) sx );
2497 es += 2;
2498 octet_count += cdAppShort( es, (short int) sy );
2499 es += 2;
2500 octet_count += cdAppShort( es, (short int) ix );
2501 es += 2;
2502 octet_count += cdAppShort( es, (short int) iy );
2503 es += 2;
2504 octet_count += cdAppShort( es, (short int) ex );
2505 es += 2;
2506 octet_count += cdAppShort( es, (short int) ey );
2507 es += 2;
2508 octet_count += cdAppShort( es, (short int) cl );
2509 es += 2;
2510
2511 // add it to the buffer
2512 if ( cdAddElem( im, esp, octet_count ) )
2513 {
2514 free( esp );
2515 return 1;
2516 }
2517 else
2518 {
2519 free( esp );
2520 return 0;
2521 }
2522}
2523
2524int cdEllipse( cdImagePtr im, int cx, int cy, int d1x, int d1y, int d2x, int d2y )
2525{
2526// Graphic Primitive: Ellipse; Elem Class 4; Elem ID 17
2527//
2528// This function will draw an Ellipse using the current
2529// edge type, width, color, and visibility, and the current
2530// fill style, color, and hatch
2531//
2532 unsigned char *es, *esp;
2533 int octet_count;
2534
2535 // check to make sure the line is withing the scope of the picture
2536 // ie. the values you give for drawing the line are within
2537 // the values you created the picture with
2538 if ( !( cdImageBoundsSafe( im, cx, cy ) ) || !( cdImageBoundsSafe( im, d1x, d1y ) ) || !( cdImageBoundsSafe( im, d2x, d2y ) ) )
2539 return 0;
2540
2541 // allocate sufficent space. should be 32 bits * 4 to be safe
2542 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
2543 if ( !es )
2544 return 0; // memory allocation failed
2545 esp = es;
2546
2547 // their are six 16 bit signed integers as attributes
2548 if ( !cdcomhead( es, 4, 17, 12 ) )
2549 {
2550 free( esp ); return 0;
2551 }
2552 es += 2; octet_count = 2;
2553
2554 // now we are ready for the parameter data
2555 octet_count += cdAppShort( es, (short int) cx );
2556 es += 2;
2557 octet_count += cdAppShort( es, (short int) cy );
2558 es += 2;
2559 octet_count += cdAppShort( es, (short int) d1x );
2560 es += 2;
2561 octet_count += cdAppShort( es, (short int) d1y );
2562 es += 2;
2563 octet_count += cdAppShort( es, (short int) d2x );
2564 es += 2;
2565 octet_count += cdAppShort( es, (short int) d2y );
2566 es += 2;
2567
2568 // add it to the buffer
2569 if ( cdAddElem( im, esp, octet_count ) )
2570 {
2571 free( esp );
2572 return 1;
2573 }
2574 else
2575 {
2576 free( esp );
2577 return 0;
2578 }
2579}
2580
2582{
2583// Graphic Primitive: Polygon; Elem Class 4; Elem ID 7
2584//
2585// cdPointPtr is defined in cd.h, basically, it is two arrays of integers
2586// p[m].x and p[m].y containing the x and y values respectively. n
2587// is the number of points in this array (not the index of the last point,
2588// which is n-1). n must be at least 3 (otherwise
2589// you really don't have much of a polygon, it is closer to a line.)
2590//
2591// This function will draw a Polygon using the current
2592// edge type, width, color, and visibility, and the current
2593// fill style, color, and hatch
2594//
2595 unsigned char *es, *esp;
2596 int octet_count;
2597 int x; // counter
2598
2599 if ( n < 3 )
2600 return 0; // it is either a point or a line
2601
2602 if ( n < 8 )
2603 {
2604 // It fits in the short form of the command, lets us
2605 // add it right now, shall we?
2606 // allocate sufficent space. Should be 32 bits*10 to be safe
2607 es = (unsigned char *) calloc( 4 * 10, SIZEOF( unsigned char ) );
2608 if ( !es )
2609 return 0; // memory allocation failed
2610 esp = es;
2611
2612
2613 // their are n*2 16 bit signed integers as attributes
2614 if ( !cdcomhead( es, 4, 7, ( n * 4 ) ) )
2615 {
2616 free( esp ); return 0;
2617 }
2618 es += 2; octet_count = 2;
2619 }
2620 else if ( n < 8191 )
2621 {
2622 // there are more than 7 points in it, that sucks
2623 // gej, so basically, for this one, I set the header
2624 // to cdcomhead(es, 4, 7, 31) then write a function for the long
2625 // form that takes the first 15 bits of n and tags a 0 in front
2626 // of it and puts it in es, than I do the for loop all over again
2627 // that doesn't seem too hard. But I will leave that for another
2628 // day.
2629 //
2630 // keep in mind that if CDGROWLISTSIZE is smaller than n*4
2631 // (at most 32769) then things could fail in a most unsavory fashion.
2632 //
2633 // allocate sufficent space. 32 bits*(n+1) to be safe
2634 es = (unsigned char *) calloc( 4 * ( n + 1 ), SIZEOF( unsigned char ) );
2635 if ( !es )
2636 return 0; // memory allocation failed
2637 esp = es;
2638
2639 if ( !cdcomheadlong( es, 4, 7, ( n * 4 ) ) )
2640 {
2641 free( esp ); return 0;
2642 }
2643 es += 4; octet_count = 4;
2644 }
2645 else
2646 {
2647 // there are more than 8191 points in it, I am not going to implement
2648 // that, if you want it that bad, do it yourself.
2649 return 0;
2650 }
2651
2652
2653 for ( x = 0; x < n; x++ )
2654 {
2655 // now we are ready for the parameter data
2656 es += cdAppShort( es, (short int) p->x );
2657 es += cdAppShort( es, (short int) p->y );
2658 octet_count += 4;
2659 p++;
2660 }
2661
2662 // add it to the buffer
2663 if ( cdAddElem( im, esp, octet_count ) )
2664 {
2665 free( esp );
2666 return 1;
2667 }
2668 else
2669 {
2670 free( esp );
2671 return 0;
2672 }
2673}
2674
2676{
2677// Graphic Primitive: Polygon; Elem Class 4; Elem ID 8
2678//
2679// cdPointPtr is defined in cd.h, basically, it is three arrays of integers
2680// p[m].x and p[m].y containing the x and y values respectively and p[m].e
2681// the characteristics of the line leaving point n (0=invisible,1=visible,
2682// 2=close,invisible, 3=close,visible). n is the number of points in this
2683// array (not the index of the last point, which is n-1).
2684// n must be at least 3 (otherwise you really don't have much of a polygon,
2685// it is closer to a line.)
2686//
2687// This function will draw a set of Polygons using the current
2688// edge type, width, color, and the current
2689// fill style, color, and hatch
2690//
2691 unsigned char *es, *esp;
2692 int octet_count;
2693 int x; // counter
2694
2695 if ( n < 3 )
2696 return 0; // it is either a point or a line
2697
2698 if ( n < 6 )
2699 {
2700 // It fits in the short form of the command, lets us
2701 // add it right now, shall we?
2702 // allocate sufficent space. Should be 48 bits*10 to be safe
2703 es = (unsigned char *) calloc( 6 * 10, SIZEOF( unsigned char ) );
2704 if ( !es )
2705 return 0; // memory allocation failed
2706 esp = es;
2707
2708
2709 // their are n*2 16 bit signed integers as attributes
2710 if ( !cdcomhead( es, 4, 8, ( n * 6 ) ) )
2711 {
2712 free( esp ); return 0;
2713 }
2714 es += 2; octet_count = 2;
2715 }
2716 else if ( n < 5462 )
2717 {
2718 // there are more than 5 points in it, that sucks
2719 // gej, so basically, for this one, I set the header
2720 // to cdcomhead(es, 4, 7, 31) then write a function for the long
2721 // form that takes the first 15 bits of n and tags a 0 in front
2722 // of it and puts it in es, than I do the for loop all over again
2723 // that doesn't seem too hard. But I will leave that for another
2724 // day.
2725 //
2726 // keep in mind that if CDGROWLISTSIZE is smaller than n*6
2727 // (at most 32769) then things could fail in a most unsavory fashion.
2728 //
2729 // allocate sufficent space. 48 bits*(n+1) to be safe
2730 es = (unsigned char *) calloc( 6 * ( n + 1 ), SIZEOF( unsigned char ) );
2731 if ( !es )
2732 return 0; // memory allocation failed
2733 esp = es;
2734
2735 if ( !cdcomheadlong( es, 4, 8, ( n * 6 ) ) )
2736 {
2737 free( esp ); return 0;
2738 }
2739 es += 4; octet_count = 4;
2740 }
2741 else
2742 {
2743 // there are more than 5462 points in it, I am not going to implement
2744 // that, if you want it that bad, do it yourself.
2745 return 0;
2746 }
2747
2748
2749 for ( x = 0; x < n; x++ )
2750 {
2751 // now we are ready for the parameter data
2752 es += cdAppShort( es, (short int) p->x );
2753 es += cdAppShort( es, (short int) p->y );
2754 es += cdAppShort( es, (short int) p->e );
2755 octet_count += 6;
2756 p++;
2757 }
2758
2759 // add it to the buffer
2760 if ( cdAddElem( im, esp, octet_count ) )
2761 {
2762 free( esp );
2763 return 1;
2764 }
2765 else
2766 {
2767 free( esp );
2768 return 0;
2769 }
2770}
2771
2773{
2774// Graphic Primitive: Polyline; Elem Class 4; Elem ID 1
2775//
2776// cdPointPtr is defined in cd.h, basically, it is two arrays of integers
2777// p[m].x and p[m].y containing the x and y values respectively. n
2778// is the number of points in this array (not the index of the last point,
2779// which is n-1). if n is 2, it is a regular line, like cdline
2780//
2781// This function will draw a Polyline using the current
2782// line type, width, color, and visibility,
2783//
2784 unsigned char *es, *esp;
2785 int octet_count;
2786 int x; // counter
2787
2788 if ( n < 2 )
2789 return 0; // it is a point
2790
2791 if ( n < 8 )
2792 {
2793 // It fits in the short form of the command, lets us
2794 // add it right now, shall we?
2795 // allocate sufficent space. Should be 32 bits*10 to be safe
2796 es = (unsigned char *) calloc( 4 * 10, SIZEOF( unsigned char ) );
2797 if ( !es )
2798 return 0; // memory allocation failed
2799 esp = es;
2800
2801
2802 // their are n*2 16 bit signed integers as attributes
2803 if ( !cdcomhead( es, 4, 1, ( n * 4 ) ) )
2804 {
2805 free( esp ); return 0;
2806 }
2807 es += 2; octet_count = 2;
2808 }
2809 else if ( n < 8191 )
2810 {
2811 // there are more than 7 points in it, that sucks
2812 // gej, so basically, for this one, I set the header
2813 // using the long version cdcomheadlong(es, 4, 1, n*4)
2814 //
2815 // keep in mind that if CDGROWLISTSIZE is smaller than n*4
2816 // (at most 32769) then the list may have to grow several times
2817 //
2818 // allocate sufficent space. 32 bits*(n+1) to be safe
2819 es = (unsigned char *) calloc( 4 * ( n + 1 ), SIZEOF( unsigned char ) );
2820 if ( !es )
2821 return 0; // memory allocation failed
2822 esp = es;
2823
2824 if ( !cdcomheadlong( es, 4, 1, ( n * 4 ) ) )
2825 {
2826 free( esp ); return 0;
2827 }
2828 es += 4; octet_count = 4;
2829 }
2830 else
2831 {
2832 // there are more than 8191 points in it, I am not going to implement
2833 // that, if you want it that bad, do it yourself.
2834 return 0;
2835 }
2836
2837 for ( x = 0; x < n; x++ )
2838 {
2839 // now we are ready for the parameter data
2840 es += cdAppShort( es, (short int) p->x );
2841 es += cdAppShort( es, (short int) p->y );
2842 octet_count += 4;
2843 p++;
2844 }
2845
2846 // add it to the buffer
2847 if ( cdAddElem( im, esp, octet_count ) )
2848 {
2849 free( esp );
2850 return 1;
2851 }
2852 else
2853 {
2854 free( esp );
2855 return 0;
2856 }
2857}
2858
2860{
2861// Graphic Primitive: PolyMarker; Elem Class 4; Elem ID 3
2862//
2863// cdPointPtr is defined in cd.h, basically, it is two arrays of integers
2864// p[m].x and p[m].y containing the x and y values respectively. n
2865// is the number of points in this array (not the index of the last point,
2866// which is n-1). if n is 2, it is a regular line, like cdline
2867//
2868// This function will insert n markers using the current
2869// Marker type, width, color, and visibility,
2870//
2871 unsigned char *es, *esp;
2872 int octet_count;
2873 int x; // counter
2874
2875 if ( n < 1 )
2876 return 0; // it is nothing
2877 if ( n < 8 )
2878 {
2879 // It fits in the short form of the command, lets us
2880 // add it right now, shall we?
2881 // allocate sufficent space. Should be 32 bits*10 to be safe
2882 es = (unsigned char *) calloc( 4 * 10, SIZEOF( unsigned char ) );
2883 if ( !es )
2884 return 0; // memory allocation failed
2885 esp = es;
2886
2887
2888 // their are n*2 16 bit signed integers as attributes
2889 if ( !cdcomhead( es, 4, 3, ( n * 4 ) ) )
2890 {
2891 free( esp ); return 0;
2892 }
2893 es += 2; octet_count = 2;
2894 }
2895 else if ( n < 8191 )
2896 {
2897 // there are more than 7 points in it, that sucks
2898 // gej, so basically, for this one, I set the header
2899 // using the long version cdcomheadlong(es, 4, 1, n*4)
2900 //
2901 // keep in mind that if CDGROWLISTSIZE is smaller than n*4
2902 // (at most 32769) then the list may have to grow several times
2903 //
2904 // allocate sufficent space. 32 bits*(n+1) to be safe
2905 es = (unsigned char *) calloc( 4 * ( n + 1 ), SIZEOF( unsigned char ) );
2906 if ( !es )
2907 return 0; // memory allocation failed
2908 esp = es;
2909
2910 if ( !cdcomheadlong( es, 4, 3, ( n * 4 ) ) )
2911 {
2912 free( esp ); return 0;
2913 }
2914 es += 4; octet_count = 4;
2915 }
2916 else
2917 {
2918 // there are more than 8191 points in it, I am not going to implement
2919 // that, if you want it that bad, do it yourself.
2920 return 0;
2921 }
2922
2923 for ( x = 0; x < n; x++ )
2924 {
2925 // now we are ready for the parameter data
2926 es += cdAppShort( es, (short int) p->x );
2927 es += cdAppShort( es, (short int) p->y );
2928 octet_count += 4;
2929 p++;
2930 }
2931
2932 // add it to the buffer
2933 if ( cdAddElem( im, esp, octet_count ) )
2934 {
2935 free( esp );
2936 return 1;
2937 }
2938 else
2939 {
2940 free( esp );
2941 return 0;
2942 }
2943}
2944
2945int cdText( cdImagePtr im, int x, int y, const char *ts )
2946{
2947// Graphic Primitive: Text; Elem Class 4; Elem ID 4
2948// add text to the picture. Start it at the point (x,y)
2949// this should be the lower left corner of where the text is
2950// the parameters are point, enumerated(set to 1), string
2951//
2952// String encoding in CGM is a little strange. After you have the other
2953// parameter info, the first octet for the string is either 0..254 which
2954// is the number of octets of string data, or 255 which signifies a long
2955// string. if it is 255 then the next 16 bits indicate the length of the
2956// string. the first bit (bit15) is 0 if this is the last part of the
2957// string and 1 if another part follows it. the next 15 bits are in the
2958// range 0..32767 and are the number of octets of string info following.
2959// so the length stored in the command header is the whole enchelada.
2960//
2961 int tslen, curly;
2962 unsigned char *es, *esp;
2963 int octet_count;
2964
2965 // check to make sure the Text is within the scope of the picture
2966 // actually, I am only checking the start of it
2967 //
2968 if ( !( cdImageBoundsSafe( im, x, y ) ) )
2969 return 0;
2970
2971 // allocate sufficent space. should be tslen+ 32 bits * 4 to be safe
2972 tslen = strlen( ts );
2973
2974 // if there are more than 32700 characters fail
2975 // gej: this could go as high as 32767 I think, but lets
2976 // cut it off at 32700
2977 if ( ( tslen > 32700 ) || ( tslen < 0 ) )
2978 return 0;
2979
2980 es = (unsigned char *) calloc( ( ( 4 * 4 ) + tslen ), SIZEOF( unsigned char ) );
2981 if ( !es )
2982 return 0; // memory allocation failed
2983 esp = es;
2984
2985 if ( !cdcomheadlong( es, 4, 4, 9 + tslen ) )
2986 {
2987 free( esp ); return 0;
2988 }
2989 es += 4; octet_count = 4;
2990
2991 // add the x position, the y position, then 1, which signifies
2992 // that this is all the text, there is none appended after it
2993 es += cdAppShort( es, (short int) x );
2994 es += cdAppShort( es, (short int) y );
2995 es += cdAppShort( es, (short int) 1 );
2996 octet_count += 6;
2997
2998 // now take care of the string information, for strings 254 bytes
2999 // or less, I could use a short one, but why bother, use the long
3000 // form for everything
3001 es += cdAppByte( es, (short int) 255 );
3002 es += cdAppShort( es, (short int) tslen );
3003 octet_count += 3;
3004 // gej: I should set bit 15 to 0 because it is the final part of a
3005 // string but I am not going to since I already checked that it was
3006 // a 16 number that was non-negative
3007
3008 while ( *ts )
3009 {
3010 *es++ = (unsigned char) *ts++;
3011 }
3012 octet_count += tslen;
3013 // now if the octet_count is not divisible by 4 add null padding
3014 curly = 4 - ( octet_count % 4 );
3015 if ( curly % 4 )
3016 {
3017 octet_count += curly;
3018 es += cdAppNull( es, curly );
3019 }
3020
3021 // add it to the buffer
3022 if ( cdAddElem( im, esp, octet_count ) )
3023 {
3024 free( esp );
3025 return 1;
3026 }
3027 else
3028 {
3029 free( esp );
3030 return 0;
3031 }
3032}
3033
3034int cdImageLine( cdImagePtr im, int x1, int y1, int x2, int y2, int color )
3035// gej: this should be so much easier to do as a cgm
3036// This is in for compatibility with gd, if you don't need that, use
3037// cdLine instead
3038{
3039 int ltstate;
3040
3041
3042 // save the linetype state
3043 ltstate = im->ltype;
3044 // set the attributes of the line
3045 if ( !cdSetLineAttrib( im, 1, -1, color ) )
3046 return 0;
3047 if ( !cdLine( im, x1, y1, x2, y2 ) )
3048 return 0; // draw the line
3049 // restore the state If it fails, don't return an error, because
3050 // the line was still drawn
3051 cdSetLineType( im, ltstate );
3052
3053 return 1;
3054}
3055
3056int cdImageDashedLine( cdImagePtr im, int x1, int y1, int x2, int y2, int color )
3057// gej: this should be so much easier to do as a cgm
3058// in order to really get a dashed line you must call cdSetLineType first
3059// This is in for compatibility with gd, if you don't need that, use
3060// cdLine instead
3061{
3062 // set the attributes of the line
3063 if ( !cdSetLineAttrib( im, -1, -1, color ) )
3064 return 0;
3065 // generate the line
3066 if ( !cdLine( im, x1, y1, x2, y2 ) )
3067 return 0;
3068
3069 // everthing is A-OK
3070 return 1;
3071}
3072
3073int cdImageBoundsSafe( cdImagePtr im, int x, int y )
3074// From gd library, see README file for copyright information
3075// gej: this should work unchanged
3076{
3077 return ( !( ( ( y < 0 ) || ( y >= im->sy ) ) ||
3078 ( ( x < 0 ) || ( x >= im->sx ) ) ) );
3079}
3080
3081
3082int cdImageRectangle( cdImagePtr im, int x1, int y1, int x2, int y2, int color )
3083// Graphic Primitive: rectangle; Elem Class 4; Elem ID 11
3084//
3085
3086// gej: but I think I will use the cgm rectangle
3087{
3088 if ( !cdImageLine( im, x1, y1, x2, y1, color ) )
3089 return 0;
3090 if ( !cdImageLine( im, x1, y2, x2, y2, color ) )
3091 return 0;
3092 if ( !cdImageLine( im, x1, y1, x1, y2, color ) )
3093 return 0;
3094 if ( !cdImageLine( im, x2, y1, x2, y2, color ) )
3095 return 0;
3096
3097 return 1;
3098}
3099
3100
3101// Expert functions. If you need more control, you can use these
3102// functions, but you probably won't need to.
3103
3104int cdImageSetSize( cdImagePtr im, int x, int y )
3105// sets the width and height of subsequent pictures.
3106{
3107 im->sx = x;
3108 im->sy = y;
3109 return 1;
3110}
3111
3112int cdImageSetLineSpec( cdImagePtr im, int specmode )
3113// Picture Descriptor: Line Width Specification Mode; Elem Class 2; Elem ID 3
3114// sets the Line Width Specification mode of subsequent pictures.
3115// 1 is scaled (default), 2 is absolute
3116{
3117 if ( ( specmode < 0 ) || ( specmode > 2 ) )
3118 return 0;
3119 im->linespec = specmode;
3120 return 1;
3121}
3122
3123int cdImageSetMarkerSpec( cdImagePtr im, int specmode )
3124// Picture Descriptor: Marker Size Specification Mode; Elem Class 2; Elem ID 4
3125// sets the Marker Width Specification mode of subsequent pictures.
3126// 1 is scaled (default), 2 is absolute
3127{
3128 if ( ( specmode < 0 ) || ( specmode > 2 ) )
3129 return 0;
3130 im->linespec = specmode;
3131 return 1;
3132}
3133
3134int cdImageSetEdgeSpec( cdImagePtr im, int specmode )
3135// Picture Descriptor: Edge Width Specification Mode; Elem Class 2; Elem ID 5
3136// sets the Edge Width Specification mode of subsequent pictures.
3137// 1 is scaled (default), 2 is absolute
3138{
3139 if ( ( specmode < 0 ) || ( specmode > 2 ) )
3140 return 0;
3141 im->edgespec = specmode;
3142 return 1;
3143}
3144
3145int cdImageSetOutput( cdImagePtr im, FILE *output )
3146// sets the output file to *output. which must already be open.
3147// does not close the file
3148// Useful if you want to write the file as you go along, or if you
3149// want to write it to a stream
3150//
3151{
3152 if ( output )
3153 {
3154 im->outfile = output;
3155 return 1;
3156 }
3157 else
3158 {
3159 return 0;
3160 }
3161}
3162
3163int cdImageAddFont( cdImagePtr im, const char *fontname )
3164// adds a font to the list of fonts. This only has an effect
3165// if you are using the expert functions for starting pictures, and
3166// have not yet opened the first picture. Returns 0 for failure,
3167// and the font index on success
3168{
3169 unsigned char *oldfonts;
3170 int listsize;
3171 oldfonts = im->fontlist;
3172 if ( oldfonts )
3173 {
3174 listsize = strlen( (char *) oldfonts ) + 1 + strlen( fontname ) + 1;
3175 }
3176 else
3177 {
3178 listsize = strlen( fontname ) + 1;
3179 }
3180 im->fontlist = (unsigned char *) calloc( listsize, SIZEOF( unsigned char ) );
3181 if ( !im->fontlist )
3182 return 0; // memory allocation failed
3183 if ( oldfonts )
3184 {
3185 sprintf( (char *) im->fontlist, "%s%s%s", (char *) oldfonts, ",", fontname );
3186 }
3187 else
3188 {
3189 sprintf( (char *) im->fontlist, "%s", fontname );
3190 }
3191 im->numfonts++;
3192 if ( oldfonts )
3193 free( oldfonts );
3194 oldfonts = NULL;
3195 return im->numfonts;
3196}
3197
3199// clears out ALL fonts from the font list, including the ones the
3200// package has be default. Useful if you want totally different fonts.
3201//
3202{
3203 free( im->fontlist );
3204 im->fontlist = NULL;
3205 im->numfonts = 0;
3206 return 1;
3207}
3208
3210// resets the defaults to what is in defines.h
3211{
3212 // you must be either before any picture has been created,
3213 // or after a picture has closed to call this
3214 if ( ( im->state != 0 ) && ( im->state != 2 ) )
3215 return 0;
3216 // set line_width, line_height, line_color to the defaults
3217 im->ltype = CDLTYPE;
3218 im->lwidth = CDLWIDTH;
3219 im->lcolor = CDLCOLOR;
3220 // interior_style, fill_color, hatch_index
3221 im->shapestyle = CDSHAPESTYLE;
3222 im->shapecolor = CDSHAPECOLOR;
3223 im->shapehatch = CDSHAPEHATCH;
3224 // edge_type, edge_width, edge_color, edge_visibility
3225 im->edgetype = CDEDGETYPE;
3226 im->edgecolor = CDEDGECOLOR;
3227 im->edgewidth = CDEDGEWIDTH;
3228 im->edgevis = CDEDGEVIS;
3229 // text_color, text_height, text_font
3230 im->textcolor = CDTEXTCOLOR;
3231 im->textheight = CDTEXTHEIGHT;
3232 im->textfont = CDTEXTFONT;
3233 im->textpath = CDTEXTPATH;
3234 // set marker_width, marker_size, marker_color to the defaults
3235 im->ltype = CDMTYPE;
3236 im->lwidth = CDMSIZE;
3237 im->lcolor = CDMCOLOR;
3238 // this is set by the expert functions. the defaults should be ok
3239 im->linespec = CDLINESPEC;
3240 im->edgespec = CDEDGESPEC;
3241 im->markerspec = CDMARKERSPEC;
3242
3243 return 1;
3244}
3245
3247// initializes the CGM and sets up the defaults. If you are using
3248// the "expert" functions, you should call this first. _ge
3249{
3250 const char *tmps;
3251 int tmpsl;
3252 cdImagePtr im;
3253 im = (cdImage *) calloc( SIZEOF( cdImage ), 1 );
3254 if ( !im )
3255 return 0; // memory allocation failed
3256 // elemlist is set to some number, when it is full, make it bigger
3257 im->elemlist = (unsigned char *) calloc( CDSTARTLISTSIZE, SIZEOF( unsigned char ) );
3258 if ( !im->elemlist )
3259 {
3260 free( im ); return 0;
3261 } // memory allocation failed
3262 im->colorsTotal = 0;
3263 // you can have multiple pictures in a file, keep track of
3264 // which one you are on
3265 im->picnum = 0;
3266 im->outfile = NULL;
3267 // the next three are used for maintaining the element list
3268 // don't change these ever
3269 im->bytestoend = CDSTARTLISTSIZE;
3270 im->listlen = CDSTARTLISTSIZE;
3271 im->curelemlist = im->elemlist;
3272
3273 // don't make this longer than 250 characters
3274 tmps = "'ProfileId: Model-Profile''ProfileEd:1''ColourClass:colour''Source:NIST CGMDraw 1.3''Date: 1996-12-16'";
3275 tmpsl = strlen( tmps );
3276 if ( tmpsl > 250 )
3277 tmpsl = 250;
3278 im->desc = (unsigned char *) calloc( tmpsl + 1, SIZEOF( unsigned char ) );
3279 strncpy( (char *) im->desc, tmps, tmpsl );
3280 // The font list can be quite long, but individual font names can
3281 // can only be 250 chars
3282 tmps = "TIMES_ROMAN,TIMES_BOLD,TIMES_ITALIC,TIMES_BOLD_ITALIC,HELVETICA,HELVETICA_BOLD,HELVETICA_ITALIC,HELVETICA_BOLD_ITALIC,COURIER,COURIER_BOLD,COURIER_ITALIC,COURIER_BOLD_ITALIC";
3283 im->numfonts = 12;
3284 tmpsl = strlen( tmps );
3285 im->fontlist = (unsigned char *) calloc( tmpsl + 1, SIZEOF( unsigned char ) );
3286 strcpy( (char *) im->fontlist, tmps );
3287 im->outfile = NULL;
3288
3289 if ( !cdImageSetDefaults( im ) )
3290 {
3291 cdImageDestroy( im );
3292 }
3293 // set the state
3294 im->state = 0; // 0 no pictures started, 1 in a picture,
3295 // 2 after a picture
3296
3297 return im;
3298}
3299
3301// close the current picture
3302{
3303 unsigned char *es, *esp;
3304 int octet_count = 0;
3305
3306 // make sure we are really in a picture before ending it
3307 if ( im->state != 1 )
3308 {
3309 return 0;
3310 }
3311
3312 esp = (unsigned char *) calloc( 1024, SIZEOF( unsigned char ) );
3313 if ( !esp )
3314 return 0; // memory allocation failed
3315 es = esp;
3316
3317 // Attribute: End Picture; Elem Class 0; Elem ID 5; Length 0
3318 if ( !cdcomhead( es, 0, 5, 0 ) )
3319 {
3320 free( esp ); return 0;
3321 }
3322 octet_count += 2;
3323
3324 if ( cdAddElem( im, esp, octet_count ) )
3325 {
3326 free( esp );
3327 im->state = 2;
3328 return 1;
3329 }
3330 else
3331 {
3332 free( esp );
3333 return 0;
3334 }
3335}
3336
3338// close the current CGM file. If an output stream is
3339// defined, write the CGM to it
3340{
3341 int x; // counter
3342 int used; // number of bytes used in the list
3343 unsigned char *efile, *efilep; // end of file information
3344
3345 cdImageEndPic( im );
3346 if ( im->state == 2 ) // We have closed the pic, but not the CGM
3347 {
3348 efile = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) );
3349 if ( !efile )
3350 return 0; // memory allocation failed
3351 efilep = efile;
3352 // Attribute: End Metafile; Elem Class 0; Elem ID 2
3353 cdcomhead( efilep, 0, 2, 0 );
3354
3355
3356 if ( cdAddElem( im, efile, 2 ) )
3357 {
3358 free( efile );
3359 efile = 0;
3360 efilep = 0;
3361 }
3362 else
3363 {
3364 free( efile );
3365 return 0;
3366 }
3367 }
3368
3369 if ( im->outfile )
3370 {
3371 // now output the CGM, one byte at a time
3372 used = im->listlen - im->bytestoend;
3373 for ( x = 0; x < used; x++ )
3374 {
3375 putc( (unsigned char) im->elemlist[x], im->outfile );
3376 }
3377 } // else do nothing
3378
3379 return 1;
3380}
int cdPolygonSet(cdImagePtr im, cdPointPtr p, int n)
Definition cd.c:2675
int cdSetEdgeWidth(cdImagePtr im, int edwidth)
Definition cd.c:1010
int cdSetLineType(cdImagePtr im, int lntype)
Definition cd.c:574
int cdSetEdgeColor(cdImagePtr im, int edcolor)
Definition cd.c:1080
int cdSetEdgeVis(cdImagePtr im, int edvis)
Definition cd.c:1137
int cdImageSetSize(cdImagePtr im, int x, int y)
Definition cd.c:3104
static int cdImageAddColorIndex(cdImagePtr im, int r, int g, int b)
Definition cd.c:1848
int cdSetTextHeight(cdImagePtr im, int height)
Definition cd.c:1311
int cdSetLineAttrib(cdImagePtr im, int lntype, int lnwidth, int lncolor)
Definition cd.c:1652
int cdPolyMarker(cdImagePtr im, cdPointPtr p, int n)
Definition cd.c:2859
int cdImageSetEdgeSpec(cdImagePtr im, int specmode)
Definition cd.c:3134
int cdImageSetDefaults(cdImagePtr im)
Definition cd.c:3209
int cdImageColorDeallocate(cdImagePtr im, int color)
Definition cd.c:2104
int cdEllipse(cdImagePtr im, int cx, int cy, int d1x, int d1y, int d2x, int d2y)
Definition cd.c:2524
int cdImageCgm(cdImagePtr im, FILE *out)
Definition cd.c:560
int cdImageBoundsSafe(cdImagePtr im, int x, int y)
Definition cd.c:3073
int cdCgmNewPic(cdImagePtr im, int sticky)
Definition cd.c:542
int cdPolyLine(cdImagePtr im, cdPointPtr p, int n)
Definition cd.c:2772
int cdMarker(cdImagePtr im, int x, int y)
Definition cd.c:2188
int cdLine(cdImagePtr im, int x1, int y1, int x2, int y2)
Definition cd.c:2116
int cdImageSetLineSpec(cdImagePtr im, int specmode)
Definition cd.c:3112
int cdImageClearFonts(cdImagePtr im)
Definition cd.c:3198
int cdSetTextAttrib(cdImagePtr im, int font, int color, int height)
Definition cd.c:1720
int cdCgmHeader(cdImagePtr im)
Definition cd.c:214
static int cdAddElem(cdImagePtr im, unsigned char *es, int octet_count)
Definition cd.c:173
int cdImageSetOutput(cdImagePtr im, FILE *output)
Definition cd.c:3145
static int cdcomheadlong(unsigned char *es, int elemclass, int id, int len)
Definition cd.c:148
int cdImageEndPic(cdImagePtr im)
Definition cd.c:3300
int cdSetFillHatch(cdImagePtr im, int inhatch)
Definition cd.c:880
int cdImageColorExact(cdImagePtr im, int r, int g, int b)
Definition cd.c:1826
int cdCircle(cdImagePtr im, int cx, int cy, int r)
Definition cd.c:2309
int cdSetTextFont(cdImagePtr im, int font)
Definition cd.c:1192
int cdSetTextOrient(cdImagePtr im, int xup, int yup, int xbase, int ybase)
Definition cd.c:1409
int cdSetMarkerType(cdImagePtr im, int mtype)
Definition cd.c:1465
int cdImageEndCgm(cdImagePtr im)
Definition cd.c:3337
cdImagePtr cdImageStartCgm()
Definition cd.c:3246
int cdImageDashedLine(cdImagePtr im, int x1, int y1, int x2, int y2, int color)
Definition cd.c:3056
int cdImageColorClear(cdImagePtr im)
Definition cd.c:1815
int cdSetEdgeType(cdImagePtr im, int edtype)
Definition cd.c:947
int cdArc3Pt(cdImagePtr im, int sx, int sy, int ix, int iy, int ex, int ey)
Definition cd.c:2376
int cdImageRectangle(cdImagePtr im, int x1, int y1, int x2, int y2, int color)
Definition cd.c:3082
int cdCgmPic(cdImagePtr im, int sticky)
Definition cd.c:365
int cdSetMarkerAttrib(cdImagePtr im, int mtype, int msize, int mcolor)
Definition cd.c:1750
int cdPolygon(cdImagePtr im, cdPointPtr p, int n)
Definition cd.c:2581
int cdImageColorAllocate(cdImagePtr im, int r, int g, int b)
Definition cd.c:1966
static int cdAppShort(unsigned char *es, short int addme)
Definition cd.c:85
int cdSetLineWidth(cdImagePtr im, int lnwidth)
Definition cd.c:631
int cdSetFillColor(cdImagePtr im, int incolor)
Definition cd.c:822
static int cdcomhead(unsigned char *es, int elemclass, int id, int len)
Definition cd.c:122
int cdImageSetMarkerSpec(cdImagePtr im, int specmode)
Definition cd.c:3123
int cdImageAddFont(cdImagePtr im, const char *fontname)
Definition cd.c:3163
static int cdImageAddColor(cdImagePtr im, int si, int ei)
Definition cd.c:1881
int cdText(cdImagePtr im, int x, int y, const char *ts)
Definition cd.c:2945
int cdImageColor16(cdImagePtr im)
Definition cd.c:1989
int cdSetMarkerColor(cdImagePtr im, int mcolor)
Definition cd.c:1594
int cdSetFillStyle(cdImagePtr im, int instyle)
Definition cd.c:761
int cdSetShapeFillAttrib(cdImagePtr im, int instyle, int incolor, int inhatch)
Definition cd.c:1668
static int cdAppByte(unsigned char *es, short int addme)
Definition cd.c:75
int cdSetTextColor(cdImagePtr im, int color)
Definition cd.c:1257
int cdSetShapeEdgeAttrib(cdImagePtr im, int edtype, int edwidth, int edcolor, int edvis)
Definition cd.c:1693
int cdArc3PtClose(cdImagePtr im, int sx, int sy, int ix, int iy, int ex, int ey, int cl)
Definition cd.c:2458
int cdRectangle(cdImagePtr im, int x1, int y1, int x2, int y2)
Definition cd.c:2235
int cdSetLineColor(cdImagePtr im, int lncolor)
Definition cd.c:703
static int cdAppNull(unsigned char *es, int x)
Definition cd.c:61
int cdSetMarkerSize(cdImagePtr im, int msize)
Definition cd.c:1522
int cdImageDestroy(cdImagePtr im)
Definition cd.c:1766
int cdSetTextPath(cdImagePtr im, int tpath)
Definition cd.c:1357
int cdImageColorClosest(cdImagePtr im, int r, int g, int b)
Definition cd.c:1786
int cdImageLine(cdImagePtr im, int x1, int y1, int x2, int y2, int color)
Definition cd.c:3034
cdImagePtr cdImageCreate(int sx, int sy)
Definition cd.c:31
#define CDGROWLISTSIZE
Definition cd.h:49
#define CDSTARTLISTSIZE
Definition cd.h:41
#define SIZEOF(object)
Definition cd.h:240
#define cdMaxColors
Definition cd.h:30
#define CDSHAPEHATCH
Definition defines.h:44
#define CDSHAPESTYLE
Definition defines.h:42
#define CDEDGECOLOR
Definition defines.h:46
#define CDMSIZE
Definition defines.h:54
#define CDLWIDTH
Definition defines.h:40
#define CDTEXTHEIGHT
Definition defines.h:51
#define CDTEXTPATH
Definition defines.h:52
#define CDTEXTFONT
Definition defines.h:49
#define CDEDGESPEC
Definition defines.h:57
#define CDLTYPE
Definition defines.h:39
#define CDMCOLOR
Definition defines.h:55
#define CDMARKERSPEC
Definition defines.h:58
#define CDEDGETYPE
Definition defines.h:45
#define CDEDGEWIDTH
Definition defines.h:47
#define CDEDGEVIS
Definition defines.h:48
#define CDSHAPECOLOR
Definition defines.h:43
#define CDLINESPEC
Definition defines.h:56
#define CDMTYPE
Definition defines.h:53
#define CDTEXTCOLOR
Definition defines.h:50
#define CDLCOLOR
Definition defines.h:41
static int color
Definition ps.c:78
unsigned char * elemlist
Definition cd.h:63
int x
Definition cd.h:130
int e
Definition cd.h:130
int y
Definition cd.h:130
static char buf[200]
Definition tclAPI.c:873
static tclMatrixXtnsnDescr * head
Definition tclMatrix.c:460