⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphics.c

📁 用c++写的用于FPGA设计中布图布线的工具源码
💻 C
📖 第 1 页 / 共 4 页
字号:
 * 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.                                                           */ 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; }}void event_loop (void (*act_on_button) (float x, float y),     void (*drawscreen) (void)) {/* 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.      */ 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 clearscreen (void) { 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); }}static int rect_off_screen (float x1, float y1, float x2, float y2) {/* 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.                                                       */ 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 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.                         */ if (rect_off_screen(x1,y1,x2,y2))    return; if (disp_type == SCREEN) {    /* Xlib.h prototype has x2 and y1 mixed up. */     XDrawLine(display, toplevel, gc, xcoord(x1), ycoord(y1),        xcoord(x2), ycoord(y2)); } else {    fprintf(ps,"%.2f %.2f %.2f %.2f drawline\n",XPOST(x1),YPOST(y1),          XPOST(x2),YPOST(y2)); }}void drawrect (float x1, float y1, float x2, float y2) {/* (x1,y1) and (x2,y2) are diagonally opposed corners, in world coords. */ 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 fillrect (float x1, float y1, float x2, float y2) {/* (x1,y1) and (x2,y2) are diagonally opposed corners in world coords. */ 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)); }}static float angnorm (float ang) {/* Normalizes an angle to be between 0 and 360 degrees. */ int scale; if (ang < 0) {    scale = (int) (ang / 360. - 1); } else {    scale = (int) (ang / 360.); } ang = ang - scale * 360.; return (ang);}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.                  */ int xl, yt; unsigned int width, height;/* Conservative (but fast) clip test -- check containing rectangle of * * a circle.                                                          */  if (rect_off_screen (xc-rad,yc-rad,xc+rad,yc+rad))     return;/* X Windows has trouble with very large angles. (Over 360).    * * Do following to prevent its inaccurate (overflow?) problems. */ if (fabs(angextent) > 360.)      angextent = 360.; startang = angnorm (startang);  if (disp_type == SCREEN) {    xl = (int) (xcoord(xc) - fabs(xmult*rad));    yt = (int) (ycoord(yc) - fabs(ymult*rad));    width = (unsigned int) (2*fabs(xmult*rad));    height = width;    XDrawArc (display, toplevel, gc, xl, yt, width, height,      (int) (startang*64), (int) (angextent*64)); } else {    fprintf(ps,"%.2f %.2f %.2f %.2f %.2f %s stroke\n", XPOST(xc),        YPOST(yc), fabs(rad*ps_xmult), startang, startang+angextent,        (angextent < 0) ? "drawarcn" : "drawarc") ; }}void 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.                                           */ 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) { 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 drawtext (float xc, float yc, char *text, float boundx) {/* Draws text centered on xc,yc if it fits in boundx */ 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 flushinput (void) { if (disp_type != SCREEN) return; XFlush(display);}void init_world (float x1, float y1, float x2, float y2) {/* Sets the coordinate system the user wants to draw into.          */ xleft = x1; xright = x2; ytop = y1; ybot = y2; saved_xleft = xleft;     /* Save initial world coordinates to allow full */ saved_xright = xright;   /* view button to zoom all the way out.         */ saved_ytop = ytop; saved_ybot = ybot; if (disp_type == SCREEN) {    update_transform(); } else {    update_ps_transform(); }}void draw_message (void) {/* Draw the current message in the text area at the screen bottom. */ 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -