PLplot
5.10.0
|
00001 00002 // cd.c main file for cgmdraw module. 00003 // 00004 // Written by G. Edward Johnson <mailto:lorax@nist.gov> 00005 // Date: April 1996 00006 // Copyright: cd software produced by NIST, an agency of the 00007 // U.S. government, is by statute not subject to copyright 00008 // in the United States. Recipients of this software assume all 00009 // responsibilities associated with its operation, modification 00010 // and maintenance. 00011 // 00012 // Portions of this package are from the gd package written by 00013 // Thomas Boutell and are copyright 1994, 1995, Quest Protein 00014 // Database Center, Cold Spring Harbor Labs. They are marked in the 00015 // source code. 00016 // 00017 00018 #ifndef NOMALLOCH 00019 #include <malloc.h> 00020 #endif 00021 #include <stdio.h> 00022 #include <math.h> 00023 #include <string.h> 00024 #include <stdlib.h> 00025 #include "defines.h" 00026 #include "cd.h" 00027 00028 00029 static int cdImageAddColor( cdImagePtr im, int si, int ei ); 00030 00031 cdImagePtr cdImageCreate( int sx, int sy ) 00032 // Creates a new image of size (sx,sy). Most people should always 00033 // start by calling this function 00034 { 00035 cdImagePtr im; 00036 00037 im = cdImageStartCgm(); 00038 if ( !im ) 00039 return 0; // memory allocation failed 00040 if ( !cdImageSetSize( im, sx, sy ) ) 00041 { 00042 free( im ); return 0; 00043 } 00044 00045 if ( !cdCgmHeader( im ) ) 00046 { 00047 free( im ); return 0; 00048 } 00049 00050 if ( cdCgmPic( im, 0 ) ) 00051 { 00052 return im; 00053 } 00054 else 00055 { 00056 free( im ); 00057 return 0; 00058 } 00059 } 00060 00061 static int cdAppNull( unsigned char *es, int x ) 00062 { 00063 // put x nulls in the string. 00064 // return value is number of octets added (1) 00065 int y; 00066 00067 for ( y = 0; y < x; y++ ) 00068 { 00069 *es = '\0'; 00070 es++; 00071 } 00072 return x; 00073 } 00074 00075 static int cdAppByte( unsigned char *es, short int addme ) 00076 { 00077 // Append an octet to the end of es 00078 // Return value is number of octets added 00079 // for internal cd functions only, do not call 00080 // 00081 *es = (unsigned char) addme & 0377; 00082 return 1; 00083 } 00084 00085 static int cdAppShort( unsigned char *es, short int addme ) 00086 { 00087 // Append a short to the end of es 00088 // return value is number of octets added 00089 // For internal cd functions only, do not call! 00090 // 00091 short int temp; 00092 00093 temp = addme >> 8; 00094 *es = (unsigned char) temp & 0377; 00095 es++; 00096 *es = (unsigned char) addme & 0377; 00097 return 2; 00098 } 00099 00100 // static int cdAppWord(unsigned char *es, int addme){ 00101 // Append an word to es 00102 // Return value is number of octets added 00103 // For internal cd functions only, do not call! 00104 // 00105 // 00106 // int temp; 00107 // temp = addme >> 24; 00108 //es = (unsigned char) temp & 0377; 00109 // es++; 00110 // temp = addme >> 16; 00111 //es = (unsigned char) temp & 0377; 00112 // es++; 00113 // temp = addme >> 8; 00114 //es = (unsigned char) temp & 0377; 00115 // es++; 00116 //es = (unsigned char) addme & 0377; 00117 // es++; 00118 // return 4; 00119 // } 00120 // 00121 00122 static int cdcomhead( unsigned char *es, int elemclass, int id, int len ) 00123 { 00124 // sets the command header in the first two bytes of string es 00125 // element class is in bits 15-12 00126 // element id is in bits 11-5 00127 // parameter list length is in bits 4-0 00128 // 00129 int temp; 00130 00131 if ( !es ) 00132 return 0; // the string must be allocated first 00133 00134 // set the element class 00135 *es = (unsigned char) elemclass << 4; 00136 // set the element id 00137 temp = 0177 & id; 00138 temp = temp >> 3; 00139 *es = *es | temp; 00140 es++; 00141 id = id << 5; 00142 *es = (unsigned char) id; 00143 *es = *es | (unsigned char) ( 037 & len ); 00144 00145 return 1; 00146 } 00147 00148 static int cdcomheadlong( unsigned char *es, int elemclass, int id, int len ) 00149 { 00150 // sets the command header for the long form. 00151 // first 16 bits: 00152 // element class is in bits 15-12 00153 // element id is in bits 11-5 00154 // parameter list length is in bits 4-0 = 31 00155 // second 16 bits: 00156 // bit 15 = 0 (for last partition) 00157 // bit 14-0 param list len 00158 // 00159 00160 // I'm lazy, call cdcomhead to set the first two bytes 00161 if ( !cdcomhead( es, elemclass, id, 31 ) ) 00162 return 0; 00163 es += 2; 00164 00165 // now set the second two bytes 00166 cdAppShort( es, (short int) len ); 00167 *es = *es & 0177; // make bit 15 = 0 00168 es += 2; 00169 00170 return 1; 00171 } 00172 00173 static int cdAddElem( cdImagePtr im, unsigned char *es, int octet_count ) 00174 // adds a string, which is a CGM element to the elemlist. 00175 // This function is called by other functions in this library and 00176 // should NOT be called by users of the library 00177 // For internal cd functions only, do not call! 00178 // 00179 { 00180 unsigned char *newlist; // in case memory allocation fails 00181 int x; // counter 00182 00183 while ( ( octet_count + 1 ) >= im->bytestoend ) 00184 { 00185 // not enough space, must grow elemlist 00186 im->listlen = im->listlen + CDGROWLISTSIZE; 00187 newlist = (unsigned char *) realloc( im->elemlist, SIZEOF( unsigned char ) * im->listlen ); 00188 if ( newlist ) 00189 { 00190 // successfully allocated memory 00191 im->elemlist = newlist; 00192 im->bytestoend = im->bytestoend + CDGROWLISTSIZE; 00193 im->curelemlist = im->elemlist + ( im->listlen - im->bytestoend ); 00194 } 00195 else 00196 { 00197 // memory allocation failed, save yurself 00198 im->listlen = im->listlen - CDGROWLISTSIZE; 00199 return 0; 00200 } 00201 } 00202 00203 // ok, if we get to here, there is enough space, so add it. 00204 for ( x = 0; x < octet_count; x++ ) 00205 { 00206 *im->curelemlist = (unsigned char) *es; 00207 im->curelemlist++; 00208 es++; 00209 } 00210 im->bytestoend = im->bytestoend - octet_count; 00211 return 1; 00212 } 00213 00214 int cdCgmHeader( cdImagePtr im ) 00215 { 00216 // add the cgm header to the imagepointer's element list 00217 // do it all in a string than call cdAddElem on it 00218 // For internal cd functions only, do not call! 00219 // 00220 unsigned char *headerp; 00221 unsigned char *head; 00222 const unsigned char *buf, *buf2; 00223 int octet_count = 0; 00224 int blen; // length of buf 00225 int curly; 00226 int fontlistlen; // each font in the font list is stored as a string, 00227 // with a single octet in front of the string 00228 // giving its length, fontlistlen is the sum of 00229 // the lengths of all the font strings + the 00230 // length octets. 00231 00232 if ( im->state != 0 ) 00233 return 0; 00234 headerp = (unsigned char *) calloc( 1024, SIZEOF( unsigned char ) ); 00235 if ( !headerp ) 00236 return 0; // memory allocation failed 00237 head = headerp; 00238 00239 //** Attribute: BegMF; Elem Class 0; Elem ID 1 00240 buf = (const unsigned char *) "cd: CgmDraw Library"; 00241 blen = strlen( (const char *) buf ); 00242 cdcomhead( head, 0, 1, blen + 1 ); 00243 head += 2; 00244 head += cdAppByte( head, (short int) blen ); 00245 buf2 = buf; 00246 while ( *buf2 ) 00247 { 00248 *head++ = *buf2++; 00249 } 00250 octet_count += ( blen + 3 ); 00251 curly = 4 - ( octet_count % 4 ); 00252 if ( curly % 4 ) 00253 { 00254 octet_count += curly; 00255 head += cdAppNull( head, curly ); 00256 } 00257 00258 //** Attribute: MFVersion; Elem Class 1; Elem ID 1 00259 cdcomhead( head, 1, 1, 2 ); 00260 head += 2; 00261 head += cdAppShort( head, (short int) 1 ); 00262 octet_count += 4; 00263 00264 //** Attribute: MFDesc; Elem Class 1; Elem ID 2 00265 blen = strlen( (char *) im->desc ); 00266 cdcomheadlong( head, 1, 2, blen + 1 ); 00267 head += 4; 00268 head += cdAppByte( head, (short int) blen ); 00269 buf2 = im->desc; 00270 while ( *buf2 ) 00271 { 00272 *head++ = *buf2++; 00273 } 00274 octet_count += ( blen + 5 ); 00275 curly = 4 - ( octet_count % 4 ); 00276 if ( curly % 4 ) 00277 { 00278 octet_count += curly; 00279 head += cdAppNull( head, curly ); 00280 } 00281 00282 //** Attribute: ColrPrec; Elem Class 1; Elem ID 7 00283 cdcomhead( head, 1, 7, 2 ); 00284 head += 2; 00285 head += cdAppShort( head, (short int) 8 ); 00286 octet_count += 4; 00287 00288 //** Attribute: ColrIndexPrec; Elem Class 1; Elem ID 8 00289 cdcomhead( head, 1, 8, 2 ); 00290 head += 2; 00291 head += cdAppShort( head, (short int) 8 ); 00292 octet_count += 4; 00293 00294 //** Attribute: MaxColrIndex; Elem Class 1; Elem ID 9 00295 cdcomhead( head, 1, 9, 1 ); 00296 head += 2; 00297 head += cdAppByte( head, (short int) 255 ); 00298 octet_count += 4; head++; 00299 00300 //** Attribute: MFElemList; Elem Class 1; Elem ID 11 00301 // shorthand here. 1 means 1 element specified, (-1,1) 00302 // means drawing-plus-control set 00303 cdcomhead( head, 1, 11, 6 ); 00304 head += 2; 00305 head += cdAppShort( head, (short int) 1 ); 00306 head += cdAppShort( head, (short int) -1 ); 00307 head += cdAppShort( head, (short int) 1 ); 00308 octet_count += 8; 00309 00310 //** Attribute: FontList; Elem Class 1; Elem ID 13 00311 // im->fontlist contains a comma separated list of font names 00312 // since we don't need the commas, and every font except one has 00313 // a comma, and we do need a length octet, that means that 00314 // taking the string length will give us one less than the 00315 // correct length. 00316 buf = im->fontlist; 00317 if ( buf ) // don't do this if there aren't any fonts 00318 { 00319 fontlistlen = strlen( (const char *) buf ) + 1; 00320 cdcomheadlong( head, 1, 13, fontlistlen ); 00321 head += 4; 00322 00323 while ( *buf ) 00324 { 00325 blen = 0; 00326 buf2 = buf; 00327 while ( ( *buf ) && ( *buf != ',' ) ) 00328 { 00329 buf++; 00330 blen++; 00331 } 00332 head += cdAppByte( head, (short int) blen ); 00333 while ( buf2 < buf ) 00334 { 00335 *head++ = *buf2++; 00336 } 00337 if ( *buf ) 00338 { 00339 buf++; 00340 } 00341 } 00342 octet_count += ( 4 + fontlistlen ); 00343 curly = 4 - ( octet_count % 4 ); 00344 if ( curly % 4 ) 00345 { 00346 octet_count += curly; 00347 head += cdAppNull( head, curly ); 00348 } 00349 } // end of check to see if any fonts 00350 00351 if ( cdAddElem( im, headerp, octet_count ) ) 00352 { 00353 free( headerp ); 00354 headerp = 0; 00355 return 1; 00356 } 00357 else 00358 { 00359 free( headerp ); 00360 return 0; 00361 } 00362 } 00363 00364 00365 int cdCgmPic( cdImagePtr im, int sticky ) 00366 { 00367 // Start the picture. if the sticky bit is set, set and use the defaults 00368 // of the previous picture. Otherwise, reset all defaults. 00369 // Gej: sticky = 0 reset defaults, 1 dont reset anything, 2 only 00370 // reset the color table 00371 // 00372 unsigned char *headerp; 00373 unsigned char *head; 00374 unsigned char *buf, *buf2; 00375 char *tb; 00376 int octet_count = 0; 00377 int blen; // length of buf 00378 int x1, x2, x3, x4; // needed for setting defaults 00379 00380 if ( ( im->state != 0 ) && ( im->state != 2 ) ) 00381 return 0; 00382 if ( ( sticky > 2 ) || ( sticky < 0 ) ) 00383 return 0; // invalid sticky bit 00384 // increment the picture number 00385 im->picnum++; 00386 tb = (char *) calloc( 4 * 4, SIZEOF( char ) ); 00387 if ( !tb ) 00388 return 0; // memory allocation failed 00389 headerp = (unsigned char *) calloc( 1024, SIZEOF( unsigned char ) ); 00390 if ( !headerp ) 00391 { // memory allocation failed 00392 free( tb ); 00393 return 0; 00394 } 00395 head = headerp; 00396 00397 //** Attribute: BegPic; Elem Class 0; Elem ID 3 00398 sprintf( tb, "picture %d", im->picnum ); 00399 buf = (unsigned char *) tb; 00400 // buf = (unsigned char *) "picture 1"; 00401 blen = strlen( (char *) buf ); 00402 cdcomhead( head, 0, 3, blen + 1 ); 00403 head += 2; 00404 head += cdAppByte( head, (short int) blen ); 00405 buf2 = buf; 00406 while ( *buf2 ) 00407 { 00408 *head++ = *buf2++; 00409 } 00410 free( tb ); 00411 octet_count += ( blen + 3 ); 00412 if ( !( blen % 2 ) ) 00413 { 00414 octet_count++; 00415 head += cdAppNull( head, 1 ); 00416 } 00417 if ( octet_count % 4 ) 00418 { 00419 octet_count += 2; 00420 head += cdAppNull( head, 2 ); 00421 } 00422 00423 //** Attribute: ColrMode; Elem Class 2; Elem ID 2 00424 cdcomhead( head, 2, 2, 2 ); 00425 head += 2; 00426 head += cdAppShort( head, (short int) 0 ); 00427 octet_count += 4; 00428 // Picture Descriptor: Line Width Specification Mode; 00429 // Elem Class 2; Elem ID 3 00430 if ( sticky && ( im->linespec != CDLINESPEC ) ) 00431 { 00432 cdcomhead( head, 2, 3, 2 ); 00433 head += 2; 00434 head += cdAppShort( head, (short int) im->linespec ); 00435 octet_count += 4; 00436 } 00437 // Picture Descriptor: Marker Size Specification Mode; 00438 // Elem Class 2; Elem ID 4 00439 if ( sticky && ( im->markerspec != CDMARKERSPEC ) ) 00440 { 00441 cdcomhead( head, 2, 4, 2 ); 00442 head += 2; 00443 head += cdAppShort( head, (short int) im->markerspec ); 00444 octet_count += 4; 00445 } 00446 // Picture Descriptor: Edge Width Specification Mode; 00447 // Elem Class 2; Elem ID 5 00448 if ( sticky && ( im->edgespec != CDEDGESPEC ) ) 00449 { 00450 cdcomhead( head, 2, 5, 2 ); 00451 head += 2; 00452 head += cdAppShort( head, (short int) im->edgespec ); 00453 octet_count += 4; 00454 } 00455 00456 //** Attribute: VDCExt; Elem Class 2; Elem ID 6 00457 cdcomhead( head, 2, 6, 8 ); 00458 head += 2; 00459 head += cdAppShort( head, (short int) 0 ); 00460 head += cdAppShort( head, (short int) 0 ); 00461 head += cdAppShort( head, (short int) im->sx ); 00462 head += cdAppShort( head, (short int) im->sy ); 00463 octet_count += 10; 00464 00465 //** Attribute: Begin Picture Body; Elem Class 0; Elem ID 4 00466 cdcomhead( head, 0, 4, 0 ); 00467 head += 2; 00468 octet_count += 2; 00469 00470 if ( cdAddElem( im, headerp, octet_count ) ) 00471 { 00472 free( headerp ); 00473 } 00474 else 00475 { 00476 free( headerp ); 00477 return 0; 00478 } 00479 00480 if ( sticky ) 00481 { 00482 // keep defaults the way they are 00483 if ( sticky == 1 ) 00484 { 00485 // keep the color table 00486 if ( cdImageAddColor( im, 0, im->colorsTotal - 1 ) == -1 ) 00487 { 00488 // no colortable 00489 return 1; 00490 } 00491 } 00492 else 00493 { 00494 // Nuke the color table if there is one 00495 cdImageColorClear( im ); 00496 } 00497 im->state = 1; 00498 x1 = im->ltype; x2 = im->lwidth; x3 = im->lcolor; 00499 im->ltype = CDLTYPE; im->lwidth = CDLWIDTH; im->lcolor = CDLCOLOR; 00500 if ( !cdSetLineAttrib( im, x1, x2, x3 ) ) 00501 return 0; 00502 00503 x1 = im->shapestyle; x2 = im->shapecolor; x3 = im->shapehatch; 00504 im->shapestyle = CDSHAPESTYLE; im->shapecolor = CDSHAPECOLOR; 00505 im->shapehatch = CDSHAPEHATCH; 00506 if ( !cdSetShapeFillAttrib( im, x1, x2, x3 ) ) 00507 return 0; 00508 00509 x1 = im->edgetype; x2 = im->edgewidth; 00510 x3 = im->edgecolor; x4 = im->edgevis; 00511 im->edgetype = CDEDGETYPE; im->edgewidth = CDEDGEWIDTH; 00512 im->edgecolor = CDEDGECOLOR; im->edgevis = CDEDGEVIS; 00513 if ( !cdSetShapeEdgeAttrib( im, x1, x2, x3, x4 ) ) 00514 return 0; 00515 00516 x1 = im->textfont; x2 = im->textcolor; x3 = im->textheight; 00517 im->textfont = CDTEXTFONT; im->textcolor = CDTEXTCOLOR; 00518 im->textheight = CDTEXTHEIGHT; 00519 if ( !cdSetTextAttrib( im, x1, x2, x3 ) ) 00520 return 0; 00521 00522 x1 = im->textpath; im->textpath = CDTEXTPATH; 00523 if ( !cdSetTextPath( im, x1 ) ) 00524 return 0; 00525 00526 x1 = im->mtype; x2 = im->msize; x3 = im->mcolor; 00527 im->ltype = CDMTYPE; im->lwidth = CDMSIZE; im->lcolor = CDMCOLOR; 00528 if ( !cdSetMarkerAttrib( im, x1, x2, x3 ) ) 00529 return 0; 00530 } 00531 else 00532 { 00533 // reset all the defaults 00534 cdImageSetDefaults( im ); 00535 // Nuke the color table if there is one 00536 cdImageColorClear( im ); 00537 im->state = 1; // now we are officially in the picture 00538 } 00539 return 1; 00540 } 00541 00542 int cdCgmNewPic( cdImagePtr im, int sticky ) 00543 // The CGM standard allows multiple images in a single file. This function 00544 // will close the current picture, then open a new one. 00545 // if sticky is 0 then all attributes will be reset to the defaults 00546 // if sticky is 1 then all attributes will be inherited from the prevous 00547 // picture. 00548 // if sticky is 2 all attributes except the color table will be inherited 00549 // from the previous picture 00550 // 00551 { 00552 // close the current picture 00553 if ( !cdImageEndPic( im ) ) 00554 return 0; 00555 00556 // now start the new picture 00557 return ( cdCgmPic( im, sticky ) ); 00558 } 00559 00560 int cdImageCgm( cdImagePtr im, FILE *out ) 00561 // Gej: Write the image to file *out, which must be open already 00562 // does not close the file 00563 { 00564 // 00565 // if (out) { 00566 // im->outfile = out; 00567 // } 00568 // 00569 cdImageSetOutput( im, out ); 00570 return cdImageEndCgm( im ); 00571 } 00572 00573 00574 int cdSetLineType( cdImagePtr im, int lntype ) 00575 { 00576 // Attribute: Line Type; Elem Class 5; Elem ID 2 00577 // Set the line type. Possible values are: 00578 // 1=solid, 2=dash, 3=dot, 4=dash-dot, 5=dash-dot-dot 00579 // Even though new ones can be defined, I am limiting lntype to these values 00580 // If you really need more, you can make the proper changes. 00581 // 00582 unsigned char *es, *esp; 00583 int octet_count; 00584 00585 // First check and see if the user doesn't want any changes, 00586 // if so, just return success 00587 if ( lntype == -1 ) 00588 return 1; 00589 00590 // Check and see if the value it is being set to is the current 00591 // value, if so, don't make any changes, just return 1 00592 if ( lntype == im->ltype ) 00593 return 1; 00594 00595 // Make sure that lntype is between 1 and 5 00596 if ( ( lntype < 1 ) || ( lntype > 5 ) ) 00597 return 0; 00598 00599 // allocate sufficent space. should be 32 bits * 4 to be safe 00600 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 00601 if ( !es ) 00602 return 0; // memory allocation failed 00603 esp = es; 00604 00605 if ( !cdcomhead( es, 5, 2, 2 ) ) 00606 { 00607 free( esp ); return 0; 00608 } 00609 es += 2; 00610 // set Param_List_Len to 2 (signed int at index precision) 00611 00612 // add in the value of lntype 00613 es += cdAppShort( es, (short int) lntype ); 00614 00615 octet_count = 4; // we just know this 00616 00617 // add it to the buffer 00618 if ( cdAddElem( im, esp, octet_count ) ) 00619 { 00620 im->ltype = (short int) lntype; 00621 free( esp ); 00622 return 1; 00623 } 00624 else 00625 { 00626 free( esp ); 00627 return 0; 00628 } 00629 } 00630 00631 int cdSetLineWidth( cdImagePtr im, int lnwidth ) 00632 { 00633 // Attribute: Line Width; Elem Class 5; Elem ID 3 00634 // sets the line width. with an image of height X with line width 1 00635 // the displayed width will be 1/X%. as an example, if you image is 00636 // x=5, y=10, and you set line width = 1, and draw a vertical line, the 00637 // resulting line will cover 20% of horizontal area. 00638 // 00639 unsigned char *es, *esp; 00640 int octet_count; 00641 00642 // First check and see if the user doesn't want any changes, 00643 // if so, just return success 00644 if ( lnwidth == -1 ) 00645 return 1; 00646 00647 // Check and see if the value it is being set to is the current 00648 // value, if so, don't make any changes, just return 1 00649 if ( lnwidth == im->lwidth ) 00650 return 1; 00651 00652 // allocate sufficent space. should be 32 bits * 4 to be safe 00653 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 00654 if ( !es ) 00655 return 0; // memory allocation failed 00656 esp = es; 00657 00658 00659 //gej: line width is 32 bit floating point number, 16 bits before the 00660 // decimal, 16 bits after if Line Spec is default (1, scaled) 00661 // if Line Spec is 0 (0, absolute) then it is 16 bit SI 00662 if ( im->linespec ) 00663 { 00664 if ( !cdcomhead( es, 5, 3, 4 ) ) 00665 { 00666 free( esp ); return 0; 00667 } 00668 es += 2; 00669 octet_count = 2; 00670 es += cdAppShort( es, (short int) lnwidth ); 00671 octet_count += 2; 00672 // the next two (after decimal point) will always be zero 00673 es += cdAppNull( es, 2 ); 00674 octet_count += 2; 00675 } 00676 else 00677 { 00678 if ( !cdcomhead( es, 5, 3, 2 ) ) 00679 { 00680 free( esp ); return 0; 00681 } 00682 octet_count = 2; 00683 es += 2; 00684 es += cdAppShort( es, (short int) lnwidth ); 00685 octet_count += 2; 00686 } 00687 00688 00689 // add it to the buffer 00690 if ( cdAddElem( im, esp, octet_count ) ) 00691 { 00692 im->lwidth = lnwidth; 00693 free( esp ); 00694 return 1; 00695 } 00696 else 00697 { 00698 free( esp ); 00699 return 0; 00700 } 00701 } 00702 00703 int cdSetLineColor( cdImagePtr im, int lncolor ) 00704 { 00705 // Attribute: Line Colour; Elem Class 5; Elem ID 4 00706 // Sets the line color. lncolor should be an index into the color 00707 // table that you have previously allocated. 00708 // 00709 unsigned char *es, *esp; 00710 int octet_count; 00711 // First check and see if the user doesn't want any changes, 00712 // if so, just return success 00713 if ( lncolor == -1 ) 00714 return 1; 00715 00716 // Check and see if the value it is being set to is the current 00717 // value, if so, don't make any changes, just return 1 00718 if ( lncolor == im->lcolor ) 00719 return 1; 00720 00721 // Make sure the color they want to use has been allocated. 00722 // also, that color must be non-negative 00723 if ( ( lncolor >= im->colorsTotal ) || ( lncolor < 0 ) ) 00724 return 0; // you must allocate a color before you use it 00725 00726 // allocate sufficent space. should be 32 bits * 4 to be safe 00727 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 00728 if ( !es ) 00729 return 0; // memory allocation failed 00730 esp = es; 00731 00732 00733 if ( !cdcomhead( es, 5, 4, 1 ) ) 00734 { 00735 free( esp ); return 0; 00736 } 00737 es += 2; 00738 00739 *es = 0377 & lncolor; // mask off last 8 bits and put in es 00740 es++; 00741 00742 es += cdAppNull( es, 1 ); 00743 00744 octet_count = 4; // we just know this; 2 octets of header, 00745 // 1 octet of data, 1 octet of null data 00746 00747 // add it to the buffer 00748 if ( cdAddElem( im, esp, octet_count ) ) 00749 { 00750 im->lcolor = (short int) lncolor; 00751 free( esp ); 00752 return 1; 00753 } 00754 else 00755 { 00756 free( esp ); 00757 return 0; 00758 } 00759 } 00760 00761 int cdSetFillStyle( cdImagePtr im, int instyle ) 00762 { 00763 // set the style of the interior of filled area elements. 00764 // Attribute: Interior Style; Elem Class 5; Elem ID 22 00765 // These attributes stay in effect until changed, so you don't have to output 00766 // them every time. 00767 // Interior Style: (integers 0-6, corresponding to: hollow, solid, 00768 // [not pattern], hatch, empty, [not geometric pattern], 00769 // interpolated.) 00770 // attribute is 16 bit signed int 00771 // 00772 unsigned char *es, *esp; 00773 int octet_count; 00774 00775 // First check and see if the user doesn't want any changes, 00776 // if so, just return success 00777 if ( instyle == -1 ) 00778 return 1; 00779 00780 // Check and see if the value it is being set to is the current 00781 // value, if so, don't make any changes, just return 1 00782 if ( instyle == im->shapestyle ) 00783 return 1; 00784 00785 // Make sure that lnhatch is between 0 and 6, but not 00786 // 2, 5, or 6 00787 if ( ( instyle < 0 ) || ( instyle > 4 ) || ( instyle == 2 ) ) 00788 return 0; 00789 00790 // allocate sufficent space. should be 32 bits * 4 to be safe 00791 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 00792 if ( !es ) 00793 return 0; // memory allocation failed 00794 esp = es; 00795 00796 // set the header to Class 5, ID 22, Length 2 00797 if ( !cdcomhead( es, 5, 22, 2 ) ) 00798 { 00799 free( esp ); return 0; 00800 } 00801 es += 2; 00802 00803 // add in the value of inhatch 00804 es += cdAppShort( es, (short int) instyle ); 00805 00806 octet_count = 4; // we just know this 00807 00808 // add it to the buffer 00809 if ( cdAddElem( im, esp, octet_count ) ) 00810 { 00811 im->shapestyle = (short int) instyle; 00812 free( esp ); 00813 return 1; 00814 } 00815 else 00816 { 00817 free( esp ); 00818 return 0; 00819 } 00820 } 00821 00822 int cdSetFillColor( cdImagePtr im, int incolor ) 00823 { 00824 // set the color of the interior of filled area elements 00825 // Attribute: Fill Colour; Elem Class 5; Elem ID 23 00826 // These attributes stay in effect until changed, so you don't have to output 00827 // them every time. 00828 // Fill Colour: (index into the color table) 00829 // 00830 unsigned char *es, *esp; 00831 int octet_count; 00832 // First check and see if the user doesn't want any changes, 00833 // if so, just return success 00834 if ( incolor == -1 ) 00835 return 1; 00836 00837 // Check and see if the value it is being set to is the current 00838 // value, if so, don't make any changes, just return 1 00839 if ( incolor == im->shapecolor ) 00840 return 1; 00841 00842 // Make sure the color they want to use has been allocated. 00843 // also, that color must be non-negative 00844 if ( ( incolor >= im->colorsTotal ) || ( incolor < 0 ) ) 00845 return 0; // you must allocate a color before you use it 00846 00847 // allocate sufficent space. should be 32 bits * 4 to be safe 00848 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 00849 if ( !es ) 00850 return 0; // memory allocation failed 00851 esp = es; 00852 00853 if ( !cdcomhead( es, 5, 23, 1 ) ) 00854 { 00855 free( esp ); return 0; 00856 } 00857 es += 2; 00858 00859 *es = 0377 & incolor; // mask off last 8 bits and put in es 00860 es++; 00861 es += cdAppNull( es, 1 ); 00862 00863 octet_count = 4; // we just know this; 2 octets of header, 00864 // 1 octet of data, 1 octet of null data 00865 00866 // add it to the buffer 00867 if ( cdAddElem( im, esp, octet_count ) ) 00868 { 00869 im->shapecolor = (short int) incolor; 00870 free( esp ); 00871 return 1; 00872 } 00873 else 00874 { 00875 free( esp ); 00876 return 0; 00877 } 00878 } 00879 00880 int cdSetFillHatch( cdImagePtr im, int inhatch ) 00881 { 00882 // Set the hatch pattern for the interior of filled-area elements 00883 // the fill style must be set to hatch for this to have an effect. 00884 // Attribute: Hatch Index; Elem Class 5; Elem ID 24 00885 // These attributes stay in effect until changed, so you don't have to output 00886 // them every time. 00887 // Hatch Index: (integers 1-6, corresponding to: horizontal lines, 00888 // vertical lines, pos. slope parallel lines, 00889 // neg. slope parallel lines, horizontal/vertical 00890 // crosshatch, positive/negative slope crosshatch) 00891 // 00892 00893 unsigned char *es, *esp; 00894 int octet_count, temp; 00895 00896 00897 // First check and see if the user doesn't want any changes, 00898 // if so, just return success 00899 if ( inhatch == -1 ) 00900 return 1; 00901 00902 // Check and see if the value it is being set to is the current 00903 // value, if so, don't make any changes, just return 1 00904 if ( inhatch == im->shapehatch ) 00905 return 1; 00906 00907 // Make sure that lnhatch is between 1 and 6 00908 if ( ( inhatch < 1 ) || ( inhatch > 6 ) ) 00909 return 0; 00910 00911 // allocate sufficent space. should be 32 bits * 4 to be safe 00912 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 00913 if ( !es ) 00914 return 0; // memory allocation failed 00915 esp = es; 00916 00917 // set the command header to class 5, id 24, length 2 00918 if ( !cdcomhead( es, 5, 24, 2 ) ) 00919 { 00920 free( esp ); return 0; 00921 } 00922 es += 2; 00923 00924 // add in the value of inhatch 00925 temp = inhatch >> 8; 00926 *es = *es | ( temp & 0377 ); 00927 es++; 00928 *es = *es | ( inhatch & 0377 ); 00929 es++; 00930 00931 octet_count = 4; // we just know this 00932 00933 // add it to the buffer 00934 if ( cdAddElem( im, esp, octet_count ) ) 00935 { 00936 im->shapehatch = (short int) inhatch; 00937 free( esp ); 00938 return 1; 00939 } 00940 else 00941 { 00942 free( esp ); 00943 return 0; 00944 } 00945 } 00946 00947 int cdSetEdgeType( cdImagePtr im, int edtype ) 00948 { 00949 // set the type of the edge of filled-area elements. 00950 // Attribute: Edge Type; Elem Class 5; Elem ID 27 00951 // These attributes stay in effect until changed, so you don't have to output 00952 // them every time. 00953 // Edge Type (integers 1-5, corresponding to: solid, dash, dot, 00954 // dash-dot, dash-dot-dot. These are the same as those used 00955 // for line type.) 00956 // In Part 3 of the standard (Binary Encoding) on page 47 it says that 00957 // edge type is integer. This is incorrect. Edge type is Index, just 00958 // like line type. 00959 // Even though new ones can be defined, I am limiting lntype to these values 00960 // If you really need more, you can make the proper changes. 00961 // 00962 unsigned char *es, *esp; 00963 int octet_count; 00964 00965 // First check and see if the user doesn't want any changes, 00966 // if so, just return success 00967 if ( edtype == -1 ) 00968 return 1; 00969 00970 // Check and see if the value it is being set to is the current 00971 // value, if so, don't make any changes, just return 1 00972 if ( edtype == im->edgetype ) 00973 return 1; 00974 00975 // Make sure that lntype is between 1 and 5 00976 if ( ( edtype < 1 ) || ( edtype > 5 ) ) 00977 return 0; 00978 00979 // allocate sufficent space. should be 32 bits * 4 to be safe 00980 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 00981 if ( !es ) 00982 return 0; // memory allocation failed 00983 esp = es; 00984 00985 if ( !cdcomhead( es, 5, 27, 2 ) ) 00986 { 00987 free( esp ); return 0; 00988 } 00989 es += 2; 00990 00991 // add in the value of edtype 00992 es += cdAppShort( es, (short int) edtype ); 00993 00994 octet_count = 4; // we just know this 00995 00996 // add it to the buffer 00997 if ( cdAddElem( im, esp, octet_count ) ) 00998 { 00999 im->edgetype = (short int) edtype; 01000 free( esp ); 01001 return 1; 01002 } 01003 else 01004 { 01005 free( esp ); 01006 return 0; 01007 } 01008 } 01009 01010 int cdSetEdgeWidth( cdImagePtr im, int edwidth ) 01011 { 01012 // Set the width of the edge of filled-area elements. 01013 // Attribute: Edge Width; Elem Class 5; Elem ID 28 01014 // These attributes stay in effect until changed, so you don't have to output 01015 // them every time. 01016 // Edge Width (should be the same as line width) 01017 // 01018 unsigned char *es, *esp; 01019 int octet_count; 01020 01021 // First check and see if the user doesn't want any changes, 01022 // if so, just return success 01023 if ( edwidth == -1 ) 01024 return 1; 01025 01026 // Check and see if the value it is being set to is the current 01027 // value, if so, don't make any changes, just return 1 01028 if ( edwidth == im->edgewidth ) 01029 return 1; 01030 01031 // allocate sufficent space. should be 32 bits * 4 to be safe 01032 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 01033 if ( !es ) 01034 return 0; // memory allocation failed 01035 esp = es; 01036 01037 //gej: edge width is 32 bit floating point number, 16 bits before the 01038 // decimal, 16 bits after for default edge spec (1, scaled) if 01039 // edge spec is absolute (0) then just 16 bit SI 01040 if ( im->edgespec ) 01041 { 01042 if ( !cdcomhead( es, 5, 28, 4 ) ) 01043 { 01044 free( esp ); return 0; 01045 } 01046 es += 2; 01047 octet_count = 2; 01048 es += cdAppShort( es, edwidth ); 01049 octet_count += 2; 01050 // the next two (after decimal point) will always be zero 01051 es += cdAppNull( es, 2 ); 01052 octet_count += 2; 01053 } 01054 else 01055 { 01056 if ( !cdcomhead( es, 5, 28, 2 ) ) 01057 { 01058 free( esp ); return 0; 01059 } 01060 es += 2; 01061 octet_count = 2; 01062 es += cdAppShort( es, edwidth ); 01063 octet_count += 2; 01064 } 01065 01066 // add it to the buffer 01067 if ( cdAddElem( im, esp, octet_count ) ) 01068 { 01069 im->edgewidth = edwidth; 01070 free( esp ); 01071 return 1; 01072 } 01073 else 01074 { 01075 free( esp ); 01076 return 0; 01077 } 01078 } 01079 01080 int cdSetEdgeColor( cdImagePtr im, int edcolor ) 01081 { 01082 // Set the color of the edge of filled-area elements. 01083 // Attribute: Edge Color; Elem Class 5; Elem ID 29 01084 // These attributes stay in effect until changed, so you don't have to output 01085 // them every time. 01086 // Edge Colour (index into the color table) 01087 // 01088 unsigned char *es, *esp; 01089 int octet_count; 01090 // First check and see if the user doesn't want any changes, 01091 // if so, just return success 01092 if ( edcolor == -1 ) 01093 return 1; 01094 01095 // Check and see if the value it is being set to is the current 01096 // value, if so, don't make any changes, just return 1 01097 if ( edcolor == im->edgecolor ) 01098 return 1; 01099 01100 // Make sure the color they want to use has been allocated. 01101 // also, that color must be non-negative 01102 if ( ( edcolor >= im->colorsTotal ) || ( edcolor < 0 ) ) 01103 return 0; // you must allocate a color before you use it 01104 01105 // allocate sufficent space. should be 32 bits * 4 to be safe 01106 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 01107 if ( !es ) 01108 return 0; // memory allocation failed 01109 esp = es; 01110 if ( !cdcomhead( es, 5, 29, 1 ) ) 01111 { 01112 free( esp ); return 0; 01113 } 01114 es += 2; 01115 01116 *es = 0377 & edcolor; // mask off last 8 bits and put in es 01117 es++; 01118 es += cdAppNull( es, 1 ); 01119 01120 octet_count = 4; // we just know this; 2 octets of header, 01121 // 1 octet of data, 1 octet of null data 01122 01123 // add it to the buffer 01124 if ( cdAddElem( im, esp, octet_count ) ) 01125 { 01126 im->edgecolor = (short int) edcolor; 01127 free( esp ); 01128 return 1; 01129 } 01130 else 01131 { 01132 free( esp ); 01133 return 0; 01134 } 01135 } 01136 01137 int cdSetEdgeVis( cdImagePtr im, int edvis ) 01138 { 01139 // Set the visibility of the edge of filled-area elements. 01140 // Attribute: Edge Visibility; Elem Class 5; Elem ID 30 01141 // These attributes stay in effect until changed, so you don't have to output 01142 // them every time. 01143 // Edge Visibility (integer 0 or 1, corresponding to: Off, On) 01144 // Attribute is 16 bit signed int. 01145 // 01146 unsigned char *es, *esp; 01147 int octet_count, temp; 01148 01149 // First check and see if the user doesn't want any changes, 01150 // if so, just return success 01151 if ( edvis == -1 ) 01152 return 1; 01153 01154 // Check and see if the value it is being set to is the current 01155 // value, if so, don't make any changes, just return 1 01156 if ( edvis == im->edgevis ) 01157 return 1; 01158 01159 // allocate sufficent space. should be 32 bits * 4 to be safe 01160 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 01161 if ( !es ) 01162 return 0; // memory allocation failed 01163 esp = es; 01164 01165 if ( !cdcomhead( es, 5, 30, 2 ) ) 01166 { 01167 free( esp ); return 0; 01168 } 01169 es += 2; octet_count = 2; 01170 temp = edvis >> 8; 01171 *es = *es | ( temp & 0377 ); 01172 es++; 01173 *es = *es | ( edvis & 0377 ); 01174 es++; 01175 octet_count += 2; 01176 01177 01178 // add it to the buffer 01179 if ( cdAddElem( im, esp, octet_count ) ) 01180 { 01181 im->edgevis = (short int) edvis; 01182 free( esp ); 01183 return 1; 01184 } 01185 else 01186 { 01187 free( esp ); 01188 return 0; 01189 } 01190 } 01191 01192 int cdSetTextFont( cdImagePtr im, int font ) 01193 { 01194 // Attribute: Text Font Index; Elem Class 5; Elem ID 10 01195 // font is an index into the font table. it can have one of the following 01196 // values: 01197 // 1 Times Roman 01198 // 2 Times Bold 01199 // 3 Times Italic 01200 // 4 Times Bold Italic 01201 // 5 Helvetica 01202 // 6 Helvetica Bold 01203 // 7 Helvetica Italic 01204 // 8 Helvetica Bold Italic 01205 // 9 Courier 01206 // 10 Courier Bold 01207 // 11 Courier Italic 01208 // 12 Courier Bold Italic 01209 // 01210 unsigned char *es, *esp; 01211 int octet_count; 01212 01213 // First check and see if the user doesn't want any changes, 01214 // if so, just return success 01215 if ( font == -1 ) 01216 return 1; 01217 01218 // Check and see if the value it is being set to is the current 01219 // value, if so, don't make any changes, just return 1 01220 if ( font == im->textfont ) 01221 return 1; 01222 01223 // Make sure that font is between 1 and the number of fonts 01224 if ( ( font < 1 ) || ( font > im->numfonts ) ) 01225 return 0; 01226 01227 // allocate sufficent space. should be 32 bits * 4 to be safe 01228 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 01229 if ( !es ) 01230 return 0; // memory allocation failed 01231 esp = es; 01232 01233 if ( !cdcomhead( es, 5, 10, 2 ) ) 01234 { 01235 free( esp ); return 0; 01236 } 01237 es += 2; 01238 01239 es += cdAppShort( es, (short int) font ); 01240 01241 octet_count = 4; // we just know this 01242 01243 // add it to the buffer 01244 if ( cdAddElem( im, esp, octet_count ) ) 01245 { 01246 im->textfont = (short int) font; 01247 free( esp ); 01248 return 1; 01249 } 01250 else 01251 { 01252 free( esp ); 01253 return 0; 01254 } 01255 } 01256 01257 int cdSetTextColor( cdImagePtr im, int color ) 01258 { 01259 // Attribute: Text Colour ; Elem Class 5; Elem ID 14 01260 // set the forground color of text 01261 // 01262 unsigned char *es, *esp; 01263 int octet_count; 01264 // First check and see if the user doesn't want any changes, 01265 // if so, just return success 01266 if ( color == -1 ) 01267 return 1; 01268 01269 // Check and see if the value it is being set to is the current 01270 // value, if so, don't make any changes, just return 1 01271 if ( color == im->textcolor ) 01272 return 1; 01273 01274 // Make sure the color they want to use has been allocated. 01275 // also, that color must be non-negative 01276 if ( ( color >= im->colorsTotal ) || ( color < 0 ) ) 01277 return 0; // you must allocate a color before you use it 01278 01279 // allocate sufficent space. should be 32 bits * 4 to be safe 01280 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 01281 if ( !es ) 01282 return 0; // memory allocation failed 01283 esp = es; 01284 01285 if ( !cdcomhead( es, 5, 14, 1 ) ) 01286 { 01287 free( esp ); return 0; 01288 } 01289 es += 2; 01290 01291 *es = 0377 & color; // mask off last 8 bits and put in es 01292 es++; 01293 01294 octet_count = 4; // we just know this; 2 octets of header, 01295 // 1 octet of data, 1 octet of null data 01296 01297 // add it to the buffer 01298 if ( cdAddElem( im, esp, octet_count ) ) 01299 { 01300 im->textcolor = (short int) color; 01301 free( esp ); 01302 return 1; 01303 } 01304 else 01305 { 01306 free( esp ); 01307 return 0; 01308 } 01309 } 01310 01311 int cdSetTextHeight( cdImagePtr im, int height ) 01312 { 01313 // Attribute: Character Height; Elem Class 5; Elem ID 15 01314 // the height is in the same units as line width 01315 // 01316 unsigned char *es, *esp; 01317 int octet_count; 01318 // First check and see if the user doesn't want any changes, 01319 // if so, just return success 01320 if ( height == -1 ) 01321 return 1; 01322 01323 // Check and see if the value it is being set to is the current 01324 // value, if so, don't make any changes, just return 1 01325 if ( height == im->textheight ) 01326 return 1; 01327 01328 // allocate sufficent space. should be 32 bits * 4 to be safe 01329 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 01330 if ( !es ) 01331 return 0; // memory allocation failed 01332 esp = es; 01333 01334 if ( !cdcomhead( es, 5, 15, 2 ) ) 01335 { 01336 free( esp ); return 0; 01337 } 01338 octet_count = 2; es += 2; 01339 01340 es += cdAppShort( es, height ); 01341 octet_count += 2; 01342 01343 // add it to the buffer 01344 if ( cdAddElem( im, esp, octet_count ) ) 01345 { 01346 im->textheight = height; 01347 free( esp ); 01348 return 1; 01349 } 01350 else 01351 { 01352 free( esp ); 01353 return 0; 01354 } 01355 } 01356 01357 int cdSetTextPath( cdImagePtr im, int tpath ) 01358 { 01359 // Attribute: Text Path; Elem Class 5; Elem ID 17 01360 // Is one of: 01361 // 0 right -- Means the direction of the character base vector 01362 // 1 left -- means 180 degrees from the character base vector 01363 // 2 up -- means the direction of the character up vector 01364 // 3 down -- means 180 degrees from the character up vector 01365 // 01366 unsigned char *es, *esp; 01367 int octet_count; 01368 01369 // First check and see if the user doesn't want any changes, 01370 // if so, just return success 01371 if ( tpath == -1 ) 01372 return 1; 01373 01374 // Check and see if the value it is being set to is the current 01375 // value, if so, don't make any changes, just return 1 01376 if ( tpath == im->textpath ) 01377 return 1; 01378 01379 // allocate sufficent space. should be 32 bits * 4 to be safe 01380 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 01381 if ( !es ) 01382 return 0; // memory allocation failed 01383 esp = es; 01384 octet_count = 0; 01385 01386 if ( !cdcomhead( es, 5, 17, 2 ) ) 01387 { 01388 free( esp ); return 0; 01389 } 01390 es += 2; octet_count = 2; 01391 01392 es += cdAppShort( es, (short int) tpath ); 01393 octet_count += 2; 01394 01395 // add it to the buffer 01396 if ( cdAddElem( im, esp, octet_count ) ) 01397 { 01398 im->textpath = (short int) tpath; 01399 free( esp ); 01400 return 1; 01401 } 01402 else 01403 { 01404 free( esp ); 01405 return 0; 01406 } 01407 } 01408 01409 int cdSetTextOrient( cdImagePtr im, int xup, int yup, int xbase, int ybase ) 01410 { 01411 // Attribute: Character Orientation; Elem Class 5; Elem ID 16 01412 // (xbase,ybase) is the run and the rise of the line that the text is 01413 // written along. For regular text at an angle, set xup = -ybase 01414 // and yup = xbase. Setting it to something different will result in 01415 // skewed text (which may be what you want.) Text written from bottom to 01416 // top at a 90 degree angle would have the following parameters 01417 // xup=-1, yup=0, xbase=0, ybase=1 01418 // 01419 // This function adds the Orientation to the metafile every time. 01420 // It does not follow the normal -1 for no change, although if you 01421 // put in the same numbers it won't re-add it to the meta file. 01422 // 01423 unsigned char *es, *esp; 01424 int octet_count; 01425 01426 01427 // allocate sufficent space. should be 32 bits * 4 to be safe 01428 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 01429 if ( !es ) 01430 return 0; // memory allocation failed 01431 esp = es; 01432 octet_count = 0; 01433 01434 if ( !cdcomhead( es, 5, 16, 8 ) ) 01435 { 01436 free( esp ); return 0; 01437 } 01438 es += 2; octet_count += 2; 01439 01440 // In the metafile it is a 16 bit signed integer 01441 // add xup 01442 es += cdAppShort( es, (short int) xup ); 01443 octet_count += 2; 01444 // add the rest 01445 es += cdAppShort( es, (short int) yup ); 01446 octet_count += 2; 01447 es += cdAppShort( es, (short int) xbase ); 01448 octet_count += 2; 01449 es += cdAppShort( es, (short int) ybase ); 01450 octet_count += 2; 01451 01452 // add it to the buffer 01453 if ( cdAddElem( im, esp, octet_count ) ) 01454 { 01455 free( esp ); 01456 return 1; 01457 } 01458 else 01459 { 01460 free( esp ); 01461 return 0; 01462 } 01463 } 01464 01465 int cdSetMarkerType( cdImagePtr im, int mtype ) 01466 { 01467 // Attribute: Marker Type; Elem Class 5; Elem ID 6 01468 // Set the Marker type. Possible values are: 01469 // 1=dot, 2=plus, 3=asterisk, 4=circle, 5=cross 01470 // Even though new ones can be defined, I am limiting lntype to these values 01471 // If you really need more, you can make the proper changes. 01472 // 01473 unsigned char *es, *esp; 01474 int octet_count; 01475 01476 // First check and see if the user doesn't want any changes, 01477 // if so, just return success 01478 if ( mtype == -1 ) 01479 return 1; 01480 01481 // Check and see if the value it is being set to is the current 01482 // value, if so, don't make any changes, just return 1 01483 if ( mtype == im->mtype ) 01484 return 1; 01485 01486 // Make sure that mtype is between 1 and 5 01487 if ( ( mtype < 1 ) || ( mtype > 5 ) ) 01488 return 0; 01489 01490 // allocate sufficent space. should be 32 bits * 4 to be safe 01491 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 01492 if ( !es ) 01493 return 0; // memory allocation failed 01494 esp = es; 01495 01496 if ( !cdcomhead( es, 5, 6, 2 ) ) 01497 { 01498 free( esp ); return 0; 01499 } 01500 es += 2; 01501 // set Param_List_Len to 2 (signed int at index precision) 01502 01503 // add in the value of mtype 01504 es += cdAppShort( es, (short int) mtype ); 01505 01506 octet_count = 4; // we just know this 01507 01508 // add it to the buffer 01509 if ( cdAddElem( im, esp, octet_count ) ) 01510 { 01511 im->mtype = (short int) mtype; 01512 free( esp ); 01513 return 1; 01514 } 01515 else 01516 { 01517 free( esp ); 01518 return 0; 01519 } 01520 } 01521 01522 int cdSetMarkerSize( cdImagePtr im, int msize ) 01523 { 01524 // Attribute: Marker Size; Elem Class 5; Elem ID 7 01525 // sets the marker size. with an image of height X with marker size 1 01526 // the displayed size will be 1/X%. as an example, if you image is 01527 // x=5, y=10, and you set marker size = 1, and draw a marker, the 01528 // resulting marker will cover 20% of horizontal area. 01529 // 01530 unsigned char *es, *esp; 01531 int octet_count; 01532 01533 // First check and see if the user doesn't want any changes, 01534 // if so, just return success 01535 if ( msize == -1 ) 01536 return 1; 01537 01538 // Check and see if the value it is being set to is the current 01539 // value, if so, don't make any changes, just return 1 01540 if ( msize == im->msize ) 01541 return 1; 01542 01543 // allocate sufficent space. should be 32 bits * 4 to be safe 01544 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 01545 if ( !es ) 01546 return 0; // memory allocation failed 01547 esp = es; 01548 01549 01550 //gej: marker size is 32 bit floating point number, 16 bits before the 01551 // decimal, 16 bits after if marker spec is default (1, scaled) 01552 // for absolute mode (0, absolute) it is 16 bit SI 01553 if ( im->markerspec ) 01554 { 01555 if ( !cdcomhead( es, 5, 7, 4 ) ) 01556 { 01557 free( esp ); return 0; 01558 } 01559 octet_count = 2; 01560 es += 2; 01561 es += cdAppShort( es, (short int) msize ); 01562 octet_count += 2; 01563 // the next two (after decimal point) will always be zero 01564 es += cdAppNull( es, 2 ); 01565 octet_count += 2; 01566 } 01567 else 01568 { 01569 if ( !cdcomhead( es, 5, 7, 4 ) ) 01570 { 01571 free( esp ); return 0; 01572 } 01573 octet_count = 2; 01574 es += 2; 01575 es += cdAppShort( es, (short int) msize ); 01576 octet_count += 2; 01577 } 01578 01579 01580 // add it to the buffer 01581 if ( cdAddElem( im, esp, octet_count ) ) 01582 { 01583 im->msize = msize; 01584 free( esp ); 01585 return 1; 01586 } 01587 else 01588 { 01589 free( esp ); 01590 return 0; 01591 } 01592 } 01593 01594 int cdSetMarkerColor( cdImagePtr im, int mcolor ) 01595 { 01596 // Attribute: Marker Colour; Elem Class 5; Elem ID 8 01597 // Sets the marker color. mcolor should be an index into the color 01598 // table that you have previously allocated. 01599 // 01600 unsigned char *es, *esp; 01601 int octet_count; 01602 // First check and see if the user doesn't want any changes, 01603 // if so, just return success 01604 if ( mcolor == -1 ) 01605 return 1; 01606 01607 // Check and see if the value it is being set to is the current 01608 // value, if so, don't make any changes, just return 1 01609 if ( mcolor == im->mcolor ) 01610 return 1; 01611 01612 // Make sure the color they want to use has been allocated. 01613 // also, that color must be non-negative 01614 if ( ( mcolor >= im->colorsTotal ) || ( mcolor < 0 ) ) 01615 return 0; // you must allocate a color before you use it 01616 01617 // allocate sufficent space. should be 32 bits * 4 to be safe 01618 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 01619 if ( !es ) 01620 return 0; // memory allocation failed 01621 esp = es; 01622 01623 01624 if ( !cdcomhead( es, 5, 8, 1 ) ) 01625 { 01626 free( esp ); return 0; 01627 } 01628 es += 2; 01629 01630 *es = 0377 & mcolor; // mask off last 8 bits and put in es 01631 es++; 01632 01633 es += cdAppNull( es, 1 ); 01634 01635 octet_count = 4; // we just know this; 2 octets of header, 01636 // 1 octet of data, 1 octet of null data 01637 01638 // add it to the buffer 01639 if ( cdAddElem( im, esp, octet_count ) ) 01640 { 01641 im->mcolor = (short int) mcolor; 01642 free( esp ); 01643 return 1; 01644 } 01645 else 01646 { 01647 free( esp ); 01648 return 0; 01649 } 01650 } 01651 01652 int cdSetLineAttrib( cdImagePtr im, int lntype, int lnwidth, int lncolor ) 01653 { 01654 // Spits out the attributes of lines. These attributes stay in effect 01655 // until changed, so you don't have to output them every time. 01656 // 01657 01658 if ( !cdSetLineType( im, lntype ) ) 01659 return 0; 01660 if ( !cdSetLineWidth( im, lnwidth ) ) 01661 return 0; 01662 if ( !cdSetLineColor( im, lncolor ) ) 01663 return 0; 01664 01665 return 1; 01666 } 01667 01668 int cdSetShapeFillAttrib( cdImagePtr im, int instyle, int incolor, int inhatch ) 01669 { 01670 // Spits out the attributes for the interior of filled-area elements. 01671 // These attributes stay in effect until changed, so you don't have to output 01672 // them every time. 01673 // Set the following attributes: 01674 // Interior Style: (integers 0-6, corresponding to: hollow, solid, 01675 // [not pattern], hatch, empty, [not geometric pattern], 01676 // interpolated.) 01677 // Fill Colour: (index into the color table) 01678 // Hatch Index: (integers 1-6, corresponding to: horizontal lines, 01679 // vertical lines, pos. slope parallel lines, 01680 // neg. slope parallel lines, horizontal/vertical 01681 // crosshatch, positive/negative slope crosshatch) 01682 // 01683 if ( !cdSetFillStyle( im, instyle ) ) 01684 return 0; 01685 if ( !cdSetFillColor( im, incolor ) ) 01686 return 0; 01687 if ( !cdSetFillHatch( im, inhatch ) ) 01688 return 0; 01689 01690 return 1; 01691 } 01692 01693 int cdSetShapeEdgeAttrib( cdImagePtr im, int edtype, int edwidth, int edcolor, int edvis ) 01694 { 01695 // Spits out the attributes for the edges of filled-area elements. It may 01696 // seem logical that these would be the same as the corresponding line 01697 // attributes, but this is not the case. 01698 // These attributes stay in effect until changed, so you don't have to output 01699 // them every time. 01700 // Set the following attributes: 01701 // Edge Type (integers 1-5, corresponding to: solid, dash, dot, 01702 // dash-dot, dash-dot-dot. These are the same as those used 01703 // for line type.) 01704 // Edge Width (should be the same as line width) 01705 // Edge Colour (index into the color table) 01706 // Edge Visibility (integer 0 or 1, corresponding to: Off, On) 01707 // 01708 if ( !cdSetEdgeType( im, edtype ) ) 01709 return 0; 01710 if ( !cdSetEdgeWidth( im, edwidth ) ) 01711 return 0; 01712 if ( !cdSetEdgeColor( im, edcolor ) ) 01713 return 0; 01714 if ( !cdSetEdgeVis( im, edvis ) ) 01715 return 0; 01716 01717 return 1; 01718 } 01719 01720 int cdSetTextAttrib( cdImagePtr im, int font, int color, int height ) 01721 { 01722 // Set the attributes of text. the font is an integer pointer into the 01723 // font list where: 01724 // 1 Times 01725 // 2 Times Bold 01726 // 3 Times Italic 01727 // 4 Times Bold Italic 01728 // 5 Helvetica 01729 // 6 Helvetica Bold 01730 // 7 Helvetica Italic 01731 // 8 Helvetica Bold Italic 01732 // 9 Courier 01733 // 10 Courier Bold 01734 // 11 Courier Italic 01735 // 12 Courier Bold Italic 01736 // color is an index into the colortable which is the color of the text 01737 // size is the approximate size you want the text written in. 01738 // 01739 01740 if ( !cdSetTextFont( im, font ) ) 01741 return 0; 01742 if ( !cdSetTextColor( im, color ) ) 01743 return 0; 01744 if ( !cdSetTextHeight( im, height ) ) 01745 return 0; 01746 01747 return 1; 01748 } 01749 01750 int cdSetMarkerAttrib( cdImagePtr im, int mtype, int msize, int mcolor ) 01751 { 01752 // Spits out the attributes of Markers. These attributes stay in effect 01753 // until changed, so you don't have to output them every time. 01754 // 01755 01756 if ( !cdSetMarkerType( im, mtype ) ) 01757 return 0; 01758 if ( !cdSetMarkerSize( im, msize ) ) 01759 return 0; 01760 if ( !cdSetMarkerColor( im, mcolor ) ) 01761 return 0; 01762 01763 return 1; 01764 } 01765 01766 int cdImageDestroy( cdImagePtr im ) 01767 // gej: should work, unless I make changes to cdImage Struct 01768 { 01769 if ( im->elemlist ) 01770 { 01771 free( im->elemlist ); 01772 } 01773 if ( im->desc ) 01774 { 01775 free( im->desc ); 01776 } 01777 if ( im->fontlist ) 01778 { 01779 free( im->fontlist ); 01780 } 01781 free( im ); 01782 01783 return 1; 01784 } 01785 01786 int cdImageColorClosest( cdImagePtr im, int r, int g, int b ) 01787 // From gd library, see README file for copyright information 01788 // gej: should work unchanged 01789 // gej: 5/96, changed the colors to use short int 01790 { 01791 short int i; 01792 long rd, gd, bd; 01793 int ct = ( -1 ); 01794 long mindist = 0; 01795 for ( i = 0; ( i < ( im->colorsTotal ) ); i++ ) 01796 { 01797 long dist; 01798 if ( im->open[i] ) 01799 { 01800 continue; 01801 } 01802 rd = ( im->red[i] - r ); 01803 gd = ( im->green[i] - g ); 01804 bd = ( im->blue[i] - b ); 01805 dist = rd * rd + gd * gd + bd * bd; 01806 if ( ( i == 0 ) || ( dist < mindist ) ) 01807 { 01808 mindist = dist; 01809 ct = i; 01810 } 01811 } 01812 return ct; 01813 } 01814 01815 int cdImageColorClear( cdImagePtr im ) 01816 { 01817 // mark all entries in the color table as open 01818 short int i; 01819 for ( i = 0; ( i < ( cdMaxColors ) ); i++ ) 01820 { 01821 im->open[i] = 1; 01822 } 01823 return 1; 01824 } 01825 01826 int cdImageColorExact( cdImagePtr im, int r, int g, int b ) 01827 // From gd library, see README file for copyright information 01828 // gej: should work unchanged 01829 // gej: 5/96, changed colors to work with short ints 01830 { 01831 short int i; 01832 for ( i = 0; ( i < ( im->colorsTotal ) ); i++ ) 01833 { 01834 if ( im->open[i] ) 01835 { 01836 continue; 01837 } 01838 if ( ( im->red[i] == r ) && 01839 ( im->green[i] == g ) && 01840 ( im->blue[i] == b ) ) 01841 { 01842 return i; 01843 } 01844 } 01845 return -1; 01846 } 01847 01848 static int cdImageAddColorIndex( cdImagePtr im, int r, int g, int b ) 01849 // adds the specified color to the colortable in the cdImagePtr. 01850 // does not add it to the cgm file, cdImageAddColor does. 01851 // do not use either of these two functions, use cdImageColorAllocate. 01852 // 01853 { 01854 short int i; 01855 short int ct = ( -1 ); 01856 for ( i = 0; ( i < ( im->colorsTotal ) ); i++ ) 01857 { 01858 if ( im->open[i] ) 01859 { 01860 ct = i; 01861 break; 01862 } 01863 } 01864 if ( ct == ( -1 ) ) 01865 { 01866 ct = im->colorsTotal; 01867 if ( ct == cdMaxColors ) 01868 { 01869 return -1; 01870 } 01871 im->colorsTotal++; 01872 } 01873 im->red[ct] = (short int) r; 01874 im->green[ct] = (short int) g; 01875 im->blue[ct] = (short int) b; 01876 im->open[ct] = (short int) 0; 01877 01878 return ct; 01879 } 01880 01881 static int cdImageAddColor( cdImagePtr im, int si, int ei ) 01882 // adds colors to the cgm file, gets values from the color table. 01883 // adds all colors from si to ei inclusive. 01884 // Use cdImageColorAllocate, not this one. 01885 // 01886 { 01887 unsigned char *cts, *ctsp; // GEJ: color table attribute 01888 int octet_count; // GEJ: octet count 01889 int numco, curly; 01890 octet_count = 0; 01891 // 01892 // Attribute: Colour Table; Elem Class 5; Elem ID 34 01893 // two parameters P1: Starting colour table index (1 octet, UI) 01894 // P2: list of direct colour values 3-tuples (3 one-octet values) 01895 // 01896 // G E J: find out how many values are being added 01897 if ( ei < 0 ) 01898 return -1; // no colors being added 01899 numco = ei - si + 1; 01900 01901 if ( ( numco > 0 ) && ( numco < 10 ) ) 01902 { 01903 // we can use the short form of the command 01904 // allocate sufficent space. Should be 32 bits * 10 to be safe 01905 cts = (unsigned char *) calloc( 4 * 10, SIZEOF( unsigned char ) ); 01906 if ( !cts ) 01907 return -1; // memory allocation failed 01908 ctsp = cts; 01909 if ( !cdcomhead( ctsp, 5, 34, ( numco * 3 ) + 1 ) ) 01910 { 01911 free( cts ); return -1; 01912 } 01913 ctsp += 2; octet_count += 2; 01914 } 01915 else if ( ( numco > 9 ) && ( numco < 256 ) ) 01916 { 01917 // we must use the long form of the command 01918 // allocate sufficent space. Should be 32 bits*256 to be safe 01919 cts = (unsigned char *) calloc( 256 * 4, SIZEOF( unsigned char ) ); 01920 if ( !cts ) 01921 return -1; // memory allocation failed 01922 ctsp = cts; 01923 if ( !cdcomheadlong( ctsp, 5, 34, ( numco * 3 ) + 1 ) ) 01924 { 01925 free( cts ); return -1; 01926 } 01927 ctsp += 4; octet_count += 4; 01928 } 01929 else 01930 { 01931 return -1; 01932 } 01933 01934 //ctsp += cdAppByte(ctsp, (short int) si); 01935 cdAppByte( ctsp, (short int) si ); 01936 ctsp++; 01937 octet_count++; 01938 for ( numco = si; numco <= ei; numco++ ) 01939 { 01940 ctsp += cdAppByte( ctsp, im->red[numco] ); 01941 ctsp += cdAppByte( ctsp, im->green[numco] ); 01942 ctsp += cdAppByte( ctsp, im->blue[numco] ); 01943 octet_count += 3; 01944 } 01945 01946 01947 curly = 4 - ( octet_count % 4 ); 01948 if ( curly % 4 ) 01949 { 01950 octet_count += curly; 01951 ctsp += cdAppNull( ctsp, curly ); 01952 } 01953 // add it to the buffer 01954 if ( cdAddElem( im, cts, octet_count ) ) 01955 { 01956 free( cts ); 01957 return 1; 01958 } 01959 else 01960 { 01961 free( cts ); 01962 return -1; 01963 } 01964 } 01965 01966 int cdImageColorAllocate( cdImagePtr im, int r, int g, int b ) 01967 // From gd library, see README file for copyright information 01968 // gej: modified to allocate the color in the CGM buffer as well 01969 // as the color table 01970 // gej: 5/96, modified to use short ints for colors 01971 { 01972 short int ct; 01973 ct = cdImageAddColorIndex( im, r, g, b ); 01974 if ( ct == -1 ) 01975 return -1; 01976 // GEJ: w we have successfully alocated it in the color table 01977 // so let's put it in the CGM as well. 01978 // 01979 if ( cdImageAddColor( im, ct, ct ) == -1 ) 01980 { 01981 return -1; 01982 } 01983 else 01984 { 01985 return ct; 01986 } 01987 } 01988 01989 int cdImageColor16( cdImagePtr im ) 01990 { 01991 // allocate the 16 basic colors in the windows pallete 01992 // 01993 // cdImageColorAllocate(im, 0, 0, 0); 01994 // cdImageColorAllocate(im, 0, 0, 0); 01995 // cdImageColorAllocate(im, 0, 0, 0); 01996 // cdImageColorAllocate(im, 0, 0, 0); 01997 // cdImageColorAllocate(im, 0, 0, 0); 01998 // cdImageColorAllocate(im, 0, 0, 0); 01999 // cdImageColorAllocate(im, 0, 0, 0); 02000 // cdImageColorAllocate(im, 0, 0, 0); 02001 // cdImageColorAllocate(im, 0, 0, 0); 02002 // cdImageColorAllocate(im, 0, 0, 0); 02003 // cdImageColorAllocate(im, 0, 0, 0); 02004 // cdImageColorAllocate(im, 0, 0, 0); 02005 // cdImageColorAllocate(im, 0, 0, 0); 02006 // cdImageColorAllocate(im, 0, 0, 0); 02007 // cdImageColorAllocate(im, 0, 0, 0); 02008 // cdImageColorAllocate(im, 0, 0, 0); 02009 // 02010 int si, ei, li; 02011 si = cdImageAddColorIndex( im, 255, 255, 255 ); 02012 if ( si == -1 ) 02013 return 0; 02014 li = -1; ei = si; 02015 ei = cdImageAddColorIndex( im, 0, 0, 0 ); 02016 if ( ei != -1 ) 02017 { 02018 li = ei; 02019 } 02020 ei = cdImageAddColorIndex( im, 128, 0, 0 ); 02021 if ( ei != -1 ) 02022 { 02023 li = ei; 02024 } 02025 ei = cdImageAddColorIndex( im, 0, 128, 0 ); 02026 if ( ei != -1 ) 02027 { 02028 li = ei; 02029 } 02030 ei = cdImageAddColorIndex( im, 128, 128, 0 ); 02031 if ( ei != -1 ) 02032 { 02033 li = ei; 02034 } 02035 ei = cdImageAddColorIndex( im, 0, 0, 128 ); 02036 if ( ei != -1 ) 02037 { 02038 li = ei; 02039 } 02040 ei = cdImageAddColorIndex( im, 128, 0, 128 ); 02041 if ( ei != -1 ) 02042 { 02043 li = ei; 02044 } 02045 ei = cdImageAddColorIndex( im, 0, 128, 128 ); 02046 if ( ei != -1 ) 02047 { 02048 li = ei; 02049 } 02050 ei = cdImageAddColorIndex( im, 128, 128, 128 ); 02051 if ( ei != -1 ) 02052 { 02053 li = ei; 02054 } 02055 ei = cdImageAddColorIndex( im, 192, 192, 192 ); 02056 if ( ei != -1 ) 02057 { 02058 li = ei; 02059 } 02060 ei = cdImageAddColorIndex( im, 255, 0, 0 ); 02061 if ( ei != -1 ) 02062 { 02063 li = ei; 02064 } 02065 ei = cdImageAddColorIndex( im, 0, 255, 0 ); 02066 if ( ei != -1 ) 02067 { 02068 li = ei; 02069 } 02070 ei = cdImageAddColorIndex( im, 255, 255, 0 ); 02071 if ( ei != -1 ) 02072 { 02073 li = ei; 02074 } 02075 ei = cdImageAddColorIndex( im, 0, 0, 255 ); 02076 if ( ei != -1 ) 02077 { 02078 li = ei; 02079 } 02080 ei = cdImageAddColorIndex( im, 255, 0, 255 ); 02081 if ( ei != -1 ) 02082 { 02083 li = ei; 02084 } 02085 ei = cdImageAddColorIndex( im, 0, 255, 255 ); 02086 if ( ei != -1 ) 02087 { 02088 li = ei; 02089 } 02090 02091 if ( ei == -1 ) 02092 { 02093 ei = li; 02094 } 02095 if ( cdImageAddColor( im, si, ei ) == -1 ) 02096 { 02097 return -1; 02098 } 02099 else 02100 { 02101 return ei; 02102 } 02103 } 02104 int cdImageColorDeallocate( cdImagePtr im, int color ) 02105 // wogl: the parameter names are commented to avoid compiler warnings 02106 // From gd library, see README file for copyright information 02107 // gej: should work unchanged 02108 { 02109 // Mark it open. 02110 //im->open[color] = 1; 02111 // gej: really can't work, we are not allowing redefinition 02112 // of color table entries 02113 return 0; 02114 } 02115 02116 int cdLine( cdImagePtr im, int x1, int y1, int x2, int y2 ) 02117 // Graphic Primitive: Polyline; Elem Class 4; Elem ID 1 02118 // Actually generate the line, if you are writing a program to use this 02119 // library, use this function, not cdImageLine or cdImageDashedLine, 02120 // those are just in for compatiblilty with gd 02121 // 02122 // This function will draw a line using the current line type, width, and color 02123 // 02124 { 02125 unsigned char *es, *esp; 02126 int octet_count; 02127 short int sweet; 02128 short int sour; 02129 02130 // check to make sure the line is withing the scope of the picture 02131 // ie. the values you give for drawing the line are within 02132 // the values you created the picture with 02133 if ( !( cdImageBoundsSafe( im, x1, y1 ) ) || !( cdImageBoundsSafe( im, x2, y2 ) ) ) 02134 return 0; 02135 02136 // allocate sufficent space. should be 32 bits * 4 to be safe 02137 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 02138 if ( !es ) 02139 return 0; // memory allocation failed 02140 esp = es; 02141 02142 if ( !cdcomhead( es, 4, 1, 8 ) ) 02143 { 02144 free( esp ); return 0; 02145 } 02146 es += 2; 02147 octet_count = 2; 02148 02149 // now we are ready for the parameter data 02150 sweet = (short int) x1; 02151 sour = sweet >> 8; 02152 *es = *es | ( sour & 0377 ); 02153 es++; octet_count++; 02154 *es = (unsigned char) sweet; 02155 es++; octet_count++; 02156 sweet = (short int) y1; 02157 sour = sweet >> 8; 02158 *es = *es | ( sour & 0377 ); 02159 es++; octet_count++; 02160 *es = (unsigned char) sweet; 02161 es++; octet_count++; 02162 sweet = (short int) x2; 02163 sour = sweet >> 8; 02164 *es = *es | ( sour & 0377 ); 02165 es++; octet_count++; 02166 *es = (unsigned char) sweet; 02167 es++; octet_count++; 02168 sweet = (short int) y2; 02169 sour = sweet >> 8; 02170 *es = *es | ( sour & 0377 ); 02171 es++; octet_count++; 02172 *es = (unsigned char) sweet; 02173 octet_count++; 02174 02175 // add it to the buffer 02176 if ( cdAddElem( im, esp, octet_count ) ) 02177 { 02178 free( esp ); 02179 return 1; 02180 } 02181 else 02182 { 02183 free( esp ); 02184 return 0; 02185 } 02186 } 02187 02188 int cdMarker( cdImagePtr im, int x, int y ) 02189 // Graphic Primitive: PolyMarker; Elem Class 4; Elem ID 3 02190 // puts a marker in the file, it will have characteristics set by 02191 // cdSetMarkerAttrib 02192 // 02193 { 02194 unsigned char *es, *esp; 02195 int octet_count; 02196 02197 // check to make sure the line is withing the scope of the picture 02198 // ie. the values you give for drawing the line are within 02199 // the values you created the picture with 02200 if ( !cdImageBoundsSafe( im, x, y ) ) 02201 return 0; 02202 02203 // allocate sufficent space. should be 32 bits * 4 to be safe 02204 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 02205 if ( !es ) 02206 return 0; // memory allocation failed 02207 esp = es; 02208 02209 if ( !cdcomhead( es, 4, 3, 4 ) ) 02210 { 02211 free( esp ); return 0; 02212 } 02213 es += 2; 02214 octet_count = 2; 02215 02216 octet_count += cdAppShort( es, (short int) x ); 02217 es += 2; 02218 octet_count += cdAppShort( es, (short int) y ); 02219 es += 2; 02220 02221 // add it to the buffer 02222 if ( cdAddElem( im, esp, octet_count ) ) 02223 { 02224 free( esp ); 02225 return 1; 02226 } 02227 else 02228 { 02229 free( esp ); 02230 return 0; 02231 } 02232 } 02233 02234 02235 int cdRectangle( cdImagePtr im, int x1, int y1, int x2, int y2 ) 02236 { 02237 // Graphic Primitive: rectangle; Elem Class 4; Elem ID 11 02238 // Actually generate the rectangle, if you are writing a program to use this 02239 // library, use this function, not cdImageRectangle, 02240 // those are just in for compatiblilty with gd 02241 // 02242 // This function will draw a Rectangle using the current 02243 // edge type, width, color, and visibility, and the current 02244 // fill style, color, and hatch 02245 // 02246 unsigned char *es, *esp; 02247 int octet_count; 02248 short int sweet; 02249 short int sour; 02250 02251 // check to make sure the line is withing the scope of the picture 02252 // ie. the values you give for drawing the line are within 02253 // the values you created the picture with 02254 if ( !( cdImageBoundsSafe( im, x1, y1 ) ) || !( cdImageBoundsSafe( im, x2, y2 ) ) ) 02255 return 0; 02256 02257 // allocate sufficent space. should be 32 bits * 4 to be safe 02258 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 02259 if ( !es ) 02260 return 0; // memory allocation failed 02261 esp = es; 02262 02263 // their are four 16 bit signed integers as attributes 02264 if ( !cdcomhead( es, 4, 11, 8 ) ) 02265 { 02266 free( esp ); return 0; 02267 } 02268 es += 2; octet_count = 2; 02269 02270 // now we are ready for the parameter data 02271 sweet = (short int) x1; 02272 sour = sweet >> 8; 02273 *es = *es | ( sour & 0377 ); 02274 es++; octet_count++; 02275 *es = (unsigned char) sweet; 02276 es++; octet_count++; 02277 sweet = (short int) y1; 02278 sour = sweet >> 8; 02279 *es = *es | ( sour & 0377 ); 02280 es++; octet_count++; 02281 *es = (unsigned char) sweet; 02282 es++; octet_count++; 02283 sweet = (short int) x2; 02284 sour = sweet >> 8; 02285 *es = *es | ( sour & 0377 ); 02286 es++; octet_count++; 02287 *es = (unsigned char) sweet; 02288 es++; octet_count++; 02289 sweet = (short int) y2; 02290 sour = sweet >> 8; 02291 *es = *es | ( sour & 0377 ); 02292 es++; octet_count++; 02293 *es = (unsigned char) sweet; 02294 octet_count++; 02295 02296 // add it to the buffer 02297 if ( cdAddElem( im, esp, octet_count ) ) 02298 { 02299 free( esp ); 02300 return 1; 02301 } 02302 else 02303 { 02304 free( esp ); 02305 return 0; 02306 } 02307 } 02308 02309 int cdCircle( cdImagePtr im, int cx, int cy, int r ) 02310 { 02311 // Graphic Primitive: circle; Elem Class 4; Elem ID 12 02312 // cx,cy is the center of the circle, r is the radius 02313 // 02314 // This function will draw a Circle using the current 02315 // edge type, width, color, and visibility, and the current 02316 // fill style, color, and hatch 02317 // 02318 unsigned char *es, *esp; 02319 int octet_count; 02320 short int sweet; 02321 short int sour; 02322 02323 // check to make sure the circle is withing the scope of the picture 02324 // ie. the values you give for drawing the circle are within 02325 // the values you created the picture with 02326 if ( !( cdImageBoundsSafe( im, cx, cy ) ) ) 02327 return 0; 02328 02329 // allocate sufficent space. should be 32 bits * 4 to be safe 02330 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 02331 if ( !es ) 02332 return 0; // memory allocation failed 02333 esp = es; 02334 02335 // their are three 16 bit signed integers as attributes 02336 if ( !cdcomhead( es, 4, 12, 6 ) ) 02337 { 02338 free( esp ); return 0; 02339 } 02340 es += 2; octet_count = 2; 02341 02342 // now we are ready for the parameter data 02343 sweet = (short int) cx; 02344 sour = sweet >> 8; 02345 *es = *es | ( sour & 0377 ); 02346 es++; octet_count++; 02347 *es = (unsigned char) sweet; 02348 es++; octet_count++; 02349 sweet = (short int) cy; 02350 sour = sweet >> 8; 02351 *es = *es | ( sour & 0377 ); 02352 es++; octet_count++; 02353 *es = (unsigned char) sweet; 02354 es++; octet_count++; 02355 sweet = (short int) r; 02356 sour = sweet >> 8; 02357 *es = *es | ( sour & 0377 ); 02358 es++; octet_count++; 02359 *es = (unsigned char) sweet; 02360 octet_count++; 02361 02362 02363 // add it to the buffer 02364 if ( cdAddElem( im, esp, octet_count ) ) 02365 { 02366 free( esp ); 02367 return 1; 02368 } 02369 else 02370 { 02371 free( esp ); 02372 return 0; 02373 } 02374 } 02375 02376 int cdArc3Pt( cdImagePtr im, int sx, int sy, int ix, int iy, int ex, int ey ) 02377 { 02378 // Graphic Primitive: Cicular Arc 3 Point; Elem Class 4; Elem ID 13 02379 // 02380 // This function will draw a Circular Arc using the current 02381 // Line type, width, and color, 02382 // 02383 unsigned char *es, *esp; 02384 int octet_count; 02385 short int sweet; 02386 short int sour; 02387 02388 // check to make sure the line is withing the scope of the picture 02389 // ie. the values you give for drawing the line are within 02390 // the values you created the picture with 02391 if ( !( cdImageBoundsSafe( im, sx, sy ) ) || !( cdImageBoundsSafe( im, ix, iy ) ) || !( cdImageBoundsSafe( im, ex, ey ) ) ) 02392 return 0; 02393 02394 // allocate sufficent space. should be 32 bits * 4 to be safe 02395 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 02396 if ( !es ) 02397 return 0; // memory allocation failed 02398 esp = es; 02399 02400 // their are six 16 bit signed integers as attributes 02401 if ( !cdcomhead( es, 4, 13, 12 ) ) 02402 { 02403 free( esp ); return 0; 02404 } 02405 es += 2; octet_count = 2; 02406 02407 // now we are ready for the parameter data 02408 sweet = (short int) sx; 02409 sour = sweet >> 8; 02410 *es = *es | ( sour & 0377 ); 02411 es++; octet_count++; 02412 *es = (unsigned char) sweet; 02413 es++; octet_count++; 02414 sweet = (short int) sy; 02415 sour = sweet >> 8; 02416 *es = *es | ( sour & 0377 ); 02417 es++; octet_count++; 02418 *es = (unsigned char) sweet; 02419 es++; octet_count++; 02420 sweet = (short int) ix; 02421 sour = sweet >> 8; 02422 *es = *es | ( sour & 0377 ); 02423 es++; octet_count++; 02424 *es = (unsigned char) sweet; 02425 es++; octet_count++; 02426 sweet = (short int) iy; 02427 sour = sweet >> 8; 02428 *es = *es | ( sour & 0377 ); 02429 es++; octet_count++; 02430 *es = (unsigned char) sweet; 02431 es++; octet_count++; 02432 sweet = (short int) ex; 02433 sour = sweet >> 8; 02434 *es = *es | ( sour & 0377 ); 02435 es++; octet_count++; 02436 *es = (unsigned char) sweet; 02437 es++; octet_count++; 02438 sweet = (short int) ey; 02439 sour = sweet >> 8; 02440 *es = *es | ( sour & 0377 ); 02441 es++; octet_count++; 02442 *es = (unsigned char) sweet; 02443 octet_count++; 02444 02445 // add it to the buffer 02446 if ( cdAddElem( im, esp, octet_count ) ) 02447 { 02448 free( esp ); 02449 return 1; 02450 } 02451 else 02452 { 02453 free( esp ); 02454 return 0; 02455 } 02456 } 02457 02458 int cdArc3PtClose( cdImagePtr im, int sx, int sy, int ix, int iy, int ex, int ey, int cl ) 02459 { 02460 // Graphic Primitive: Cicular Arc 3 Point Close; Elem Class 4; Elem ID 14 02461 // 02462 // This function will draw a Circle using the current 02463 // edge type, width, color, and visibility, and the current 02464 // fill style, color, and hatch 02465 // 02466 // cd is the closure type. It can be either 0 for pie closure or 02467 // 1 for chord closure. 02468 // 02469 unsigned char *es, *esp; 02470 int octet_count; 02471 02472 // check to make sure the line is withing the scope of the picture 02473 // ie. the values you give for drawing the line are within 02474 // the values you created the picture with 02475 if ( !( cdImageBoundsSafe( im, sx, sy ) ) || !( cdImageBoundsSafe( im, ix, iy ) ) || !( cdImageBoundsSafe( im, ex, ey ) ) ) 02476 return 0; 02477 02478 // make sure that they close the arc either with pie (0) or chord (1) 02479 if ( ( cl != 0 ) && ( cl != 1 ) ) 02480 return 0; 02481 02482 // allocate sufficent space. should be 32 bits * 6 to be safe 02483 es = (unsigned char *) calloc( 4 * 6, SIZEOF( unsigned char ) ); 02484 if ( !es ) 02485 return 0; // memory allocation failed 02486 esp = es; 02487 02488 // their are seven 16 bit signed integers as attributes 02489 if ( !cdcomhead( es, 4, 14, 14 ) ) 02490 { 02491 free( esp ); return 0; 02492 } 02493 es += 2; octet_count = 2; 02494 02495 // now we are ready for the parameter data 02496 octet_count += cdAppShort( es, (short int) sx ); 02497 es += 2; 02498 octet_count += cdAppShort( es, (short int) sy ); 02499 es += 2; 02500 octet_count += cdAppShort( es, (short int) ix ); 02501 es += 2; 02502 octet_count += cdAppShort( es, (short int) iy ); 02503 es += 2; 02504 octet_count += cdAppShort( es, (short int) ex ); 02505 es += 2; 02506 octet_count += cdAppShort( es, (short int) ey ); 02507 es += 2; 02508 octet_count += cdAppShort( es, (short int) cl ); 02509 es += 2; 02510 02511 // add it to the buffer 02512 if ( cdAddElem( im, esp, octet_count ) ) 02513 { 02514 free( esp ); 02515 return 1; 02516 } 02517 else 02518 { 02519 free( esp ); 02520 return 0; 02521 } 02522 } 02523 02524 int cdEllipse( cdImagePtr im, int cx, int cy, int d1x, int d1y, int d2x, int d2y ) 02525 { 02526 // Graphic Primitive: Ellipse; Elem Class 4; Elem ID 17 02527 // 02528 // This function will draw an Ellipse using the current 02529 // edge type, width, color, and visibility, and the current 02530 // fill style, color, and hatch 02531 // 02532 unsigned char *es, *esp; 02533 int octet_count; 02534 02535 // check to make sure the line is withing the scope of the picture 02536 // ie. the values you give for drawing the line are within 02537 // the values you created the picture with 02538 if ( !( cdImageBoundsSafe( im, cx, cy ) ) || !( cdImageBoundsSafe( im, d1x, d1y ) ) || !( cdImageBoundsSafe( im, d2x, d2y ) ) ) 02539 return 0; 02540 02541 // allocate sufficent space. should be 32 bits * 4 to be safe 02542 es = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 02543 if ( !es ) 02544 return 0; // memory allocation failed 02545 esp = es; 02546 02547 // their are six 16 bit signed integers as attributes 02548 if ( !cdcomhead( es, 4, 17, 12 ) ) 02549 { 02550 free( esp ); return 0; 02551 } 02552 es += 2; octet_count = 2; 02553 02554 // now we are ready for the parameter data 02555 octet_count += cdAppShort( es, (short int) cx ); 02556 es += 2; 02557 octet_count += cdAppShort( es, (short int) cy ); 02558 es += 2; 02559 octet_count += cdAppShort( es, (short int) d1x ); 02560 es += 2; 02561 octet_count += cdAppShort( es, (short int) d1y ); 02562 es += 2; 02563 octet_count += cdAppShort( es, (short int) d2x ); 02564 es += 2; 02565 octet_count += cdAppShort( es, (short int) d2y ); 02566 es += 2; 02567 02568 // add it to the buffer 02569 if ( cdAddElem( im, esp, octet_count ) ) 02570 { 02571 free( esp ); 02572 return 1; 02573 } 02574 else 02575 { 02576 free( esp ); 02577 return 0; 02578 } 02579 } 02580 02581 int cdPolygon( cdImagePtr im, cdPointPtr p, int n ) 02582 { 02583 // Graphic Primitive: Polygon; Elem Class 4; Elem ID 7 02584 // 02585 // cdPointPtr is defined in cd.h, basically, it is two arrays of integers 02586 // p[m].x and p[m].y containing the x and y values respectively. n 02587 // is the number of points in this array (not the index of the last point, 02588 // which is n-1). n must be at least 3 (otherwise 02589 // you really don't have much of a polygon, it is closer to a line.) 02590 // 02591 // This function will draw a Polygon using the current 02592 // edge type, width, color, and visibility, and the current 02593 // fill style, color, and hatch 02594 // 02595 unsigned char *es, *esp; 02596 int octet_count; 02597 int x; // counter 02598 02599 if ( n < 3 ) 02600 return 0; // it is either a point or a line 02601 02602 if ( n < 8 ) 02603 { 02604 // It fits in the short form of the command, lets us 02605 // add it right now, shall we? 02606 // allocate sufficent space. Should be 32 bits*10 to be safe 02607 es = (unsigned char *) calloc( 4 * 10, SIZEOF( unsigned char ) ); 02608 if ( !es ) 02609 return 0; // memory allocation failed 02610 esp = es; 02611 02612 02613 // their are n*2 16 bit signed integers as attributes 02614 if ( !cdcomhead( es, 4, 7, ( n * 4 ) ) ) 02615 { 02616 free( esp ); return 0; 02617 } 02618 es += 2; octet_count = 2; 02619 } 02620 else if ( n < 8191 ) 02621 { 02622 // there are more than 7 points in it, that sucks 02623 // gej, so basically, for this one, I set the header 02624 // to cdcomhead(es, 4, 7, 31) then write a function for the long 02625 // form that takes the first 15 bits of n and tags a 0 in front 02626 // of it and puts it in es, than I do the for loop all over again 02627 // that doesn't seem too hard. But I will leave that for another 02628 // day. 02629 // 02630 // keep in mind that if CDGROWLISTSIZE is smaller than n*4 02631 // (at most 32769) then things could fail in a most unsavory fashion. 02632 // 02633 // allocate sufficent space. 32 bits*(n+1) to be safe 02634 es = (unsigned char *) calloc( 4 * ( n + 1 ), SIZEOF( unsigned char ) ); 02635 if ( !es ) 02636 return 0; // memory allocation failed 02637 esp = es; 02638 02639 if ( !cdcomheadlong( es, 4, 7, ( n * 4 ) ) ) 02640 { 02641 free( esp ); return 0; 02642 } 02643 es += 4; octet_count = 4; 02644 } 02645 else 02646 { 02647 // there are more than 8191 points in it, I am not going to implement 02648 // that, if you want it that bad, do it yourself. 02649 return 0; 02650 } 02651 02652 02653 for ( x = 0; x < n; x++ ) 02654 { 02655 // now we are ready for the parameter data 02656 es += cdAppShort( es, (short int) p->x ); 02657 es += cdAppShort( es, (short int) p->y ); 02658 octet_count += 4; 02659 p++; 02660 } 02661 02662 // add it to the buffer 02663 if ( cdAddElem( im, esp, octet_count ) ) 02664 { 02665 free( esp ); 02666 return 1; 02667 } 02668 else 02669 { 02670 free( esp ); 02671 return 0; 02672 } 02673 } 02674 02675 int cdPolygonSet( cdImagePtr im, cdPointPtr p, int n ) 02676 { 02677 // Graphic Primitive: Polygon; Elem Class 4; Elem ID 8 02678 // 02679 // cdPointPtr is defined in cd.h, basically, it is three arrays of integers 02680 // p[m].x and p[m].y containing the x and y values respectively and p[m].e 02681 // the characteristics of the line leaving point n (0=invisible,1=visible, 02682 // 2=close,invisible, 3=close,visible). n is the number of points in this 02683 // array (not the index of the last point, which is n-1). 02684 // n must be at least 3 (otherwise you really don't have much of a polygon, 02685 // it is closer to a line.) 02686 // 02687 // This function will draw a set of Polygons using the current 02688 // edge type, width, color, and the current 02689 // fill style, color, and hatch 02690 // 02691 unsigned char *es, *esp; 02692 int octet_count; 02693 int x; // counter 02694 02695 if ( n < 3 ) 02696 return 0; // it is either a point or a line 02697 02698 if ( n < 6 ) 02699 { 02700 // It fits in the short form of the command, lets us 02701 // add it right now, shall we? 02702 // allocate sufficent space. Should be 48 bits*10 to be safe 02703 es = (unsigned char *) calloc( 6 * 10, SIZEOF( unsigned char ) ); 02704 if ( !es ) 02705 return 0; // memory allocation failed 02706 esp = es; 02707 02708 02709 // their are n*2 16 bit signed integers as attributes 02710 if ( !cdcomhead( es, 4, 8, ( n * 6 ) ) ) 02711 { 02712 free( esp ); return 0; 02713 } 02714 es += 2; octet_count = 2; 02715 } 02716 else if ( n < 5462 ) 02717 { 02718 // there are more than 5 points in it, that sucks 02719 // gej, so basically, for this one, I set the header 02720 // to cdcomhead(es, 4, 7, 31) then write a function for the long 02721 // form that takes the first 15 bits of n and tags a 0 in front 02722 // of it and puts it in es, than I do the for loop all over again 02723 // that doesn't seem too hard. But I will leave that for another 02724 // day. 02725 // 02726 // keep in mind that if CDGROWLISTSIZE is smaller than n*6 02727 // (at most 32769) then things could fail in a most unsavory fashion. 02728 // 02729 // allocate sufficent space. 48 bits*(n+1) to be safe 02730 es = (unsigned char *) calloc( 6 * ( n + 1 ), SIZEOF( unsigned char ) ); 02731 if ( !es ) 02732 return 0; // memory allocation failed 02733 esp = es; 02734 02735 if ( !cdcomheadlong( es, 4, 8, ( n * 6 ) ) ) 02736 { 02737 free( esp ); return 0; 02738 } 02739 es += 4; octet_count = 4; 02740 } 02741 else 02742 { 02743 // there are more than 5462 points in it, I am not going to implement 02744 // that, if you want it that bad, do it yourself. 02745 return 0; 02746 } 02747 02748 02749 for ( x = 0; x < n; x++ ) 02750 { 02751 // now we are ready for the parameter data 02752 es += cdAppShort( es, (short int) p->x ); 02753 es += cdAppShort( es, (short int) p->y ); 02754 es += cdAppShort( es, (short int) p->e ); 02755 octet_count += 6; 02756 p++; 02757 } 02758 02759 // add it to the buffer 02760 if ( cdAddElem( im, esp, octet_count ) ) 02761 { 02762 free( esp ); 02763 return 1; 02764 } 02765 else 02766 { 02767 free( esp ); 02768 return 0; 02769 } 02770 } 02771 02772 int cdPolyLine( cdImagePtr im, cdPointPtr p, int n ) 02773 { 02774 // Graphic Primitive: Polyline; Elem Class 4; Elem ID 1 02775 // 02776 // cdPointPtr is defined in cd.h, basically, it is two arrays of integers 02777 // p[m].x and p[m].y containing the x and y values respectively. n 02778 // is the number of points in this array (not the index of the last point, 02779 // which is n-1). if n is 2, it is a regular line, like cdline 02780 // 02781 // This function will draw a Polyline using the current 02782 // line type, width, color, and visibility, 02783 // 02784 unsigned char *es, *esp; 02785 int octet_count; 02786 int x; // counter 02787 02788 if ( n < 2 ) 02789 return 0; // it is a point 02790 02791 if ( n < 8 ) 02792 { 02793 // It fits in the short form of the command, lets us 02794 // add it right now, shall we? 02795 // allocate sufficent space. Should be 32 bits*10 to be safe 02796 es = (unsigned char *) calloc( 4 * 10, SIZEOF( unsigned char ) ); 02797 if ( !es ) 02798 return 0; // memory allocation failed 02799 esp = es; 02800 02801 02802 // their are n*2 16 bit signed integers as attributes 02803 if ( !cdcomhead( es, 4, 1, ( n * 4 ) ) ) 02804 { 02805 free( esp ); return 0; 02806 } 02807 es += 2; octet_count = 2; 02808 } 02809 else if ( n < 8191 ) 02810 { 02811 // there are more than 7 points in it, that sucks 02812 // gej, so basically, for this one, I set the header 02813 // using the long version cdcomheadlong(es, 4, 1, n*4) 02814 // 02815 // keep in mind that if CDGROWLISTSIZE is smaller than n*4 02816 // (at most 32769) then the list may have to grow several times 02817 // 02818 // allocate sufficent space. 32 bits*(n+1) to be safe 02819 es = (unsigned char *) calloc( 4 * ( n + 1 ), SIZEOF( unsigned char ) ); 02820 if ( !es ) 02821 return 0; // memory allocation failed 02822 esp = es; 02823 02824 if ( !cdcomheadlong( es, 4, 1, ( n * 4 ) ) ) 02825 { 02826 free( esp ); return 0; 02827 } 02828 es += 4; octet_count = 4; 02829 } 02830 else 02831 { 02832 // there are more than 8191 points in it, I am not going to implement 02833 // that, if you want it that bad, do it yourself. 02834 return 0; 02835 } 02836 02837 for ( x = 0; x < n; x++ ) 02838 { 02839 // now we are ready for the parameter data 02840 es += cdAppShort( es, (short int) p->x ); 02841 es += cdAppShort( es, (short int) p->y ); 02842 octet_count += 4; 02843 p++; 02844 } 02845 02846 // add it to the buffer 02847 if ( cdAddElem( im, esp, octet_count ) ) 02848 { 02849 free( esp ); 02850 return 1; 02851 } 02852 else 02853 { 02854 free( esp ); 02855 return 0; 02856 } 02857 } 02858 02859 int cdPolyMarker( cdImagePtr im, cdPointPtr p, int n ) 02860 { 02861 // Graphic Primitive: PolyMarker; Elem Class 4; Elem ID 3 02862 // 02863 // cdPointPtr is defined in cd.h, basically, it is two arrays of integers 02864 // p[m].x and p[m].y containing the x and y values respectively. n 02865 // is the number of points in this array (not the index of the last point, 02866 // which is n-1). if n is 2, it is a regular line, like cdline 02867 // 02868 // This function will insert n markers using the current 02869 // Marker type, width, color, and visibility, 02870 // 02871 unsigned char *es, *esp; 02872 int octet_count; 02873 int x; // counter 02874 02875 if ( n < 1 ) 02876 return 0; // it is nothing 02877 if ( n < 8 ) 02878 { 02879 // It fits in the short form of the command, lets us 02880 // add it right now, shall we? 02881 // allocate sufficent space. Should be 32 bits*10 to be safe 02882 es = (unsigned char *) calloc( 4 * 10, SIZEOF( unsigned char ) ); 02883 if ( !es ) 02884 return 0; // memory allocation failed 02885 esp = es; 02886 02887 02888 // their are n*2 16 bit signed integers as attributes 02889 if ( !cdcomhead( es, 4, 3, ( n * 4 ) ) ) 02890 { 02891 free( esp ); return 0; 02892 } 02893 es += 2; octet_count = 2; 02894 } 02895 else if ( n < 8191 ) 02896 { 02897 // there are more than 7 points in it, that sucks 02898 // gej, so basically, for this one, I set the header 02899 // using the long version cdcomheadlong(es, 4, 1, n*4) 02900 // 02901 // keep in mind that if CDGROWLISTSIZE is smaller than n*4 02902 // (at most 32769) then the list may have to grow several times 02903 // 02904 // allocate sufficent space. 32 bits*(n+1) to be safe 02905 es = (unsigned char *) calloc( 4 * ( n + 1 ), SIZEOF( unsigned char ) ); 02906 if ( !es ) 02907 return 0; // memory allocation failed 02908 esp = es; 02909 02910 if ( !cdcomheadlong( es, 4, 3, ( n * 4 ) ) ) 02911 { 02912 free( esp ); return 0; 02913 } 02914 es += 4; octet_count = 4; 02915 } 02916 else 02917 { 02918 // there are more than 8191 points in it, I am not going to implement 02919 // that, if you want it that bad, do it yourself. 02920 return 0; 02921 } 02922 02923 for ( x = 0; x < n; x++ ) 02924 { 02925 // now we are ready for the parameter data 02926 es += cdAppShort( es, (short int) p->x ); 02927 es += cdAppShort( es, (short int) p->y ); 02928 octet_count += 4; 02929 p++; 02930 } 02931 02932 // add it to the buffer 02933 if ( cdAddElem( im, esp, octet_count ) ) 02934 { 02935 free( esp ); 02936 return 1; 02937 } 02938 else 02939 { 02940 free( esp ); 02941 return 0; 02942 } 02943 } 02944 02945 int cdText( cdImagePtr im, int x, int y, const char *ts ) 02946 { 02947 // Graphic Primitive: Text; Elem Class 4; Elem ID 4 02948 // add text to the picture. Start it at the point (x,y) 02949 // this should be the lower left corner of where the text is 02950 // the parameters are point, enumerated(set to 1), string 02951 // 02952 // String encoding in CGM is a little strange. After you have the other 02953 // parameter info, the first octet for the string is either 0..254 which 02954 // is the number of octets of string data, or 255 which signifies a long 02955 // string. if it is 255 then the next 16 bits indicate the length of the 02956 // string. the first bit (bit15) is 0 if this is the last part of the 02957 // string and 1 if another part follows it. the next 15 bits are in the 02958 // range 0..32767 and are the number of octets of string info following. 02959 // so the length stored in the command header is the whole enchelada. 02960 // 02961 int tslen, curly; 02962 unsigned char *es, *esp; 02963 int octet_count; 02964 02965 // check to make sure the Text is within the scope of the picture 02966 // actually, I am only checking the start of it 02967 // 02968 if ( !( cdImageBoundsSafe( im, x, y ) ) ) 02969 return 0; 02970 02971 // allocate sufficent space. should be tslen+ 32 bits * 4 to be safe 02972 tslen = strlen( ts ); 02973 02974 // if there are more than 32700 characters fail 02975 // gej: this could go as high as 32767 I think, but lets 02976 // cut it off at 32700 02977 if ( ( tslen > 32700 ) || ( tslen < 0 ) ) 02978 return 0; 02979 02980 es = (unsigned char *) calloc( ( ( 4 * 4 ) + tslen ), SIZEOF( unsigned char ) ); 02981 if ( !es ) 02982 return 0; // memory allocation failed 02983 esp = es; 02984 02985 if ( !cdcomheadlong( es, 4, 4, 9 + tslen ) ) 02986 { 02987 free( esp ); return 0; 02988 } 02989 es += 4; octet_count = 4; 02990 02991 // add the x position, the y position, then 1, which signifies 02992 // that this is all the text, there is none appended after it 02993 es += cdAppShort( es, (short int) x ); 02994 es += cdAppShort( es, (short int) y ); 02995 es += cdAppShort( es, (short int) 1 ); 02996 octet_count += 6; 02997 02998 // now take care of the string information, for strings 254 bytes 02999 // or less, I could use a short one, but why bother, use the long 03000 // form for everything 03001 es += cdAppByte( es, (short int) 255 ); 03002 es += cdAppShort( es, (short int) tslen ); 03003 octet_count += 3; 03004 // gej: I should set bit 15 to 0 because it is the final part of a 03005 // string but I am not going to since I already checked that it was 03006 // a 16 number that was non-negative 03007 03008 while ( *ts ) 03009 { 03010 *es++ = (unsigned char) *ts++; 03011 } 03012 octet_count += tslen; 03013 // now if the octet_count is not divisible by 4 add null padding 03014 curly = 4 - ( octet_count % 4 ); 03015 if ( curly % 4 ) 03016 { 03017 octet_count += curly; 03018 es += cdAppNull( es, curly ); 03019 } 03020 03021 // add it to the buffer 03022 if ( cdAddElem( im, esp, octet_count ) ) 03023 { 03024 free( esp ); 03025 return 1; 03026 } 03027 else 03028 { 03029 free( esp ); 03030 return 0; 03031 } 03032 } 03033 03034 int cdImageLine( cdImagePtr im, int x1, int y1, int x2, int y2, int color ) 03035 // gej: this should be so much easier to do as a cgm 03036 // This is in for compatibility with gd, if you don't need that, use 03037 // cdLine instead 03038 { 03039 int ltstate; 03040 03041 03042 // save the linetype state 03043 ltstate = im->ltype; 03044 // set the attributes of the line 03045 if ( !cdSetLineAttrib( im, 1, -1, color ) ) 03046 return 0; 03047 if ( !cdLine( im, x1, y1, x2, y2 ) ) 03048 return 0; // draw the line 03049 // restore the state If it fails, don't return an error, because 03050 // the line was still drawn 03051 cdSetLineType( im, ltstate ); 03052 03053 return 1; 03054 } 03055 03056 int cdImageDashedLine( cdImagePtr im, int x1, int y1, int x2, int y2, int color ) 03057 // gej: this should be so much easier to do as a cgm 03058 // in order to really get a dashed line you must call cdSetLineType first 03059 // This is in for compatibility with gd, if you don't need that, use 03060 // cdLine instead 03061 { 03062 // set the attributes of the line 03063 if ( !cdSetLineAttrib( im, -1, -1, color ) ) 03064 return 0; 03065 // generate the line 03066 if ( !cdLine( im, x1, y1, x2, y2 ) ) 03067 return 0; 03068 03069 // everthing is A-OK 03070 return 1; 03071 } 03072 03073 int cdImageBoundsSafe( cdImagePtr im, int x, int y ) 03074 // From gd library, see README file for copyright information 03075 // gej: this should work unchanged 03076 { 03077 return ( !( ( ( y < 0 ) || ( y >= im->sy ) ) || 03078 ( ( x < 0 ) || ( x >= im->sx ) ) ) ); 03079 } 03080 03081 03082 int cdImageRectangle( cdImagePtr im, int x1, int y1, int x2, int y2, int color ) 03083 // Graphic Primitive: rectangle; Elem Class 4; Elem ID 11 03084 // 03085 03086 // gej: but I think I will use the cgm rectangle 03087 { 03088 if ( !cdImageLine( im, x1, y1, x2, y1, color ) ) 03089 return 0; 03090 if ( !cdImageLine( im, x1, y2, x2, y2, color ) ) 03091 return 0; 03092 if ( !cdImageLine( im, x1, y1, x1, y2, color ) ) 03093 return 0; 03094 if ( !cdImageLine( im, x2, y1, x2, y2, color ) ) 03095 return 0; 03096 03097 return 1; 03098 } 03099 03100 03101 // Expert functions. If you need more control, you can use these 03102 // functions, but you probably won't need to. 03103 03104 int cdImageSetSize( cdImagePtr im, int x, int y ) 03105 // sets the width and height of subsequent pictures. 03106 { 03107 im->sx = x; 03108 im->sy = y; 03109 return 1; 03110 } 03111 03112 int cdImageSetLineSpec( cdImagePtr im, int specmode ) 03113 // Picture Descriptor: Line Width Specification Mode; Elem Class 2; Elem ID 3 03114 // sets the Line Width Specification mode of subsequent pictures. 03115 // 1 is scaled (default), 2 is absolute 03116 { 03117 if ( ( specmode < 0 ) || ( specmode > 2 ) ) 03118 return 0; 03119 im->linespec = specmode; 03120 return 1; 03121 } 03122 03123 int cdImageSetMarkerSpec( cdImagePtr im, int specmode ) 03124 // Picture Descriptor: Marker Size Specification Mode; Elem Class 2; Elem ID 4 03125 // sets the Marker Width Specification mode of subsequent pictures. 03126 // 1 is scaled (default), 2 is absolute 03127 { 03128 if ( ( specmode < 0 ) || ( specmode > 2 ) ) 03129 return 0; 03130 im->linespec = specmode; 03131 return 1; 03132 } 03133 03134 int cdImageSetEdgeSpec( cdImagePtr im, int specmode ) 03135 // Picture Descriptor: Edge Width Specification Mode; Elem Class 2; Elem ID 5 03136 // sets the Edge Width Specification mode of subsequent pictures. 03137 // 1 is scaled (default), 2 is absolute 03138 { 03139 if ( ( specmode < 0 ) || ( specmode > 2 ) ) 03140 return 0; 03141 im->edgespec = specmode; 03142 return 1; 03143 } 03144 03145 int cdImageSetOutput( cdImagePtr im, FILE *output ) 03146 // sets the output file to *output. which must already be open. 03147 // does not close the file 03148 // Useful if you want to write the file as you go along, or if you 03149 // want to write it to a stream 03150 // 03151 { 03152 if ( output ) 03153 { 03154 im->outfile = output; 03155 return 1; 03156 } 03157 else 03158 { 03159 return 0; 03160 } 03161 } 03162 03163 int cdImageAddFont( cdImagePtr im, const char *fontname ) 03164 // adds a font to the list of fonts. This only has an effect 03165 // if you are using the expert functions for starting pictures, and 03166 // have not yet opened the first picture. Returns 0 for failure, 03167 // and the font index on success 03168 { 03169 unsigned char *oldfonts; 03170 int listsize; 03171 oldfonts = im->fontlist; 03172 if ( oldfonts ) 03173 { 03174 listsize = strlen( (char *) oldfonts ) + 1 + strlen( fontname ) + 1; 03175 } 03176 else 03177 { 03178 listsize = strlen( fontname ) + 1; 03179 } 03180 im->fontlist = (unsigned char *) calloc( listsize, SIZEOF( unsigned char ) ); 03181 if ( !im->fontlist ) 03182 return 0; // memory allocation failed 03183 if ( oldfonts ) 03184 { 03185 sprintf( (char *) im->fontlist, "%s%s%s", (char *) oldfonts, ",", fontname ); 03186 } 03187 else 03188 { 03189 sprintf( (char *) im->fontlist, "%s", fontname ); 03190 } 03191 im->numfonts++; 03192 if ( oldfonts ) 03193 free( oldfonts ); 03194 oldfonts = NULL; 03195 return im->numfonts; 03196 } 03197 03198 int cdImageClearFonts( cdImagePtr im ) 03199 // clears out ALL fonts from the font list, including the ones the 03200 // package has be default. Useful if you want totally different fonts. 03201 // 03202 { 03203 free( im->fontlist ); 03204 im->fontlist = NULL; 03205 im->numfonts = 0; 03206 return 1; 03207 } 03208 03209 int cdImageSetDefaults( cdImagePtr im ) 03210 // resets the defaults to what is in defines.h 03211 { 03212 // you must be either before any picture has been created, 03213 // or after a picture has closed to call this 03214 if ( ( im->state != 0 ) && ( im->state != 2 ) ) 03215 return 0; 03216 // set line_width, line_height, line_color to the defaults 03217 im->ltype = CDLTYPE; 03218 im->lwidth = CDLWIDTH; 03219 im->lcolor = CDLCOLOR; 03220 // interior_style, fill_color, hatch_index 03221 im->shapestyle = CDSHAPESTYLE; 03222 im->shapecolor = CDSHAPECOLOR; 03223 im->shapehatch = CDSHAPEHATCH; 03224 // edge_type, edge_width, edge_color, edge_visibility 03225 im->edgetype = CDEDGETYPE; 03226 im->edgecolor = CDEDGECOLOR; 03227 im->edgewidth = CDEDGEWIDTH; 03228 im->edgevis = CDEDGEVIS; 03229 // text_color, text_height, text_font 03230 im->textcolor = CDTEXTCOLOR; 03231 im->textheight = CDTEXTHEIGHT; 03232 im->textfont = CDTEXTFONT; 03233 im->textpath = CDTEXTPATH; 03234 // set marker_width, marker_size, marker_color to the defaults 03235 im->ltype = CDMTYPE; 03236 im->lwidth = CDMSIZE; 03237 im->lcolor = CDMCOLOR; 03238 // this is set by the expert functions. the defaults should be ok 03239 im->linespec = CDLINESPEC; 03240 im->edgespec = CDEDGESPEC; 03241 im->markerspec = CDMARKERSPEC; 03242 03243 return 1; 03244 } 03245 03246 cdImagePtr cdImageStartCgm() 03247 // initializes the CGM and sets up the defaults. If you are using 03248 // the "expert" functions, you should call this first. _ge 03249 { 03250 const char *tmps; 03251 int tmpsl; 03252 cdImagePtr im; 03253 im = (cdImage *) calloc( SIZEOF( cdImage ), 1 ); 03254 if ( !im ) 03255 return 0; // memory allocation failed 03256 // elemlist is set to some number, when it is full, make it bigger 03257 im->elemlist = (unsigned char *) calloc( CDSTARTLISTSIZE, SIZEOF( unsigned char ) ); 03258 if ( !im->elemlist ) 03259 { 03260 free( im ); return 0; 03261 } // memory allocation failed 03262 im->colorsTotal = 0; 03263 // you can have multiple pictures in a file, keep track of 03264 // which one you are on 03265 im->picnum = 0; 03266 im->outfile = NULL; 03267 // the next three are used for maintaining the element list 03268 // don't change these ever 03269 im->bytestoend = CDSTARTLISTSIZE; 03270 im->listlen = CDSTARTLISTSIZE; 03271 im->curelemlist = im->elemlist; 03272 03273 // don't make this longer than 250 characters 03274 tmps = "'ProfileId: Model-Profile''ProfileEd:1''ColourClass:colour''Source:NIST CGMDraw 1.3''Date: 1996-12-16'"; 03275 tmpsl = strlen( tmps ); 03276 if ( tmpsl > 250 ) 03277 tmpsl = 250; 03278 im->desc = (unsigned char *) calloc( tmpsl + 1, SIZEOF( unsigned char ) ); 03279 strncpy( (char *) im->desc, tmps, tmpsl ); 03280 // The font list can be quite long, but individual font names can 03281 // can only be 250 chars 03282 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"; 03283 im->numfonts = 12; 03284 tmpsl = strlen( tmps ); 03285 im->fontlist = (unsigned char *) calloc( tmpsl + 1, SIZEOF( unsigned char ) ); 03286 strcpy( (char *) im->fontlist, tmps ); 03287 im->outfile = NULL; 03288 03289 if ( !cdImageSetDefaults( im ) ) 03290 { 03291 cdImageDestroy( im ); 03292 } 03293 // set the state 03294 im->state = 0; // 0 no pictures started, 1 in a picture, 03295 // 2 after a picture 03296 03297 return im; 03298 } 03299 03300 int cdImageEndPic( cdImagePtr im ) 03301 // close the current picture 03302 { 03303 unsigned char *es, *esp; 03304 int octet_count = 0; 03305 03306 // make sure we are really in a picture before ending it 03307 if ( im->state != 1 ) 03308 { 03309 return 0; 03310 } 03311 03312 esp = (unsigned char *) calloc( 1024, SIZEOF( unsigned char ) ); 03313 if ( !esp ) 03314 return 0; // memory allocation failed 03315 es = esp; 03316 03317 // Attribute: End Picture; Elem Class 0; Elem ID 5; Length 0 03318 if ( !cdcomhead( es, 0, 5, 0 ) ) 03319 { 03320 free( esp ); return 0; 03321 } 03322 octet_count += 2; 03323 03324 if ( cdAddElem( im, esp, octet_count ) ) 03325 { 03326 free( esp ); 03327 im->state = 2; 03328 return 1; 03329 } 03330 else 03331 { 03332 free( esp ); 03333 return 0; 03334 } 03335 } 03336 03337 int cdImageEndCgm( cdImagePtr im ) 03338 // close the current CGM file. If an output stream is 03339 // defined, write the CGM to it 03340 { 03341 int x; // counter 03342 int used; // number of bytes used in the list 03343 unsigned char *efile, *efilep; // end of file information 03344 03345 cdImageEndPic( im ); 03346 if ( im->state == 2 ) // We have closed the pic, but not the CGM 03347 { 03348 efile = (unsigned char *) calloc( 4 * 4, SIZEOF( unsigned char ) ); 03349 if ( !efile ) 03350 return 0; // memory allocation failed 03351 efilep = efile; 03352 // Attribute: End Metafile; Elem Class 0; Elem ID 2 03353 cdcomhead( efilep, 0, 2, 0 ); 03354 03355 03356 if ( cdAddElem( im, efile, 2 ) ) 03357 { 03358 free( efile ); 03359 efile = 0; 03360 efilep = 0; 03361 } 03362 else 03363 { 03364 free( efile ); 03365 return 0; 03366 } 03367 } 03368 03369 if ( im->outfile ) 03370 { 03371 // now output the CGM, one byte at a time 03372 used = im->listlen - im->bytestoend; 03373 for ( x = 0; x < used; x++ ) 03374 { 03375 putc( (unsigned char) im->elemlist[x], im->outfile ); 03376 } 03377 } // else do nothing 03378 03379 return 1; 03380 }