VPR-6.0
|
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 | drawtext (float xc, float yc, const char *text, float boundx) |
void | clearscreen (void) |
int | init_postscript (char *fname) |
void | close_postscript (void) |
void | setcolor (int cindex) |
int | getcolor () |
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 | create_button (char *prev_button_text, char *button_text, void(*button_func)(void(*drawscreen)(void))) |
void | destroy_button (char *button_text) |
#define MAXPTS 100 |
Maximum number of points drawable by fillpoly
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 | ) |
Erases the screen
Definition at line 1196 of file graphics.c.
{ int savecolor; if(disp_type == SCREEN) { XClearWindow(display, toplevel); } else { /* erases current page. Don't use erasepage, since this will erase * * everything, (even stuff outside the clipping path) causing * * problems if this picture is incorporated into a larger document. */ savecolor = currentcolor; setcolor(WHITE); fprintf(ps, "clippath fill\n\n"); setcolor(savecolor); } }
void close_graphics | ( | void | ) |
Closes X display
Release all my drawing structures (through the X server) and close down the connection.
Definition at line 1924 of file graphics.c.
{ int i; for(i = 1; i <= MAX_FONT_SIZE; i++) if(font_is_loaded[i]) XFreeFont(display, font_info[i]); XFreeGC(display, gc); XFreeGC(display, gcxor); XFreeGC(display, gc_menus); if(private_cmap != None) XFreeColormap(display, private_cmap); XCloseDisplay(display); free(button); }
void close_postscript | ( | void | ) |
Closes file and directs output to screen again.
Properly ends postscript output and redirects output to screen.
Definition at line 2081 of file graphics.c.
{ fprintf(ps, "showpage\n"); fprintf(ps, "\n%%%%Trailer\n"); fclose(ps); disp_type = SCREEN; update_transform(); /* Ensure screen world reflects any changes * * made while printing. */ /* Need to make sure that we really set up the graphics context -- * * don't want the change requested to match the current setting and * * do nothing -> force the changes. */ force_setcolor(currentcolor); force_setlinestyle(currentlinestyle); force_setlinewidth(currentlinewidth); force_setfontsize(currentfontsize); }
void create_button | ( | char * | prev_button_text, |
char * | button_text, | ||
void(*)(void(*drawscreen)(void)) | button_func | ||
) |
Creates a new button below the button containing prev_button_text. The text and button function are set according to button_text and button_func, respectively.
Definition at line 590 of file graphics.c.
{ int i, bnum, space; space = 8; /* Only allow new buttons that are text (not poly) types. */ bnum = -1; for(i = 4; i < num_buttons; i++) { if(button[i].istext == 1 && strcmp(button[i].text, prev_button_text) == 0) { bnum = i + 1; break; } } if(bnum == -1) { printf ("Error in create_button: button with text %s not found.\n", prev_button_text); exit(1); } num_buttons++; button = (t_button *) my_realloc(button, num_buttons * sizeof(t_button)); /* NB: Requirement that you specify the button that this button goes under * * guarantees that button[num_buttons-2] exists and is a text button. */ button[num_buttons - 1].xleft = button[num_buttons - 2].xleft; button[num_buttons - 1].ytop = button[num_buttons - 2].ytop + button[num_buttons - 2].height + space; button[num_buttons - 1].height = button[num_buttons - 2].height; button[num_buttons - 1].width = button[num_buttons - 2].width; map_button(num_buttons - 1); for(i = num_buttons - 1; i > bnum; i--) { button[i].ispoly = button[i - 1].ispoly; /* No poly copy for now, as I'm only providing the ability to create text * * buttons. */ button[i].istext = button[i - 1].istext; strcpy(button[i].text, button[i - 1].text); button[i].fcn = button[i - 1].fcn; button[i].ispressed = button[i - 1].ispressed; } button[bnum].istext = 1; button[bnum].ispoly = 0; my_strncpy(button[bnum].text, button_text, BUTTON_TEXT_LEN); button[bnum].fcn = button_func; button[bnum].ispressed = 1; }
void destroy_button | ( | char * | button_text | ) |
Destroys the button with text button_text.
Definition at line 655 of file graphics.c.
{ int i, bnum; bnum = -1; for(i = 4; i < num_buttons; i++) { if(button[i].istext == 1 && strcmp(button[i].text, button_text) == 0) { bnum = i; break; } } if(bnum == -1) { printf ("Error in destroy_button: button with text %s not found.\n", button_text); exit(1); } for(i = bnum + 1; i < num_buttons; i++) { button[i - 1].ispoly = button[i].ispoly; /* No poly copy for now, as I'm only providing the ability to create text * * buttons. */ button[i - 1].istext = button[i].istext; strcpy(button[i - 1].text, button[i].text); button[i - 1].fcn = button[i].fcn; button[i - 1].ispressed = button[i].ispressed; } unmap_button(num_buttons - 1); num_buttons--; button = (t_button *) my_realloc(button, num_buttons * sizeof(t_button)); }
void draw_message | ( | void | ) |
Normal users shouldn't have to use draw_message. Should only be useful if using non-interactive graphics and you want to redraw yourself because of an expose.
Draw the current message in the text area at the screen bottom.
Definition at line 1597 of file graphics.c.
{ int len, width, savefontsize, savecolor; float ylow; if(disp_type == SCREEN) { XClearWindow(display, textarea); len = strlen(message); width = XTextWidth(font_info[menu_font_size], message, len); XSetForeground(display, gc_menus, colors[BLACK]); XDrawString(display, textarea, gc_menus, (top_width - MWIDTH - width) / 2, (T_AREA_HEIGHT - 4) / 2 + (font_info[menu_font_size]->ascent - font_info[menu_font_size]->descent) / 2, message, len); } else { /* Draw the message in the bottom margin. Printer's generally can't * * print on the bottom 1/4" (area with y < 18 in PostScript coords.) */ savecolor = currentcolor; setcolor(BLACK); savefontsize = currentfontsize; setfontsize(menu_font_size - 2); /* Smaller OK on paper */ ylow = ps_bot - 8.; fprintf(ps, "(%s) %.2f %.2f censhow\n", message, (ps_left + ps_right) / 2., ylow); setcolor(savecolor); setfontsize(savefontsize); } }
void drawarc | ( | float | xc, |
float | yc, | ||
float | rad, | ||
float | startang, | ||
float | angextent | ||
) |
Draws a circular arc. X11 can do elliptical arcs quite simply, and PostScript could do them by scaling the coordinate axes. Too much work for now, and probably too complex an object for users to draw much, so I'm just doing circular arcs. Startang is relative to the Window's positive x direction. Angles in degrees.
Definition at line 1370 of file graphics.c.
{ int xl, yt; unsigned int width, height; /* Conservative (but fast) clip test -- check containing rectangle of * * a circle. */ if(rect_off_screen(xc - rad, yc - rad, xc + rad, yc + rad)) return; /* X Windows has trouble with very large angles. (Over 360). * * Do following to prevent its inaccurate (overflow?) problems. */ if(fabs(angextent) > 360.) angextent = 360.; startang = angnorm(startang); if(disp_type == SCREEN) { xl = (int)(xcoord(xc) - fabs(xmult * rad)); yt = (int)(ycoord(yc) - fabs(ymult * rad)); width = (unsigned int)(2 * fabs(xmult * rad)); height = width; XDrawArc(display, toplevel, gc, xl, yt, width, height, (int)(startang * 64), (int)(angextent * 64)); } else { fprintf(ps, "%.2f %.2f %.2f %.2f %.2f %s stroke\n", XPOST(xc), YPOST(yc), fabs(rad * ps_xmult), startang, startang + angextent, (angextent < 0) ? "drawarcn" : "drawarc"); } }
void drawline | ( | float | x1, |
float | y1, | ||
float | x2, | ||
float | y2 | ||
) |
Draw a line from (x1,y1) to (x2,y2) in the user-drawable area. Coordinates are in world (user) space.
Definition at line 1255 of file graphics.c.
{ if(rect_off_screen(x1, y1, x2, y2)) return; if(disp_type == SCREEN) { /* Xlib.h prototype has x2 and y1 mixed up. */ XDrawLine(display, toplevel, gc, xcoord(x1), ycoord(y1), xcoord(x2), ycoord(y2)); } else { fprintf(ps, "%.2f %.2f %.2f %.2f drawline\n", XPOST(x1), YPOST(y1), XPOST(x2), YPOST(y2)); } }
void drawrect | ( | float | x1, |
float | y1, | ||
float | x2, | ||
float | y2 | ||
) |
(x1,y1) and (x2,y2) are diagonally opposed corners, in world coords.
Definition at line 1278 of file graphics.c.
{ unsigned int width, height; int xw1, yw1, xw2, yw2, xl, yt; if(rect_off_screen(x1, y1, x2, y2)) return; if(disp_type == SCREEN) { /* translate to X Windows calling convention. */ xw1 = xcoord(x1); xw2 = xcoord(x2); yw1 = ycoord(y1); yw2 = ycoord(y2); xl = min(xw1, xw2); yt = min(yw1, yw2); width = abs(xw1 - xw2); height = abs(yw1 - yw2); XDrawRectangle(display, toplevel, gc, xl, yt, width, height); } else { fprintf(ps, "%.2f %.2f %.2f %.2f drawrect\n", XPOST(x1), YPOST(y1), XPOST(x2), YPOST(y2)); } }
void drawtext | ( | float | xc, |
float | yc, | ||
const char * | text, | ||
float | boundx | ||
) |
boundx specifies horizontal bounding box. If text won't fit in the space specified by boundx (world coordinates) text isn't drawn
Draws text centered on xc,yc if it fits in boundx
Definition at line 1517 of file graphics.c.
{ int len, width, xw_off, yw_off; len = strlen(text); width = XTextWidth(font_info[currentfontsize], text, len); if(width > fabs(boundx * xmult)) return; /* Don't draw if it won't fit */ xw_off = width / (2. * xmult); /* NB: sign doesn't matter. */ /* NB: 2 * descent makes this slightly conservative but simplifies code. */ yw_off = (font_info[currentfontsize]->ascent + 2 * font_info[currentfontsize]->descent) / (2. * ymult); /* Note: text can be clipped when a little bit of it would be visible * * right now. Perhaps X doesn't return extremely accurate width and * * ascent values, etc? Could remove this completely by multiplying * * xw_off and yw_off by, 1.2 or 1.5. */ if(rect_off_screen(xc - xw_off, yc - yw_off, xc + xw_off, yc + yw_off)) return; if(disp_type == SCREEN) { XDrawString(display, toplevel, gc, xcoord(xc) - width / 2, ycoord(yc) + (font_info[currentfontsize]->ascent - font_info[currentfontsize]->descent) / 2, text, len); } else { fprintf(ps, "(%s) %.2f %.2f censhow\n", text, XPOST(xc), YPOST(yc)); } }
void event_loop | ( | void(*)(float x, float y) | act_on_button, |
void(*)(void) | drawscreen | ||
) |
Routine for X Windows Input. act_on_button responds to buttons being pressed in the graphics area. drawscreen is the user's routine that can redraw all the graphics.
The program's main event loop. Must be passed a user routine drawscreen which redraws the screen. It handles all window resizing zooming etc. itself. If the user clicks a button in the graphics (toplevel) area, the act_on_button routine passed in is called.
Definition at line 1115 of file graphics.c.
{ XEvent report; int bnum; float x, y; #define OFF 1 #define ON 0 turn_on_off(ON); while(1) { XNextEvent(display, &report); switch (report.type) { case Expose: #ifdef VERBOSE printf("Got an expose event.\n"); printf("Count is: %d.\n", report.xexpose.count); printf("Window ID is: %d.\n", report.xexpose.window); #endif if(report.xexpose.count != 0) break; if(report.xexpose.window == menu) drawmenu(); else if(report.xexpose.window == toplevel) drawscreen(); else if(report.xexpose.window == textarea) draw_message(); break; case ConfigureNotify: top_width = report.xconfigure.width; top_height = report.xconfigure.height; update_transform(); #ifdef VERBOSE printf("Got a ConfigureNotify.\n"); printf("New width: %d New height: %d.\n", top_width, top_height); #endif break; case ButtonPress: #ifdef VERBOSE printf("Got a buttonpress.\n"); printf("Window ID is: %d.\n", report.xbutton.window); #endif if(report.xbutton.window == toplevel) { x = XTOWORLD(report.xbutton.x); y = YTOWORLD(report.xbutton.y); act_on_button(x, y); } else { /* A menu button was pressed. */ bnum = which_button(report.xbutton.window); #ifdef VERBOSE printf("Button number is %d\n", bnum); #endif button[bnum].ispressed = 1; drawbut(bnum); XFlush(display); /* Flash the button */ button[bnum].fcn(drawscreen); button[bnum].ispressed = 0; drawbut(bnum); if(button[bnum].fcn == proceed) { turn_on_off(OFF); flushinput(); return; /* Rather clumsy way of returning * * control to the simulator */ } } break; } } }
void fillarc | ( | float | xc, |
float | yc, | ||
float | rad, | ||
float | startang, | ||
float | angextent | ||
) |
Fills a circular arc. Startang is relative to the Window's positive x direction. Angles in degrees.
Definition at line 1415 of file graphics.c.
{ int xl, yt; unsigned int width, height; /* Conservative (but fast) clip test -- check containing rectangle of * * a circle. */ if(rect_off_screen(xc - rad, yc - rad, xc + rad, yc + rad)) return; /* X Windows has trouble with very large angles. (Over 360). * * Do following to prevent its inaccurate (overflow?) problems. */ if(fabs(angextent) > 360.) angextent = 360.; startang = angnorm(startang); if(disp_type == SCREEN) { xl = (int)(xcoord(xc) - fabs(xmult * rad)); yt = (int)(ycoord(yc) - fabs(ymult * rad)); width = (unsigned int)(2 * fabs(xmult * rad)); height = width; XFillArc(display, toplevel, gc, xl, yt, width, height, (int)(startang * 64), (int)(angextent * 64)); } else { fprintf(ps, "%.2f %.2f %.2f %.2f %.2f %s\n", fabs(rad * ps_xmult), startang, startang + angextent, XPOST(xc), YPOST(yc), (angextent < 0) ? "fillarcn" : "fillarc"); } }
void fillpoly | ( | t_point * | points, |
int | npoints | ||
) |
Use a constant from clist
Definition at line 1458 of file graphics.c.
{ XPoint transpoints[MAXPTS]; int i; float xmin, ymin, xmax, ymax; if(npoints > MAXPTS) { printf ("Error in fillpoly: Only %d points allowed per polygon.\n", MAXPTS); printf("%d points were requested. Polygon is not drawn.\n", npoints); return; } /* Conservative (but fast) clip test -- check containing rectangle of * * polygon. */ xmin = xmax = points[0].x; ymin = ymax = points[0].y; for(i = 1; i < npoints; i++) { xmin = min(xmin, points[i].x); xmax = max(xmax, points[i].x); ymin = min(ymin, points[i].y); ymax = max(ymax, points[i].y); } if(rect_off_screen(xmin, ymin, xmax, ymax)) return; if(disp_type == SCREEN) { for(i = 0; i < npoints; i++) { transpoints[i].x = (short)xcoord(points[i].x); transpoints[i].y = (short)ycoord(points[i].y); } XFillPolygon(display, toplevel, gc, transpoints, npoints, Complex, CoordModeOrigin); } else { fprintf(ps, "\n"); for(i = npoints - 1; i >= 0; i--) fprintf(ps, "%.2f %.2f\n", XPOST(points[i].x), YPOST(points[i].y)); fprintf(ps, "%d fillpoly\n", npoints); } }
void fillrect | ( | float | x1, |
float | y1, | ||
float | x2, | ||
float | y2 | ||
) |
(x1,y1) and (x2,y2) are diagonally opposed corners in world coords.
Definition at line 1312 of file graphics.c.
{ unsigned int width, height; int xw1, yw1, xw2, yw2, xl, yt; if(rect_off_screen(x1, y1, x2, y2)) return; if(disp_type == SCREEN) { /* translate to X Windows calling convention. */ xw1 = xcoord(x1); xw2 = xcoord(x2); yw1 = ycoord(y1); yw2 = ycoord(y2); xl = min(xw1, xw2); yt = min(yw1, yw2); width = abs(xw1 - xw2); height = abs(yw1 - yw2); XFillRectangle(display, toplevel, gc, xl, yt, width, height); } else { fprintf(ps, "%.2f %.2f %.2f %.2f fillrect\n", XPOST(x1), YPOST(y1), XPOST(x2), YPOST(y2)); } }
void flushinput | ( | void | ) |
Empties event queue
Definition at line 1559 of file graphics.c.
int getcolor | ( | ) |
Use a constant from clist
Definition at line 300 of file graphics.c.
{ return currentcolor; }
void init_graphics | ( | char * | window_name | ) |
Initializes X display
Open the toplevel window, get the colors, 2 graphics contexts, load a font, and set up the toplevel window Calls build_default_menu to set up the default menu.
Definition at line 701 of file graphics.c.
{ char *display_name = NULL; int x, y; /* window position */ unsigned int border_width = 2; /* ignored by OpenWindows */ XTextProperty windowName; /* X Windows' names for my colours. */ char *cnames[NUM_COLOR] = { "white", "black", "grey55", "grey75", "blue", "green", "yellow", "cyan", "red", "RGBi:0.0/0.5/0.0", "magenta", "bisque", "lightblue", "thistle", "plum", "khaki", "coral", "turquoise", "mediumpurple", "darkslateblue", "darkkhaki" }; XColor exact_def; Colormap cmap; int i; unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */ XGCValues values; XEvent event; disp_type = SCREEN; /* Graphics go to screen, not ps */ for(i = 0; i <= MAX_FONT_SIZE; i++) font_is_loaded[i] = 0; /* No fonts loaded yet. */ /* connect to X server */ if((display = XOpenDisplay(display_name)) == NULL) { fprintf(stderr, "Cannot connect to X server %s\n", XDisplayName(display_name)); exit(-1); } /* get screen size from display structure macro */ screen_num = DefaultScreen(display); display_width = DisplayWidth(display, screen_num); display_height = DisplayHeight(display, screen_num); x = y = 0; top_width = 2 * display_width / 3; top_height = 4 * display_height / 5; cmap = DefaultColormap(display, screen_num); private_cmap = None; for(i = 0; i < NUM_COLOR; i++) { if(!XParseColor(display, cmap, cnames[i], &exact_def)) { fprintf(stderr, "Color name %s not in database", cnames[i]); exit(-1); } if(!XAllocColor(display, cmap, &exact_def)) { fprintf(stderr, "Couldn't allocate color %s.\n", cnames[i]); if(private_cmap == None) { fprintf(stderr, "Will try to allocate a private colourmap.\n"); fprintf(stderr, "Colours will only display correctly when your " "cursor is in the graphics window.\n" "Exit other colour applications and rerun this " "program if you don't like that.\n\n"); private_cmap = XCopyColormapAndFree(display, cmap); cmap = private_cmap; if(!XAllocColor(display, cmap, &exact_def)) { fprintf(stderr, "Couldn't allocate color %s as private.\n", cnames[i]); exit(1); } } else { fprintf(stderr, "Couldn't allocate color %s as private.\n", cnames[i]); exit(1); } } colors[i] = exact_def.pixel; } toplevel = XCreateSimpleWindow(display, RootWindow(display, screen_num), x, y, top_width, top_height, border_width, colors[BLACK], colors[WHITE]); if(private_cmap != None) XSetWindowColormap(display, toplevel, private_cmap); /* hints stuff deleted. */ XSelectInput(display, toplevel, ExposureMask | StructureNotifyMask | ButtonPressMask); /* Create default Graphics Contexts. valuemask = 0 -> use defaults. */ gc = XCreateGC(display, toplevel, valuemask, &values); gc_menus = XCreateGC(display, toplevel, valuemask, &values); /* Create XOR graphics context for Rubber Banding */ values.function = GXxor; values.foreground = colors[BLACK]; gcxor = XCreateGC(display, toplevel, (GCFunction | GCForeground), &values); /* specify font for menus. */ load_font(menu_font_size); font_is_loaded[menu_font_size] = 1; XSetFont(display, gc_menus, font_info[menu_font_size]->fid); /* Set drawing defaults for user-drawable area. Use whatever the * * initial values of the current stuff was set to. */ force_setfontsize(currentfontsize); force_setcolor(currentcolor); force_setlinestyle(currentlinestyle); force_setlinewidth(currentlinewidth); XStringListToTextProperty(&window_name, 1, &windowName); XSetWMName(display, toplevel, &windowName); /* Uncomment to set icon name */ /* XSetWMIconName (display, toplevel, &windowName); */ /* XStringListToTextProperty copies the window_name string into * * windowName.value. Free this memory now. */ free(windowName.value); XMapWindow(display, toplevel); build_textarea(); build_default_menu(); /* The following is completely unnecessary if the user is using the * * interactive (event_loop) graphics. It waits for the first Expose * * event before returning so that I can tell the window manager has got * * the top-level window up and running. Thus the user can start drawing * * into this window immediately, and there's no danger of the window not * * being ready and output being lost. */ XPeekIfEvent(display, &event, test_if_exposed, NULL); }
int init_postscript | ( | char * | fname | ) |
Opens file for postscript commands and initializes it. All subsequent drawing commands go to this file until close_postscript is called. Returns 1 if successful
Opens a file for PostScript output. The header information, clipping path, etc. are all dumped out. If the file could not be opened, the routine returns 0; otherwise it returns 1.
Definition at line 1949 of file graphics.c.
{ ps = fopen(fname, "w"); if(ps == NULL) { printf("Error: could not open %s for PostScript output.\n", fname); printf("Drawing to screen instead.\n"); return (0); } disp_type = POSTSCRIPT; /* Graphics go to postscript file now. */ /* Header for minimal conformance with the Adobe structuring convention */ fprintf(ps, "%%!PS-Adobe-1.0\n"); fprintf(ps, "%%%%DocumentFonts: Helvetica\n"); fprintf(ps, "%%%%Pages: 1\n"); /* Set up postscript transformation macros and page boundaries */ update_ps_transform(); /* Bottom margin is at ps_bot - 15. to leave room for the on-screen message. */ fprintf(ps, "%%%%BoundingBox: %d %d %d %d\n", (int)ps_left, (int)(ps_bot - 15.), (int)ps_right, (int)ps_top); fprintf(ps, "%%%%EndComments\n"); fprintf(ps, "/censhow %%draw a centered string\n"); fprintf(ps, " { moveto %% move to proper spot\n"); fprintf(ps, " dup stringwidth pop %% get x length of string\n"); fprintf(ps, " -2 div %% Proper left start\n"); fprintf(ps, " yoff rmoveto %% Move left that much and down half font height\n"); fprintf(ps, " show newpath } def %% show the string\n\n"); fprintf(ps, "/setfontsize %% set font to desired size and compute " "centering yoff\n"); fprintf(ps, " { /Helvetica findfont\n"); fprintf(ps, " exch scalefont\n"); fprintf(ps, " setfont %% Font size set ...\n\n"); fprintf(ps, " 0 0 moveto %% Get vertical centering offset\n"); fprintf(ps, " (Xg) true charpath\n"); fprintf(ps, " flattenpath pathbbox\n"); fprintf(ps, " /ascent exch def pop -1 mul /descent exch def pop\n"); fprintf(ps, " newpath\n"); fprintf(ps, " descent ascent sub 2 div /yoff exch def } def\n\n"); fprintf(ps, "%% Next two lines for debugging only.\n"); fprintf(ps, "/str 20 string def\n"); fprintf(ps, "/pnum {str cvs print ( ) print} def\n"); fprintf(ps, "/drawline %% draw a line from (x2,y2) to (x1,y1)\n"); fprintf(ps, " { moveto lineto stroke } def\n\n"); fprintf(ps, "/rect %% outline a rectangle \n"); fprintf(ps, " { /y2 exch def /x2 exch def /y1 exch def /x1 exch def\n"); fprintf(ps, " x1 y1 moveto\n"); fprintf(ps, " x2 y1 lineto\n"); fprintf(ps, " x2 y2 lineto\n"); fprintf(ps, " x1 y2 lineto\n"); fprintf(ps, " closepath } def\n\n"); fprintf(ps, "/drawrect %% draw outline of a rectanagle\n"); fprintf(ps, " { rect stroke } def\n\n"); fprintf(ps, "/fillrect %% fill in a rectanagle\n"); fprintf(ps, " { rect fill } def\n\n"); fprintf(ps, "/drawarc { arc stroke } def %% draw an arc\n"); fprintf(ps, "/drawarcn { arcn stroke } def " " %% draw an arc in the opposite direction\n\n"); fprintf(ps, "%%Fill a counterclockwise or clockwise arc sector, " "respectively.\n"); fprintf(ps, "/fillarc { moveto currentpoint 5 2 roll arc closepath fill } " "def\n"); fprintf(ps, "/fillarcn { moveto currentpoint 5 2 roll arcn closepath fill } " "def\n\n"); fprintf(ps, "/fillpoly { 3 1 roll moveto %% move to first point\n" " 2 exch 1 exch {pop lineto} for %% line to all other points\n" " closepath fill } def\n\n"); fprintf(ps, "%%Color Definitions:\n"); fprintf(ps, "/white { 1 setgray } def\n"); fprintf(ps, "/black { 0 setgray } def\n"); fprintf(ps, "/grey55 { .55 setgray } def\n"); fprintf(ps, "/grey75 { .75 setgray } def\n"); fprintf(ps, "/blue { 0 0 1 setrgbcolor } def\n"); fprintf(ps, "/green { 0 1 0 setrgbcolor } def\n"); fprintf(ps, "/yellow { 1 1 0 setrgbcolor } def\n"); fprintf(ps, "/cyan { 0 1 1 setrgbcolor } def\n"); fprintf(ps, "/red { 1 0 0 setrgbcolor } def\n"); fprintf(ps, "/darkgreen { 0 0.5 0 setrgbcolor } def\n"); fprintf(ps, "/magenta { 1 0 1 setrgbcolor } def\n"); fprintf(ps, "/bisque { 1 0.9 0.8 setrgbcolor } def\n"); fprintf(ps, "/lightblue { 0.7 0.8 0.9 setrgbcolor } def\n"); fprintf(ps, "/thistle { 0.8 0.7 0.8 setrgbcolor } def\n"); fprintf(ps, "/plum {0.8 0.6 0.8 setrgbcolor } def\n"); fprintf(ps, "/khaki { 1 0.9 0.6 setrgbcolor } def\n"); fprintf(ps, "/coral { 1 0.7 0.6 setrgbcolor } def\n"); fprintf(ps, "/turquoise { 0.5 0.6 0.9 setrgbcolor } def\n"); fprintf(ps, "/mediumpurple { 0.7 0.6 0.7 setrgbcolor } def\n"); fprintf(ps, "/darkslateblue { 0.7 0.5 0.7 setrgbcolor } def\n"); fprintf(ps, "/darkkhaki { 0.9 0.7 0.4 setrgbcolor } def\n"); fprintf(ps, "\n%%Solid and dashed line definitions:\n"); fprintf(ps, "/linesolid {[] 0 setdash} def\n"); fprintf(ps, "/linedashed {[3 3] 0 setdash} def\n"); fprintf(ps, "\n%%%%EndProlog\n"); fprintf(ps, "%%%%Page: 1 1\n\n"); /* Set up PostScript graphics state to match current one. */ force_setcolor(currentcolor); force_setlinestyle(currentlinestyle); force_setlinewidth(currentlinewidth); force_setfontsize(currentfontsize); /* Draw this in the bottom margin -- must do before the clippath is set */ draw_message(); /* Set clipping on page. */ fprintf(ps, "%.2f %.2f %.2f %.2f rect ", ps_left, ps_bot, ps_right, ps_top); fprintf(ps, "clip newpath\n\n"); return (1); }
void init_world | ( | float | x1, |
float | y1, | ||
float | x2, | ||
float | y2 | ||
) |
Sets world coordinates
Sets the coordinate system the user wants to draw into.
Definition at line 1569 of file graphics.c.
{ xleft = x1; xright = x2; ytop = y1; ybot = y2; saved_xleft = xleft; /* Save initial world coordinates to allow full */ saved_xright = xright; /* view button to zoom all the way out. */ saved_ytop = ytop; saved_ybot = ybot; if(disp_type == SCREEN) { update_transform(); } else { update_ps_transform(); } }
void setcolor | ( | int | cindex | ) |
Use a constant from clist
Definition at line 293 of file graphics.c.
{ if(currentcolor != cindex) force_setcolor(cindex); }
void setfontsize | ( | int | pointsize | ) |
For efficiency, this routine doesn't do anything if no change is implied. If you want to force the graphics context or PS file to have font info set, call force_setfontsize (this is necessary in initialization and X11 / Postscript switches).
Definition at line 410 of file graphics.c.
{ if(pointsize != currentfontsize) force_setfontsize(pointsize); }
void setlinestyle | ( | int | linestyle | ) |
Use a constant from clist
Definition at line 331 of file graphics.c.
{ if(linestyle != currentlinestyle) force_setlinestyle(linestyle); }
void setlinewidth | ( | int | linewidth | ) |
Use a constant from clist
Definition at line 363 of file graphics.c.
{ if(linewidth != currentlinewidth) force_setlinewidth(linewidth); }
void update_message | ( | char * | msg | ) |
Changes message in text area.
Changes the message to be displayed on screen.
Definition at line 1637 of file graphics.c.
{ my_strncpy(message, msg, BUFSIZE); draw_message(); }