Go to the source code of this file.
Data Structures | |
struct | t_point |
Defines | |
#define | SCREEN 0 |
#define | POSTSCRIPT 1 |
#define | MAXPTS 100 |
Enumerations | |
enum | color_types { WHITE, BLACK, DARKGREY, LIGHTGREY, BLUE, GREEN, YELLOW, CYAN, RED, DARKGREEN, MAGENTA, BISQUE, LIGHTBLUE, THISTLE, PLUM, KHAKI, CORAL, TURQUOISE, MEDIUMPURPLE, DARKSLATEBLUE, DARKKHAKI, NUM_COLOR } |
enum | line_types { SOLID, DASHED } |
Functions | |
void | event_loop (void(*act_on_button)(float x, float y), void(*drawscreen)(void)) |
void | init_graphics (char *window_name) |
void | close_graphics (void) |
void | update_message (char *msg) |
void | draw_message (void) |
void | init_world (float xl, float yt, float xr, float yb) |
void | flushinput (void) |
void | setcolor (int cindex) |
void | setlinestyle (int linestyle) |
void | setlinewidth (int linewidth) |
void | setfontsize (int pointsize) |
void | drawline (float x1, float y1, float x2, float y2) |
void | drawrect (float x1, float y1, float x2, float y2) |
void | fillrect (float x1, float y1, float x2, float y2) |
void | fillpoly (t_point *points, int npoints) |
void | drawarc (float xcen, float ycen, float rad, float startang, float angextent) |
void | fillarc (float xcen, float ycen, float rad, float startang, float angextent) |
void | drawtext (float xc, float yc, const char *text, float boundx) |
void | clearscreen (void) |
void | create_button (char *prev_button_text, char *button_text, void(*button_func)(void(*drawscreen)(void))) |
void | destroy_button (char *button_text) |
int | init_postscript (char *fname) |
void | close_postscript (void) |
#define MAXPTS 100 |
Definition at line 13 of file graphics.h.
#define POSTSCRIPT 1 |
Definition at line 2 of file graphics.h.
#define SCREEN 0 |
Definition at line 1 of file graphics.h.
enum color_types |
WHITE | |
BLACK | |
DARKGREY | |
LIGHTGREY | |
BLUE | |
GREEN | |
YELLOW | |
CYAN | |
RED | |
DARKGREEN | |
MAGENTA | |
BISQUE | |
LIGHTBLUE | |
THISTLE | |
PLUM | |
KHAKI | |
CORAL | |
TURQUOISE | |
MEDIUMPURPLE | |
DARKSLATEBLUE | |
DARKKHAKI | |
NUM_COLOR |
Definition at line 4 of file graphics.h.
enum line_types |
void clearscreen | ( | void | ) |
Definition at line 1205 of file graphics.c.
01206 { 01207 int savecolor; 01208 01209 if(disp_type == SCREEN) 01210 { 01211 XClearWindow(display, toplevel); 01212 } 01213 else 01214 { 01215 /* erases current page. Don't use erasepage, since this will erase * 01216 * everything, (even stuff outside the clipping path) causing * 01217 * problems if this picture is incorporated into a larger document. */ 01218 savecolor = currentcolor; 01219 setcolor(WHITE); 01220 fprintf(ps, "clippath fill\n\n"); 01221 setcolor(savecolor); 01222 } 01223 }
void close_graphics | ( | void | ) |
Definition at line 1958 of file graphics.c.
01959 { 01960 01961 /* Release all my drawing structures (through the X server) and * 01962 * close down the connection. */ 01963 01964 int i; 01965 01966 for(i = 1; i <= MAX_FONT_SIZE; i++) 01967 if(font_is_loaded[i]) 01968 XFreeFont(display, font_info[i]); 01969 01970 XFreeGC(display, gc); 01971 XFreeGC(display, gcxor); 01972 XFreeGC(display, gc_menus); 01973 01974 if(private_cmap != None) 01975 XFreeColormap(display, private_cmap); 01976 01977 XCloseDisplay(display); 01978 free(button); 01979 }
void close_postscript | ( | void | ) |
Definition at line 2118 of file graphics.c.
02119 { 02120 02121 /* Properly ends postscript output and redirects output to screen. */ 02122 02123 fprintf(ps, "showpage\n"); 02124 fprintf(ps, "\n%%%%Trailer\n"); 02125 fclose(ps); 02126 disp_type = SCREEN; 02127 update_transform(); /* Ensure screen world reflects any changes * 02128 * made while printing. */ 02129 02130 /* Need to make sure that we really set up the graphics context -- * 02131 * don't want the change requested to match the current setting and * 02132 * do nothing -> force the changes. */ 02133 02134 force_setcolor(currentcolor); 02135 force_setlinestyle(currentlinestyle); 02136 force_setlinewidth(currentlinewidth); 02137 force_setfontsize(currentfontsize); 02138 }
void create_button | ( | char * | prev_button_text, | |
char * | button_text, | |||
void(*)(void(*drawscreen)(void)) | button_func | |||
) |
Definition at line 585 of file graphics.c.
00588 { 00589 00590 /* Creates a new button below the button containing prev_button_text. * 00591 * The text and button function are set according to button_text and * 00592 * button_func, respectively. */ 00593 00594 int i, bnum, space; 00595 00596 space = 8; 00597 00598 /* Only allow new buttons that are text (not poly) types. */ 00599 00600 bnum = -1; 00601 for(i = 4; i < num_buttons; i++) 00602 { 00603 if(button[i].istext == 1 && 00604 strcmp(button[i].text, prev_button_text) == 0) 00605 { 00606 bnum = i + 1; 00607 break; 00608 } 00609 } 00610 00611 if(bnum == -1) 00612 { 00613 printf 00614 ("Error in create_button: button with text %s not found.\n", 00615 prev_button_text); 00616 exit(1); 00617 } 00618 00619 num_buttons++; 00620 button = (t_button *) my_realloc(button, num_buttons * sizeof(t_button)); 00621 00622 /* NB: Requirement that you specify the button that this button goes under * 00623 * guarantees that button[num_buttons-2] exists and is a text button. */ 00624 00625 button[num_buttons - 1].xleft = button[num_buttons - 2].xleft; 00626 button[num_buttons - 1].ytop = button[num_buttons - 2].ytop + 00627 button[num_buttons - 2].height + space; 00628 button[num_buttons - 1].height = button[num_buttons - 2].height; 00629 button[num_buttons - 1].width = button[num_buttons - 2].width; 00630 map_button(num_buttons - 1); 00631 00632 00633 for(i = num_buttons - 1; i > bnum; i--) 00634 { 00635 button[i].ispoly = button[i - 1].ispoly; 00636 /* No poly copy for now, as I'm only providing the ability to create text * 00637 * buttons. */ 00638 00639 button[i].istext = button[i - 1].istext; 00640 strcpy(button[i].text, button[i - 1].text); 00641 button[i].fcn = button[i - 1].fcn; 00642 button[i].ispressed = button[i - 1].ispressed; 00643 } 00644 00645 button[bnum].istext = 1; 00646 button[bnum].ispoly = 0; 00647 my_strncpy(button[bnum].text, button_text, BUTTON_TEXT_LEN); 00648 button[bnum].fcn = button_func; 00649 button[bnum].ispressed = 1; 00650 }
void destroy_button | ( | char * | button_text | ) |
Definition at line 654 of file graphics.c.
00655 { 00656 00657 /* Destroys the button with text button_text. */ 00658 00659 int i, bnum; 00660 00661 bnum = -1; 00662 for(i = 4; i < num_buttons; i++) 00663 { 00664 if(button[i].istext == 1 && 00665 strcmp(button[i].text, button_text) == 0) 00666 { 00667 bnum = i; 00668 break; 00669 } 00670 } 00671 00672 if(bnum == -1) 00673 { 00674 printf 00675 ("Error in destroy_button: button with text %s not found.\n", 00676 button_text); 00677 exit(1); 00678 } 00679 00680 for(i = bnum + 1; i < num_buttons; i++) 00681 { 00682 button[i - 1].ispoly = button[i].ispoly; 00683 /* No poly copy for now, as I'm only providing the ability to create text * 00684 * buttons. */ 00685 00686 button[i - 1].istext = button[i].istext; 00687 strcpy(button[i - 1].text, button[i].text); 00688 button[i - 1].fcn = button[i].fcn; 00689 button[i - 1].ispressed = button[i].ispressed; 00690 } 00691 00692 unmap_button(num_buttons - 1); 00693 num_buttons--; 00694 button = (t_button *) my_realloc(button, num_buttons * sizeof(t_button)); 00695 }
void draw_message | ( | void | ) |
Definition at line 1617 of file graphics.c.
01618 { 01619 01620 /* Draw the current message in the text area at the screen bottom. */ 01621 01622 int len, width, savefontsize, savecolor; 01623 float ylow; 01624 01625 if(disp_type == SCREEN) 01626 { 01627 XClearWindow(display, textarea); 01628 len = strlen(message); 01629 width = XTextWidth(font_info[menu_font_size], message, len); 01630 01631 XSetForeground(display, gc_menus, colors[BLACK]); 01632 XDrawString(display, textarea, gc_menus, 01633 (top_width - MWIDTH - width) / 2, 01634 (T_AREA_HEIGHT - 4) / 2 + 01635 (font_info[menu_font_size]->ascent - 01636 font_info[menu_font_size]->descent) / 2, message, 01637 len); 01638 } 01639 01640 else 01641 { 01642 /* Draw the message in the bottom margin. Printer's generally can't * 01643 * print on the bottom 1/4" (area with y < 18 in PostScript coords.) */ 01644 01645 savecolor = currentcolor; 01646 setcolor(BLACK); 01647 savefontsize = currentfontsize; 01648 setfontsize(menu_font_size - 2); /* Smaller OK on paper */ 01649 ylow = ps_bot - 8.; 01650 fprintf(ps, "(%s) %.2f %.2f censhow\n", message, 01651 (ps_left + ps_right) / 2., ylow); 01652 setcolor(savecolor); 01653 setfontsize(savefontsize); 01654 } 01655 }
void drawarc | ( | float | xcen, | |
float | ycen, | |||
float | rad, | |||
float | startang, | |||
float | angextent | |||
) |
Definition at line 1380 of file graphics.c.
01385 { 01386 01387 /* Draws a circular arc. X11 can do elliptical arcs quite simply, and * 01388 * PostScript could do them by scaling the coordinate axes. Too much * 01389 * work for now, and probably too complex an object for users to draw * 01390 * much, so I'm just doing circular arcs. Startang is relative to the * 01391 * Window's positive x direction. Angles in degrees. */ 01392 01393 int xl, yt; 01394 unsigned int width, height; 01395 01396 /* Conservative (but fast) clip test -- check containing rectangle of * 01397 * a circle. */ 01398 01399 if(rect_off_screen(xc - rad, yc - rad, xc + rad, yc + rad)) 01400 return; 01401 01402 /* X Windows has trouble with very large angles. (Over 360). * 01403 * Do following to prevent its inaccurate (overflow?) problems. */ 01404 if(fabs(angextent) > 360.) 01405 angextent = 360.; 01406 01407 startang = angnorm(startang); 01408 01409 if(disp_type == SCREEN) 01410 { 01411 xl = (int)(xcoord(xc) - fabs(xmult * rad)); 01412 yt = (int)(ycoord(yc) - fabs(ymult * rad)); 01413 width = (unsigned int)(2 * fabs(xmult * rad)); 01414 height = width; 01415 XDrawArc(display, toplevel, gc, xl, yt, width, height, 01416 (int)(startang * 64), (int)(angextent * 64)); 01417 } 01418 else 01419 { 01420 fprintf(ps, "%.2f %.2f %.2f %.2f %.2f %s stroke\n", XPOST(xc), 01421 YPOST(yc), fabs(rad * ps_xmult), startang, 01422 startang + angextent, 01423 (angextent < 0) ? "drawarcn" : "drawarc"); 01424 } 01425 }
void drawline | ( | float | x1, | |
float | y1, | |||
float | x2, | |||
float | y2 | |||
) |
Definition at line 1262 of file graphics.c.
01266 { 01267 01268 /* Draw a line from (x1,y1) to (x2,y2) in the user-drawable area. * 01269 * Coordinates are in world (user) space. */ 01270 01271 if(rect_off_screen(x1, y1, x2, y2)) 01272 return; 01273 01274 if(disp_type == SCREEN) 01275 { 01276 /* Xlib.h prototype has x2 and y1 mixed up. */ 01277 XDrawLine(display, toplevel, gc, xcoord(x1), ycoord(y1), 01278 xcoord(x2), ycoord(y2)); 01279 } 01280 else 01281 { 01282 fprintf(ps, "%.2f %.2f %.2f %.2f drawline\n", XPOST(x1), 01283 YPOST(y1), XPOST(x2), YPOST(y2)); 01284 } 01285 }
void drawrect | ( | float | x1, | |
float | y1, | |||
float | x2, | |||
float | y2 | |||
) |
Definition at line 1288 of file graphics.c.
01292 { 01293 01294 /* (x1,y1) and (x2,y2) are diagonally opposed corners, in world coords. */ 01295 01296 unsigned int width, height; 01297 int xw1, yw1, xw2, yw2, xl, yt; 01298 01299 if(rect_off_screen(x1, y1, x2, y2)) 01300 return; 01301 01302 if(disp_type == SCREEN) 01303 { 01304 /* translate to X Windows calling convention. */ 01305 xw1 = xcoord(x1); 01306 xw2 = xcoord(x2); 01307 yw1 = ycoord(y1); 01308 yw2 = ycoord(y2); 01309 xl = min(xw1, xw2); 01310 yt = min(yw1, yw2); 01311 width = abs(xw1 - xw2); 01312 height = abs(yw1 - yw2); 01313 XDrawRectangle(display, toplevel, gc, xl, yt, width, height); 01314 } 01315 else 01316 { 01317 fprintf(ps, "%.2f %.2f %.2f %.2f drawrect\n", XPOST(x1), 01318 YPOST(y1), XPOST(x2), YPOST(y2)); 01319 } 01320 }
void drawtext | ( | float | xc, | |
float | yc, | |||
const char * | text, | |||
float | boundx | |||
) |
Definition at line 1533 of file graphics.c.
01537 { 01538 01539 /* Draws text centered on xc,yc if it fits in boundx */ 01540 01541 int len, width, xw_off, yw_off; 01542 01543 len = strlen(text); 01544 width = XTextWidth(font_info[currentfontsize], text, len); 01545 if(width > fabs(boundx * xmult)) 01546 return; /* Don't draw if it won't fit */ 01547 01548 xw_off = width / (2. * xmult); /* NB: sign doesn't matter. */ 01549 01550 /* NB: 2 * descent makes this slightly conservative but simplifies code. */ 01551 yw_off = (font_info[currentfontsize]->ascent + 01552 2 * font_info[currentfontsize]->descent) / (2. * ymult); 01553 01554 /* Note: text can be clipped when a little bit of it would be visible * 01555 * right now. Perhaps X doesn't return extremely accurate width and * 01556 * ascent values, etc? Could remove this completely by multiplying * 01557 * xw_off and yw_off by, 1.2 or 1.5. */ 01558 01559 if(rect_off_screen(xc - xw_off, yc - yw_off, xc + xw_off, yc + yw_off)) 01560 return; 01561 01562 if(disp_type == SCREEN) 01563 { 01564 XDrawString(display, toplevel, gc, xcoord(xc) - width / 2, 01565 ycoord(yc) + (font_info[currentfontsize]->ascent - 01566 font_info[currentfontsize]->descent) / 01567 2, text, len); 01568 } 01569 else 01570 { 01571 fprintf(ps, "(%s) %.2f %.2f censhow\n", text, XPOST(xc), 01572 YPOST(yc)); 01573 } 01574 }
void event_loop | ( | void(*)(float x, float y) | act_on_button, | |
void(*)(void) | drawscreen | |||
) |
Definition at line 1118 of file graphics.c.
01121 { 01122 01123 /* The program's main event loop. Must be passed a user routine * 01124 * drawscreen which redraws the screen. It handles all window resizing * 01125 * zooming etc. itself. If the user clicks a button in the graphics * 01126 * (toplevel) area, the act_on_button routine passed in is called. */ 01127 01128 XEvent report; 01129 int bnum; 01130 float x, y; 01131 01132 #define OFF 1 01133 #define ON 0 01134 01135 turn_on_off(ON); 01136 while(1) 01137 { 01138 XNextEvent(display, &report); 01139 switch (report.type) 01140 { 01141 case Expose: 01142 #ifdef VERBOSE 01143 printf("Got an expose event.\n"); 01144 printf("Count is: %d.\n", report.xexpose.count); 01145 printf("Window ID is: %d.\n", report.xexpose.window); 01146 #endif 01147 if(report.xexpose.count != 0) 01148 break; 01149 if(report.xexpose.window == menu) 01150 drawmenu(); 01151 else if(report.xexpose.window == toplevel) 01152 drawscreen(); 01153 else if(report.xexpose.window == textarea) 01154 draw_message(); 01155 break; 01156 case ConfigureNotify: 01157 top_width = report.xconfigure.width; 01158 top_height = report.xconfigure.height; 01159 update_transform(); 01160 #ifdef VERBOSE 01161 printf("Got a ConfigureNotify.\n"); 01162 printf("New width: %d New height: %d.\n", top_width, 01163 top_height); 01164 #endif 01165 break; 01166 case ButtonPress: 01167 #ifdef VERBOSE 01168 printf("Got a buttonpress.\n"); 01169 printf("Window ID is: %d.\n", report.xbutton.window); 01170 #endif 01171 if(report.xbutton.window == toplevel) 01172 { 01173 x = XTOWORLD(report.xbutton.x); 01174 y = YTOWORLD(report.xbutton.y); 01175 act_on_button(x, y); 01176 } 01177 else 01178 { /* A menu button was pressed. */ 01179 bnum = which_button(report.xbutton.window); 01180 #ifdef VERBOSE 01181 printf("Button number is %d\n", bnum); 01182 #endif 01183 button[bnum].ispressed = 1; 01184 drawbut(bnum); 01185 XFlush(display); /* Flash the button */ 01186 button[bnum].fcn(drawscreen); 01187 button[bnum].ispressed = 0; 01188 drawbut(bnum); 01189 if(button[bnum].fcn == proceed) 01190 { 01191 turn_on_off(OFF); 01192 flushinput(); 01193 return; /* Rather clumsy way of returning * 01194 * control to the simulator */ 01195 } 01196 } 01197 break; 01198 } 01199 } 01200 }
void fillarc | ( | float | xcen, | |
float | ycen, | |||
float | rad, | |||
float | startang, | |||
float | angextent | |||
) |
Definition at line 1429 of file graphics.c.
01434 { 01435 01436 /* Fills a circular arc. Startang is relative to the Window's positive x * 01437 * direction. Angles in degrees. */ 01438 01439 int xl, yt; 01440 unsigned int width, height; 01441 01442 /* Conservative (but fast) clip test -- check containing rectangle of * 01443 * a circle. */ 01444 01445 if(rect_off_screen(xc - rad, yc - rad, xc + rad, yc + rad)) 01446 return; 01447 01448 /* X Windows has trouble with very large angles. (Over 360). * 01449 * Do following to prevent its inaccurate (overflow?) problems. */ 01450 01451 if(fabs(angextent) > 360.) 01452 angextent = 360.; 01453 01454 startang = angnorm(startang); 01455 01456 if(disp_type == SCREEN) 01457 { 01458 xl = (int)(xcoord(xc) - fabs(xmult * rad)); 01459 yt = (int)(ycoord(yc) - fabs(ymult * rad)); 01460 width = (unsigned int)(2 * fabs(xmult * rad)); 01461 height = width; 01462 XFillArc(display, toplevel, gc, xl, yt, width, height, 01463 (int)(startang * 64), (int)(angextent * 64)); 01464 } 01465 else 01466 { 01467 fprintf(ps, "%.2f %.2f %.2f %.2f %.2f %s\n", fabs(rad * ps_xmult), 01468 startang, startang + angextent, XPOST(xc), YPOST(yc), 01469 (angextent < 0) ? "fillarcn" : "fillarc"); 01470 } 01471 }
void fillpoly | ( | t_point * | points, | |
int | npoints | |||
) |
Definition at line 1475 of file graphics.c.
01477 { 01478 01479 XPoint transpoints[MAXPTS]; 01480 int i; 01481 float xmin, ymin, xmax, ymax; 01482 01483 if(npoints > MAXPTS) 01484 { 01485 printf 01486 ("Error in fillpoly: Only %d points allowed per polygon.\n", 01487 MAXPTS); 01488 printf("%d points were requested. Polygon is not drawn.\n", 01489 npoints); 01490 return; 01491 } 01492 01493 /* Conservative (but fast) clip test -- check containing rectangle of * 01494 * polygon. */ 01495 01496 xmin = xmax = points[0].x; 01497 ymin = ymax = points[0].y; 01498 01499 for(i = 1; i < npoints; i++) 01500 { 01501 xmin = min(xmin, points[i].x); 01502 xmax = max(xmax, points[i].x); 01503 ymin = min(ymin, points[i].y); 01504 ymax = max(ymax, points[i].y); 01505 } 01506 01507 if(rect_off_screen(xmin, ymin, xmax, ymax)) 01508 return; 01509 01510 if(disp_type == SCREEN) 01511 { 01512 for(i = 0; i < npoints; i++) 01513 { 01514 transpoints[i].x = (short)xcoord(points[i].x); 01515 transpoints[i].y = (short)ycoord(points[i].y); 01516 } 01517 XFillPolygon(display, toplevel, gc, transpoints, npoints, Complex, 01518 CoordModeOrigin); 01519 } 01520 else 01521 { 01522 fprintf(ps, "\n"); 01523 01524 for(i = npoints - 1; i >= 0; i--) 01525 fprintf(ps, "%.2f %.2f\n", XPOST(points[i].x), 01526 YPOST(points[i].y)); 01527 01528 fprintf(ps, "%d fillpoly\n", npoints); 01529 } 01530 }
void fillrect | ( | float | x1, | |
float | y1, | |||
float | x2, | |||
float | y2 | |||
) |
Definition at line 1324 of file graphics.c.
01328 { 01329 01330 /* (x1,y1) and (x2,y2) are diagonally opposed corners in world coords. */ 01331 01332 unsigned int width, height; 01333 int xw1, yw1, xw2, yw2, xl, yt; 01334 01335 if(rect_off_screen(x1, y1, x2, y2)) 01336 return; 01337 01338 if(disp_type == SCREEN) 01339 { 01340 /* translate to X Windows calling convention. */ 01341 xw1 = xcoord(x1); 01342 xw2 = xcoord(x2); 01343 yw1 = ycoord(y1); 01344 yw2 = ycoord(y2); 01345 xl = min(xw1, xw2); 01346 yt = min(yw1, yw2); 01347 width = abs(xw1 - xw2); 01348 height = abs(yw1 - yw2); 01349 XFillRectangle(display, toplevel, gc, xl, yt, width, height); 01350 } 01351 else 01352 { 01353 fprintf(ps, "%.2f %.2f %.2f %.2f fillrect\n", XPOST(x1), 01354 YPOST(y1), XPOST(x2), YPOST(y2)); 01355 } 01356 }
void flushinput | ( | void | ) |
void init_graphics | ( | char * | window_name | ) |
Definition at line 699 of file graphics.c.
00700 { 00701 00702 /* Open the toplevel window, get the colors, 2 graphics * 00703 * contexts, load a font, and set up the toplevel window * 00704 * Calls build_default_menu to set up the default menu. */ 00705 00706 char *display_name = NULL; 00707 int x, y; /* window position */ 00708 unsigned int border_width = 2; /* ignored by OpenWindows */ 00709 XTextProperty windowName; 00710 00711 /* X Windows' names for my colours. */ 00712 char *cnames[NUM_COLOR] = { "white", "black", "grey55", "grey75", "blue", 00713 "green", "yellow", "cyan", "red", "RGBi:0.0/0.5/0.0", "magenta", 00714 "bisque", "lightblue", "thistle", "plum", "khaki", 00715 "coral", "turquoise", "mediumpurple", "darkslateblue", "darkkhaki" 00716 }; 00717 00718 XColor exact_def; 00719 Colormap cmap; 00720 int i; 00721 unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */ 00722 XGCValues values; 00723 XEvent event; 00724 00725 00726 disp_type = SCREEN; /* Graphics go to screen, not ps */ 00727 00728 for(i = 0; i <= MAX_FONT_SIZE; i++) 00729 font_is_loaded[i] = 0; /* No fonts loaded yet. */ 00730 00731 /* connect to X server */ 00732 if((display = XOpenDisplay(display_name)) == NULL) 00733 { 00734 fprintf(stderr, "Cannot connect to X server %s\n", 00735 XDisplayName(display_name)); 00736 exit(-1); 00737 } 00738 00739 /* get screen size from display structure macro */ 00740 screen_num = DefaultScreen(display); 00741 display_width = DisplayWidth(display, screen_num); 00742 display_height = DisplayHeight(display, screen_num); 00743 00744 x = y = 0; 00745 00746 top_width = 2 * display_width / 3; 00747 top_height = 4 * display_height / 5; 00748 00749 cmap = DefaultColormap(display, screen_num); 00750 private_cmap = None; 00751 00752 for(i = 0; i < NUM_COLOR; i++) 00753 { 00754 if(!XParseColor(display, cmap, cnames[i], &exact_def)) 00755 { 00756 fprintf(stderr, "Color name %s not in database", 00757 cnames[i]); 00758 exit(-1); 00759 } 00760 if(!XAllocColor(display, cmap, &exact_def)) 00761 { 00762 fprintf(stderr, "Couldn't allocate color %s.\n", 00763 cnames[i]); 00764 00765 if(private_cmap == None) 00766 { 00767 fprintf(stderr, 00768 "Will try to allocate a private colourmap.\n"); 00769 fprintf(stderr, 00770 "Colours will only display correctly when your " 00771 "cursor is in the graphics window.\n" 00772 "Exit other colour applications and rerun this " 00773 "program if you don't like that.\n\n"); 00774 00775 private_cmap = 00776 XCopyColormapAndFree(display, cmap); 00777 cmap = private_cmap; 00778 if(!XAllocColor(display, cmap, &exact_def)) 00779 { 00780 fprintf(stderr, 00781 "Couldn't allocate color %s as private.\n", 00782 cnames[i]); 00783 exit(1); 00784 } 00785 } 00786 00787 else 00788 { 00789 fprintf(stderr, 00790 "Couldn't allocate color %s as private.\n", 00791 cnames[i]); 00792 exit(1); 00793 } 00794 } 00795 colors[i] = exact_def.pixel; 00796 } 00797 00798 toplevel = 00799 XCreateSimpleWindow(display, RootWindow(display, screen_num), x, y, 00800 top_width, top_height, border_width, 00801 colors[BLACK], colors[WHITE]); 00802 00803 if(private_cmap != None) 00804 XSetWindowColormap(display, toplevel, private_cmap); 00805 00806 /* hints stuff deleted. */ 00807 00808 XSelectInput(display, toplevel, ExposureMask | StructureNotifyMask | 00809 ButtonPressMask); 00810 00811 00812 /* Create default Graphics Contexts. valuemask = 0 -> use defaults. */ 00813 gc = XCreateGC(display, toplevel, valuemask, &values); 00814 gc_menus = XCreateGC(display, toplevel, valuemask, &values); 00815 00816 /* Create XOR graphics context for Rubber Banding */ 00817 values.function = GXxor; 00818 values.foreground = colors[BLACK]; 00819 gcxor = XCreateGC(display, toplevel, (GCFunction | GCForeground), 00820 &values); 00821 00822 /* specify font for menus. */ 00823 load_font(menu_font_size); 00824 font_is_loaded[menu_font_size] = 1; 00825 XSetFont(display, gc_menus, font_info[menu_font_size]->fid); 00826 00827 /* Set drawing defaults for user-drawable area. Use whatever the * 00828 * initial values of the current stuff was set to. */ 00829 force_setfontsize(currentfontsize); 00830 force_setcolor(currentcolor); 00831 force_setlinestyle(currentlinestyle); 00832 force_setlinewidth(currentlinewidth); 00833 00834 XStringListToTextProperty(&window_name, 1, &windowName); 00835 XSetWMName(display, toplevel, &windowName); 00836 /* Uncomment to set icon name */ 00837 /* XSetWMIconName (display, toplevel, &windowName); */ 00838 00839 /* XStringListToTextProperty copies the window_name string into * 00840 * windowName.value. Free this memory now. */ 00841 00842 free(windowName.value); 00843 00844 XMapWindow(display, toplevel); 00845 build_textarea(); 00846 build_default_menu(); 00847 00848 /* The following is completely unnecessary if the user is using the * 00849 * interactive (event_loop) graphics. It waits for the first Expose * 00850 * event before returning so that I can tell the window manager has got * 00851 * the top-level window up and running. Thus the user can start drawing * 00852 * into this window immediately, and there's no danger of the window not * 00853 * being ready and output being lost. */ 00854 00855 XPeekIfEvent(display, &event, test_if_exposed, NULL); 00856 }
int init_postscript | ( | char * | fname | ) |
Definition at line 1983 of file graphics.c.
01984 { 01985 /* Opens a file for PostScript output. The header information, * 01986 * clipping path, etc. are all dumped out. If the file could * 01987 * not be opened, the routine returns 0; otherwise it returns 1. */ 01988 01989 ps = fopen(fname, "w"); 01990 if(ps == NULL) 01991 { 01992 printf("Error: could not open %s for PostScript output.\n", 01993 fname); 01994 printf("Drawing to screen instead.\n"); 01995 return (0); 01996 } 01997 disp_type = POSTSCRIPT; /* Graphics go to postscript file now. */ 01998 01999 /* Header for minimal conformance with the Adobe structuring convention */ 02000 fprintf(ps, "%%!PS-Adobe-1.0\n"); 02001 fprintf(ps, "%%%%DocumentFonts: Helvetica\n"); 02002 fprintf(ps, "%%%%Pages: 1\n"); 02003 /* Set up postscript transformation macros and page boundaries */ 02004 update_ps_transform(); 02005 /* Bottom margin is at ps_bot - 15. to leave room for the on-screen message. */ 02006 fprintf(ps, "%%%%BoundingBox: %d %d %d %d\n", 02007 (int)ps_left, (int)(ps_bot - 15.), (int)ps_right, (int)ps_top); 02008 fprintf(ps, "%%%%EndComments\n"); 02009 02010 fprintf(ps, "/censhow %%draw a centered string\n"); 02011 fprintf(ps, " { moveto %% move to proper spot\n"); 02012 fprintf(ps, " dup stringwidth pop %% get x length of string\n"); 02013 fprintf(ps, " -2 div %% Proper left start\n"); 02014 fprintf(ps, 02015 " yoff rmoveto %% Move left that much and down half font height\n"); 02016 fprintf(ps, " show newpath } def %% show the string\n\n"); 02017 02018 fprintf(ps, "/setfontsize %% set font to desired size and compute " 02019 "centering yoff\n"); 02020 fprintf(ps, " { /Helvetica findfont\n"); 02021 fprintf(ps, " exch scalefont\n"); 02022 fprintf(ps, " setfont %% Font size set ...\n\n"); 02023 fprintf(ps, " 0 0 moveto %% Get vertical centering offset\n"); 02024 fprintf(ps, " (Xg) true charpath\n"); 02025 fprintf(ps, " flattenpath pathbbox\n"); 02026 fprintf(ps, " /ascent exch def pop -1 mul /descent exch def pop\n"); 02027 fprintf(ps, " newpath\n"); 02028 fprintf(ps, " descent ascent sub 2 div /yoff exch def } def\n\n"); 02029 02030 fprintf(ps, "%% Next two lines for debugging only.\n"); 02031 fprintf(ps, "/str 20 string def\n"); 02032 fprintf(ps, "/pnum {str cvs print ( ) print} def\n"); 02033 02034 fprintf(ps, "/drawline %% draw a line from (x2,y2) to (x1,y1)\n"); 02035 fprintf(ps, " { moveto lineto stroke } def\n\n"); 02036 02037 fprintf(ps, "/rect %% outline a rectangle \n"); 02038 fprintf(ps, " { /y2 exch def /x2 exch def /y1 exch def /x1 exch def\n"); 02039 fprintf(ps, " x1 y1 moveto\n"); 02040 fprintf(ps, " x2 y1 lineto\n"); 02041 fprintf(ps, " x2 y2 lineto\n"); 02042 fprintf(ps, " x1 y2 lineto\n"); 02043 fprintf(ps, " closepath } def\n\n"); 02044 02045 fprintf(ps, "/drawrect %% draw outline of a rectanagle\n"); 02046 fprintf(ps, " { rect stroke } def\n\n"); 02047 02048 fprintf(ps, "/fillrect %% fill in a rectanagle\n"); 02049 fprintf(ps, " { rect fill } def\n\n"); 02050 02051 fprintf(ps, "/drawarc { arc stroke } def %% draw an arc\n"); 02052 fprintf(ps, "/drawarcn { arcn stroke } def " 02053 " %% draw an arc in the opposite direction\n\n"); 02054 02055 fprintf(ps, "%%Fill a counterclockwise or clockwise arc sector, " 02056 "respectively.\n"); 02057 fprintf(ps, 02058 "/fillarc { moveto currentpoint 5 2 roll arc closepath fill } " 02059 "def\n"); 02060 fprintf(ps, 02061 "/fillarcn { moveto currentpoint 5 2 roll arcn closepath fill } " 02062 "def\n\n"); 02063 02064 fprintf(ps, 02065 "/fillpoly { 3 1 roll moveto %% move to first point\n" 02066 " 2 exch 1 exch {pop lineto} for %% line to all other points\n" 02067 " closepath fill } def\n\n"); 02068 02069 02070 fprintf(ps, "%%Color Definitions:\n"); 02071 fprintf(ps, "/white { 1 setgray } def\n"); 02072 fprintf(ps, "/black { 0 setgray } def\n"); 02073 fprintf(ps, "/grey55 { .55 setgray } def\n"); 02074 fprintf(ps, "/grey75 { .75 setgray } def\n"); 02075 fprintf(ps, "/blue { 0 0 1 setrgbcolor } def\n"); 02076 fprintf(ps, "/green { 0 1 0 setrgbcolor } def\n"); 02077 fprintf(ps, "/yellow { 1 1 0 setrgbcolor } def\n"); 02078 fprintf(ps, "/cyan { 0 1 1 setrgbcolor } def\n"); 02079 fprintf(ps, "/red { 1 0 0 setrgbcolor } def\n"); 02080 fprintf(ps, "/darkgreen { 0 0.5 0 setrgbcolor } def\n"); 02081 fprintf(ps, "/magenta { 1 0 1 setrgbcolor } def\n"); 02082 fprintf(ps, "/bisque { 1 0.9 0.8 setrgbcolor } def\n"); 02083 fprintf(ps, "/lightblue { 0.7 0.8 0.9 setrgbcolor } def\n"); 02084 fprintf(ps, "/thistle { 0.8 0.7 0.8 setrgbcolor } def\n"); 02085 fprintf(ps, "/plum {0.8 0.6 0.8 setrgbcolor } def\n"); 02086 fprintf(ps, "/khaki { 1 0.9 0.6 setrgbcolor } def\n"); 02087 fprintf(ps, "/coral { 1 0.7 0.6 setrgbcolor } def\n"); 02088 fprintf(ps, "/turquoise { 0.5 0.6 0.9 setrgbcolor } def\n"); 02089 fprintf(ps, "/mediumpurple { 0.7 0.6 0.7 setrgbcolor } def\n"); 02090 fprintf(ps, "/darkslateblue { 0.7 0.5 0.7 setrgbcolor } def\n"); 02091 fprintf(ps, "/darkkhaki { 0.9 0.7 0.4 setrgbcolor } def\n"); 02092 02093 fprintf(ps, "\n%%Solid and dashed line definitions:\n"); 02094 fprintf(ps, "/linesolid {[] 0 setdash} def\n"); 02095 fprintf(ps, "/linedashed {[3 3] 0 setdash} def\n"); 02096 02097 fprintf(ps, "\n%%%%EndProlog\n"); 02098 fprintf(ps, "%%%%Page: 1 1\n\n"); 02099 02100 /* Set up PostScript graphics state to match current one. */ 02101 force_setcolor(currentcolor); 02102 force_setlinestyle(currentlinestyle); 02103 force_setlinewidth(currentlinewidth); 02104 force_setfontsize(currentfontsize); 02105 02106 /* Draw this in the bottom margin -- must do before the clippath is set */ 02107 draw_message(); 02108 02109 /* Set clipping on page. */ 02110 fprintf(ps, "%.2f %.2f %.2f %.2f rect ", ps_left, ps_bot, ps_right, 02111 ps_top); 02112 fprintf(ps, "clip newpath\n\n"); 02113 02114 return (1); 02115 }
void init_world | ( | float | xl, | |
float | yt, | |||
float | xr, | |||
float | yb | |||
) |
Definition at line 1587 of file graphics.c.
01591 { 01592 01593 /* Sets the coordinate system the user wants to draw into. */ 01594 01595 xleft = x1; 01596 xright = x2; 01597 ytop = y1; 01598 ybot = y2; 01599 01600 saved_xleft = xleft; /* Save initial world coordinates to allow full */ 01601 saved_xright = xright; /* view button to zoom all the way out. */ 01602 saved_ytop = ytop; 01603 saved_ybot = ybot; 01604 01605 if(disp_type == SCREEN) 01606 { 01607 update_transform(); 01608 } 01609 else 01610 { 01611 update_ps_transform(); 01612 } 01613 }
void setcolor | ( | int | cindex | ) |
Definition at line 286 of file graphics.c.
00287 { 00288 00289 if(currentcolor != cindex) 00290 force_setcolor(cindex); 00291 }
void setfontsize | ( | int | pointsize | ) |
Definition at line 394 of file graphics.c.
00395 { 00396 /* For efficiency, this routine doesn't do anything if no change is * 00397 * implied. If you want to force the graphics context or PS file * 00398 * to have font info set, call force_setfontsize (this is necessary * 00399 * in initialization and X11 / Postscript switches). */ 00400 00401 if(pointsize != currentfontsize) 00402 force_setfontsize(pointsize); 00403 }
void setlinestyle | ( | int | linestyle | ) |
Definition at line 320 of file graphics.c.
00321 { 00322 00323 if(linestyle != currentlinestyle) 00324 force_setlinestyle(linestyle); 00325 }
void setlinewidth | ( | int | linewidth | ) |
Definition at line 352 of file graphics.c.
00353 { 00354 00355 if(linewidth != currentlinewidth) 00356 force_setlinewidth(linewidth); 00357 }
void update_message | ( | char * | msg | ) |
Definition at line 1659 of file graphics.c.
01660 { 01661 01662 /* Changes the message to be displayed on screen. */ 01663 01664 my_strncpy(message, msg, BUFSIZE); 01665 draw_message(); 01666 }