From 2c26bfbaa9b87242c03d267075152b8e4a4c350b Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Fri, 3 Nov 2023 14:36:35 +0100 Subject: [PATCH] fix some garbage while moving / copying and zooming. faster draw_selection(gctiled) if big selection (use a single XCopyArea), do not allow to descend/go_back if other UI action is pending, initial implementation of `xschem floaters_from_selected_inst` command, get_tok_val() allow quotes in tokens, like a"22"33=123 even if with_quotes unset (it is intended for token values not for tokens themselves) --- src/actions.c | 3 +- src/draw.c | 24 +- src/move.c | 889 +++++++++++++++++++++---------------------- src/scheduler.c | 25 +- src/select.c | 60 +++ src/token.c | 4 +- src/xschem.h | 1 + tests/xschemtest.tcl | 2 +- 8 files changed, 521 insertions(+), 487 deletions(-) diff --git a/src/actions.c b/src/actions.c index 640fbf1e..0c07b522 100644 --- a/src/actions.c +++ b/src/actions.c @@ -2343,7 +2343,6 @@ void zoom_full(int dr, int sel, int flags, double shrink) void view_zoom(double z) { double factor; - /* int i; */ factor = z!=0.0 ? z : CADZOOMSTEP; if(xctx->zoomzoom/= factor; @@ -2351,6 +2350,7 @@ void view_zoom(double z) xctx->xorigin=-xctx->mousex_snap+(xctx->mousex_snap+xctx->xorigin)/factor; xctx->yorigin=-xctx->mousey_snap+(xctx->mousey_snap+xctx->yorigin)/factor; change_linewidth(-1.); + draw(); redraw_w_a_l_r_p_rubbers(); } @@ -2358,7 +2358,6 @@ void view_zoom(double z) void view_unzoom(double z) { double factor; - /* int i; */ factor = z!=0.0 ? z : CADZOOMSTEP; if(xctx->zoom>CADMAXZOOM) return; xctx->zoom*= factor; diff --git a/src/draw.c b/src/draw.c index 21f288b8..90b09f31 100644 --- a/src/draw.c +++ b/src/draw.c @@ -721,7 +721,6 @@ void draw_temp_symbol(int what, GC gc, int n,int layer,short tmp_flip, short rot #if HAS_CAIRO==1 int customfont; #endif - int fix_broken = (gc == xctx->gctiled) && (fix_broken_tiled_fill || !_unix); if(xctx->inst[n].ptr == -1) return; if(!has_x) return; @@ -755,8 +754,6 @@ void draw_temp_symbol(int what, GC gc, int n,int layer,short tmp_flip, short rot xctx->inst[n].xx2 + xoffset, xctx->inst[n].yy2 + yoffset); xctx->inst[n].flags|=1; return; - } else if(fix_broken) { - xctx->inst[n].flags|=1; } else xctx->inst[n].flags&=~1; if(hide) { @@ -774,13 +771,6 @@ void draw_temp_symbol(int what, GC gc, int n,int layer,short tmp_flip, short rot drawtemprect(gc,what,xctx->inst[n].xx1 + xoffset, xctx->inst[n].yy1 + yoffset, xctx->inst[n].xx2 + xoffset, xctx->inst[n].yy2 + yoffset); } - if(fix_broken) { /* do a copyArea on first layer only. Faster. */ - symbol_bbox(n, &xctx->inst[n].x1, &xctx->inst[n].y1, &xctx->inst[n].x2, &xctx->inst[n].y2); - MyXCopyAreaDouble(display, xctx->save_pixmap, xctx->window, xctx->gc[0], - xctx->inst[n].x1 + xoffset, xctx->inst[n].y1 + yoffset, - xctx->inst[n].x2 + xoffset, xctx->inst[n].y2 + yoffset, - xctx->inst[n].x1 + xoffset, xctx->inst[n].y1 + yoffset, xctx->lw); - } } else if(xctx->inst[n].flags&1) { dbg(2, "draw_symbol(): skipping inst %d\n", n); return; @@ -4144,15 +4134,15 @@ void MyXCopyAreaDouble(Display* display, Drawable src, Drawable dest, GC gc, { double isx1, isy1, isx2, isy2, idx1, idy1; unsigned int width, height; - + int intlw = INT_WIDTH(lw); dbg(1, "MyXCopyAreaDouble(%g, %g, %g, %g)\n", sx1, sy1, sx2, sy2); - isx1=X_TO_SCREEN(sx1) - 2 * INT_WIDTH(lw); - isy1=Y_TO_SCREEN(sy1) - 2 * INT_WIDTH(lw); - isx2=X_TO_SCREEN(sx2) + 2 * INT_WIDTH(lw); - isy2=Y_TO_SCREEN(sy2) + 2 * INT_WIDTH(lw); + isx1=X_TO_SCREEN(sx1) - 2 * intlw; + isy1=Y_TO_SCREEN(sy1) - 2 * intlw; + isx2=X_TO_SCREEN(sx2) + 2 * intlw; + isy2=Y_TO_SCREEN(sy2) + 2 * intlw; - idx1=X_TO_SCREEN(dx1) - 2 * INT_WIDTH(lw); - idy1=Y_TO_SCREEN(dy1) - 2 * INT_WIDTH(lw); + idx1=X_TO_SCREEN(dx1) - 2 * intlw; + idy1=Y_TO_SCREEN(dy1) - 2 * intlw; width = (unsigned int)isx2 - (unsigned int)isx1; height = (unsigned int)isy2 - (unsigned int)isy1; diff --git a/src/move.c b/src/move.c index bd1cadfa..2ba48d19 100644 --- a/src/move.c +++ b/src/move.c @@ -197,6 +197,12 @@ void draw_selection(GC g, int interruptable) #endif dbg(1,"draw_selection %s\n", g == xctx->gctiled ? "gctiled" : "gcselect"); if(g != xctx->gctiled) xctx->movelastsel = xctx->lastsel; + + if((fix_broken_tiled_fill || !_unix) && g == xctx->gctiled && xctx->movelastsel > 800) { + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], xctx->xrect[0].x, xctx->xrect[0].y, + xctx->xrect[0].width, xctx->xrect[0].height, xctx->xrect[0].x, xctx->xrect[0].y); + return; + } for(i=0;imovelastsel; ++i) { c = xctx->sel_array[i].col;n = xctx->sel_array[i].n; @@ -443,46 +449,11 @@ void draw_selection(GC g, int interruptable) xctx->inst[n].x0, xctx->inst[n].y0, xctx->rx1,xctx->ry1); } - if((fix_broken_tiled_fill || !_unix) && g == xctx->gctiled) { - short save_flip, save_rot; - double save_x0, save_y0; - double save_x1, save_y1, save_x2, save_y2; - double x1, y1, x2, y2; - - /* Can be made simpler ? */ - dbg(1, "rot=%d flip=%d deltax=%g deltay=%g\n", - xctx->move_rot, xctx->move_flip, xctx->deltax, xctx->deltay); - save_flip = xctx->inst[n].flip; - save_rot = xctx->inst[n].rot; - save_x0 = xctx->inst[n].x0; - save_y0 = xctx->inst[n].y0; - save_x1 = xctx->inst[n].xx1; - save_y1 = xctx->inst[n].yy1; - save_x2 = xctx->inst[n].xx2; - save_y2 = xctx->inst[n].yy2; - xctx->inst[n].flip = xctx->move_flip ^ xctx->inst[n].flip; - xctx->inst[n].rot = (xctx->inst[n].rot + xctx->move_rot) & 0x3; - xctx->inst[n].x0 = xctx->rx1+xctx->deltax; - xctx->inst[n].y0 = xctx->ry1+xctx->deltay; - symbol_bbox(n, &x1, &y1, &x2, &y2); - xctx->inst[n].rot = save_rot; - xctx->inst[n].flip = save_flip; - xctx->inst[n].x0 = save_x0; - xctx->inst[n].y0 = save_y0; - xctx->inst[n].xx1 = save_x1; - xctx->inst[n].yy1 = save_y1; - xctx->inst[n].xx2 = save_x2; - xctx->inst[n].yy2 = save_y2; - - MyXCopyAreaDouble(display, xctx->save_pixmap, xctx->window, xctx->gc[0], - x1, y1, x2, y2, x1, y1, - xctx->lw); - } else { - for(k=0;kmove_flip, - ( xctx->move_flip && (xctx->inst[n].rot & 1) ) ? xctx->move_rot+2 : xctx->move_rot, - xctx->rx1-xctx->inst[n].x0+xctx->deltax,xctx->ry1-xctx->inst[n].y0+xctx->deltay); - } + for(k=0;kmove_flip, + xctx->move_rot, + /* (( xctx->move_flip && (xctx->inst[n].rot & 1) ) ? xctx->move_rot+2 : xctx->move_rot) & 0x3, */ + xctx->rx1-xctx->inst[n].x0+xctx->deltax,xctx->ry1-xctx->inst[n].y0+xctx->deltay); } break; } @@ -528,6 +499,7 @@ void copy_objects(int what) xctx->rotatelocal=0; dbg(1, "copy_objects(): START copy\n"); rebuild_selected_array(); + update_symbol_bboxes(0, 0); if(xctx->connect_by_kissing == 2) xctx->kissing = connect_by_kissing(); else xctx->kissing = 0; @@ -902,432 +874,431 @@ void copy_objects(int what) /* merge param unused, RFU */ void move_objects(int what, int merge, double dx, double dy) { - int c, i, n, k, tmpint; - double angle, dtmp; - double tx1,ty1; /* temporaries for swapping coordinates 20070302 */ - #if HAS_CAIRO==1 - int customfont; - #endif - xLine ** const line = xctx->line; - xWire * const wire = xctx->wire; - - if(what & START) - { - xctx->rotatelocal=0; - xctx->deltax = xctx->deltay = 0.0; - rebuild_selected_array(); - /* if connect_by_kissing==2 it was set in callback.c ('M' command) */ - if(xctx->connect_by_kissing == 2) xctx->kissing = connect_by_kissing(); - else xctx->kissing = 0; - xctx->movelastsel = xctx->lastsel; - if(xctx->lastsel==1 && xctx->sel_array[0].type==ARC && - xctx->arc[c=xctx->sel_array[0].col][n=xctx->sel_array[0].n].sel!=SELECTED) { - xctx->x1 = xctx->arc[c][n].x; - xctx->y_1 = xctx->arc[c][n].y; - } else {xctx->x1=xctx->mousex_snap;xctx->y_1=xctx->mousey_snap;} - xctx->move_flip = 0;xctx->move_rot = 0; - xctx->ui_state|=STARTMOVE; - } - if(what & ABORT) /* draw objects while moving */ - { - draw_selection(xctx->gctiled,0); - if(xctx->kissing) { - pop_undo(0, 0); - if(xctx->connect_by_kissing == 2) xctx->connect_by_kissing = 0; - } - - xctx->move_rot=xctx->move_flip=0; - xctx->deltax=xctx->deltay=0.; - xctx->ui_state &= ~STARTMOVE; - update_symbol_bboxes(0, 0); - } - if(what & RUBBER) /* abort operation */ - { - xctx->x2=xctx->mousex_snap;xctx->y_2=xctx->mousey_snap; - draw_selection(xctx->gctiled,0); - xctx->deltax = xctx->x2-xctx->x1; xctx->deltay = xctx->y_2 - xctx->y_1; - } - if(what & ROTATELOCAL) { - xctx->rotatelocal=1; - } - if(what & ROTATE) { - draw_selection(xctx->gctiled,0); - xctx->move_rot= (xctx->move_rot+1) & 0x3; - update_symbol_bboxes(xctx->move_rot, xctx->move_flip); - } - if(what & FLIP) - { - draw_selection(xctx->gctiled,0); - xctx->move_flip = !xctx->move_flip; - update_symbol_bboxes(xctx->move_rot, xctx->move_flip); - } - if(what & END) /* move selected objects */ - { - int firsti, firstw; - - if(xctx->connect_by_kissing == 2) xctx->connect_by_kissing = 0; - /* no undo push for MERGE ad PLACE, already done before */ - if( !xctx->kissing && !(xctx->ui_state & (STARTMERGE | PLACE_SYMBOL | PLACE_TEXT)) ) { - dbg(1, "move_objects(): push undo state\n"); - xctx->push_undo(); - } - if((xctx->ui_state & PLACE_SYMBOL)) { - int n = xctx->sel_array[0].n; - const char *f = abs_sym_path((xctx->inst[n].ptr+ xctx->sym)->name, ""); - tclvareval("c_toolbar::add {",f, "}; c_toolbar::display", NULL); - } - xctx->ui_state &= ~PLACE_SYMBOL; - xctx->ui_state &= ~PLACE_TEXT; - if(dx!=0.0 || dy!=0.0) { - xctx->deltax = dx; - xctx->deltay = dy; - } - - /* calculate moving symbols bboxes before actually doing the move */ - firsti = firstw = 1; - draw_selection(xctx->gctiled,0); - update_symbol_bboxes(0, 0); - for(k=0;kline; + xWire * const wire = xctx->wire; + + if(what & START) { - for(i=0;ilastsel; ++i) + xctx->rotatelocal=0; + xctx->deltax = xctx->deltay = 0.0; + rebuild_selected_array(); + update_symbol_bboxes(0, 0); + /* if connect_by_kissing==2 it was set in callback.c ('M' command) */ + if(xctx->connect_by_kissing == 2) xctx->kissing = connect_by_kissing(); + else xctx->kissing = 0; + xctx->movelastsel = xctx->lastsel; + if(xctx->lastsel==1 && xctx->sel_array[0].type==ARC && + xctx->arc[c=xctx->sel_array[0].col][n=xctx->sel_array[0].n].sel!=SELECTED) { + xctx->x1 = xctx->arc[c][n].x; + xctx->y_1 = xctx->arc[c][n].y; + } else {xctx->x1=xctx->mousex_snap;xctx->y_1=xctx->mousey_snap;} + xctx->move_flip = 0;xctx->move_rot = 0; + xctx->ui_state|=STARTMOVE; + } + if(what & ABORT) /* draw objects while moving */ + { + draw_selection(xctx->gctiled,0); + if(xctx->kissing) { + pop_undo(0, 0); + if(xctx->connect_by_kissing == 2) xctx->connect_by_kissing = 0; + } + + xctx->move_rot=xctx->move_flip=0; + xctx->deltax=xctx->deltay=0.; + xctx->ui_state &= ~STARTMOVE; + update_symbol_bboxes(0, 0); + } + if(what & RUBBER) /* abort operation */ + { + xctx->x2=xctx->mousex_snap;xctx->y_2=xctx->mousey_snap; + draw_selection(xctx->gctiled,0); + xctx->deltax = xctx->x2-xctx->x1; xctx->deltay = xctx->y_2 - xctx->y_1; + } + if(what & ROTATELOCAL) { + xctx->rotatelocal=1; + } + if(what & ROTATE) { + draw_selection(xctx->gctiled,0); + xctx->move_rot= (xctx->move_rot+1) & 0x3; + update_symbol_bboxes(xctx->move_rot, xctx->move_flip); + } + if(what & FLIP) + { + draw_selection(xctx->gctiled,0); + xctx->move_flip = !xctx->move_flip; + update_symbol_bboxes(xctx->move_rot, xctx->move_flip); + } + if(what & END) /* move selected objects */ + { + int firsti, firstw; + + if(xctx->connect_by_kissing == 2) xctx->connect_by_kissing = 0; + /* no undo push for MERGE ad PLACE, already done before */ + if( !xctx->kissing && !(xctx->ui_state & (STARTMERGE | PLACE_SYMBOL | PLACE_TEXT)) ) { + dbg(1, "move_objects(): push undo state\n"); + xctx->push_undo(); + } + if((xctx->ui_state & PLACE_SYMBOL)) { + int n = xctx->sel_array[0].n; + const char *f = abs_sym_path((xctx->inst[n].ptr+ xctx->sym)->name, ""); + tclvareval("c_toolbar::add {",f, "}; c_toolbar::display", NULL); + } + xctx->ui_state &= ~PLACE_SYMBOL; + xctx->ui_state &= ~PLACE_TEXT; + if(dx!=0.0 || dy!=0.0) { + xctx->deltax = dx; + xctx->deltay = dy; + } + + /* calculate moving symbols bboxes before actually doing the move */ + firsti = firstw = 1; + draw_selection(xctx->gctiled,0); + update_symbol_bboxes(0, 0); + for(k=0;ksel_array[i].col;n = xctx->sel_array[i].n; - switch(xctx->sel_array[i].type) + for(i=0;ilastsel; ++i) { - case WIRE: - xctx->prep_hash_wires=0; - firstw = 0; - if(k == 0) { - if(xctx->rotatelocal) { - ROTATION(xctx->move_rot, xctx->move_flip, wire[n].x1, wire[n].y1, - wire[n].x1, wire[n].y1, xctx->rx1,xctx->ry1); - ROTATION(xctx->move_rot, xctx->move_flip, wire[n].x1, wire[n].y1, - wire[n].x2, wire[n].y2, xctx->rx2,xctx->ry2); - } else { - ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, - wire[n].x1, wire[n].y1, xctx->rx1,xctx->ry1); - ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, - wire[n].x2, wire[n].y2, xctx->rx2,xctx->ry2); - } - if( wire[n].sel & (SELECTED|SELECTED1) ) - { + c = xctx->sel_array[i].col;n = xctx->sel_array[i].n; + switch(xctx->sel_array[i].type) + { + case WIRE: + xctx->prep_hash_wires=0; + firstw = 0; + if(k == 0) { + if(xctx->rotatelocal) { + ROTATION(xctx->move_rot, xctx->move_flip, wire[n].x1, wire[n].y1, + wire[n].x1, wire[n].y1, xctx->rx1,xctx->ry1); + ROTATION(xctx->move_rot, xctx->move_flip, wire[n].x1, wire[n].y1, + wire[n].x2, wire[n].y2, xctx->rx2,xctx->ry2); + } else { + ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, + wire[n].x1, wire[n].y1, xctx->rx1,xctx->ry1); + ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, + wire[n].x2, wire[n].y2, xctx->rx2,xctx->ry2); + } + if( wire[n].sel & (SELECTED|SELECTED1) ) + { + xctx->rx1+=xctx->deltax; + xctx->ry1+=xctx->deltay; + } + if( wire[n].sel & (SELECTED|SELECTED2) ) + { + xctx->rx2+=xctx->deltax; + xctx->ry2+=xctx->deltay; + } + wire[n].x1=xctx->rx1; + wire[n].y1=xctx->ry1; + ORDER(xctx->rx1,xctx->ry1,xctx->rx2,xctx->ry2); + if( wire[n].x1 == xctx->rx2 && wire[n].y1 == xctx->ry2) + { + if(wire[n].sel == SELECTED1) wire[n].sel = SELECTED2; + else if(wire[n].sel == SELECTED2) wire[n].sel = SELECTED1; + } + wire[n].x1=xctx->rx1; + wire[n].y1=xctx->ry1; + wire[n].x2=xctx->rx2; + wire[n].y2=xctx->ry2; + } + break; + + case LINE: + if(c!=k) break; + if(xctx->rotatelocal) { + ROTATION(xctx->move_rot, xctx->move_flip, line[c][n].x1, line[c][n].y1, + line[c][n].x1, line[c][n].y1, xctx->rx1,xctx->ry1); + ROTATION(xctx->move_rot, xctx->move_flip, line[c][n].x1, line[c][n].y1, + line[c][n].x2, line[c][n].y2, xctx->rx2,xctx->ry2); + } else { + ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, + line[c][n].x1, line[c][n].y1, xctx->rx1,xctx->ry1); + ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, + line[c][n].x2, line[c][n].y2, xctx->rx2,xctx->ry2); + } + + if( line[c][n].sel & (SELECTED|SELECTED1) ) + { + xctx->rx1+=xctx->deltax; + xctx->ry1+=xctx->deltay; + } + if( line[c][n].sel & (SELECTED|SELECTED2) ) + { + xctx->rx2+=xctx->deltax; + xctx->ry2+=xctx->deltay; + } + line[c][n].x1=xctx->rx1; + line[c][n].y1=xctx->ry1; + ORDER(xctx->rx1,xctx->ry1,xctx->rx2,xctx->ry2); + if( line[c][n].x1 == xctx->rx2 && line[c][n].y1 == xctx->ry2) + { + if(line[c][n].sel == SELECTED1) line[c][n].sel = SELECTED2; + else if(line[c][n].sel == SELECTED2) line[c][n].sel = SELECTED1; + } + line[c][n].x1=xctx->rx1; + line[c][n].y1=xctx->ry1; + line[c][n].x2=xctx->rx2; + line[c][n].y2=xctx->ry2; + break; + + case POLYGON: + if(c!=k) break; + { + xPoly *p = &xctx->poly[c][n]; + double bx1=0., by1=0., bx2=0., by2=0.; + int j; + double savex0, savey0; + savex0 = p->x[0]; + savey0 = p->y[0]; + for(j=0; jpoints; ++j) { + if(j==0 || p->x[j] < bx1) bx1 = p->x[j]; + if(j==0 || p->y[j] < by1) by1 = p->y[j]; + if(j==0 || p->x[j] > bx2) bx2 = p->x[j]; + if(j==0 || p->y[j] > by2) by2 = p->y[j]; + + if( p->sel==SELECTED || p->selected_point[j]) { + if(xctx->rotatelocal) { + ROTATION(xctx->move_rot, xctx->move_flip, savex0, savey0, p->x[j], p->y[j], + xctx->rx1,xctx->ry1); + } else { + ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, p->x[j], p->y[j], + xctx->rx1,xctx->ry1); + } + + p->x[j] = xctx->rx1+xctx->deltax; + p->y[j] = xctx->ry1+xctx->deltay; + } + + } + + for(j=0; jpoints; ++j) { + if(j==0 || p->x[j] < bx1) bx1 = p->x[j]; + if(j==0 || p->y[j] < by1) by1 = p->y[j]; + if(j==0 || p->x[j] > bx2) bx2 = p->x[j]; + if(j==0 || p->y[j] > by2) by2 = p->y[j]; + } + } + break; + + case ARC: + if(c!=k) break; + if(xctx->rotatelocal) { + /* rotate center wrt itself: do nothing */ + xctx->rx1 = xctx->arc[c][n].x; + xctx->ry1 = xctx->arc[c][n].y; + } else { + ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, + xctx->arc[c][n].x, xctx->arc[c][n].y, xctx->rx1,xctx->ry1); + } + angle = xctx->arc[c][n].a; + if(xctx->move_flip) { + angle = 270.*xctx->move_rot+180.-xctx->arc[c][n].b-xctx->arc[c][n].a; + } else { + angle = xctx->arc[c][n].a+xctx->move_rot*270.; + } + angle = fmod(angle, 360.); + if(angle<0.) angle+=360.; + + if(xctx->arc[c][n].sel == SELECTED) { + xctx->arc[c][n].x = xctx->rx1+xctx->deltax; + xctx->arc[c][n].y = xctx->ry1+xctx->deltay; + xctx->arc[c][n].a = angle; + } else if(xctx->arc[c][n].sel == SELECTED1) { + xctx->arc[c][n].x = xctx->rx1; + xctx->arc[c][n].y = xctx->ry1; + if(xctx->arc[c][n].r+xctx->deltax) xctx->arc[c][n].r = fabs(xctx->arc[c][n].r+xctx->deltax); + xctx->arc[c][n].a = angle; + } else if(xctx->arc[c][n].sel == SELECTED2) { + angle = my_round(fmod(atan2(-xctx->deltay, xctx->deltax)*180./XSCH_PI+angle, 360.)); + if(angle<0.) angle +=360.; + xctx->arc[c][n].x = xctx->rx1; + xctx->arc[c][n].y = xctx->ry1; + xctx->arc[c][n].a = angle; + } else if(xctx->arc[c][n].sel==SELECTED3) { + angle = my_round(fmod(atan2(-xctx->deltay, xctx->deltax)*180./XSCH_PI+xctx->arc[c][n].b, 360.)); + if(angle<0.) angle +=360.; + if(angle==0) angle=360.; + xctx->arc[c][n].x = xctx->rx1; + xctx->arc[c][n].y = xctx->ry1; + xctx->arc[c][n].b = angle; + } + break; + + case xRECT: + if(c!=k) break; + /* bbox before move */ + if(xctx->rotatelocal) { + ROTATION(xctx->move_rot, xctx->move_flip, xctx->rect[c][n].x1, xctx->rect[c][n].y1, + xctx->rect[c][n].x1, xctx->rect[c][n].y1, xctx->rx1,xctx->ry1); + ROTATION(xctx->move_rot, xctx->move_flip, xctx->rect[c][n].x1, xctx->rect[c][n].y1, + xctx->rect[c][n].x2, xctx->rect[c][n].y2, xctx->rx2,xctx->ry2); + } else { + ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, + xctx->rect[c][n].x1, xctx->rect[c][n].y1, xctx->rx1,xctx->ry1); + ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, + xctx->rect[c][n].x2, xctx->rect[c][n].y2, xctx->rx2,xctx->ry2); + } + + if( xctx->rect[c][n].sel == SELECTED) { xctx->rx1+=xctx->deltax; xctx->ry1+=xctx->deltay; - } - if( wire[n].sel & (SELECTED|SELECTED2) ) - { xctx->rx2+=xctx->deltax; xctx->ry2+=xctx->deltay; - } - wire[n].x1=xctx->rx1; - wire[n].y1=xctx->ry1; - ORDER(xctx->rx1,xctx->ry1,xctx->rx2,xctx->ry2); - if( wire[n].x1 == xctx->rx2 && wire[n].y1 == xctx->ry2) - { - if(wire[n].sel == SELECTED1) wire[n].sel = SELECTED2; - else if(wire[n].sel == SELECTED2) wire[n].sel = SELECTED1; - } - wire[n].x1=xctx->rx1; - wire[n].y1=xctx->ry1; - wire[n].x2=xctx->rx2; - wire[n].y2=xctx->ry2; - } - break; - - case LINE: - if(c!=k) break; - if(xctx->rotatelocal) { - ROTATION(xctx->move_rot, xctx->move_flip, line[c][n].x1, line[c][n].y1, - line[c][n].x1, line[c][n].y1, xctx->rx1,xctx->ry1); - ROTATION(xctx->move_rot, xctx->move_flip, line[c][n].x1, line[c][n].y1, - line[c][n].x2, line[c][n].y2, xctx->rx2,xctx->ry2); - } else { - ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, - line[c][n].x1, line[c][n].y1, xctx->rx1,xctx->ry1); - ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, - line[c][n].x2, line[c][n].y2, xctx->rx2,xctx->ry2); - } - - if( line[c][n].sel & (SELECTED|SELECTED1) ) - { - xctx->rx1+=xctx->deltax; - xctx->ry1+=xctx->deltay; - } - if( line[c][n].sel & (SELECTED|SELECTED2) ) - { - xctx->rx2+=xctx->deltax; - xctx->ry2+=xctx->deltay; - } - line[c][n].x1=xctx->rx1; - line[c][n].y1=xctx->ry1; - ORDER(xctx->rx1,xctx->ry1,xctx->rx2,xctx->ry2); - if( line[c][n].x1 == xctx->rx2 && line[c][n].y1 == xctx->ry2) - { - if(line[c][n].sel == SELECTED1) line[c][n].sel = SELECTED2; - else if(line[c][n].sel == SELECTED2) line[c][n].sel = SELECTED1; - } - line[c][n].x1=xctx->rx1; - line[c][n].y1=xctx->ry1; - line[c][n].x2=xctx->rx2; - line[c][n].y2=xctx->ry2; - break; - - case POLYGON: - if(c!=k) break; - { - xPoly *p = &xctx->poly[c][n]; - double bx1=0., by1=0., bx2=0., by2=0.; - int j; - double savex0, savey0; - savex0 = p->x[0]; - savey0 = p->y[0]; - for(j=0; jpoints; ++j) { - if(j==0 || p->x[j] < bx1) bx1 = p->x[j]; - if(j==0 || p->y[j] < by1) by1 = p->y[j]; - if(j==0 || p->x[j] > bx2) bx2 = p->x[j]; - if(j==0 || p->y[j] > by2) by2 = p->y[j]; - - if( p->sel==SELECTED || p->selected_point[j]) { - if(xctx->rotatelocal) { - ROTATION(xctx->move_rot, xctx->move_flip, savex0, savey0, p->x[j], p->y[j], - xctx->rx1,xctx->ry1); - } else { - ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, p->x[j], p->y[j], - xctx->rx1,xctx->ry1); - } - - p->x[j] = xctx->rx1+xctx->deltax; - p->y[j] = xctx->ry1+xctx->deltay; - } - - } - - for(j=0; jpoints; ++j) { - if(j==0 || p->x[j] < bx1) bx1 = p->x[j]; - if(j==0 || p->y[j] < by1) by1 = p->y[j]; - if(j==0 || p->x[j] > bx2) bx2 = p->x[j]; - if(j==0 || p->y[j] > by2) by2 = p->y[j]; - } - } - break; - - case ARC: - if(c!=k) break; - if(xctx->rotatelocal) { - /* rotate center wrt itself: do nothing */ - xctx->rx1 = xctx->arc[c][n].x; - xctx->ry1 = xctx->arc[c][n].y; - } else { - ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, - xctx->arc[c][n].x, xctx->arc[c][n].y, xctx->rx1,xctx->ry1); - } - angle = xctx->arc[c][n].a; - if(xctx->move_flip) { - angle = 270.*xctx->move_rot+180.-xctx->arc[c][n].b-xctx->arc[c][n].a; - } else { - angle = xctx->arc[c][n].a+xctx->move_rot*270.; - } - angle = fmod(angle, 360.); - if(angle<0.) angle+=360.; - - if(xctx->arc[c][n].sel == SELECTED) { - xctx->arc[c][n].x = xctx->rx1+xctx->deltax; - xctx->arc[c][n].y = xctx->ry1+xctx->deltay; - xctx->arc[c][n].a = angle; - } else if(xctx->arc[c][n].sel == SELECTED1) { - xctx->arc[c][n].x = xctx->rx1; - xctx->arc[c][n].y = xctx->ry1; - if(xctx->arc[c][n].r+xctx->deltax) xctx->arc[c][n].r = fabs(xctx->arc[c][n].r+xctx->deltax); - xctx->arc[c][n].a = angle; - } else if(xctx->arc[c][n].sel == SELECTED2) { - angle = my_round(fmod(atan2(-xctx->deltay, xctx->deltax)*180./XSCH_PI+angle, 360.)); - if(angle<0.) angle +=360.; - xctx->arc[c][n].x = xctx->rx1; - xctx->arc[c][n].y = xctx->ry1; - xctx->arc[c][n].a = angle; - } else if(xctx->arc[c][n].sel==SELECTED3) { - angle = my_round(fmod(atan2(-xctx->deltay, xctx->deltax)*180./XSCH_PI+xctx->arc[c][n].b, 360.)); - if(angle<0.) angle +=360.; - if(angle==0) angle=360.; - xctx->arc[c][n].x = xctx->rx1; - xctx->arc[c][n].y = xctx->ry1; - xctx->arc[c][n].b = angle; - } - break; - - case xRECT: - if(c!=k) break; - /* bbox before move */ - if(xctx->rotatelocal) { - ROTATION(xctx->move_rot, xctx->move_flip, xctx->rect[c][n].x1, xctx->rect[c][n].y1, - xctx->rect[c][n].x1, xctx->rect[c][n].y1, xctx->rx1,xctx->ry1); - ROTATION(xctx->move_rot, xctx->move_flip, xctx->rect[c][n].x1, xctx->rect[c][n].y1, - xctx->rect[c][n].x2, xctx->rect[c][n].y2, xctx->rx2,xctx->ry2); - } else { - ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, - xctx->rect[c][n].x1, xctx->rect[c][n].y1, xctx->rx1,xctx->ry1); - ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, - xctx->rect[c][n].x2, xctx->rect[c][n].y2, xctx->rx2,xctx->ry2); - } - - if( xctx->rect[c][n].sel == SELECTED) { - xctx->rx1+=xctx->deltax; - xctx->ry1+=xctx->deltay; - xctx->rx2+=xctx->deltax; - xctx->ry2+=xctx->deltay; - } - else if( xctx->rect[c][n].sel == SELECTED1) { /* 20070302 stretching on rectangles */ - xctx->rx1+=xctx->deltax; - xctx->ry1+=xctx->deltay; - } - else if( xctx->rect[c][n].sel == SELECTED2) { - xctx->rx2+=xctx->deltax; - xctx->ry1+=xctx->deltay; - } - else if( xctx->rect[c][n].sel == SELECTED3) { - xctx->rx1+=xctx->deltax; - xctx->ry2+=xctx->deltay; - } - else if( xctx->rect[c][n].sel == SELECTED4) { - xctx->rx2+=xctx->deltax; - xctx->ry2+=xctx->deltay; - } - else if(xctx->rect[c][n].sel==(SELECTED1|SELECTED2)) - { - xctx->ry1+=xctx->deltay; - } - else if(xctx->rect[c][n].sel==(SELECTED3|SELECTED4)) - { - xctx->ry2+=xctx->deltay; - } - else if(xctx->rect[c][n].sel==(SELECTED1|SELECTED3)) - { - xctx->rx1+=xctx->deltax; - } - else if(xctx->rect[c][n].sel==(SELECTED2|SELECTED4)) - { - xctx->rx2+=xctx->deltax; - } - - tx1 = xctx->rx1; - ty1 = xctx->ry1; - RECTORDER(xctx->rx1,xctx->ry1,xctx->rx2,xctx->ry2); - - if( xctx->rx2 == tx1) { - if(xctx->rect[c][n].sel==SELECTED1) xctx->rect[c][n].sel = SELECTED2; - else if(xctx->rect[c][n].sel==SELECTED2) xctx->rect[c][n].sel = SELECTED1; - else if(xctx->rect[c][n].sel==SELECTED3) xctx->rect[c][n].sel = SELECTED4; - else if(xctx->rect[c][n].sel==SELECTED4) xctx->rect[c][n].sel = SELECTED3; - } - if( xctx->ry2 == ty1) { - if(xctx->rect[c][n].sel==SELECTED1) xctx->rect[c][n].sel = SELECTED3; - else if(xctx->rect[c][n].sel==SELECTED3) xctx->rect[c][n].sel = SELECTED1; - else if(xctx->rect[c][n].sel==SELECTED2) xctx->rect[c][n].sel = SELECTED4; - else if(xctx->rect[c][n].sel==SELECTED4) xctx->rect[c][n].sel = SELECTED2; - } - - xctx->rect[c][n].x1 = xctx->rx1; - xctx->rect[c][n].y1 = xctx->ry1; - xctx->rect[c][n].x2 = xctx->rx2; - xctx->rect[c][n].y2 = xctx->ry2; - - /* bbox after move */ - break; - - case xTEXT: - if(k!=TEXTLAYER) break; - #if HAS_CAIRO==1 /* bbox before move */ - customfont = set_text_custom_font(&xctx->text[n]); - #endif - text_bbox(get_text_floater(n), xctx->text[n].xscale, - xctx->text[n].yscale, xctx->text[n].rot,xctx->text[n].flip, xctx->text[n].hcenter, - xctx->text[n].vcenter, xctx->text[n].x0, xctx->text[n].y0, - &xctx->rx1,&xctx->ry1, &xctx->rx2,&xctx->ry2, &tmpint, &dtmp); - #if HAS_CAIRO==1 - if(customfont) { - cairo_restore(xctx->cairo_ctx); - } - #endif - if(xctx->rotatelocal) { - ROTATION(xctx->move_rot, xctx->move_flip, xctx->text[n].x0, xctx->text[n].y0, - xctx->text[n].x0, xctx->text[n].y0, xctx->rx1,xctx->ry1); - } else { - ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, + } + else if( xctx->rect[c][n].sel == SELECTED1) { /* 20070302 stretching on rectangles */ + xctx->rx1+=xctx->deltax; + xctx->ry1+=xctx->deltay; + } + else if( xctx->rect[c][n].sel == SELECTED2) { + xctx->rx2+=xctx->deltax; + xctx->ry1+=xctx->deltay; + } + else if( xctx->rect[c][n].sel == SELECTED3) { + xctx->rx1+=xctx->deltax; + xctx->ry2+=xctx->deltay; + } + else if( xctx->rect[c][n].sel == SELECTED4) { + xctx->rx2+=xctx->deltax; + xctx->ry2+=xctx->deltay; + } + else if(xctx->rect[c][n].sel==(SELECTED1|SELECTED2)) + { + xctx->ry1+=xctx->deltay; + } + else if(xctx->rect[c][n].sel==(SELECTED3|SELECTED4)) + { + xctx->ry2+=xctx->deltay; + } + else if(xctx->rect[c][n].sel==(SELECTED1|SELECTED3)) + { + xctx->rx1+=xctx->deltax; + } + else if(xctx->rect[c][n].sel==(SELECTED2|SELECTED4)) + { + xctx->rx2+=xctx->deltax; + } + + tx1 = xctx->rx1; + ty1 = xctx->ry1; + RECTORDER(xctx->rx1,xctx->ry1,xctx->rx2,xctx->ry2); + + if( xctx->rx2 == tx1) { + if(xctx->rect[c][n].sel==SELECTED1) xctx->rect[c][n].sel = SELECTED2; + else if(xctx->rect[c][n].sel==SELECTED2) xctx->rect[c][n].sel = SELECTED1; + else if(xctx->rect[c][n].sel==SELECTED3) xctx->rect[c][n].sel = SELECTED4; + else if(xctx->rect[c][n].sel==SELECTED4) xctx->rect[c][n].sel = SELECTED3; + } + if( xctx->ry2 == ty1) { + if(xctx->rect[c][n].sel==SELECTED1) xctx->rect[c][n].sel = SELECTED3; + else if(xctx->rect[c][n].sel==SELECTED3) xctx->rect[c][n].sel = SELECTED1; + else if(xctx->rect[c][n].sel==SELECTED2) xctx->rect[c][n].sel = SELECTED4; + else if(xctx->rect[c][n].sel==SELECTED4) xctx->rect[c][n].sel = SELECTED2; + } + + xctx->rect[c][n].x1 = xctx->rx1; + xctx->rect[c][n].y1 = xctx->ry1; + xctx->rect[c][n].x2 = xctx->rx2; + xctx->rect[c][n].y2 = xctx->ry2; + + /* bbox after move */ + break; + + case xTEXT: + if(k!=TEXTLAYER) break; + #if HAS_CAIRO==1 /* bbox before move */ + customfont = set_text_custom_font(&xctx->text[n]); + #endif + text_bbox(get_text_floater(n), xctx->text[n].xscale, + xctx->text[n].yscale, xctx->text[n].rot,xctx->text[n].flip, xctx->text[n].hcenter, + xctx->text[n].vcenter, xctx->text[n].x0, xctx->text[n].y0, + &xctx->rx1,&xctx->ry1, &xctx->rx2,&xctx->ry2, &tmpint, &dtmp); + #if HAS_CAIRO==1 + if(customfont) { + cairo_restore(xctx->cairo_ctx); + } + #endif + if(xctx->rotatelocal) { + ROTATION(xctx->move_rot, xctx->move_flip, xctx->text[n].x0, xctx->text[n].y0, xctx->text[n].x0, xctx->text[n].y0, xctx->rx1,xctx->ry1); - } - xctx->text[n].x0=xctx->rx1+xctx->deltax; - xctx->text[n].y0=xctx->ry1+xctx->deltay; - xctx->text[n].rot=(xctx->text[n].rot + - ( (xctx->move_flip && (xctx->text[n].rot & 1) ) ? xctx->move_rot+2 : xctx->move_rot) ) & 0x3; - xctx->text[n].flip=xctx->move_flip^xctx->text[n].flip; - - #if HAS_CAIRO==1 /* bbox after move */ - customfont = set_text_custom_font(&xctx->text[n]); - #endif - text_bbox(get_text_floater(n), xctx->text[n].xscale, - xctx->text[n].yscale, xctx->text[n].rot,xctx->text[n].flip, xctx->text[n].hcenter, - xctx->text[n].vcenter, xctx->text[n].x0, xctx->text[n].y0, - &xctx->rx1,&xctx->ry1, &xctx->rx2,&xctx->ry2, &tmpint, &dtmp); - #if HAS_CAIRO==1 - if(customfont) { - cairo_restore(xctx->cairo_ctx); - } - #endif - - break; - - default: - break; - } /* end switch(xctx->sel_array[i].type) */ - } /* end for(i=0;ilastsel; ++i) */ - } /*end for(k=0;klastsel; ++i) { - n = xctx->sel_array[i].n; - if(xctx->sel_array[i].type == ELEMENT) { - xctx->prep_hash_inst=0; - firsti = 0; - if(xctx->rotatelocal) { - ROTATION(xctx->move_rot, xctx->move_flip, xctx->inst[n].x0, xctx->inst[n].y0, - xctx->inst[n].x0, xctx->inst[n].y0, xctx->rx1,xctx->ry1); - } else { - ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, - xctx->inst[n].x0, xctx->inst[n].y0, xctx->rx1,xctx->ry1); - } - xctx->inst[n].x0 = xctx->rx1+xctx->deltax; - xctx->inst[n].y0 = xctx->ry1+xctx->deltay; - xctx->inst[n].rot = (xctx->inst[n].rot + - ( (xctx->move_flip && (xctx->inst[n].rot & 1) ) ? xctx->move_rot+2 : xctx->move_rot) ) & 0x3; - xctx->inst[n].flip = xctx->move_flip ^ xctx->inst[n].flip; - symbol_bbox(n, - &xctx->inst[n].x1, &xctx->inst[n].y1, - &xctx->inst[n].x2, &xctx->inst[n].y2); - } + } else { + ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, + xctx->text[n].x0, xctx->text[n].y0, xctx->rx1,xctx->ry1); + } + xctx->text[n].x0=xctx->rx1+xctx->deltax; + xctx->text[n].y0=xctx->ry1+xctx->deltay; + xctx->text[n].rot=(xctx->text[n].rot + + ( (xctx->move_flip && (xctx->text[n].rot & 1) ) ? xctx->move_rot+2 : xctx->move_rot) ) & 0x3; + xctx->text[n].flip=xctx->move_flip^xctx->text[n].flip; + + #if HAS_CAIRO==1 /* bbox after move */ + customfont = set_text_custom_font(&xctx->text[n]); + #endif + text_bbox(get_text_floater(n), xctx->text[n].xscale, + xctx->text[n].yscale, xctx->text[n].rot,xctx->text[n].flip, xctx->text[n].hcenter, + xctx->text[n].vcenter, xctx->text[n].x0, xctx->text[n].y0, + &xctx->rx1,&xctx->ry1, &xctx->rx2,&xctx->ry2, &tmpint, &dtmp); + #if HAS_CAIRO==1 + if(customfont) { + cairo_restore(xctx->cairo_ctx); + } + #endif + + break; + + default: + break; + } /* end switch(xctx->sel_array[i].type) */ + } /* end for(i=0;ilastsel; ++i) */ + } /*end for(k=0;klastsel; ++i) { + n = xctx->sel_array[i].n; + if(xctx->sel_array[i].type == ELEMENT) { + xctx->prep_hash_inst=0; + firsti = 0; + if(xctx->rotatelocal) { + ROTATION(xctx->move_rot, xctx->move_flip, xctx->inst[n].x0, xctx->inst[n].y0, + xctx->inst[n].x0, xctx->inst[n].y0, xctx->rx1,xctx->ry1); + } else { + ROTATION(xctx->move_rot, xctx->move_flip, xctx->x1, xctx->y_1, + xctx->inst[n].x0, xctx->inst[n].y0, xctx->rx1,xctx->ry1); + } + xctx->inst[n].x0 = xctx->rx1+xctx->deltax; + xctx->inst[n].y0 = xctx->ry1+xctx->deltay; + xctx->inst[n].rot = (xctx->inst[n].rot + + ( (xctx->move_flip && (xctx->inst[n].rot & 1) ) ? xctx->move_rot+2 : xctx->move_rot) ) & 0x3; + xctx->inst[n].flip = xctx->move_flip ^ xctx->inst[n].flip; + symbol_bbox(n, + &xctx->inst[n].x1, &xctx->inst[n].y1, + &xctx->inst[n].x2, &xctx->inst[n].y2); + } + } + if(!firsti || !firstw) { + xctx->prep_net_structs=0; + xctx->prep_hi_structs=0; + } + /* build after copying and after recalculating prepare_netlist_structs() */ + check_collapsing_objects(); + unselect_partial_sel_wires(); + if(tclgetboolvar("autotrim_wires")) trim_wires(); + + if(xctx->hilight_nets) { + propagate_hilights(1, 1, XINSERT_NOREPLACE); + } + + xctx->ui_state &= ~STARTMOVE; + if(xctx->ui_state & STARTMERGE) xctx->ui_state |= SELECTION; /* leave selection state so objects can be deleted */ + xctx->ui_state &= ~STARTMERGE; + xctx->move_rot=xctx->move_flip=0; + xctx->x1=xctx->y_1=xctx->x2=xctx->y_2=xctx->deltax=xctx->deltay=0.; + set_modify(1); /* must be done before draw() if floaters are present to force cached values update */ + draw(); + xctx->rotatelocal=0; } - if(!firsti || !firstw) { - xctx->prep_net_structs=0; - xctx->prep_hi_structs=0; - } - /* build after copying and after recalculating prepare_netlist_structs() */ - check_collapsing_objects(); - unselect_partial_sel_wires(); - if(tclgetboolvar("autotrim_wires")) trim_wires(); - - if(xctx->hilight_nets) { - propagate_hilights(1, 1, XINSERT_NOREPLACE); - } - - xctx->ui_state &= ~STARTMOVE; - if(xctx->ui_state & STARTMERGE) xctx->ui_state |= SELECTION; /* leave selection state so objects can be deleted */ - xctx->ui_state &= ~STARTMERGE; - xctx->move_rot=xctx->move_flip=0; - xctx->x1=xctx->y_1=xctx->x2=xctx->y_2=xctx->deltax=xctx->deltay=0.; - set_modify(1); /* must be done before draw() if floaters are present to force cached values update */ - draw(); - xctx->rotatelocal=0; - - - } - draw_selection(xctx->gc[SELLAYER], 0); - if(tclgetboolvar("draw_crosshair")) draw_crosshair(0); + draw_selection(xctx->gc[SELLAYER], 0); + if(tclgetboolvar("draw_crosshair")) draw_crosshair(0); } diff --git a/src/scheduler.c b/src/scheduler.c index c558357a..b2d653fd 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -624,11 +624,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg { int ret=0; if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} - if(argc > 2) { - int n = atoi(argv[2]); - ret = descend_schematic(n); - } else { - ret = descend_schematic(0); + if(xctx->semaphore == 0) { + if(argc > 2) { + int n = atoi(argv[2]); + ret = descend_schematic(n); + } else { + ret = descend_schematic(0); + } } Tcl_SetResult(interp, dtoa(ret), TCL_VOLATILE); } @@ -638,7 +640,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if(!strcmp(argv[1], "descend_symbol")) { if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} - descend_symbol(); + if(xctx->semaphore == 0) descend_symbol(); Tcl_ResetResult(interp); } @@ -931,6 +933,15 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg Tcl_ResetResult(interp); } + /* floaters_from_selected_inst + * flatten to current level selected instance texts */ + else if(!strcmp(argv[1], "floaters_from_selected_inst")) + { + if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} + floaters_from_selected_inst(); + Tcl_ResetResult(interp); + } + /* fullscreen * Toggle fullscreen modes: fullscreen with menu & status, fullscreen, normal */ else if(!strcmp(argv[1], "fullscreen")) @@ -1658,7 +1669,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if(!strcmp(argv[1], "go_back")) { if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} - go_back(1); + if((xctx->semaphore == 0)) go_back(1); Tcl_ResetResult(interp); } else { cmd_found = 0;} diff --git a/src/select.c b/src/select.c index 8289d1c0..5ad9339e 100644 --- a/src/select.c +++ b/src/select.c @@ -940,6 +940,7 @@ void select_element(int i,unsigned short select_mode, int fast, int override_loc draw_temp_symbol(ADD, xctx->gc[SELLAYER], i,c,0,0,0.0,0.0); } } else { + symbol_bbox(i, &xctx->inst[i].x1, &xctx->inst[i].y1, &xctx->inst[i].x2, &xctx->inst[i].y2 ); for(c=0;cgctiled, i,c,0,0,0.0,0.0); } @@ -1581,6 +1582,65 @@ void select_touch(double x1,double y1, double x2, double y2, int sel) /*added un } + +int floaters_from_selected_inst() +{ + int res = 0, first = 1; + int i, n, t; + int instrot, instflip; + double instx0, insty0; + xSymbol *sym; + for(n = 0; n < xctx->lastsel; ++n) { + i = xctx->sel_array[n].n; + if(xctx->sel_array[n].type == ELEMENT) { + if(xctx->inst[i].ptr < 0) continue; + if(xctx->inst[i].flags & HIDE_SYMBOL_TEXTS) continue; + sym = xctx->sym + xctx->inst[i].ptr; + if( sym->type && (IS_LABEL_SH_OR_PIN(sym->type) || !strcmp(sym->type, "probe") )) continue; + instx0 = xctx->inst[i].x0; + insty0 = xctx->inst[i].y0; + instrot = xctx->inst[i].rot; + instflip = xctx->inst[i].flip; + if(first) { + xctx->push_undo(); + set_modify(1); + first = 0; + } + my_strdup2(_ALLOC_ID_, &xctx->inst[i].prop_ptr, + subst_token(xctx->inst[i].prop_ptr, "hide_texts", "true")); + set_inst_flags(&xctx->inst[i]); + for(t = 0; t < sym->texts; t++) { + double txtx0, txty0; + int txtrot, txtflip; + int rot, flip; + double x0, y0; + xText *symtxt; + symtxt = &sym->text[t]; + if(strstr(symtxt->txt_ptr, ":net_name")) continue; + txtx0 = symtxt->x0; + txty0 = symtxt->y0; + txtrot = symtxt->rot; + txtflip = symtxt->flip; + + rot = (txtrot + ( (instflip && (txtrot & 1) ) ? instrot+2 : instrot) ) & 0x3; + flip = txtflip ^ instflip; + + ROTATION(instrot, instflip, 0.0, 0.0, txtx0, txty0, x0, y0); + x0 += instx0; + y0 += insty0; + + create_text(0, x0, y0, rot, flip, symtxt->txt_ptr, + subst_token(symtxt->prop_ptr, "name", xctx->inst[i].instname), + symtxt->xscale, symtxt->yscale); + + set_text_flags(symtxt); + dbg(1, "instance %d: symtext %d: %s\n", i, t, symtxt->txt_ptr); + } + } + } + return res; +} + void select_all(void) { int c,i; diff --git a/src/token.c b/src/token.c index c747901f..648a08de 100644 --- a/src/token.c +++ b/src/token.c @@ -481,7 +481,9 @@ const char *get_tok_value(const char *s,const char *tok, int with_quotes) result[0] = '\0'; return result; } - if( (with_quotes & 1) || escape || (c != '\\' && c != '"')) token[token_pos++]=(char)c; + /* if( (with_quotes & 1) || escape || (c != '\\' && c != '"')) token[token_pos++]=(char)c; */ + token[token_pos++]=(char)c; + } else if(state == TOK_VALUE) { if( with_quotes & 1) result[value_pos++] = (char)c; else if(( with_quotes & 4) && (escape || c != '"')) result[value_pos++] = (char)c; diff --git a/src/xschem.h b/src/xschem.h index 6a869270..302c55ef 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1236,6 +1236,7 @@ extern void print_version(void); extern int set_netlist_dir(int force, const char *dir); extern void netlist_options(int i); extern int check_lib(int what, const char *s); +extern int floaters_from_selected_inst(); extern void select_all(void); extern void change_linewidth(double w); extern void schematic_in_new_window(int new_process); diff --git a/tests/xschemtest.tcl b/tests/xschemtest.tcl index df8caf63..c0f135a6 100644 --- a/tests/xschemtest.tcl +++ b/tests/xschemtest.tcl @@ -198,7 +198,7 @@ proc netlist_test {} { hierarchical_tedax.sch tedax 998070173 LCC_instances.sch spice 1619668159 pcb_test1.sch tedax 1925087189 - test_doublepin.sch spice 3039193840 + test_doublepin.sch spice 4159808692 simulate_ff.sch spice 574849766 test_symbolgen.sch spice 2593807370 inst_sch_select.sch spice 801962545