/************************************************************************/ /* Copyright Pittsburgh Supercomputing Center 1987, 1988, 1990 */ /* All Rights Reserved */ /* Author Joel Welling */ /* cgm_textem.c version 1.0 */ /* */ /************************************************************************/ /* This module provides a handy interface to GPlot's Hershey font text emulation facility. */ /* This module recognizes what type of machine it's on by the presence of the symbol VMS, unix, CRAY, or ardent. The following makes the machine assignment less ambiguous. */ # include #if (unix && (!CRAY && !ardent)) #define USE_UNIX #endif #ifdef _IBMR2 #include #include #endif #ifdef VMS #include descrip #include stdio #endif #ifdef CRAY #include #include #include #endif #ifdef USE_UNIX #include #include #endif #ifdef ardent #include #include #endif #include "defs.h" #include "cgm_textem.h" typedef struct driver_struct { int (**attr)(), (**gprim)(); struct info_struct *dev_info; struct pic_d_struct *a2; struct attrib_struct *a5; float mag; } driver_info; /* Handle for current (and at this point only) driver data object */ static driver_info *c_d= NULL; /* Flag to indicate debugging status */ static int debug_flag= 0; void textem_toggledebug() /* This function turns debuging on if it's off or vice versa */ { if (debug_flag) { fprintf(stderr,"textem_toggledebug: debugging off\n"); debug_flag= 0; } else { fprintf(stderr,"textem_toggledebug: debugging on\n"); debug_flag= 1; } } static int execute_text(x, y, final, instring) int x, y, final; char *instring; /* This function is what actually gets called when text is to be executed. */ { int ret=1, old_c_index, old_l_width = 1, new_l_width, font_size; float r0, g0, b0, l0; double mag; enum line_enum old_l_type = solid_l; if (debug_flag) fprintf(stderr, "execute_text: text string <%s> being emulated; final= %d\n", instring, final); if (!c_d) { fprintf(stderr,"execute_text: called but not initialized!\n"); exit(2); } /* check to make sure polyline function is still there */ if ( !c_d->gprim[(int) PolyLine] ) { fprintf(stderr,"execute_text: device polyline has disappeared!\n"); return(2); /* survivable error code */ } /* get font size information */ (void)hl_check(&font_size); /* now decide the relevant font magnification */ mag = (double) c_d->a5->c_height / font_size; /* need to set the colour, line size/type */ /* first the colour */ old_c_index = c_d->a5->line_colour.ind; r0 = c_d->a5->line_colour.red; g0 = c_d->a5->line_colour.green; b0 = c_d->a5->line_colour.blue; c_d->a5->line_colour.ind = c_d->a5->text_colour.ind; c_d->a5->line_colour.red = c_d->a5->text_colour.red; c_d->a5->line_colour.green = c_d->a5->text_colour.green; c_d->a5->line_colour.blue = c_d->a5->text_colour.blue; if (c_d->attr[(int) LColour]) (*(c_d->attr[(int) LColour])) (c_d->a5->text_colour.red, c_d->a5->text_colour.green, c_d->a5->text_colour.blue, c_d->a5->text_colour.ind); /* now the line type */ if (c_d->a5->line_type != solid_l) { old_l_type = c_d->a5->line_type; c_d->a5->line_type = solid_l; if (c_d->attr[(int) LType]) (*(c_d->attr[(int) LType])) (c_d->a5->line_type); } /* now the line width */ new_l_width = 0.5 + mag; if (new_l_width < 1) new_l_width = 1; if (new_l_width != c_d->a5->line_width.i) { old_l_width = c_d->a5->line_width.i; l0 = c_d->a5->line_width.r; c_d->a5->line_width.i = new_l_width; if (!c_d->dev_info->d_l_width) c_d->dev_info->d_l_width = 1; c_d->a5->line_width.r = (float) c_d->a5->line_width.i / c_d->dev_info->d_l_width; if (c_d->attr[(int) LWidth]) (*(c_d->attr[(int) LWidth])) (c_d->a5->line_width.i, c_d->a5->line_width.r); } /* actually set the text */ ret = hl_text(x, y, instring, c_d->gprim[(int) PolyLine], c_d->a2, c_d->a5, strlen(instring), c_d->dev_info->capability, NULL, mag); /* reset attributes */ c_d->a5->line_colour.ind = old_c_index; c_d->a5->line_colour.red = r0; c_d->a5->line_colour.green = g0; c_d->a5->line_colour.blue = b0; if (c_d->attr[(int) LColour]) (*(c_d->attr[(int) LColour])) (c_d->a5->line_colour.red, c_d->a5->line_colour.green, c_d->a5->line_colour.blue, c_d->a5->line_colour.ind); if (old_l_type != solid_l) { c_d->a5->line_type = old_l_type; if (c_d->attr[(int) LType]) (*(c_d->attr[(int) LType])) (c_d->a5->line_type); } if (old_l_width != 1) { c_d->a5->line_width.i = old_l_width; c_d->a5->line_width.r = l0; if (c_d->attr[(int) LWidth]) (*(c_d->attr[(int) LWidth])) (c_d->a5->line_width.i, c_d->a5->line_width.r); } /* all done */ return(ret); } int (*textem_create(attr, gprim, dev_info, a2, a5))() int (**attr)(), (**gprim)(); struct info_struct *dev_info; struct pic_d_struct *a2; struct attrib_struct *a5; /* This function creates a driver_info struct with the given information. */ { if (debug_flag) fprintf(stderr,"textem_create: creating Hershey text emulator\n"); if (c_d) { fprintf(stderr,"textem_create: called twice; not supported\n"); exit(2); } if ( !(c_d= (driver_info *)malloc( sizeof(driver_info) )) ) { fprintf(stderr,"textem_create: unable to allocate %d bytes!\n", sizeof(driver_info)); exit(2); } c_d->attr= attr; c_d->gprim= gprim; c_d->dev_info= dev_info; c_d->a2= a2; c_d->a5= a5; if ( !gprim[(int) PolyLine] ) { fprintf(stderr,"textem_create: can't emulate; device has no polyline.\n"); return(NULL); } else return( execute_text ); /*NOTREACHED*/ }