📄 graphics.c
字号:
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 map_button (int bnum) {/* Maps a button onto the screen and set it up for input, etc. */ 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 unmap_button (int bnum) {/* Unmaps a button from the screen. */ XUnmapWindow (display, button[bnum].win);}void create_button (char *prev_button_text , char *button_text, void (*button_func) (void (*drawscreen) (void))) {/* 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. */ 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; 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. */ 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 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. */ 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" }; 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 */ /* 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);/* 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); }static Bool test_if_exposed (Display *disp, XEvent *event_ptr, XPointer dummy) {/* 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. */ if (event_ptr->type == Expose) { return (True); } return (False);}static void menutext(Window win, int xc, int yc, char *text) {/* draws text center at xc, yc -- used only by menu drawing stuff */ 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 drawbut (int bnum) {/* Draws button bnum in either its pressed or unpressed state. */ 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); }}static void turn_on_off (int pressed) {/* Shows when the menu is active or inactive by colouring the * * buttons. */ int i; for (i=0;i<num_buttons;i++) { button[i].ispressed = pressed; drawbut(i); }}static int which_button (Window win) { 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 void drawmenu(void) { int i; for (i=0;i<num_buttons;i++) { drawbut(i); }}static void update_transform (void) {/* Set up the factors for transforming from the user world to X Windows * * coordinates. */ 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_ps_transform (void) {/* Postscript coordinates start at (0,0) for the lower left hand corner *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -