VPR-6.0
|
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "util.h"
#include "graphics.h"
#include "vpr_types.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
Go to the source code of this file.
Data Structures | |
struct | t_button |
Defines | |
#define | max(a, b) (((a) > (b))? (a) : (b)) |
#define | min(a, b) ((a) > (b)? (b) : (a)) |
#define | MWIDTH 104 |
#define | T_AREA_HEIGHT 24 |
#define | MAX_FONT_SIZE 40 |
#define | PI 3.141592654 |
#define | BUTTON_TEXT_LEN 20 |
#define | MAXPIXEL 15000 |
#define | MINPIXEL -15000 |
#define | OFF 1 |
#define | ON 0 |
#define | XPOST(worldx) (((worldx)-xleft)*ps_xmult + ps_left) |
#define | YPOST(worldy) (((worldy)-ybot)*ps_ymult + ps_bot) |
#define | XTOWORLD(x) (((float) x)/xmult + xleft) |
#define | YTOWORLD(y) (((float) y)/ymult + ytop) |
Functions | |
static void | translate_up (void(*drawscreen)(void)) |
static void | translate_left (void(*drawscreen)(void)) |
static void | translate_right (void(*drawscreen)(void)) |
static void | translate_down (void(*drawscreen)(void)) |
static void | zoom_in (void(*drawscreen)(void)) |
static void | zoom_out (void(*drawscreen)(void)) |
static void | zoom_fit (void(*drawscreen)(void)) |
static void | adjustwin (void(*drawscreen)(void)) |
static void | postscript (void(*drawscreen)(void)) |
static void | proceed (void(*drawscreen)(void)) |
static void | quit (void(*drawscreen)(void)) |
static Bool | test_if_exposed (Display *disp, XEvent *event_ptr, XPointer dummy) |
static void | map_button (int bnum) |
static void | unmap_button (int bnum) |
static int | xcoord (float worldx) |
static int | ycoord (float worldy) |
static void | load_font (int pointsize) |
static void | force_setcolor (int cindex) |
void | setcolor (int cindex) |
int | getcolor () |
static void | force_setlinestyle (int linestyle) |
void | setlinestyle (int linestyle) |
static void | force_setlinewidth (int linewidth) |
void | setlinewidth (int linewidth) |
static void | force_setfontsize (int pointsize) |
void | setfontsize (int pointsize) |
static void | build_textarea (void) |
static void | setpoly (int bnum, int xc, int yc, int r, float theta) |
static void | build_default_menu (void) |
void | create_button (char *prev_button_text, char *button_text, void(*button_func)(void(*drawscreen)(void))) |
void | destroy_button (char *button_text) |
void | init_graphics (char *window_name) |
static void | menutext (Window win, int xc, int yc, char *text) |
static void | drawbut (int bnum) |
static void | turn_on_off (int pressed) |
static int | which_button (Window win) |
static void | drawmenu (void) |
static void | update_transform (void) |
static void | update_ps_transform (void) |
void | event_loop (void(*act_on_button)(float x, float y), void(*drawscreen)(void)) |
void | clearscreen (void) |
static int | rect_off_screen (float x1, float y1, float x2, float y2) |
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) |
static float | angnorm (float ang) |
void | drawarc (float xc, float yc, float rad, float startang, float angextent) |
void | fillarc (float xc, float yc, float rad, float startang, float angextent) |
void | fillpoly (t_point *points, int npoints) |
void | drawtext (float xc, float yc, const char *text, float boundx) |
void | flushinput (void) |
void | init_world (float x1, float y1, float x2, float y2) |
void | draw_message (void) |
void | update_message (char *msg) |
static void | update_win (int x[2], int y[2], void(*drawscreen)(void)) |
void | close_graphics (void) |
int | init_postscript (char *fname) |
void | close_postscript (void) |
Variables | |
static const int | menu_font_size = 14 |
static t_button * | button |
static int | num_buttons |
static int | disp_type |
static Display * | display |
static int | screen_num |
static GC | gc |
static GC | gcxor |
static GC | gc_menus |
static XFontStruct * | font_info [MAX_FONT_SIZE+1] |
static int | font_is_loaded [MAX_FONT_SIZE+1] |
static unsigned int | display_width |
static unsigned int | display_height |
static unsigned int | top_width |
static unsigned int | top_height |
static Window | toplevel |
static Window | menu |
static Window | textarea |
static float | xleft |
static float | xright |
static float | ytop |
static float | ybot |
static float | saved_xleft |
static float | saved_xright |
static float | saved_ytop |
static float | saved_ybot |
static float | ps_left |
static float | ps_right |
static float | ps_top |
static float | ps_bot |
static float | ps_xmult |
static float | ps_ymult |
static float | xmult |
static float | ymult |
static Colormap | private_cmap |
static char | message [BUFSIZE] = "\0" |
static int | colors [NUM_COLOR] |
static FILE * | ps |
static int | currentcolor = BLACK |
static int | currentlinestyle = SOLID |
static int | currentlinewidth = 0 |
static int | currentfontsize = 10 |
Written by Vaughn Betz at the University of Toronto, Department of Electrical and Computer Engineering. Graphics package Version 1.3. All rights reserved by U of T, etc.
You may freely use this graphics interface for non-commercial purposes as long as you leave the written by Vaughn Betz message in it -- who knows, maybe someday an employer will see it and give me a job or large sums of money :).
Revision History:
Sept. 19, 1997: Incorporated Zoom Fit code of Haneef Mohammed at Cypress. Makes it easy to zoom to a full view of the graphics.
Sept. 11, 1997: Added the create_button and delete_button interface to make it easy to add and destroy buttons from user code. Removed the bnum parameter to the button functions, since it wasn't really needed.
June 28, 1997: Added filled arc drawing primitive. Minor modifications to PostScript driver to make the PostScript output slightly smaller.
April 15, 1997: Added code to init_graphics so it waits for a window to be exposed before returning. This ensures that users of non- interactive graphics can never draw to a window before it is available.
Feb. 24, 1997: Added code so the package will allocate a private colormap if the default colormap doesn't have enough free colours.
June 28, 1996: Converted all internal functions in graphics.c to have internal (static) linkage to avoid any conflicts with user routines in the rest of the program.
June 12, 1996: Added setfontsize and setlinewidth attributes. Added pre-clipping of objects for speed (and compactness of PS output) when graphics are zoomed in. Rewrote PostScript engine to shrink the output and make it easier to read. Made drawscreen a callback function passed in rather than a global. Graphics attribute calls are more efficient -- they check if they have to change anything before doing it.
October 27, 1995: Added the message area, a callback function for interacting with user button clicks, and implemented a workaround for a Sun X Server bug that misdisplays extremely highly zoomed graphics.
Jan. 13, 1995: Modified to incorporate PostScript Support.
Definition in file graphics.c.
#define BUTTON_TEXT_LEN 20 |
Definition at line 101 of file graphics.c.
#define max | ( | a, | |
b | |||
) | (((a) > (b))? (a) : (b)) |
Definition at line 93 of file graphics.c.
#define MAX_FONT_SIZE 40 |
Largest point size of text
Definition at line 98 of file graphics.c.
#define MAXPIXEL 15000 |
MAXPIXEL and MINPIXEL are set to prevent what appears to be overflow with very large pixel values on the Sun X Server.
Definition at line 167 of file graphics.c.
#define min | ( | a, | |
b | |||
) | ((a) > (b)? (b) : (a)) |
Definition at line 94 of file graphics.c.
#define MINPIXEL -15000 |
Definition at line 168 of file graphics.c.
#define MWIDTH 104 |
width of menu window
Definition at line 96 of file graphics.c.
#define OFF 1 |
#define ON 0 |
#define PI 3.141592654 |
Definition at line 99 of file graphics.c.
#define T_AREA_HEIGHT 24 |
Height of text window
Definition at line 97 of file graphics.c.
Macros for translation from world to PostScript coordinates
Definition at line 80 of file graphics.c.
Macros to convert from X Windows Internal Coordinates to my World Coordinates. (This macro is used only rarely, so the divides don't hurt speed).
Definition at line 89 of file graphics.c.
Macros for translation from world to PostScript coordinates
Definition at line 81 of file graphics.c.
Macros to convert from X Windows Internal Coordinates to my World Coordinates. (This macro is used only rarely, so the divides don't hurt speed).
Definition at line 90 of file graphics.c.
static void adjustwin | ( | void(*)(void) | drawscreen | ) | [static] |
The window button was pressed. Let the user click on the two diagonally opposed corners, and zoom in on this area.
Definition at line 1787 of file graphics.c.
{ XEvent report; int corner, xold, yold, x[2], y[2]; corner = 0; xold = -1; yold = -1; /* Don't need to init yold, but stops compiler warning. */ while(corner < 2) { 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(); xold = -1; /* No rubber band on screen */ } 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); printf("Location (%d, %d).\n", report.xbutton.x, report.xbutton.y); #endif if(report.xbutton.window != toplevel) break; x[corner] = report.xbutton.x; y[corner] = report.xbutton.y; if(corner == 0) { XSelectInput(display, toplevel, ExposureMask | StructureNotifyMask | ButtonPressMask | PointerMotionMask); } else { update_win(x, y, drawscreen); } corner++; break; case MotionNotify: #ifdef VERBOSE printf("Got a MotionNotify Event.\n"); printf("x: %d y: %d\n", report.xmotion.x, report.xmotion.y); #endif if(xold >= 0) { /* xold set -ve before we draw first box */ XDrawRectangle(display, toplevel, gcxor, min(x[0], xold), min(y[0], yold), abs(x[0] - xold), abs(y[0] - yold)); } /* Don't allow user to window under menu region */ xold = min(report.xmotion.x, top_width - 1 - MWIDTH); yold = report.xmotion.y; XDrawRectangle(display, toplevel, gcxor, min(x[0], xold), min(y[0], yold), abs(x[0] - xold), abs(y[0] - yold)); break; } } XSelectInput(display, toplevel, ExposureMask | StructureNotifyMask | ButtonPressMask); }
static float angnorm | ( | float | ang | ) | [static] |
Normalizes an angle to be between 0 and 360 degrees.
Definition at line 1346 of file graphics.c.
{ int scale; if(ang < 0) { scale = (int)(ang / 360. - 1); } else { scale = (int)(ang / 360.); } ang = ang - scale * 360.; return (ang); }
static void build_default_menu | ( | void | ) | [static] |
Sets up the default menu buttons on the right hand side of the window.
Definition at line 462 of file graphics.c.
{ XSetWindowAttributes menu_attributes; unsigned long valuemask; int i, xcen, x1, y1, bwid, bheight, space; menu = XCreateSimpleWindow(display, toplevel, top_width - MWIDTH, 0, MWIDTH - 4, display_height, 2, colors[BLACK], colors[LIGHTGREY]); menu_attributes.event_mask = ExposureMask; /* Ignore button presses on the menu background. */ menu_attributes.do_not_propagate_mask = ButtonPressMask; /* Keep menu on top right */ menu_attributes.win_gravity = NorthEastGravity; valuemask = CWWinGravity | CWEventMask | CWDontPropagate; XChangeWindowAttributes(display, menu, valuemask, &menu_attributes); XMapWindow(display, menu); num_buttons = 11; button = (t_button *) my_malloc(num_buttons * sizeof(t_button)); /* Now do the arrow buttons */ bwid = 28; space = 3; y1 = 10; xcen = 51; x1 = xcen - bwid / 2; button[0].xleft = x1; button[0].ytop = y1; setpoly(0, bwid / 2, bwid / 2, bwid / 3, -PI / 2.); /* Up */ button[0].fcn = translate_up; y1 += bwid + space; x1 = xcen - 3 * bwid / 2 - space; button[1].xleft = x1; button[1].ytop = y1; setpoly(1, bwid / 2, bwid / 2, bwid / 3, PI); /* Left */ button[1].fcn = translate_left; x1 = xcen + bwid / 2 + space; button[2].xleft = x1; button[2].ytop = y1; setpoly(2, bwid / 2, bwid / 2, bwid / 3, 0); /* Right */ button[2].fcn = translate_right; y1 += bwid + space; x1 = xcen - bwid / 2; button[3].xleft = x1; button[3].ytop = y1; setpoly(3, bwid / 2, bwid / 2, bwid / 3, +PI / 2.); /* Down */ button[3].fcn = translate_down; for(i = 0; i < 4; i++) { button[i].width = bwid; button[i].height = bwid; } /* Rectangular buttons */ y1 += bwid + space + 6; space = 8; bwid = 90; bheight = 26; x1 = xcen - bwid / 2; for(i = 4; i < num_buttons; i++) { button[i].xleft = x1; button[i].ytop = y1; y1 += bheight + space; button[i].istext = 1; button[i].ispoly = 0; button[i].width = bwid; button[i].height = bheight; } strcpy(button[4].text, "Zoom In"); strcpy(button[5].text, "Zoom Out"); strcpy(button[6].text, "Zoom Fit"); strcpy(button[7].text, "Window"); strcpy(button[8].text, "PostScript"); strcpy(button[9].text, "Proceed"); strcpy(button[10].text, "Exit"); button[4].fcn = zoom_in; button[5].fcn = zoom_out; button[6].fcn = zoom_fit; button[7].fcn = adjustwin; button[8].fcn = postscript; button[9].fcn = proceed; button[10].fcn = quit; for(i = 0; i < num_buttons; i++) map_button(i); }
static void build_textarea | ( | void | ) | [static] |
Creates a small window at the top of the graphics area for text messages
Definition at line 419 of file graphics.c.
{ XSetWindowAttributes menu_attributes; unsigned long valuemask; textarea = XCreateSimpleWindow(display, toplevel, 0, top_height - T_AREA_HEIGHT, display_width, T_AREA_HEIGHT - 4, 2, colors[BLACK], colors[LIGHTGREY]); menu_attributes.event_mask = ExposureMask; /* ButtonPresses in this area are ignored. */ menu_attributes.do_not_propagate_mask = ButtonPressMask; /* Keep text area on bottom left */ menu_attributes.win_gravity = SouthWestGravity; valuemask = CWWinGravity | CWEventMask | CWDontPropagate; XChangeWindowAttributes(display, textarea, valuemask, &menu_attributes); XMapWindow(display, textarea); }
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 | ) |
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 | ) |
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 | ) |
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"); } }
static void drawbut | ( | int | bnum | ) | [static] |
Draws button bnum in either its pressed or unpressed state.
Definition at line 894 of file graphics.c.
{ int width, height, thick, i, ispressed; XPoint mypoly[6]; ispressed = button[bnum].ispressed; thick = 2; width = button[bnum].width; height = button[bnum].height; /* Draw top and left edges of 3D box. */ if(ispressed) { XSetForeground(display, gc_menus, colors[BLACK]); } else { XSetForeground(display, gc_menus, colors[WHITE]); } /* Note: X Windows doesn't appear to draw the bottom pixel of * * a polygon with XFillPolygon, so I make this 1 pixel thicker * * to compensate. */ mypoly[0].x = 0; mypoly[0].y = height; mypoly[1].x = 0; mypoly[1].y = 0; mypoly[2].x = width; mypoly[2].y = 0; mypoly[3].x = width - thick; mypoly[3].y = thick; mypoly[4].x = thick; mypoly[4].y = thick; mypoly[5].x = thick; mypoly[5].y = height - thick; XFillPolygon(display, button[bnum].win, gc_menus, mypoly, 6, Convex, CoordModeOrigin); /* Draw bottom and right edges of 3D box. */ if(ispressed) { XSetForeground(display, gc_menus, colors[WHITE]); } else { XSetForeground(display, gc_menus, colors[BLACK]); } mypoly[0].x = 0; mypoly[0].y = height; mypoly[1].x = width; mypoly[1].y = height; mypoly[2].x = width; mypoly[2].y = 0; mypoly[3].x = width - thick; mypoly[3].y = thick; mypoly[4].x = width - thick; mypoly[4].y = height - thick; mypoly[5].x = thick; mypoly[5].y = height - thick; XFillPolygon(display, button[bnum].win, gc_menus, mypoly, 6, Convex, CoordModeOrigin); /* Draw background */ if(ispressed) { XSetForeground(display, gc_menus, colors[DARKGREY]); } else { XSetForeground(display, gc_menus, colors[LIGHTGREY]); } /* Give x,y of top corner and width and height */ XFillRectangle(display, button[bnum].win, gc_menus, thick, thick, width - 2 * thick, height - 2 * thick); /* Draw polygon, if there is one */ if(button[bnum].ispoly) { for(i = 0; i < 3; i++) { mypoly[i].x = button[bnum].poly[i][0]; mypoly[i].y = button[bnum].poly[i][1]; } XSetForeground(display, gc_menus, colors[BLACK]); XFillPolygon(display, button[bnum].win, gc_menus, mypoly, 3, Convex, CoordModeOrigin); } /* Draw text, if there is any */ if(button[bnum].istext) { XSetForeground(display, gc_menus, colors[BLACK]); menutext(button[bnum].win, button[bnum].width / 2, button[bnum].height / 2, button[bnum].text); } }
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)); } }
static void drawmenu | ( | void | ) | [static] |
Definition at line 1025 of file graphics.c.
{ int i; for(i = 0; i < num_buttons; i++) { drawbut(i); } }
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 | ||
) |
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 | ||
) |
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 | ||
) |
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.
static void force_setcolor | ( | int | cindex | ) | [static] |
Definition at line 269 of file graphics.c.
{ static char *ps_cnames[NUM_COLOR] = { "white", "black", "grey55", "grey75", "blue", "green", "yellow", "cyan", "red", "darkgreen", "magenta", "bisque", "lightblue", "thistle", "plum", "khaki", "coral", "turquoise", "mediumpurple", "darkslateblue", "darkkhaki" }; currentcolor = cindex; if(disp_type == SCREEN) { XSetForeground(display, gc, colors[cindex]); } else { fprintf(ps, "%s\n", ps_cnames[cindex]); } }
static void force_setfontsize | ( | int | pointsize | ) | [static] |
Definition at line 372 of file graphics.c.
{ /* Valid point sizes are between 1 and MAX_FONT_SIZE */ if(pointsize < 1) pointsize = 1; else if(pointsize > MAX_FONT_SIZE) pointsize = MAX_FONT_SIZE; currentfontsize = pointsize; if(disp_type == SCREEN) { if(!font_is_loaded[pointsize]) { load_font(pointsize); font_is_loaded[pointsize] = 1; } XSetFont(display, gc, font_info[pointsize]->fid); } else { /* PostScript: set up font and centering function */ fprintf(ps, "%d setfontsize\n", pointsize); } }
static void force_setlinestyle | ( | int | linestyle | ) | [static] |
Definition at line 306 of file graphics.c.
{ /* Note SOLID is 0 and DASHED is 1 for linestyle. */ /* PostScript and X commands needed, respectively. */ static char *ps_text[2] = { "linesolid", "linedashed" }; static int x_vals[2] = { LineSolid, LineOnOffDash }; currentlinestyle = linestyle; if(disp_type == SCREEN) { XSetLineAttributes(display, gc, currentlinewidth, x_vals[linestyle], CapButt, JoinMiter); } else { fprintf(ps, "%s\n", ps_text[linestyle]); } }
static void force_setlinewidth | ( | int | linewidth | ) | [static] |
Definition at line 340 of file graphics.c.
{ /* linewidth should be greater than or equal to 0 to make any sense. */ /* Note SOLID is 0 and DASHED is 1 for linestyle. */ static int x_vals[2] = { LineSolid, LineOnOffDash }; currentlinewidth = linewidth; if(disp_type == SCREEN) { XSetLineAttributes(display, gc, linewidth, x_vals[currentlinestyle], CapButt, JoinMiter); } else { fprintf(ps, "%d setlinewidth\n", linewidth); } }
int getcolor | ( | ) |
Definition at line 300 of file graphics.c.
{ return currentcolor; }
void init_graphics | ( | char * | window_name | ) |
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 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 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(); } }
static void load_font | ( | int | pointsize | ) | [static] |
Makes sure the font of the specified size is loaded. Point_size MUST be between 1 and MAX_FONT_SIZE -- no check is performed here. Use proper point-size medium-weight upright helvetica font
Definition at line 246 of file graphics.c.
{ char fontname[44]; sprintf(fontname, "-*-helvetica-medium-r-*--*-%d0-*-*-*-*-*-*", pointsize); #ifdef VERBOSE printf("Loading font: point size: %d, fontname: %s\n", pointsize, fontname); #endif /* Load font and get font information structure. */ if((font_info[pointsize] = XLoadQueryFont(display, fontname)) == NULL) { fprintf(stderr, "Cannot open desired font\n"); exit(-1); } }
static void map_button | ( | int | bnum | ) | [static] |
Maps a button onto the screen and set it up for input, etc.
Definition at line 563 of file graphics.c.
{ button[bnum].win = XCreateSimpleWindow(display, menu, button[bnum].xleft, button[bnum].ytop, button[bnum].width, button[bnum].height, 0, colors[WHITE], colors[LIGHTGREY]); XMapWindow(display, button[bnum].win); XSelectInput(display, button[bnum].win, ButtonPressMask); button[bnum].ispressed = 1; }
static void menutext | ( | Window | win, |
int | xc, | ||
int | yc, | ||
char * | text | ||
) | [static] |
draws text center at xc, yc -- used only by menu drawing stuff
Definition at line 877 of file graphics.c.
{ int len, width; len = strlen(text); width = XTextWidth(font_info[menu_font_size], text, len); XDrawString(display, win, gc_menus, xc - width / 2, yc + (font_info[menu_font_size]->ascent - font_info[menu_font_size]->descent) / 2, text, len); }
static void postscript | ( | void(*)(void) | drawscreen | ) | [static] |
Takes a snapshot of the screen and stores it in pic?.ps. The first picture goes in pic1.ps, the second in pic2.ps, etc.
Definition at line 1883 of file graphics.c.
{ static int piccount = 1; int success; char fname[20]; sprintf(fname, "pic%d.ps", piccount); success = init_postscript(fname); if(success == 0) return; /* Couldn't open file, abort. */ drawscreen(); close_postscript(); piccount++; }
static void proceed | ( | void(*)(void) | drawscreen | ) | [static] |
Dummy routine. Just exit the event loop.
Definition at line 1903 of file graphics.c.
{
/* Dummy routine. Just exit the event loop. */
}
static void quit | ( | void(*)(void) | drawscreen | ) | [static] |
Definition at line 1912 of file graphics.c.
{ close_graphics(); exit(0); }
static int rect_off_screen | ( | float | x1, |
float | y1, | ||
float | x2, | ||
float | y2 | ||
) | [static] |
Return 1 if I can quarantee no part of this rectangle will lie within the user drawing area. Otherwise return 0. Note: this routine is only used to help speed (and to shrink ps files) -- it will be highly effective when the graphics are zoomed in and lots are off-screen. I don't have to pre-clip for correctness.
Definition at line 1224 of file graphics.c.
{ float xmin, xmax, ymin, ymax; xmin = min(xleft, xright); if(x1 < xmin && x2 < xmin) return (1); xmax = max(xleft, xright); if(x1 > xmax && x2 > xmax) return (1); ymin = min(ytop, ybot); if(y1 < ymin && y2 < ymin) return (1); ymax = max(ytop, ybot); if(y1 > ymax && y2 > ymax) return (1); return (0); }
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 | ) |
Definition at line 331 of file graphics.c.
{ if(linestyle != currentlinestyle) force_setlinestyle(linestyle); }
void setlinewidth | ( | int | linewidth | ) |
Definition at line 363 of file graphics.c.
{ if(linewidth != currentlinewidth) force_setlinewidth(linewidth); }
static void setpoly | ( | int | bnum, |
int | xc, | ||
int | yc, | ||
int | r, | ||
float | theta | ||
) | [static] |
Puts a triangle in the poly array for button[bnum]
Definition at line 441 of file graphics.c.
{ int i; button[bnum].istext = 0; button[bnum].ispoly = 1; for(i = 0; i < 3; i++) { button[bnum].poly[i][0] = (int)(xc + r * cos(theta) + 0.5); button[bnum].poly[i][1] = (int)(yc + r * sin(theta) + 0.5); theta += 2 * PI / 3; } }
static Bool test_if_exposed | ( | Display * | disp, |
XEvent * | event_ptr, | ||
XPointer | dummy | ||
) | [static] |
Returns True if the event passed in is an exposure event. Note that the bool type returned by this function is defined in Xlib.h.
Definition at line 861 of file graphics.c.
{ if(event_ptr->type == Expose) { return (True); } return (False); }
static void translate_down | ( | void(*)(void) | drawscreen | ) | [static] |
Moves view 1/2 screen down.
Definition at line 1713 of file graphics.c.
{ float ystep; ystep = (ybot - ytop) / 2.; ytop += ystep; ybot += ystep; update_transform(); drawscreen(); }
static void translate_left | ( | void(*)(void) | drawscreen | ) | [static] |
Moves view 1/2 screen left.
Definition at line 1727 of file graphics.c.
{ float xstep; xstep = (xright - xleft) / 2.; xleft -= xstep; xright -= xstep; update_transform(); drawscreen(); }
static void translate_right | ( | void(*)(void) | drawscreen | ) | [static] |
Moves view 1/2 screen right.
Definition at line 1741 of file graphics.c.
{ float xstep; xstep = (xright - xleft) / 2.; xleft += xstep; xright += xstep; update_transform(); drawscreen(); }
static void translate_up | ( | void(*)(void) | drawscreen | ) | [static] |
Moves view 1/2 screen up.
Definition at line 1699 of file graphics.c.
{ float ystep; ystep = (ybot - ytop) / 2.; ytop -= ystep; ybot -= ystep; update_transform(); drawscreen(); }
static void turn_on_off | ( | int | pressed | ) | [static] |
Shows when the menu is active or inactive by colouring the buttons.
Definition at line 996 of file graphics.c.
{ int i; for(i = 0; i < num_buttons; i++) { button[i].ispressed = pressed; drawbut(i); } }
static void unmap_button | ( | int | bnum | ) | [static] |
Unmaps a button from the screen.
Definition at line 579 of file graphics.c.
void update_message | ( | char * | msg | ) |
Changes the message to be displayed on screen.
Definition at line 1637 of file graphics.c.
{ my_strncpy(message, msg, BUFSIZE); draw_message(); }
static void update_ps_transform | ( | void | ) | [static] |
Postscript coordinates start at (0,0) for the lower left hand corner of the page and increase upwards and to the right. For 8.5 x 11 sheet, coordinates go from (0,0) to (612,792). Spacing is 1/72 inch. I'm leaving a minimum of half an inch (36 units) of border around each edge.
Definition at line 1076 of file graphics.c.
{ float ps_width, ps_height; ps_width = 540.; /* 72 * 7.5 */ ps_height = 720.; /* 72 * 10 */ ps_xmult = ps_width / (xright - xleft); ps_ymult = ps_height / (ytop - ybot); /* Need to use same scaling factor to preserve aspect ratio. * * I show exactly as much on paper as the screen window shows, * * or the user specifies. */ if(fabs(ps_xmult) <= fabs(ps_ymult)) { ps_left = 36.; ps_right = 36. + ps_width; ps_bot = 396. - fabs(ps_xmult * (ytop - ybot)) / 2.; ps_top = 396. + fabs(ps_xmult * (ytop - ybot)) / 2.; /* Maintain aspect ratio but watch signs */ ps_ymult = (ps_xmult * ps_ymult < 0) ? -ps_xmult : ps_xmult; } else { ps_bot = 36.; ps_top = 36. + ps_height; ps_left = 306. - fabs(ps_ymult * (xright - xleft)) / 2.; ps_right = 306. + fabs(ps_ymult * (xright - xleft)) / 2.; /* Maintain aspect ratio but watch signs */ ps_xmult = (ps_xmult * ps_ymult < 0) ? -ps_ymult : ps_ymult; } }
static void update_transform | ( | void | ) | [static] |
Set up the factors for transforming from the user world to X Windows coordinates.
Definition at line 1040 of file graphics.c.
{ float mult, y1, y2, x1, x2; /* X Window coordinates go from (0,0) to (width-1,height-1) */ xmult = ((float)top_width - 1. - MWIDTH) / (xright - xleft); ymult = ((float)top_height - 1. - T_AREA_HEIGHT) / (ybot - ytop); /* Need to use same scaling factor to preserve aspect ratio */ if(fabs(xmult) <= fabs(ymult)) { mult = fabs(ymult / xmult); y1 = ytop - (ybot - ytop) * (mult - 1.) / 2.; y2 = ybot + (ybot - ytop) * (mult - 1.) / 2.; ytop = y1; ybot = y2; } else { mult = fabs(xmult / ymult); x1 = xleft - (xright - xleft) * (mult - 1.) / 2.; x2 = xright + (xright - xleft) * (mult - 1.) / 2.; xleft = x1; xright = x2; } xmult = ((float)top_width - 1. - MWIDTH) / (xright - xleft); ymult = ((float)top_height - 1. - T_AREA_HEIGHT) / (ybot - ytop); }
static void update_win | ( | int | x[2], |
int | y[2], | ||
void(*)(void) | drawscreen | ||
) | [static] |
Definition at line 1754 of file graphics.c.
{ float x1, x2, y1, y2; x[0] = min(x[0], top_width - MWIDTH); /* Can't go under menu */ x[1] = min(x[1], top_width - MWIDTH); y[0] = min(y[0], top_height - T_AREA_HEIGHT); /* Can't go under text area */ y[1] = min(y[1], top_height - T_AREA_HEIGHT); if((x[0] == x[1]) || (y[0] == y[1])) { printf("Illegal (zero area) window. Window unchanged.\n"); return; } x1 = XTOWORLD(min(x[0], x[1])); x2 = XTOWORLD(max(x[0], x[1])); y1 = YTOWORLD(min(y[0], y[1])); y2 = YTOWORLD(max(y[0], y[1])); xleft = x1; xright = x2; ytop = y1; ybot = y2; update_transform(); drawscreen(); }
static int which_button | ( | Window | win | ) | [static] |
Definition at line 1010 of file graphics.c.
{ int i; for(i = 0; i < num_buttons; i++) { if(button[i].win == win) return (i); } printf("Error: Unknown button ID in which_button.\n"); return (0); }
static int xcoord | ( | float | worldx | ) | [static] |
Translates from my internal coordinates to X Windows coordinates * in the x direction. Add 0.5 at end for extra half-pixel accuracy.
Definition at line 201 of file graphics.c.
{ int winx; winx = (int)((worldx - xleft) * xmult + 0.5); /* Avoid overflow in the X Window routines. This will allow horizontal * * and vertical lines to be drawn correctly regardless of zooming, but * * will cause diagonal lines that go way off screen to change their * * slope as you zoom in. The only way I can think of to completely fix * * this problem is to do all the clipping in advance in floating point, * * then convert to integers and call X Windows. This is a lot of extra * * coding, and means that coordinates will be clipped twice, even though * * this "Super Zoom" problem won't occur unless users zoom way in on * * the graphics. */ winx = max(winx, MINPIXEL); winx = min(winx, MAXPIXEL); return (winx); }
static int ycoord | ( | float | worldy | ) | [static] |
Translates from my internal coordinates to X Windows coordinates in the y direction. Add 0.5 at end for extra half-pixel accuracy.
Definition at line 228 of file graphics.c.
{ int winy; winy = (int)((worldy - ytop) * ymult + 0.5); /* Avoid overflow in the X Window routines. */ winy = max(winy, MINPIXEL); winy = min(winy, MAXPIXEL); return (winy); }
static void zoom_fit | ( | void(*)(void) | drawscreen | ) | [static] |
Sets the view back to the initial view set by init_world (i.e. a full view) of all the graphics.
Definition at line 1684 of file graphics.c.
{ xleft = saved_xleft; xright = saved_xright; ytop = saved_ytop; ybot = saved_ybot; update_transform(); drawscreen(); }
static void zoom_in | ( | void(*)(void) | drawscreen | ) | [static] |
Zooms in by a factor of 1.666.
Definition at line 1646 of file graphics.c.
{ float xdiff, ydiff; xdiff = xright - xleft; ydiff = ybot - ytop; xleft += xdiff / 5.; xright -= xdiff / 5.; ytop += ydiff / 5.; ybot -= ydiff / 5.; update_transform(); drawscreen(); }
static void zoom_out | ( | void(*)(void) | drawscreen | ) | [static] |
Zooms out by a factor of 1.666.
Definition at line 1664 of file graphics.c.
{ float xdiff, ydiff; xdiff = xright - xleft; ydiff = ybot - ytop; xleft -= xdiff / 3.; xright += xdiff / 3.; ytop -= ydiff / 3.; ybot += ydiff / 3.; update_transform(); drawscreen(); }
[0..num_buttons-1]
Definition at line 126 of file graphics.c.
int colors[NUM_COLOR] [static] |
Color indices passed back from X Windows.
Definition at line 160 of file graphics.c.
int currentcolor = BLACK [static] |
Graphics state. Set start-up defaults here.
Definition at line 151 of file graphics.c.
int currentfontsize = 10 [static] |
Graphics state. Set start-up defaults here.
Definition at line 154 of file graphics.c.
int currentlinestyle = SOLID [static] |
Graphics state. Set start-up defaults here.
Definition at line 152 of file graphics.c.
int currentlinewidth = 0 [static] |
Graphics state. Set start-up defaults here.
Definition at line 153 of file graphics.c.
int disp_type [static] |
Selects SCREEN or POSTSCRIPT
Definition at line 129 of file graphics.c.
Display* display [static] |
Definition at line 130 of file graphics.c.
unsigned int display_height |
screen size
Definition at line 135 of file graphics.c.
unsigned int display_width [static] |
Definition at line 135 of file graphics.c.
XFontStruct* font_info[MAX_FONT_SIZE+1] [static] |
Data for each size
Definition at line 133 of file graphics.c.
int font_is_loaded[MAX_FONT_SIZE+1] [static] |
1: loaded, 0: not
Definition at line 134 of file graphics.c.
GC gc [static] |
Definition at line 132 of file graphics.c.
GC gc_menus |
Definition at line 132 of file graphics.c.
GC gcxor |
Definition at line 132 of file graphics.c.
Window menu |
Definition at line 137 of file graphics.c.
const int menu_font_size = 14 [static] |
Font for menus and dialog boxes.
Definition at line 124 of file graphics.c.
char message[BUFSIZE] = "\0" [static] |
User message to display
Definition at line 157 of file graphics.c.
int num_buttons [static] |
Number of menu buttons
Definition at line 127 of file graphics.c.
Colormap private_cmap [static] |
"None" unless a private cmap was allocated.
Definition at line 147 of file graphics.c.
FILE* ps [static] |
For PostScript output
Definition at line 163 of file graphics.c.
float ps_bot |
Figure boundaries for PostScript output, in PostScript coordinates.
Definition at line 143 of file graphics.c.
float ps_left [static] |
Definition at line 143 of file graphics.c.
float ps_right |
Definition at line 143 of file graphics.c.
float ps_top |
Definition at line 143 of file graphics.c.
float ps_xmult [static] |
Definition at line 145 of file graphics.c.
float ps_ymult |
Transformation for PostScript.
Definition at line 145 of file graphics.c.
float saved_xleft [static] |
Initial world coordinates
Definition at line 141 of file graphics.c.
float saved_xright |
Definition at line 141 of file graphics.c.
float saved_ybot |
Definition at line 141 of file graphics.c.
float saved_ytop |
Definition at line 141 of file graphics.c.
int screen_num [static] |
Definition at line 131 of file graphics.c.
Window textarea |
various windows
Definition at line 137 of file graphics.c.
unsigned int top_height |
window size
Definition at line 136 of file graphics.c.
unsigned int top_width [static] |
Definition at line 136 of file graphics.c.
Window toplevel [static] |
Definition at line 137 of file graphics.c.
float xleft [static] |
Definition at line 138 of file graphics.c.
float xmult [static] |
Definition at line 146 of file graphics.c.
float xright |
Definition at line 138 of file graphics.c.
float ybot |
world coordinates
Definition at line 138 of file graphics.c.
float ymult |
Transformation factors
Definition at line 146 of file graphics.c.
float ytop |
Definition at line 138 of file graphics.c.