SRC/graphics.h File Reference

This graph shows which files directly or indirectly include this file:

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 Documentation

#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.


Enumeration Type Documentation

Enumerator:
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
Enumerator:
SOLID 
DASHED 

Definition at line 10 of file graphics.h.

00011 { SOLID, DASHED };


Function Documentation

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

void flushinput ( void   ) 

Definition at line 1578 of file graphics.c.

01579 {
01580     if(disp_type != SCREEN)
01581         return;
01582     XFlush(display);
01583 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

void setcolor ( int  cindex  ) 

Definition at line 286 of file graphics.c.

00287 {
00288 
00289     if(currentcolor != cindex)
00290         force_setcolor(cindex);
00291 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

void setlinestyle ( int  linestyle  ) 

Definition at line 320 of file graphics.c.

00321 {
00322 
00323     if(linestyle != currentlinestyle)
00324         force_setlinestyle(linestyle);
00325 }

Here is the call graph for this function:

Here is the caller graph for this function:

void setlinewidth ( int  linewidth  ) 

Definition at line 352 of file graphics.c.

00353 {
00354 
00355     if(linewidth != currentlinewidth)
00356         force_setlinewidth(linewidth);
00357 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:


Generated on Tue Jan 5 15:25:45 2010 for VPR5.0 by  doxygen 1.6.1