diff --git a/src/callback.c b/src/callback.c index 435c8658..9d2edff9 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1685,7 +1685,7 @@ int rstate; /* (reduced state, without ShiftMask) */ xctx->ui_state |= START_SYMPIN; break; } - if(key=='p' && !xctx->ui_state && rstate==0) /* start polygon, 20171115 */ + if(key=='p' /* && !xctx->ui_state */ && rstate==0) /* start polygon, 20171115 */ { if(xctx->semaphore >= 2) break; dbg(1, "callback(): start polygon\n"); @@ -1820,7 +1820,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } break; } - if(key=='r' && !xctx->ui_state && rstate==0) /* start rect */ + if(key=='r' /* && !xctx->ui_state */ && rstate==0) /* start rect */ { dbg(1, "callback(): start rect\n"); xctx->mx_double_save=xctx->mousex_snap; @@ -2309,7 +2309,7 @@ int rstate; /* (reduced state, without ShiftMask) */ create_sch_from_sym(); break; } - if(key=='l' && !xctx->ui_state && rstate == 0) /* start line */ + if(key=='l' /* && !xctx->ui_state */ && rstate == 0) /* start line */ { int prev_state = xctx->ui_state; start_line(mx, my); diff --git a/src/draw.c b/src/draw.c index d2fd90c6..d56bfa50 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1662,13 +1662,79 @@ void arc_bbox(double x, double y, double r, double a, double b, /* Convex Nonconvex Complex */ #define Polygontype Nonconvex -static void drawbezier(Drawable w, GC gc, int c, double *x, double *y, int points, int fill) +void drawbezier(Drawable w, GC gc, int c, double *x, double *y, int points, int fill) { - XPoint p[512]; - int i = 0; + static int psize = 64; + static XPoint *p = NULL; + int b, i; double t; double xp, yp; + double x0, x1, x2, y0, y1, y2; + + if(points == 0 && x == NULL && y == NULL) { /* cleanup */ + my_free(_ALLOC_ID_, &p); + } + if(!p) p = my_malloc(_ALLOC_ID_, psize * sizeof(XPoint)); + if(gc == xctx->gc[SELLAYER]) for(i = 0; i < points; i++) { + drawtemparc(gc, NOW, x[i], y[i], cadhalfdotsize, 0., 360.); + } + i = 0; + for(b = 0; b < points - 2; b++) { + if(points == 3) { /* 3 points: only one bezier */ + x0 = x[0]; + y0 = y[0]; + x1 = x[1]; + y1 = y[1]; + x2 = x[2]; + y2 = y[2]; + } else if(b == points - 3) { /* last bezier */ + x0 = (x[points - 3] + x[points - 2]) / 2.0; + y0 = (y[points - 3] + y[points - 2]) / 2.0; + x1 = x[points - 2]; + y1 = y[points - 2]; + x2 = x[points - 1]; + y2 = y[points - 1]; + } else if(b == 0) { /* first bezier */ + x0 = x[0]; + y0 = y[0]; + x1 = x[1]; + y1 = y[1]; + x2 = (x[1] + x[2]) / 2.0; + y2 = (y[1] + y[2]) / 2.0; + } else { /* beziers in the middle */ + x0 = (x[b] + x[b + 1]) / 2.0; + y0 = (y[b] + y[b + 1]) / 2.0; + x1 = x[b + 1]; + y1 = y[b + 1]; + x2 = (x[b + 1] + x[b + 2]) / 2.0; + y2 = (y[b + 1] + y[b + 2]) / 2.0; + } + /* + * dbg(0, "\n-------- b=%d points=%d -----------\n", b, points); + * dbg(0, "x0=%g y0=%g\n", x0, y0); + * dbg(0, "x1=%g y1=%g\n", x1, y1); + * dbg(0, "x2=%g y2=%g\n", x2, y2); + */ + for(t = 0; t <= 1.0; t += (1.0/32.0)) { + xp = pow(1-t, 2) * x0 + 2 * (1-t) * t * x1 + pow(t, 2) * x2; + yp = pow(1-t, 2) * y0 + 2 * (1-t) * t * y1 + pow(t, 2) * y2; + if(i >= psize) { + psize *= 2; + my_realloc(_ALLOC_ID_, &p, psize * sizeof(XPoint)); + } + p[i].x = (short)X_TO_SCREEN(xp); + p[i].y = (short)Y_TO_SCREEN(yp); + /* dbg(0, "i=%d, p[i].x=%d, p[i].y=%d\n", i, p[i].x, p[i].y); */ + i++; + } + } + XDrawLines(display, w, gc, p, i, CoordModeOrigin); + if(fill) { + XFillPolygon(display, w, xctx->gcstipple[c], p, i, Polygontype, CoordModeOrigin); + } + /* example of cubic bezier */ + #if 0 if(points == 4) { if(gc == xctx->gc[SELLAYER]) for(i = 0; i < points; i++) { drawtemparc(gc, NOW, x[i], y[i], cadhalfdotsize, 0., 360.); @@ -1686,7 +1752,7 @@ static void drawbezier(Drawable w, GC gc, int c, double *x, double *y, int point XFillPolygon(display, w, xctx->gcstipple[c], p, i, Polygontype, CoordModeOrigin); } } - + #endif } /* Unused 'what' parameter used in spice data draw_graph() @@ -1723,7 +1789,7 @@ void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fil } fill = xctx->fill_pattern && xctx->fill_type[c] && poly_fill && (x[0] == x[points-1]) && (y[0] == y[points-1]); - bezier = flags && points == 4; + bezier = flags && (points > 2); if(dash) { char dash_arr[2]; dash_arr[0] = dash_arr[1] = (char)dash; @@ -1772,7 +1838,7 @@ void drawtemppolygon(GC gc, int what, double *x, double *y, int points, int flag sy2=Y_TO_SCREEN(y2); if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&sx1,&sy1,&sx2,&sy2) ) { - bezier = flags && points == 4; + bezier = flags && (points > 2); if((fix_broken_tiled_fill || !_unix) && gc == xctx->gctiled) { MyXCopyAreaDouble(display, xctx->save_pixmap, xctx->window, xctx->gc[0], x1 - cadhalfdotsize, y1 - cadhalfdotsize, diff --git a/src/scheduler.c b/src/scheduler.c index be7d9bdc..31cdf2ec 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1804,6 +1804,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg my_snprintf(res, S(res), "need_reb_sel_arr=%d\n", xctx->need_reb_sel_arr); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "undo_type=%d\n", xctx->undo_type); Tcl_AppendResult(interp, res, NULL); my_snprintf(res, S(res), "******* end global variables:*******\n"); Tcl_AppendResult(interp, res, NULL); + + my_snprintf(res, S(res), "******* Xserver options: *******\n"); Tcl_AppendResult(interp, res, NULL); + my_snprintf(res, S(res), "XMaxRequestSize=%ld\n", XMaxRequestSize(display)); + Tcl_AppendResult(interp, res, NULL); + my_snprintf(res, S(res), "XExtendedMaxRequestSize=%ld\n", XExtendedMaxRequestSize(display)); + Tcl_AppendResult(interp, res, NULL); + my_snprintf(res, S(res), "******* Compile options:*******\n"); Tcl_AppendResult(interp, res, NULL); #ifdef HAS_DUP2 my_snprintf(res, S(res), "HAS_DUP2=%d\n", HAS_DUP2); Tcl_AppendResult(interp, res, NULL); diff --git a/src/xinit.c b/src/xinit.c index 999216cb..0847f03e 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -902,6 +902,7 @@ static void xwin_exit(void) } if(xctx->infowindow_text) my_free(_ALLOC_ID_, &xctx->infowindow_text); if(has_x) new_schematic("destroy_all", "1", NULL, 1); + drawbezier(xctx->window, xctx->gc[0], 0, NULL, NULL, 0, 0); delete_schematic_data(1); if(has_x) { Tk_DestroyWindow(mainwindow); diff --git a/src/xschem.h b/src/xschem.h index 7050858e..a5716dbb 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1390,6 +1390,7 @@ extern void drawtemparc(GC gc, int what, double x, double y, double r, double a, extern void drawarc(int c, int what, double x, double y, double r, double a, double b, int arc_fill, int dash); extern void filledarc(int c, int what, double x, double y, double r, double a, double b); extern void drawtemppolygon(GC gc, int what, double *x, double *y, int points, int flags); +extern void drawbezier(Drawable w, GC gc, int c, double *x, double *y, int points, int fill); extern void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fill, int dash, int flags); extern void draw_temp_symbol(int what, GC gc, int n,int layer, short tmp_flip, short tmp_rot, double xoffset, double yoffset);