void TEST_restore_window() { char *routine = "TEST_restore_window"; printf(testing, routine); //First with a valid window Window win = active_window(); assert(restore_window(win)); activate_window(win); //Then with an invalid window assert(restore_window(20) == FALSE); printf(done, routine); }
void GLUI_StaticText::set_text( char *text ) { int orig, state; orig = set_to_glut_window(); state = glui->set_front_draw_buffer(); /**** Erase old text first *****/ glMatrixMode( GL_MODELVIEW ); glPushMatrix(); translate_to_origin(); erase_text(); glPopMatrix(); set_name( text ); if ( NOT can_draw() ) return; /**** Redraw the text in the window ****/ glMatrixMode( GL_MODELVIEW ); glPushMatrix(); translate_to_origin(); draw_text(); glPopMatrix(); glui->restore_draw_buffer(state); restore_window( orig ); }
void GLUI_Separator::draw( int x, int y ) { int width, indent, orig; int cont_x, cont_y, cont_w, cont_h, cont_x_off, cont_y_off; if ( NOT can_draw() ) return; orig = set_to_glut_window(); if ( parent() != NULL ) { get_this_column_dims(&cont_x, &cont_y, &cont_w, &cont_h, &cont_x_off, &cont_y_off); width = cont_w - cont_x_off*2; } else { width = this->w; } indent = width * .05; glLineWidth( 1.0 ); glBegin( GL_LINES ); glColor3f( .5, .5, .5 ); glVertex2i( indent, GLUI_SEPARATOR_HEIGHT/2-1 ); glVertex2i( width-indent, GLUI_SEPARATOR_HEIGHT/2-1 ); glColor3f( 1., 1., 1. ); glVertex2i( indent, GLUI_SEPARATOR_HEIGHT/2 ); glVertex2i( width-indent, GLUI_SEPARATOR_HEIGHT/2 ); glEnd(); restore_window(orig); }
void GLUI_RadioButton::draw_active_area( void ) { int text_width, left, right, orig; if ( NOT can_draw() ) return; orig = set_to_glut_window(); text_width = _glutBitmapWidthString( glui->font, name ); left = text_x_offset-3; right = left + 7 + text_width; if ( active ) { glEnable( GL_LINE_STIPPLE ); glLineStipple( 1, 0x5555 ); glColor3f( 0., 0., 0. ); } else { glColor3ub( glui->bkgd_color.r, glui->bkgd_color.g, glui->bkgd_color.b ); } glBegin( GL_LINE_LOOP ); glVertex2i(left,0); glVertex2i( right,0); glVertex2i(right,h+1); glVertex2i( left,h+1); glEnd(); glDisable( GL_LINE_STIPPLE ); restore_window(orig); }
void GLUI_RadioButton::draw( int x, int y ) { int orig; orig = set_to_glut_window(); if ( NOT group OR NOT can_draw() ) return; /*** See if we're the currently-selected button. If so, draw ***/ if ( group->int_val == this->user_id ) { if ( enabled ) glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON, 0, 0 ); else glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON_DIS, 0, 0 ); } else { if ( enabled ) glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_OFF, 0, 0 ); else glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_OFF_DIS, 0, 0 ); } draw_active_area(); draw_name( text_x_offset, 10 ); restore_window(orig); }
void GLUI_Slider::draw_translated_active_area( void ) { int orig; int win_h , win_w; if ( NOT glui ) return; orig = set_to_glut_window(); win_h = glutGet( GLUT_WINDOW_HEIGHT ); win_w = glutGet(GLUT_WINDOW_WIDTH); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); glTranslatef( (float) win_w/2.0, (float) win_h/2.0, 0.0 ); glRotatef( 180.0, 0.0, 1.0, 0.0 ); glRotatef( 180.0, 0.0, 0.0, 1.0 ); glTranslatef( (float) -win_w/2.0, (float) -win_h/2.0, 0.0 ); glTranslatef( (float) this->x_abs + .5, (float) this->y_abs + .5, 0.0 ); draw_active_area(); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); restore_window(orig); }
/** Redraw everybody in our window. */ void GLUI_Control::redraw_window(void) { if (glui==NULL || hidden) return; if ( glui->get_glut_window_id() == -1 ) return; int orig = set_to_glut_window(); glutPostRedisplay(); restore_window(orig); }
void GLUI_StaticText::set_text( const char *text ) { int orig; /**** Erase old text first *****/ glMatrixMode( GL_MODELVIEW ); glPushMatrix(); translate_to_origin(); erase_text(); glPopMatrix(); set_name( (char *) text ); if ( NOT can_draw() ) return; orig = set_to_glut_window(); /**** Redraw the text in the window ****/ glMatrixMode( GL_MODELVIEW ); glPushMatrix(); translate_to_origin(); draw_text(); glPopMatrix(); restore_window( orig ); }
void GLUI_Column::draw( int x, int y ) { int orig; int panel_x, panel_y, panel_w, panel_h, panel_x_off, panel_y_off; int y_diff; if ( NOT can_draw() ) return; if ( int_val == 1 ) { /* Draw a vertical bar */ orig = set_to_glut_window(); if ( parent() != NULL ) { get_this_column_dims(&panel_x, &panel_y, &panel_w, &panel_h, &panel_x_off, &panel_y_off); y_diff = y_abs - panel_y; if ( 0 ) { glLineWidth(1.0); glBegin( GL_LINES ); glColor3f( .5, .5, .5 ); glVertex2i( -GLUI_XOFF+1, -y_diff + GLUI_SEPARATOR_HEIGHT/2 ); glVertex2i( -GLUI_XOFF+1, -y_diff + panel_h - GLUI_SEPARATOR_HEIGHT/2); glColor3f( 1.0, 1.0, 1.0 ); glVertex2i( -GLUI_XOFF+2, -y_diff + GLUI_SEPARATOR_HEIGHT/2 ); glVertex2i( -GLUI_XOFF+2, -y_diff + panel_h - GLUI_SEPARATOR_HEIGHT/2); glEnd(); } else { glLineWidth(1.0); glBegin( GL_LINES ); glColor3f( .5, .5, .5 ); glVertex2i( -2, 0 ); glVertex2i( -2, h ); /*glVertex2i( 0, -y_diff + GLUI_SEPARATOR_HEIGHT/2 ); */ /*glVertex2i( 0, -y_diff + panel_h - GLUI_SEPARATOR_HEIGHT/2); */ glColor3f( 1.0, 1.0, 1.0 ); glVertex2i( -1, 0 ); glVertex2i( -1, h ); /*glVertex2i( 1, -y_diff + GLUI_SEPARATOR_HEIGHT/2 ); */ /*glVertex2i( 1, -y_diff + panel_h - GLUI_SEPARATOR_HEIGHT/2); */ glEnd(); } } restore_window(orig); } }
void GLUI_StaticText::draw( int x, int y ) { int orig; if ( NOT can_draw() ) return; orig = set_to_glut_window(); draw_text(); restore_window( orig ); }
void GLUI_RadioButton::draw_checked( void ) { int orig; if ( NOT can_draw() ) return; orig = set_to_glut_window(); if ( enabled ) glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON, 0, 0 ); else glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON_DIS, 0, 0 ); draw_active_area(); restore_window(orig); }
void GLUI_StaticText::draw( int x, int y ) { int orig, state; if ( NOT can_draw() ) return; orig = set_to_glut_window(); state = glui->set_front_draw_buffer(); draw_text(); glui->restore_draw_buffer(state); restore_window( orig ); }
void GLUI_Panel::set_type( int new_type ) { int old_window; if ( new_type != int_val ) { int_val = new_type; /* translate_and_draw_front(); */ update_size(); old_window = set_to_glut_window(); glutPostRedisplay( ); restore_window( old_window ); } }
void GLUI_Slider::draw( int x, int y ) { int orig; if ( NOT glui ) return; orig = set_to_glut_window(); draw_emboss_box( 0, w, GLUI_SLIDER_NAME_TOP_BORDER + GLUI_SLIDER_FONT_HEIGHT - 1 - GLUI_SLIDER_FONT_MID_HEIGHT, h ); draw_bkgd_box( GLUI_SLIDER_NAME_INDENT-1, GLUI_SLIDER_NAME_INDENT + string_width(name.string) + 2*GLUI_SLIDER_NAME_SIDE_BORDER - 1, 0, 0 + GLUI_SLIDER_FONT_FULL_HEIGHT + GLUI_SLIDER_NAME_TOP_BORDER + GLUI_SLIDER_NAME_BOTTOM_BORDER); draw_name( GLUI_SLIDER_NAME_INDENT + GLUI_SLIDER_NAME_SIDE_BORDER, GLUI_SLIDER_FONT_HEIGHT-1 + GLUI_SLIDER_NAME_TOP_BORDER); draw_active_area(); restore_window(orig); draw_active_box( GLUI_SLIDER_NAME_INDENT, GLUI_SLIDER_NAME_INDENT + string_width(name.string) + 2*GLUI_SLIDER_NAME_SIDE_BORDER - 1, 0, GLUI_SLIDER_FONT_FULL_HEIGHT + GLUI_SLIDER_NAME_TOP_BORDER + GLUI_SLIDER_NAME_BOTTOM_BORDER - 1); }
void GLUI_RadioButton::draw_O( void ) { int i, j, orig; if ( NOT can_draw() ) return; orig = set_to_glut_window(); glBegin( GL_POINTS ); for(i=3; i<=GLUI_RADIOBUTTON_SIZE-3; i++ ) for(j=3; j<=GLUI_RADIOBUTTON_SIZE-3; j++ ) glVertex2i(i,j); glEnd(); restore_window(orig); }
void GLUI_EditText::draw( int x, int y ) { int orig; int name_x; if ( NOT can_draw() ) return; orig = set_to_glut_window(); name_x = MAX(text_x_offset - string_width(this->name) - 3,0); draw_name( name_x , 13); glBegin( GL_LINES ); glColor3f( .5, .5, .5 ); glVertex2i( text_x_offset, 0 ); glVertex2i( w, 0 ); glVertex2i( text_x_offset, 0 ); glVertex2i( text_x_offset, h ); glColor3f( 1., 1., 1. ); glVertex2i( text_x_offset, h ); glVertex2i( w, h ); glVertex2i( w, h ); glVertex2i( w, 0 ); if ( enabled ) glColor3f( 0., 0., 0. ); else glColor3f( .25, .25, .25 ); glVertex2i( text_x_offset+1, 1 ); glVertex2i( w-1, 1 ); glVertex2i( text_x_offset+1, 1 ); glVertex2i( text_x_offset+1, h-1 ); glColor3f( .75, .75, .75 ); glVertex2i( text_x_offset+1, h-1 ); glVertex2i( w-1, h-1 ); glVertex2i( w-1, h-1 ); glVertex2i( w-1, 1 ); glEnd(); /** Find where to draw the text **/ update_substring_bounds(); draw_text(0,0); draw_insertion_pt(); restore_window(orig); }
void GLUI_Mouse_Interaction::draw( int x, int y ) { int orig; int text_width = string_width( this->name ); int x_left = this->w/2 - text_width/2; if ( NOT glui ) return; if ( NOT draw_active_area_only ) { orig = set_to_glut_window(); draw_name( x_left, h-4 ); restore_window(orig); draw_active_box( x_left-4, x_left+string_width( name.string )+4, h, h-14 ); } draw_active_area(); }
void GLUI_RadioGroup::draw_group( int translate ) { GLUI_RadioButton *button; int state, orig; if ( NOT can_draw() ) return; orig = set_to_glut_window(); if ( translate ) state = glui->set_front_draw_buffer(); this->int_val = int_val; glMatrixMode(GL_MODELVIEW ); button = (GLUI_RadioButton*) first_child(); while( button != NULL ) { if ( translate ) { glPushMatrix(); button->translate_to_origin(); } if ( button->int_val ) button->draw_checked(); else button->draw_unchecked(); if ( translate ) glPopMatrix(); button = (GLUI_RadioButton*) button->next(); } if ( translate ) glui->restore_draw_buffer(state); restore_window(orig); }
void GLUI_Translation::iaction_draw_active_area_ortho( void ) { int orig, state; if ( NOT can_draw() ) return; orig = set_to_glut_window(); state = glui->set_front_draw_buffer(); /********* Draw emboss circles around arcball control *********/ float radius; radius = (float)(h-22)/2.0; /* MIN((float)w/2.0, (float)h/2.0); */ glLineWidth( 1.0 ); draw_emboss_box( (int) -radius-2, (int)radius+2, (int)-radius-2, (int)radius+2 ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glTranslatef( .5, .5, .5 ); /* glScalef( radius-1.0, radius-1.0, radius-1.0 ); */ if ( trans_type == GLUI_TRANSLATION_Z ) draw_2d_z_arrows((int)radius-1); else if ( trans_type == GLUI_TRANSLATION_XY ) draw_2d_xy_arrows((int)radius-1); else if ( trans_type == GLUI_TRANSLATION_X ) draw_2d_x_arrows((int)radius-1); else if ( trans_type == GLUI_TRANSLATION_Y ) draw_2d_y_arrows((int)radius-1); glPopMatrix(); glui->restore_draw_buffer(state); restore_window( orig ); }
void GLUI_Mouse_Interaction::draw_active_area( void ) { int orig; int win_h = glutGet( GLUT_WINDOW_HEIGHT ), win_w = glutGet(GLUT_WINDOW_WIDTH); if ( NOT glui ) return; /*putchar( 'X' ); flushout; */ orig = set_to_glut_window(); int text_height = 18; /* what a kludge */ int viewport_size = h-text_height; /*MIN(w,h); */ glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); glTranslatef( (float) win_w/2.0, (float) win_h/2.0, 0.0 ); glRotatef( 180.0, 0.0, 1.0, 0.0 ); glRotatef( 180.0, 0.0, 0.0, 1.0 ); glTranslatef( (float) -win_w/2.0, (float) -win_h/2.0, 0.0 ); glTranslatef( (float) this->x_abs + .5, (float) this->y_abs + .5, 0.0 ); glTranslatef( (float)this->w/2.0, (float)viewport_size/2.0 + 2.0 , 0.0 ); /*** Draw the interaction control's orthographic elements ***/ iaction_draw_active_area_ortho(); /*** Setup and draw the interaction control's perspective elements ***/ /*** Set the viewport to just the square of the drawing area ***/ /* glViewport( this->x_abs , glui->main_panel->h - this->y_abs - this->h,*/ /*glViewport( this->x_abs+1+(this->w/2-viewport_size/2), this->h-this->y_abs-viewport_size-1, viewport_size, viewport_size );*/ viewport_size -= 4; int offset = 0; if ( ((this->w-viewport_size) % 2) == 1 ) offset = 1; glViewport( this->x_abs + (this->w-viewport_size)/2 + offset, win_h - this->y_abs - this->h + text_height, viewport_size, viewport_size ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glFrustum( -1.0*.08, 1.0*.08, -.08, .08, .1, 8.0 ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); glTranslatef( 0.0, 0.0, -3.2f ); /* glutSolidTeapot( 1.0 ); */ iaction_draw_active_area_persp(); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); glui->set_viewport(); glui->set_ortho_projection(); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); restore_window(orig); }
void GLUI_Spinner::draw( int x, int y ) { int orig; if ( NOT can_draw() ) return; orig = set_to_glut_window(); if ( enabled ) { /*** Draw the up arrow either pressed or unrpessed ***/ if ( state == GLUI_SPINNER_STATE_UP OR state == GLUI_SPINNER_STATE_BOTH ) glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_UP_ON, w-GLUI_SPINNER_ARROW_WIDTH-1, GLUI_SPINNER_ARROW_Y); else glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_UP_OFF, w-GLUI_SPINNER_ARROW_WIDTH-1, GLUI_SPINNER_ARROW_Y); /*** Draw the down arrow either pressed or unrpessed ***/ if (state == GLUI_SPINNER_STATE_DOWN OR state == GLUI_SPINNER_STATE_BOTH) glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_DOWN_ON, w-GLUI_SPINNER_ARROW_WIDTH-1, GLUI_SPINNER_ARROW_HEIGHT+GLUI_SPINNER_ARROW_Y); else glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_DOWN_OFF, w-GLUI_SPINNER_ARROW_WIDTH-1, GLUI_SPINNER_ARROW_HEIGHT+GLUI_SPINNER_ARROW_Y); } else { /**** The spinner is disabled ****/ glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_UP_DIS, w-GLUI_SPINNER_ARROW_WIDTH-1, GLUI_SPINNER_ARROW_Y); glui->std_bitmaps.draw( GLUI_STDBITMAP_SPINNER_DOWN_DIS, w-GLUI_SPINNER_ARROW_WIDTH-1, GLUI_SPINNER_ARROW_HEIGHT+GLUI_SPINNER_ARROW_Y); } if ( active ) { glColor3ub( 0, 0, 0 ); glEnable( GL_LINE_STIPPLE ); glLineStipple( 1, 0x5555 ); } else { glColor3ub( glui->bkgd_color.r,glui->bkgd_color.g,glui->bkgd_color.b ); } glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); glDisable( GL_CULL_FACE ); glBegin( GL_QUADS ); glVertex2i( w-GLUI_SPINNER_ARROW_WIDTH-2, 0 ); glVertex2i( w, 0 ); glVertex2i( w, h ); glVertex2i( w-GLUI_SPINNER_ARROW_WIDTH-2, h ); glEnd(); glDisable( GL_LINE_STIPPLE ); glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); restore_window( orig ); }
void GLUI_Panel::draw( int x, int y ) { int top, orig; if ( NOT can_draw() ) return; orig = set_to_glut_window(); if ( int_val == GLUI_PANEL_RAISED ) { top = 0; glLineWidth( 1.0 ); glColor3f( 1.0, 1.0, 1.0 ); glBegin( GL_LINE_LOOP ); glVertex2i( 0, top ); glVertex2i( w, top ); glVertex2i( 0, top ); glVertex2i( 0, h ); glEnd(); glColor3f( .5, .5, .5 ); glBegin( GL_LINE_LOOP ); glVertex2i( w, top ); glVertex2i( w, h ); glVertex2i( 0, h ); glVertex2i( w, h ); glEnd(); /** ORIGINAL RAISED PANEL METHOD - A LITTLE TOO HIGH ** glLineWidth(1.0); glBegin( GL_LINES ); glColor3f( 1.0, 1.0, 1.0 ); glVertex2i( 1, 1 ); glVertex2i( w-2, 1 ); glVertex2i( 1, 1 ); glVertex2i( 1, h-2 ); glColor3f( .5, .5, .5 ); glVertex2i( w-1, 1 ); glVertex2i( w-1, h-1 ); glVertex2i( 1, h-1 ); glVertex2i( w-1, h-1 ); glColor3f( 0.0, 0.0, 0.0 ); glVertex2i( 0, h ); glVertex2i( w, h ); glVertex2i( w, 0 ); glVertex2i( w, h ); glEnd(); -- Touch up the lines a bit (needed in some opengl implementations glBegin( GL_POINTS ); glColor3f( .5, .5, .5 ); glVertex2i( w-1, h-1 ); glColor3f( 0.0, 0.0, 0.0 ); glVertex2i( w, h ); glEnd(); **/ } else if ( int_val == GLUI_PANEL_EMBOSSED ) { if ( name[0] == '\0' ) { top = 0; } else { top = GLUI_PANEL_EMBOSS_TOP; } glLineWidth( 1.0 ); glColor3f( 1.0, 1.0, 1.0 ); glBegin( GL_LINE_LOOP ); glVertex2i( 0, top ); glVertex2i( w, top ); glVertex2i( w, h ); glVertex2i( 0, h ); glVertex2i( 1, top+1 ); glVertex2i( w-1, top+1 ); glVertex2i( w-1, h-1 ); glVertex2i( 1, h-1 ); glEnd(); glColor3f( .5, .5, .5 ); glBegin( GL_LINE_LOOP ); glVertex2i( 0, top ); glVertex2i( w-1, top ); glVertex2i( w-1, h-1 ); glVertex2i( 0, h-1 ); glEnd(); /**** Only display text in embossed panel ****/ if ( name[0] != '\0' ) { /* Only draw non-null strings */ int left = 7, height=GLUI_PANEL_NAME_DROP+1; int str_width; str_width = string_width(name); if ( glui ) glColor3ub(glui->bkgd_color.r,glui->bkgd_color.g,glui->bkgd_color.b); glDisable( GL_CULL_FACE ); glBegin( GL_QUADS ); glVertex2i( left-3, 0 ); glVertex2i( left+str_width+3, 0 ); glVertex2i( left+str_width+3, height ); glVertex2i( left-3, height ); glEnd(); draw_name( left, GLUI_PANEL_NAME_DROP ); } } glLineWidth( 1.0 ); restore_window(orig); }
void GLUI_EditText::draw_text( int x, int y ) { int text_x, i, sel_lo, sel_hi; int orig; if ( NOT can_draw() ) return; if ( debug ) dump( stdout, "-> DRAW_TEXT" ); orig = set_to_glut_window(); if ( NOT draw_text_only ) { if ( enabled ) glColor3f( 1., 1., 1. ); else set_to_bkgd_color(); glDisable( GL_CULL_FACE ); glBegin( GL_QUADS ); glVertex2i( text_x_offset+2, 2 ); glVertex2i( w-2, 2 ); glVertex2i( w-2, h-2 ); glVertex2i( text_x_offset+2, h-2 ); glEnd(); } /** Find where to draw the text **/ text_x = text_x_offset + 2 + GLUI_EDITTEXT_BOXINNERMARGINX; /*printf( "text_x: %d substr_width: %d start/end: %d/%d\n", text_x, substring_width( substring_start, substring_end ), substring_start, substring_end ); */ /** Find lower and upper selection bounds **/ sel_lo = MIN(sel_start, sel_end ); sel_hi = MAX(sel_start, sel_end ); int sel_x_start, sel_x_end, delta; /** Draw selection area dark **/ if ( sel_start != sel_end ) { sel_x_start = text_x; sel_x_end = text_x; for( i=substring_start; i<=substring_end; i++ ) { delta = char_width( text[i] ); if ( i < sel_lo ) { sel_x_start += delta; sel_x_end += delta; } else if ( i < sel_hi ) { sel_x_end += delta; } } glColor3f( 0.0f, 0.0f, .6f ); glBegin( GL_QUADS ); glVertex2i( sel_x_start, 2 ); glVertex2i( sel_x_end, 2 ); glVertex2i( sel_x_end, h-2 ); glVertex2i( sel_x_start, h-2 ); glEnd(); } if ( sel_start == sel_end ) { /* No current selection */ if ( enabled ) glColor3b( 0, 0, 0 ); else glColor3b( 32, 32, 32 ); glRasterPos2i( text_x, 13); for( i=substring_start; i<=substring_end; i++ ) { glutBitmapCharacter( get_font(), this->text[i] ); } } else { /* There is a selection */ int x = text_x; for( i=substring_start; i<=substring_end; i++ ) { if ( IN_BOUNDS( i, sel_lo, sel_hi-1)) { /* This character is selected */ glColor3f( 1., 1., 1. ); glRasterPos2i( x, 13); glutBitmapCharacter( get_font(), this->text[i] ); } else { glColor3f( 0., 0., 0. ); glRasterPos2i( x, 13); glutBitmapCharacter( get_font(), this->text[i] ); } x += char_width( text[i] ); } } restore_window( orig ); if ( debug ) dump( stdout, "<- DRAW_TEXT" ); }