/* cgmb.c 20 January 1999 */ /* copyright 1987, 1988, 1989 Phil Andrews, Pittsburgh Supercomputing Center */ # include # include # include #include #include #include "defs.h" #define byte_size 8 #define byte_mask 255 /* module for CGM binary output */ #define cgmb_rec_size 512 /* store these pointers to allow lookups into the CGM data structures */ static struct one_opt *popt; /* the command line options, in only */ static struct mf_d_struct *pc1; /* the class 1 elements, in only */ static struct pic_d_struct *pc2; /* the class 2 elements, in only */ static struct control_struct *pc3; /* the class 3 elements, in only */ static struct attrib_struct *pc5; /* the class 5 elements, in only */ static struct info_struct *dptr; /* device info, in and out */ static struct info_struct *dev1_info; /* device info to fill out, out only */ static int state_level; /* marker for where we are in inclusions */ /* now some local globals */ /* first for output command processing */ #define max_long 32766 /* longest partition of command data (even) */ #define hdr_long 4 /* 4 bytes for the command header */ #define hdr_short 2 /* a short command header length */ #define max_short 30 /* short form data length */ static char cmd_buffer[hdr_long + max_long]; /* where we buffer output */ static char *cmd_hdr; /* the command header */ static char *cmd_data; /* the command data */ static int cmd_index; /* index into the command data */ static int bfr_index = 0; /* index into the buffer */ static int partition; /* which partition in the output */ /* flags for the flush_cmd function */ #define int_flush 0 /* intermediate flush */ #define final_flush 1 /* final flush */ #define def_rep_flush 2 /* defaults replacement flush */ static double vdc_pxl; /* conversion from pxl to vdc */ static int rep_defs = 0; /* are we replacing defaults ? */ static int out_page_no; /* pages sent out */ #define debug_on (popt[(int) debug].set) /* macros to handle direct colours */ #define inddc(i, rval) ((int) (pc1->c_v_extent.min[i] + \ (rval) * (pc1->c_v_extent.max[i] - pc1->c_v_extent.min[i]))) #define rdc(rval) inddc(0, rval) #define gdc(rval) inddc(1, rval) #define bdc(rval) inddc(2, rval) /* indexing capability */ #define ind_space cgmb_rec_size /* how much space we'll leave */ static char ind_str[ind_space]; static struct ad_struct ind_ad; /* where empty space starts */ static struct ad_struct ind1_ad; /* where empty space ends */ static struct ad_struct prev_ad; /* previous index block */ static struct phead_struct { struct p_struct *first; struct p_struct *last; } p_header; #define p_s_size sizeof(struct p_struct) /* macro to produce output offset */ #ifdef VMS #define byte_dif(ad1, ad2) (cgmb_rec_size * (ad1.r_ad - ad2.r_ad) \ + (ad1.offset - ad2.offset)) #else #define byte_dif(ad1, ad2) (ad1.b_ad - ad2.b_ad) #endif /* PROCEDURE DECLARATIONS */ static cb_fixed ( double xin, struct r_struct *r_prec ); static flush_cmd ( int this_flush ); /* get an output command started */ static start_cmd(class, el) int class, el; { #define cl_max 15 #define el_max 127 if ((class > cl_max) || (class < 0)) { (void) fprintf(stderr, "illegal class for output %d\n", class); return(0); } if ((el > el_max) || (el < 0)) { (void) fprintf(stderr, "illegal element for output %d\n", el); return(0); } cmd_hdr = cmd_buffer + bfr_index; cmd_data = cmd_hdr + hdr_long; bfr_index += hdr_long; cmd_hdr[0] = (class << 4) | (el >>3); cmd_hdr[1] = el << 5; cmd_index = 0; partition = 1; return(1); } /* put out one byte */ static out_bc(c) int c; { if (cmd_index >= max_long) flush_cmd(int_flush); cmd_data[cmd_index++] = c; return(1); } /* put out multiple bytes */ static out_bs(cptr, n) char *cptr; int n; { int to_do, space_left, i; to_do = n; space_left = max_long - cmd_index; while (to_do > space_left) { for (i=0; i max_long) { (void) fprintf(stderr, "illegal command index %d\n", cmd_index); return(0); } if (partition == 1) { /* first one */ cmd_hdr[1] |= 31; if (!rep_defs) for (i=0; i> 8; cmd_hdr[3] = cmd_index & 255; if (this_flush == int_flush) cmd_hdr[2] |= 1 << 7; /* more come */ /* flush out the header */ if (!rep_defs) for (i=hdr_short; i 0) { if (to_do < max_long) { /* last one */ byte1 = to_do >> 8; byte2 = to_do & 255; out_bc(byte1); out_bc(byte2); out_bs(cptr, to_do); to_do = 0; } else { byte1 = (max_long >> 8) | (1 << 7); byte2 = max_long & 255; out_bc(byte1); out_bc(byte2); out_bs(cptr, max_long); to_do -= max_long; } } } return(1); } /* general signed integer output routine */ /* note that we assume ints are at least 4 bytes */ static cb_gint(xin, precision) int xin, precision; { int i, no_out, xshifted; char buffer[4]; no_out = precision / byte_size; if ((no_out <= 0) || (no_out > 4)) { (void) fprintf(stderr, "illegal no_out in cb_gint %d\n", no_out); return(0); } xshifted = xin; for (i=no_out - 1; i >= 0; --i) { buffer[i] = xshifted & byte_mask; xshifted >>= byte_size; } if ((xin < 0) && (buffer[0] > '\0')) /* maybe after truncation */ buffer[0] |= 1 << 7; /* assuming two's complement */ out_bs(buffer, no_out); return(1); } /* general unsigned integer output routine */ /* note that we assume ints are at least 4 bytes */ static cb_uint(xin, precision) unsigned int xin; int precision; { int i, no_out; unsigned char buffer[4]; no_out = precision / byte_size; if ((no_out <= 0) || (no_out > 4)) { (void) fprintf(stderr, "illegal no_out in cb_uint %d\n", no_out); return(0); } for (i=no_out - 1; i >= 0; --i) { buffer[i] = xin & byte_mask; xin >>= byte_size; } out_bs(buffer, no_out); return(1); } /* general real variable */ static cb_real(xin) double xin; { int ret; switch (pc1->real_prec.fixed) { case 0: ret = cb_float(xin, &pc1->real_prec); break; /* floating point */ case 1: ret = cb_fixed(xin, &pc1->real_prec); break; /* fixed point */ default: fprintf(stderr, "illegal real flag\n"); ret = 0.0; } return(ret); } /* fixed point format */ static cb_fixed ( double xin, struct r_struct *r_prec ) { int exp_part, fract_part; double fract_real; exp_part = xin; if (exp_part > xin) exp_part -= 1; /* take it below xin */ fract_real = xin - exp_part; /* fract_part = fract_real * (2 << r_prec->fract); */ fract_part = fract_real * (1 << r_prec->fract); cb_gint(exp_part, r_prec->exp); cb_uint(fract_part, r_prec->fract); return(1); } /* IEEE floating point */ cb_float(xin, r_prec) double xin; struct r_struct *r_prec; { unsigned char arry[8]; int sign_bit, i, j; unsigned int exponent; unsigned long fract; double dfract; if (xin < 0.0) { sign_bit = 1; xin = -xin; } else sign_bit = 0; /* first calculate the exponent and fraction */ if (xin == 0.0) { exponent = 0; fract = 0; } else switch (r_prec->exp + r_prec->fract) { /* first 32 bit precision */ case 32: if (xin < 1.0) { for(i=0; (xin < 1.0) && (i < 128); ++i) xin *= 2.0; exponent = 127 - i; } else if (xin >= 2.0) { for(i=0; (xin >= 2.0) && (i < 127); ++i) xin /= 2.0; exponent = 127 + i; } else exponent = 127; dfract = xin - 1.0; for (i=0; i<23; ++i) dfract *= 2.0; fract = (unsigned long) dfract; break; /* now 64 bit precision */ case 64: break; default: fprintf(stderr, "illegal real precisions !\n"); return(2); } /* now do the I/O */ switch (r_prec->exp + r_prec->fract) { /* first 32 bit precision */ case 32: arry[0] = ((sign_bit & 1) << 7) | ((exponent >> 1) & 127); arry[1] = ((exponent & 1) << 7) | ((fract >> 16) & 127); arry[2] = (fract >> 8) & 255; arry[3] = fract & 255; out_bs(arry, 4); break; /* now 64 bit precision */ case 64: break; default: fprintf(stderr, "illegal real precisions !\n"); return(2); } return(1); } /* cgm direct colour */ static cb_dcint(xin) int xin; { return(cb_uint(xin, pc1->col_prec)); } /* put out a signed int at VDC integer precision */ static cb_vint(xin) int xin; { /* first rescale, check later */ /* xin = (xin < 0) ? (int) (vdc_pxl * xin - 0.5) : (int) (vdc_pxl * xin + 0.5); */ return(cb_gint(xin, pc3->vdc_i_prec )); } /* handle the vdc real variable */ static cb_vreal(xin) double xin; { int ret; switch (pc3->vdc_r_prec.fixed) { case 0: ret = cb_float(xin, &pc3->vdc_r_prec); break;/* floating */ case 1: ret = cb_fixed(xin, &pc3->vdc_r_prec); break;/* fixed */ default: fprintf(stderr, "illegal vdc real flag\n"); ret = 0; } return(ret); } /* takes an integer vdc and changes it to real */ static cb_vireal(xin) int xin; { return(cb_vreal( (double) xin * vdc_pxl)); } /* our general vdc writer */ static int (*cb_vdc)() = cb_vint; /* default to integer VDC's */ /* standard CGM signed int */ static cb_sint(xin) int xin; { return(cb_gint(xin, pc1->int_prec )); } /* signed int at index precision */ static cb_xint(xin) int xin; { return(cb_gint(xin, pc1->ind_prec)); } /* an unsigned integer at colour index precision */ static cb_cxint(xin) int xin; { return(cb_uint((unsigned) xin, pc1->col_i_prec)); } /* put out an integer at fixed (16 bit) precision */ static cb_eint(xin) int xin; { char byte1; unsigned char byte2; byte1 = xin / 256; byte2 = xin & 255; out_bc(byte1); out_bc(byte2); return(1); } /* begin the commands */ /* the delimiter functions */ cb_begin(comment, file_name, prog_name) char *comment, *file_name, *prog_name; { int i; start_cmd(0, (int) B_Mf); if (*comment) cb_string(comment, strlen(comment)); else cb_string(NULL, 0); flush_cmd(final_flush); /* beginning of indexing */ /* start of the index string, leave room for page number */ p_header.first = NULL; p_header.last = NULL; prev_ad.r_ad = prev_ad.offset = prev_ad.b_ad = 0; if (!popt[(int) nindex].set) { /* default to setting index blocks */ /* we pad to end of record */ fb(); /* now leave one record to put in the indexing info later */ /* figure out where we are */ cgmb_inq(&ind_ad); /* and leave an empty record */ fb(); /* mark where we start up again */ cgmb_inq(&ind1_ad); } rep_defs = 0; bfr_index = 0; /* start fresh */ out_page_no = 0; if (pc1->vdc_type == vdc_int) { dev1_info->x_size = pc2->vdc_extent.i[2] - pc2->vdc_extent.i[0]; dev1_info->y_size = pc2->vdc_extent.i[3] - pc2->vdc_extent.i[1]; } else { dev1_info->x_size = pc2->vdc_extent.r[2] - pc2->vdc_extent.r[0]; dev1_info->y_size = pc2->vdc_extent.r[3] - pc2->vdc_extent.r[1]; } return(1); } cb_end(pages_done) int pages_done; { int i; /* finish up indexing */ if (!popt[(int) nindex].set) check_index(byte_dif(ind1_ad, ind_ad), 1); /* put out the end metafile command */ start_cmd(0, (int) E_Mf); flush_cmd(final_flush); fb(); /* flush out the buffer */ return(1); } /* may write out an index block */ /* make heavy use of the global index pointers and addresses */ check_index(bytes_available, last_chance) int bytes_available; /* bytes available for writing */ int last_chance; /* must we flush everything out ? */ { char *ind_ptr; struct p_struct *this_page; int str_bytes; /* how many bytes available for the string */ int pages_fit; /* how many pages we can fit in */ int bytes_used; /* how many bytes used so far */ int i, j, p_dumped; struct ad_struct pres_ad; #define this_format "%d %d " str_bytes = bytes_available - 4; /* for the cmd header */ pages_fit = 0; bytes_used = 20; /* allow for no_pages and next pointer */ this_page = p_header.first; while ( (this_page != NULL) && (bytes_used <= str_bytes) ) { (void) sprintf(ind_str, this_format, this_page->ad.b_ad, this_page->len); bytes_used += strlen(ind_str); bytes_used += this_page->len; bytes_used += 1; /* for space */ pages_fit += (int) (bytes_used <= str_bytes);/* slightly tricky */ this_page = this_page->next; } if (!last_chance && (bytes_used <= str_bytes)) /* no rush */ return(1); /* have to do something */ fb(); /* flush the present buffer */ cgmb_inq(&pres_ad); /* where are we ? */ /* now dump all that fit */ p_dumped = dump_pages(p_header.first, pages_fit, ind_str, 0, byte_dif(pres_ad, ind_ad), &ind_ad); if (p_dumped != pages_fit) fprintf(stderr, "trouble dumping pages\n"); step_pages(&p_header.first, p_dumped); /* now go back and fill out the index string */ cgmb_goto(&ind_ad); cb_esc(INDEX_FLAG, ind_str); fb(); /* flush out the buffer */ cgmb_goto(&pres_ad); /* go back home */ if (last_chance) { /* put at least a pointer in */ (void) dump_pages(p_header.first, 1, ind_str, 1, 0, &pres_ad); cb_esc(INDEX_FLAG, ind_str); return(1); } /* now need to leave room for next block */ /* save old info */ prev_ad.r_ad = ind_ad.r_ad; prev_ad.offset = ind_ad.offset; prev_ad.b_ad = ind_ad.b_ad; /* figure out where we are */ cgmb_inq(&ind_ad); /* and leave an empty record */ fb(); /* mark where we start up again */ cgmb_inq(&ind1_ad); return(1); #undef this_format } /* function to dump a specified number of pages into an index string */ dump_pages(this_page, no_pages, index_string, dump_all, next_index, this_ad) struct p_struct *this_page; int no_pages, dump_all, next_index; char *index_string; struct ad_struct *this_ad; { char *ind_ptr; int pages_dumped = 0, i, j; #define spaces_left 5 ind_ptr = index_string; for (i=0; iad, (*this_ad)), this_page->len); while (*ind_ptr) ++ind_ptr; for (j=0; j < this_page->len; ++j) *ind_ptr++ = this_page->str[j]; *ind_ptr++ = ' '; /* add a space */ ++pages_dumped; this_page = this_page->next; /* step forward */ } (void) sprintf(ind_ptr, "%d 0", next_index); /* 0 for backward compatibility with old LASL stuff */ /* go back and put in the no. of pages */ (void) sprintf(index_string, "%d", pages_dumped); *(index_string + strlen(index_string)) = ' '; return(pages_dumped); } step_pages(first_page, no_pages) struct p_struct **first_page; int no_pages; { struct p_struct *this_page; int pages_stepped = 0; while ( (pages_stepped < no_pages) && (*first_page != NULL) ) { this_page = *first_page; *first_page = (*first_page)->next; ++pages_stepped; if (this_page->len && this_page->str) (void) free(this_page->str); (void) free(this_page); } return(pages_stepped); } /* start the picture */ cb_bp(pic_name) char *pic_name; { int pic_l, i; char buffer[max_str], *bptr = buffer, *allocate_mem(); struct p_struct *this_page; struct ad_struct this_ad; ++out_page_no; /* work on the indexing */ /* see if we need to lay down an index block */ if (!popt[(int) nindex].set) check_index(byte_dif(ind1_ad, ind_ad), 0); /* now take care of this page */ this_page = (struct p_struct *) allocate_mem(p_s_size, 1); if (p_header.first == NULL) p_header.first = this_page; else p_header.last->next = this_page; p_header.last = this_page; /* where are we in output ? */ cgmb_inq(&this_ad); this_page->ad.b_ad = this_ad.b_ad; this_page->ad.r_ad = this_ad.r_ad; this_page->ad.offset = this_ad.offset; this_page->next = NULL; if (*pic_name) { this_page->len = strlen(pic_name); if (this_page->str = allocate_mem(this_page->len, 0)) for(i=0;ilen;++i) this_page->str[i] = pic_name[i]; } start_cmd(0, (int) B_Pic); if (*pic_name) cb_string(pic_name, strlen(pic_name)); else cb_string(NULL, 0); flush_cmd(final_flush); if (rep_defs) { (void) fprintf(stderr, "illegal rep_defs flag %d\n", rep_defs); rep_defs = 0; } if (pc1->vdc_type == vdc_int) { dev1_info->x_size = pc2->vdc_extent.i[2] - pc2->vdc_extent.i[0]; dev1_info->y_size = pc2->vdc_extent.i[3] - pc2->vdc_extent.i[1]; } else { dev1_info->x_size = pc2->vdc_extent.r[2] - pc2->vdc_extent.r[0]; dev1_info->y_size = pc2->vdc_extent.r[3] - pc2->vdc_extent.r[1]; } return(1); } /* start the picture body */ cb_bpage(pic_name, xoffset, yoffset, rotation, rb, gb, bb, page_no, xsize, ysize) char *pic_name; float rotation; /* how much to rotate the page */ int xoffset, yoffset; /* offset in pixels */ int page_no; /* page number */ float rb, gb, bb; /* background colour values */ int xsize, ysize; { start_cmd(0, (int) B_Pic_Body); flush_cmd(final_flush); /* try to get the right vdc_pxl */ vdc_pxl = (pc1->vdc_type == vdc_int) ? 1.0 : dev1_info->x_size / 32767.0; return(1); } /* end the picture */ cb_epage(no_copies) int no_copies; { start_cmd(0, (int) E_Pic); flush_cmd(final_flush); return(1); } /* the Metafile descriptor elements */ /* the Metafile version */ cb_mfversion(vers_no) int vers_no; { start_cmd(1, (int) MfVersion); cb_sint(vers_no); flush_cmd(final_flush); return(1); } /* Metafile description */ cb_mfdescrip(char_ptr) char *char_ptr; { start_cmd(1, MfDescrip); cb_string(char_ptr, strlen(char_ptr)); flush_cmd(final_flush); return(1); } /* VDC type */ cb_vdctype(new_type) int new_type; { switch ((enum vdc_enum) new_type) { case vdc_int: cb_vdc = cb_vint; break; case vdc_real: cb_vdc = cb_vireal; break; default: (void) fprintf(stderr, "illegal vdc_type = %d\n", new_type); } start_cmd(1, (int) vdcType); cb_eint(new_type); flush_cmd(final_flush); return(1); } /* integer precision */ cb_intprec(new_prec) int new_prec; { start_cmd(1, (int) IntPrec); cb_sint(new_prec); flush_cmd(final_flush); return(1); } /* real precision */ cb_realprec(fixed, exp_part, fract) int fixed, exp_part, fract; { start_cmd(1, (int) RealPrec); cb_sint(fixed); cb_sint(exp_part); cb_sint(fract); flush_cmd(final_flush); return(1); } /* index precision */ cb_indexprec(new_prec) int new_prec; { start_cmd(1, (int) IndexPrec); cb_sint(new_prec); flush_cmd(final_flush); return(1); } /* colour precision */ cb_colprec(new_prec) int new_prec; { start_cmd(1, (int) ColPrec); cb_sint(new_prec); flush_cmd(final_flush); return(1); } /* colour index precision */ cb_cindprec(new_prec) int new_prec; { start_cmd(1, (int) CIndPrec); cb_sint(new_prec); flush_cmd(final_flush); return(1); } /* colour value extent */ cb_cvextent(cvmin, cvmax) int *cvmin, *cvmax; { int i; start_cmd(1, (int) CVExtent); for (i=0; i<3; ++i) cb_dcint(cvmin[i]); for (i=0; i<3; ++i) cb_dcint(cvmax[i]); flush_cmd(final_flush); return(1); } /* maximum colour index */ cb_maxcind(new_index) int new_index; { start_cmd(1, (int) MaxCInd); cb_cxint(new_index); flush_cmd(final_flush); return(1); } /* Metafile element list */ cb_mfellist(no_pairs, array_ptr) int no_pairs, *array_ptr; { int i; start_cmd(1, (int) MfElList); cb_sint(no_pairs); for (i=0; i< 2 * no_pairs; ++i) cb_xint(array_ptr[i]); flush_cmd(final_flush); return(1); } /* Metafile defaults replacement list */ cb_mfdefrep(state) int state; /* 0 => start, 1 => end */ { if (state == 0) { start_cmd(1, (int) MfDefRep); rep_defs = 1; } else if (state == 1) { rep_defs = 0; flush_cmd(def_rep_flush); } else { (void) fprintf(stderr, "illegal state in MD def rep %d\n", state); return(0); } return(1); } /* font list */ cb_flist(no_strings, str_ptr) int no_strings; char str_ptr[][max_str+1]; { int i; start_cmd(1, (int) FontList); for (i=0; ireal_prec); flush_cmd(final_flush); return(1); } /* the colour selection mode */ cb_colselmode(c_s_mode) enum cs_enum c_s_mode; { start_cmd(2, (int) ColSelMode); cb_eint((int) c_s_mode); flush_cmd(final_flush); return(1); } /* the line width specification mode */ cb_lwsmode(mode) enum spec_enum mode; { start_cmd(2, (int) LWidSpecMode); cb_eint((int) mode); flush_cmd(final_flush); return(1); } /* the marker size specification mode */ cb_msmode(mode) enum spec_enum mode; { start_cmd(2, (int) MarkSizSpecMode); cb_eint((int) mode); flush_cmd(final_flush); return(1); } /* the edge width specification mode */ cb_ewmode(mode) enum spec_enum mode; { start_cmd(2, (int) EdWidSpecMode); cb_eint((int) mode); flush_cmd(final_flush); return(1); } /* the vdc extent */ cb_vdcextent(int_coords, float_coords) int *int_coords; float *float_coords; { int i; start_cmd(2, (int) vdcExtent); switch (pc1->vdc_type) { case vdc_int: for (i=0; i<4; ++i) cb_vint(int_coords[i]); dev1_info->x_size = pc2->vdc_extent.i[2] - pc2->vdc_extent.i[0]; dev1_info->y_size = pc2->vdc_extent.i[3] - pc2->vdc_extent.i[1]; break; case vdc_real: for (i=0; i<4; ++i) cb_vreal(float_coords[i]); break; default: (void) fprintf(stderr, "illegal vdc_type %d\n", (int) pc1->vdc_type); return(0); } flush_cmd(final_flush); return(1); } /* the background colour */ cb_backcol(r, g, b) int r, g, b; { start_cmd(2, (int) BackCol); cb_dcint(r); cb_dcint(g); cb_dcint(b); flush_cmd(final_flush); return(1); } /* now the control functions (class 3) */ /* set the vdc integer precision */ cb_vdcintprec(precision) int precision; { start_cmd(3, (int) vdcIntPrec); cb_sint(precision); flush_cmd(final_flush); return(1); } /* vdc real precision */ cb_vdcrprec(fixed, exp_part, fract) int fixed, exp_part, fract; { start_cmd(3, (int) vdcRPrec); cb_sint(fixed); cb_sint(exp_part); cb_sint(fract); flush_cmd(final_flush); return(1); } /* auxiliary colour */ cb_auxcol(r, g, b, index) float r, g, b; int index; { start_cmd(3, (int) AuxCol); switch (pc2->c_s_mode) { case (int) i_c_mode: cb_cxint(index); break; case (int) d_c_mode: cb_dcint(rdc(r)); cb_dcint(gdc(g)); cb_dcint(bdc(b)); break; default: (void) fprintf(stderr, "illegal col sel mode\n"); return(0); } flush_cmd(final_flush); return(1); } /* set the transparency */ cb_transp(transparency) enum boolean transparency; { start_cmd(3, Transp); cb_eint((int) transparency); flush_cmd(final_flush); return(1); } /* set the clipping rectangle */ cb_cliprect(int_coords, float_coords) int *int_coords; float *float_coords; { int i; start_cmd(3, (int) ClipRect); switch (pc1->vdc_type) { case vdc_int: for (i=0; i<4; ++i) (*cb_vdc)(int_coords[i]); break; case vdc_real: for (i=0; i<4; ++i) cb_real(float_coords[i]); break; default: (void) fprintf(stderr, "illegal vdc_type %d\n", (int) pc1->vdc_type); return(0); } flush_cmd(final_flush); return(1); } /* set the clipping indicator */ cb_clipindic(clip_ind) int clip_ind; { start_cmd(3, (int) ClipIndic); cb_eint(clip_ind); flush_cmd(final_flush); return(1); } /* the graphical primitives */ /* plot a set of lines */ cb_pline(no_pairs, x1_ptr, y1_ptr) int no_pairs, *x1_ptr, *y1_ptr; { int i; start_cmd(4, (int) PolyLine); for (i=0; il_w_s_mode) { default : (void) fprintf(stderr, "illegal l_w_s_mode"); case (int) absolute : (*cb_vdc)(line_width); break; case (int) scaled : cb_real(rmul); break; } flush_cmd(final_flush); return(1); } /* set the line colour */ cb_lcolour(r, g, b, index) float r, g, b; int index; { start_cmd(5, (int) LColour); switch (pc2->c_s_mode) { case (int) i_c_mode: cb_cxint(index); break; case (int) d_c_mode: cb_dcint(rdc(r)); cb_dcint(gdc(g)); cb_dcint(bdc(b)); break; default: (void) fprintf(stderr, "illegal col sel mode\n"); return(0); } flush_cmd(final_flush); return(1); } /* set the marker bundle index */ cb_mbindex(index) int index; { start_cmd(5, (int) MBIndex); cb_xint(index); flush_cmd(final_flush); return(1); } /* set the marker type */ cb_mtype(marker) int marker; { start_cmd(5, (int) MType); cb_xint(marker); flush_cmd(final_flush); return(1); } /* marker size */ cb_msize(mk_size, rmul) int mk_size; float rmul; { start_cmd(5, (int) MSize); switch (pc2->m_s_s_mode) { case (int) absolute : (*cb_vdc)(mk_size); break; case (int) scaled : cb_real(rmul); break; default : (void) fprintf(stderr, "illegal m_s_s_mode\n"); return(0); } flush_cmd(final_flush); return(1); } /* marker colour */ cb_mcolour(r, g, b, index) float r, g, b; int index; { start_cmd(5, (int) MColour); switch (pc2->c_s_mode) { case i_c_mode: cb_cxint(index); break; case d_c_mode: cb_dcint(rdc(r)); cb_dcint(gdc(g)); cb_dcint(bdc(b)); break; default: (void) fprintf(stderr, "illegal col sel mode\n"); return(0); } flush_cmd(final_flush); return(1); } /* set the text bundle index */ cb_tbindex(index) int index; { start_cmd(5, (int) TBIndex); cb_xint(index); flush_cmd(final_flush); return(1); } /* text font index */ cb_tfindex(index) int index; { start_cmd(5, (int) TFIndex); cb_xint(index); flush_cmd(final_flush); return(1); } /* text precision */ cb_tprec(precision) enum txt_enum precision; { start_cmd(5, (int) TPrec); cb_eint(precision); flush_cmd(final_flush); return(1); } /* character expansion factor */ cb_cexpfac(factor) float factor; { start_cmd(5, (int) CExpFac); cb_real(factor); flush_cmd(final_flush); return(1); } /* character space */ cb_cspace(space) float space; { start_cmd(5, (int) CSpace); cb_real(space); flush_cmd(final_flush); return(1); } /* text colour */ cb_tcolour(r, g, b, index) float r, g, b; int index; { start_cmd(5, (int) TColour); switch (pc2->c_s_mode) { case i_c_mode: cb_cxint(index); break; case d_c_mode: cb_dcint(rdc(r)); cb_dcint(gdc(g)); cb_dcint(bdc(b)); break; default: (void) fprintf(stderr, "illegal col sel mode\n"); return(0); } flush_cmd(final_flush); return(1); } /* character height */ cb_cheight(height) int height; { start_cmd(5, (int) CHeight); (*cb_vdc)(height); flush_cmd(final_flush); return(1); } /* character orientation */ cb_corient(x_up, y_up, x_base, y_base) int x_up, y_up, x_base, y_base; { start_cmd(5, (int) COrient); (*cb_vdc)(x_up); (*cb_vdc)(y_up); (*cb_vdc)(x_base); (*cb_vdc)(y_base); flush_cmd(final_flush); return(1); } /* text path */ cb_tpath(new_path) enum path_enum new_path; { start_cmd(5, (int) TPath); cb_eint((int) new_path); flush_cmd(final_flush); return(1); } /* text alignment */ cb_talign(hor, ver, cont_hor, cont_ver) int hor, ver; float cont_hor, cont_ver; { start_cmd(5, (int) TAlign); cb_eint(hor); cb_eint(ver); cb_real(cont_hor); cb_real(cont_ver); flush_cmd(final_flush); return(1); } /* character set index */ cb_csindex(new_index) int new_index; { start_cmd(5, (int) CSetIndex); cb_xint(new_index); flush_cmd(final_flush); return(1); } /* alternate character set index */ cb_acsindex(new_index) int new_index; { start_cmd(5, (int) AltCSetIndex); cb_xint(new_index); flush_cmd(final_flush); return(1); } /* fill bundle index */ cb_fbindex(new_index) int new_index; { start_cmd(5, (int) FillBIndex); cb_xint(new_index); flush_cmd(final_flush); return(1); } /* interior style */ cb_intstyle(style) enum is_enum style; { start_cmd(5, (int) IntStyle); cb_eint((int) style); flush_cmd(final_flush); return(1); } /* set the fill colour */ cb_fillcolour(r, g, b, index) float r, g, b; int index; { start_cmd(5, (int) FillColour); switch (pc2->c_s_mode) { case i_c_mode: cb_cxint(index); break; case d_c_mode: cb_dcint(rdc(r)); cb_dcint(gdc(g)); cb_dcint(bdc(b)); break; default: (void) fprintf(stderr, "illegal col sel mode\n"); return(0); } flush_cmd(final_flush); return(1); } /* hatch index */ cb_hindex(new_index) int new_index; { start_cmd(5, (int) HatchIndex); cb_xint(new_index); flush_cmd(final_flush); return(1); } /* pattern index */ cb_pindex(new_index) int new_index; { start_cmd(5, (int) PatIndex); cb_xint(new_index); flush_cmd(final_flush); return(1); } /* edge bundle index */ cb_ebindex(new_index) int new_index; { start_cmd(5, (int) EdBIndex); cb_xint(new_index); flush_cmd(final_flush); return(1); } /* edge type */ cb_etype(etype) enum line_enum etype; { start_cmd(5, (int) EType); cb_sint((int) etype); flush_cmd(final_flush); return(1); } /* edge width */ cb_edwidth(width, rmul) int width; float rmul; { start_cmd(5, (int) EdWidth); switch (pc2->e_w_s_mode) { case (int) absolute : (*cb_vdc)(width); break; case (int) scaled : cb_real(rmul); break; default : (void) fprintf(stderr, "illegal e_w_s_mode\n"); return(0); } flush_cmd(final_flush); return(1); } /* edge colour */ cb_edcolour(r, g, b, index) float r, g, b; int index; { start_cmd(5, (int) EdColour); switch (pc2->c_s_mode) { case i_c_mode: cb_cxint(index); break; case d_c_mode: cb_dcint(rdc(r)); cb_dcint(gdc(g)); cb_dcint(bdc(b)); break; default: (void) fprintf(stderr, "illegal col sel mode\n"); return(0); } flush_cmd(final_flush); return(1); } /* edge visibility */ cb_edvis(visible) enum boolean visible; { start_cmd(5, (int) EdVis); cb_eint((int) visible); flush_cmd(final_flush); return(1); } /* fill reference point */ cb_fillref(x, y) int x, y; { start_cmd(5, (int) FillRef); (*cb_vdc)(x); (*cb_vdc)(y); flush_cmd(final_flush); return(1); } /* pattern table entry */ cb_pattab(index, nx, ny, col_prec, dat_ptr, no_bytes) int index, nx, ny, col_prec, no_bytes; char *dat_ptr; { int i; start_cmd(5, (int) PatTab); cb_xint(index); cb_sint(nx); cb_sint(ny); cb_sint(col_prec); out_bs(dat_ptr, no_bytes); /* for speed */ flush_cmd(final_flush); return(1); } /* pattern size */ cb_patsize(size_array) int *size_array; { int i; start_cmd(5, (int) PatSize); for (i=0; i<4; ++i) (*cb_vdc)(size_array[i]); flush_cmd(final_flush); return(1); } /* colour table */ cb_coltab(beg_index, no_entries, ctab) int beg_index, no_entries; float *ctab; { int i, j; start_cmd(5, (int) ColTab); cb_cxint(beg_index); for (i=beg_index; i<(beg_index + no_entries); ++i) for (j=0; j<3; ++j) cb_dcint(inddc(j, ctab[i * 3 + j])); flush_cmd(final_flush); return(1); } /* the aspsflags */ cb_aspsflags(no_pairs, flag_array) int no_pairs, *flag_array; { int i; start_cmd(5, (int) AspsFlags); for (i=0; i<(2 * no_pairs); ++i) cb_eint(flag_array[i]); flush_cmd(final_flush); return(1); } /* Class 6; the Escape element */ cb_esc(id, str_ptr) int id; char *str_ptr; { start_cmd(6, (int) Escape); cb_sint(id); cb_string(str_ptr, strlen(str_ptr)); flush_cmd(final_flush); return(1); } /* class 7; the external functions */ /* the message element */ cb_message(action, str_ptr) enum boolean action; char *str_ptr; { start_cmd(7, (int) Message); cb_eint((int) action); cb_string(str_ptr, strlen(str_ptr)); flush_cmd(final_flush); return(1); } /* application data */ cb_apdata(id, str_ptr) int id; char *str_ptr; { start_cmd(7, Ap_Data); cb_sint(id); cb_string(str_ptr, strlen(str_ptr)); flush_cmd(final_flush); return(1); } /* this is the routine that sets everything up */ /* the initialising routine for the postscript module */ void cb_setup(opt, dev_info, c1, c2, c3, c5, delim, mfdesc, pdesc, mfctrl, gprim, attr, escfun, extfun, ctrl, pargc, argv) struct one_opt *opt; /* the command line options, in only */ struct info_struct *dev_info; /* device info to fill out, out only */ struct mf_d_struct *c1; /* the class 1 elements, in only */ struct pic_d_struct *c2; /* the class 2 elements, in only */ struct control_struct *c3; /* the class 3 elements, in only */ struct attrib_struct *c5; /* the class 5 elements, in only */ int (*delim[])(); /* delimiter functions */ int (*mfdesc[])(); /* metafile descriptor functions */ int (*pdesc[])(); /* page descriptor functions */ int (*mfctrl[])(); /* controller functions */ int (*gprim[])(); /* graphical primitives */ int (*attr[])(); /* the attribute functions */ int (*escfun[])(); /* the escape functions */ int (*extfun[])(); /* the external functions */ int (*ctrl[])(); /* external controller functions */ int *pargc; /* pointer to argc */ char **argv; /* the main argv */ { /* store the command line argument pointer */ popt = opt; /* store the device info pointer */ dptr = dev_info; /* and the cgm data strucures */ pc1 = c1; pc2 = c2; pc3 = c3; pc5 = c5; dev1_info = dev_info; /* fill out the device info structure */ dev_info->pxl_in = 1.0; dev_info->ypxl_in = 1.0; dev_info->x_size = pc2->vdc_extent.i[2] - pc2->vdc_extent.i[0]; dev_info->y_size = pc2->vdc_extent.i[3] - pc2->vdc_extent.i[1]; /* get default vdc_pxl */ vdc_pxl = 1.0; dev_info->x_offset = 0.0; dev_info->y_offset = 0.0; dev_info->rec_size = cgmb_rec_size; dev_info->c_height = 1; dev_info->c_width = 1; dev_info->d_l_width = 1; dev_info->d_e_width = 1; dev_info->d_m_size = 1; strcpy(dev_info->out_name, ".CGMB"); dev_info->capability = port_land | arb_rot | arb_trans | v_center | h_center | brk_ok | stroke_text | char_text | string_text | no_cr | need_fix | can_clip; /* store the CGM data structure pointers */ pc1 = c1; pc3 = c3; pc5 = c5; state_level = -1; /* just starting */ /* now fill out the function pointers */ /* the delimiter functions */ delim[(int) B_Mf] = cb_begin; delim[(int) E_Mf] = cb_end; delim[(int) B_Pic] = cb_bp; delim[(int) B_Pic_Body] = cb_bpage; delim[(int) E_Pic] = cb_epage; /* the Metafile Descriptor elements */ mfdesc[(int) MfVersion] = cb_mfversion; mfdesc[(int) MfDescrip] = cb_mfdescrip; mfdesc[(int) vdcType] = cb_vdctype; mfdesc[(int) IntPrec] = cb_intprec; mfdesc[(int) RealPrec] = cb_realprec; mfdesc[(int) IndexPrec] = cb_indexprec; mfdesc[(int) ColPrec] = cb_colprec; mfdesc[(int) CIndPrec] = cb_cindprec; mfdesc[(int) CVExtent] = cb_cvextent; mfdesc[(int) MaxCInd] = cb_maxcind; mfdesc[(int) MfElList] = cb_mfellist; mfdesc[(int) MfDefRep] = cb_mfdefrep; mfdesc[(int) FontList] = cb_flist; mfdesc[(int) CharList] = cb_clist; mfdesc[(int) CharAnnounce] = cb_cannounce; /* the picture descriptor elements */ pdesc[(int) ScalMode] = cb_scalmode; pdesc[(int) ColSelMode] = cb_colselmode; pdesc[(int) LWidSpecMode] = cb_lwsmode; pdesc[(int) MarkSizSpecMode] = cb_msmode; pdesc[(int) EdWidSpecMode] = cb_ewmode; pdesc[(int) vdcExtent] = cb_vdcextent; pdesc[(int) BackCol] = cb_backcol; /* the control elements */ mfctrl[(int) vdcIntPrec] = cb_vdcintprec; mfctrl[(int) vdcRPrec] = cb_vdcrprec; mfctrl[(int) AuxCol] = cb_auxcol; mfctrl[(int) Transp] = cb_transp; mfctrl[(int) ClipRect] = cb_cliprect; mfctrl[(int) ClipIndic] = cb_clipindic; /* the graphical primitives */ gprim[(int) PolyLine] = cb_pline; gprim[(int) Dis_Poly] = cb_dpline; gprim[(int) PolyMarker] = cb_pmarker; gprim[(int) Text] = cb_text; gprim[(int) Rex_Text] = cb_rex_text; gprim[(int) App_Text] = cb_app_text; gprim[(int) Polygon] = cb_pgon; gprim[(int) Poly_Set] = cb_pset; gprim[(int) Cell_Array] = cb_carray; gprim[(int) Gen_D_Prim] = cb_gdp; gprim[(int) Rectangle] = cb_rectangle; gprim[(int) Cgm_Circle] = cb_circle; gprim[(int) Circ_3] = cb_c3; gprim[(int) Circ_3_Close] = cb_c3_close; gprim[(int) Circ_Centre] = cb_c_centre; gprim[(int) Circ_C_Close] = cb_c_c_close; gprim[(int) Ellipse] = cb_ellipse; gprim[(int) Ellip_Arc] = cb_ell_arc; gprim[(int) El_Arc_Close] = cb_e_a_close; /* the attributes */ attr[(int) LBIndex] = cb_lbindex; attr[(int) LType] = cb_ltype; attr[(int) LWidth] = cb_lwidth; attr[(int) LColour] = cb_lcolour; attr[(int) MBIndex] = cb_mbindex; attr[(int) MType] = cb_mtype; attr[(int) MSize] = cb_msize; attr[(int) MColour] = cb_mcolour; attr[(int) TBIndex] = cb_tbindex; attr[(int) TFIndex] = cb_tfindex; attr[(int) TPrec] = cb_tprec; attr[(int) CExpFac] = cb_cexpfac; attr[(int) CSpace] = cb_cspace; attr[(int) TColour] = cb_tcolour; attr[(int) CHeight] = cb_cheight; attr[(int) COrient] = cb_corient; attr[(int) TPath] = cb_tpath; attr[(int) TAlign] = cb_talign; attr[(int) CSetIndex] = cb_csindex; attr[(int) AltCSetIndex] = cb_acsindex; attr[(int) FillBIndex] = cb_fbindex; attr[(int) IntStyle] = cb_intstyle; attr[(int) FillColour] = cb_fillcolour; attr[(int) HatchIndex] = cb_hindex; attr[(int) PatIndex] = cb_pindex; attr[(int) EdBIndex] = cb_ebindex; attr[(int) EType] = cb_etype; attr[(int) EdWidth] = cb_edwidth; attr[(int) EdColour] = cb_edcolour; attr[(int) EdVis] = cb_edvis; attr[(int) FillRef] = cb_fillref; attr[(int) PatTab] = cb_pattab; attr[(int) PatSize] = cb_patsize; attr[(int) ColTab] = cb_coltab; attr[(int) AspsFlags] = cb_aspsflags; /* the escape element */ escfun[(int) Escape] = cb_esc; /* the external functions */ extfun[(int) Message] = cb_message; extfun[(int) Ap_Data] = cb_apdata; return; }