diff --git a/src/Makefile.in b/src/Makefile.in index 858c8659..4eec5b71 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -17,7 +17,6 @@ put /local/install_shares { add_custom_button.tcl change_index.tcl icon.xpm resources.tcl xschemrc ngspice_backannotate.tcl gschemtoxschem.awk mouse_bindings.tcl place_sym_pins.tcl place_pins.tcl make_sch_from_spice.awk make_sym_from_spice.awk - create_symbol.tcl } # generate a list of objects from the list of source files diff --git a/src/actions.c b/src/actions.c index 5601e43b..7bcc6d42 100644 --- a/src/actions.c +++ b/src/actions.c @@ -898,7 +898,7 @@ int set_text_flags(xText *t) t->flags = 0; t->hcenter = 0; t->vcenter = 0; - t->layer = -1; + t->layer = -1; /* -1 means default TEXTLAYER is to be used */ if(t->prop_ptr) { my_strdup(_ALLOC_ID_, &t->font, get_tok_value(t->prop_ptr, "font", 0)); str = get_tok_value(t->prop_ptr, "hcenter", 0); diff --git a/src/callback.c b/src/callback.c index 4c8e98ff..9c962dc6 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1373,6 +1373,7 @@ void draw_crosshair(int what, int state) int sdw, sdp; int xhair_size = tclgetintvar("crosshair_size"); double mx, my; + int changed = 0; dbg(1, "draw_crosshair(): what=%d\n", what); sdw = xctx->draw_window; sdp = xctx->draw_pixmap; @@ -1382,9 +1383,25 @@ void draw_crosshair(int what, int state) my = xctx->mousey_snap; if( ( (xctx->ui_state & (MENUSTART | STARTWIRE) ) || xctx->ui_state == 0 ) && (state == ShiftMask) ) { - find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &mx, &my); + /* mouse not changed so closest net or symbol pin unchanged too */ + if(mx == xctx->prev_m_crossx && my == xctx->prev_m_crossy) { + mx = xctx->prev_crossx; /* get previous one */ + my = xctx->prev_crossy; + } else { + /* mouse position changed, so find new closest net or pin */ + find_closest_net_or_symbol_pin(xctx->mousex_snap, xctx->mousey_snap, &mx, &my); + changed = 1; /* we force a cursor redraw */ + dbg(1, "find\n"); + } } - if(!(what & 4) && mx == xctx->prev_crossx && my == xctx->prev_crossy) return; + + /* no changed closest pin/net, no force, mx,my is not changed. --> do nothing + | _____________| | + | | _____________________|____________________________ */ + if(!changed && !(what & 4) && mx == xctx->prev_crossx && my == xctx->prev_crossy) { + return; + } + dbg(1, "draw %d\n", what); xctx->draw_pixmap = 0; xctx->draw_window = 1; if(what & 1) { /* delete previous */ @@ -1477,9 +1494,14 @@ void draw_crosshair(int what, int state) } } if(what) draw_selection(xctx->gc[SELLAYER], 0); + if(what & 2) { + /* previous closest pin or net position (if snap wire or Shift pressed) */ xctx->prev_crossx = mx; xctx->prev_crossy = my; + /* previous mouse_snap position */ + xctx->prev_m_crossx = xctx->mousex_snap; + xctx->prev_m_crossy = xctx->mousey_snap; } xctx->draw_window = sdw; diff --git a/src/create_symbol.tcl b/src/create_symbol.tcl deleted file mode 100644 index 48b35491..00000000 --- a/src/create_symbol.tcl +++ /dev/null @@ -1,61 +0,0 @@ -# -# File: create_symbol.tcl -# -# This file is part of XSCHEM, -# a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit -# simulation. -# Copyright (C) 1998-2024 Stefan Frederik Schippers -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# -# Create an xschem symbol from a list of in, inout, out pins. -# Example: -# create_symbol test.sym {CLK RST D} {Q QB} {VCC VSS} -# -proc create_symbol {name {in {}} {out {}} {inout {}}} { - set symname [file rootname $name].sym - set res [catch {open $symname {WRONLY CREAT EXCL}} fd] - if {$res} {puts $fd; return 0} ;# Error. Print reason and exit. - puts $fd {v {xschem version=3.4.6RC file_version=1.2}} - puts $fd {K {type=subcircuit format="@name @pinlist @symname" template="name=X1"}} - set x -150 - set y 0 - foreach pin $in { ;# create all input pins on the left - puts $fd "B 5 [expr {$x - 2.5}] [expr {$y - 2.5}] [expr {$x + 2.5}] [expr {$y + 2.5}] {name=$pin dir=in}" - puts $fd "T {$pin} [expr {$x + 25}] [expr {$y - 6}] 0 0 0.2 0.2 {}" - puts $fd "L 4 $x $y [expr {$x + 20}] $y {}" - incr y 20 - } - set x 150 - set y 0 - foreach pin $out { ;# create all out pins on the top right - puts $fd "B 5 [expr {$x - 2.5}] [expr {$y - 2.5}] [expr {$x + 2.5}] [expr {$y + 2.5}] {name=$pin dir=out}" - puts $fd "T {$pin} [expr {$x - 25}] [expr {$y - 6}] 0 1 0.2 0.2 {}" - puts $fd "L 4 [expr {$x - 20}] $y $x $y {}" - incr y 20 - } - foreach pin $inout { ;# create all inout pins on the bottom right - puts $fd "B 5 [expr {$x - 2.5}] [expr {$y - 2.5}] [expr {$x + 2.5}] [expr {$y + 2.5}] {name=$pin dir=inout}" - puts $fd "T {$pin} [expr {$x - 25}] [expr {$y - 6}] 0 1 0.2 0.2 {}" - puts $fd "L 7 [expr {$x - 20}] $y $x $y {}" - incr y 20 - } - puts $fd "B 4 -130 -10 130 [expr {$y - 10}] {fill=0}" ;# symbol box - puts $fd "T {@symname} 0 [expr {($y - 20) / 2}] 0 0 0.3 0.3 {hcenter=1 vcenter=1}" ;#symbol name - puts $fd "T {@name} 130 -10 2 1 0.2 0.2 {}" ;# instance name - close $fd - puts "Created symbol ${symname}" - return 1 -} diff --git a/src/draw.c b/src/draw.c index 731f9c25..b6c5fe6e 100644 --- a/src/draw.c +++ b/src/draw.c @@ -490,63 +490,23 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot, xPoly *polygon; xText text; register xSymbol *symptr; - double angle; char *type; int lvs_ignore = 0; #if HAS_CAIRO==1 const char *textfont; #endif + type = xctx->sym[xctx->inst[n].ptr].type; lvs_ignore=tclgetboolvar("lvs_ignore"); + if(!has_x) return; if(xctx->inst[n].ptr == -1) return; if(layer == 0) { - char *type = xctx->sym[xctx->inst[n].ptr].type; - xctx->inst[n].flags &= ~IGNORE_INST; /* clear bit */ if( type && strcmp(type, "launcher") && strcmp(type, "logo") && strcmp(type, "probe") && strcmp(type, "architecture") && strcmp(type, "noconn")) { - if( - ( - xctx->netlist_type == CAD_SPICE_NETLIST && - ( - (xctx->inst[n].flags & SPICE_IGNORE) || - (xctx->sym[xctx->inst[n].ptr].flags & SPICE_IGNORE) - ) - ) || - - ( - xctx->netlist_type == CAD_VERILOG_NETLIST && - ( - (xctx->inst[n].flags & VERILOG_IGNORE) || - (xctx->sym[xctx->inst[n].ptr].flags & VERILOG_IGNORE) - ) - ) || - - ( - xctx->netlist_type == CAD_VHDL_NETLIST && - ( - (xctx->inst[n].flags & VHDL_IGNORE) || - (xctx->sym[xctx->inst[n].ptr].flags & VHDL_IGNORE) - ) - ) || - - ( - xctx->netlist_type == CAD_TEDAX_NETLIST && - ( - (xctx->inst[n].flags & TEDAX_IGNORE) || - (xctx->sym[xctx->inst[n].ptr].flags & TEDAX_IGNORE) - ) - ) || - ( - lvs_ignore && - ( - (xctx->inst[n].flags & LVS_IGNORE_OPEN) || - (xctx->sym[xctx->inst[n].ptr].flags & LVS_IGNORE_OPEN) - ) - ) - ) { - xctx->inst[n].flags |= IGNORE_INST; /* *_IGNORE_INST in current netlisting mode as evaluated above */ + if(skip_instance(n, 1, lvs_ignore)) { + xctx->inst[n].flags |= IGNORE_INST; } } } @@ -560,8 +520,6 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot, what = NOW; disabled = 1; } - - if(!has_x) return; if( (xctx->inst[n].flags & HIDE_INST) || (xctx->hide_symbols==1 && (xctx->inst[n].ptr+ xctx->sym)->prop_ptr && !strcmp( (xctx->inst[n].ptr+ xctx->sym)->type, "subcircuit") ) || @@ -570,7 +528,6 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot, } else { hide = 0; } - type = (xctx->inst[n].ptr+ xctx->sym)->type; if(layer==0) { x1=X_TO_SCREEN(xctx->inst[n].x1+xoffset); /* 20150729 added xoffset, yoffset */ x2=X_TO_SCREEN(xctx->inst[n].x2+xoffset); @@ -611,7 +568,6 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot, dbg(2, "draw_symbol(): skipping inst %d\n", n); return; } - flip = xctx->inst[n].flip; if(tmp_flip) flip = !flip; rot = (xctx->inst[n].rot + rot ) & 0x3; @@ -657,6 +613,7 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot, for(j=0;j< symptr->arcs[layer]; ++j) { int dash; + double angle; arc = &(symptr->arc[layer])[j]; dash = (disabled == 1) ? 3 : arc->dash; if(flip) { @@ -671,7 +628,7 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot, } } /* if(!hide) */ - if( (!hide && xctx->enable_layer[layer]) || + if( (!hide && xctx->enable_layer[layer]) || (hide && layer == PINLAYER && xctx->enable_layer[layer]) ) { for(j=0;j< symptr->rects[layer]; ++j) { @@ -714,7 +671,7 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot, ellipse_a, ellipse_b); } } - } + } /* if( (!hide && xctx->enable_layer[layer]) || ... */ draw_texts: @@ -814,7 +771,6 @@ void draw_temp_symbol(int what, GC gc, int n,int layer,short tmp_flip, short rot xArc *arc; xText text; register xSymbol *symptr; - double angle; #if HAS_CAIRO==1 int customfont; @@ -919,6 +875,7 @@ void draw_temp_symbol(int what, GC gc, int n,int layer,short tmp_flip, short rot } for(j=0;j< symptr->arcs[layer]; ++j) { + double angle; arc = &(symptr->arc[layer])[j]; if(flip) { angle = 270.*rot+180.-arc->b-arc->a; diff --git a/src/findnet.c b/src/findnet.c index 2616a697..ba36fc71 100644 --- a/src/findnet.c +++ b/src/findnet.c @@ -32,18 +32,20 @@ static void find_closest_wire(double mx, double my) double tmp; int i, w=-1; double threshold; + double d = distance; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; - + for(i=0;iwires; ++i) { - if( (tmp = dist(xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2, mx, my)) < distance ) + if( (tmp = dist(xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2, mx, my)) < d ) { - w = i; distance = tmp; + w = i; d = tmp; } } - if( distance <= threshold && w!=-1) + if( d <= threshold && w!=-1) { - sel.n = w; sel.type = WIRE; + sel.n = w; sel.type = WIRE; + distance = d; } } @@ -112,6 +114,7 @@ static void find_closest_polygon(double mx, double my) int i, c, j, l=-1, col = 0, bezier; double x1, y1, x2, y2; double threshold; + double d = distance; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; for(c=0;cpoints; j++) { if( POINTINSIDE(mx, my, p->x[j] - ds, p->y[j] - ds, p->x[j] + ds, p->y[j] + ds)) { - l = i; distance = 0.0;col = c; + l = i; d = 0.0;col = c; break; } } @@ -139,18 +142,19 @@ static void find_closest_polygon(double mx, double my) x2 = p->x[j+1]; y2 = p->y[j+1]; ORDER(x1, y1, x2, y2); - if( (tmp = dist(x1, y1, x2, y2, mx, my)) < distance ) + if( (tmp = dist(x1, y1, x2, y2, mx, my)) < d ) { - l = i; distance = tmp;col = c; - dbg(1, "find_closest_polygon(): distance=%.16g n=%d\n", distance, i); + l = i; d = tmp;col = c; + dbg(1, "find_closest_polygon(): d=%.16g n=%d\n", d, i); } } } } /* end for i */ } /* end for c */ - if( distance <= threshold && l!=-1) + if( d <= threshold && l!=-1) { sel.n = l; sel.type = POLYGON; sel.col = col; + distance = d; } } @@ -162,6 +166,7 @@ static void find_closest_line(double mx, double my) double tmp; int i, c, l = -1, col = 0; double threshold; + double d = distance; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; for(c=0;clines[c]; ++i) { if( (tmp = dist(xctx->line[c][i].x1, xctx->line[c][i].y1, xctx->line[c][i].x2, xctx->line[c][i].y2, mx, my)) - < distance ) + < d ) { - l = i; distance = tmp;col = c; - dbg(1, "find_closest_line(): distance=%.16g n=%d\n", distance, i); + l = i; d = tmp;col = c; + dbg(1, "find_closest_line(): d=%.16g n=%d\n", d, i); } } /* end for i */ } /* end for c */ - if( distance <= threshold && l!=-1) + if( d <= threshold && l!=-1) { sel.n = l; sel.type = LINE; sel.col = col; + distance = d; } } @@ -326,6 +332,7 @@ static void find_closest_arc(double mx, double my) int i, c, r=-1, col; int match; double threshold; + double d = distance; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; for(c=0;carcs[c]; ++i) { dist = sqrt(pow(mx-xctx->arc[c][i].x, 2) + pow(my-xctx->arc[c][i].y, 2)) - xctx->arc[c][i].r; - dist *= dist; /* square distance */ + dist *= dist; /* square d */ angle = fmod(atan2(xctx->arc[c][i].y-my, mx-xctx->arc[c][i].x)*180./XSCH_PI, 360.); if(angle<0.) angle +=360.; angle1 = xctx->arc[c][i].a; angle2 = fmod(xctx->arc[c][i].a + xctx->arc[c][i].b, 360.); match=0; - if(dist < distance) { + if(dist < d) { if(xctx->arc[c][i].b==360.) match=1; if(angle2= angle1 || angle<= angle2) { @@ -359,14 +366,15 @@ static void find_closest_arc(double mx, double my) if(match ) { dbg(1, "find_closest_arc(): i = %d\n", i); r = i; - distance = dist; + d = dist; col = c; } } /* end for i */ } /* end for c */ - if( r!=-1 && distance <= threshold ) /* * pow(xctx->arc[col][r].r, 2)) */ + if( r!=-1 && d <= threshold ) /* * pow(xctx->arc[col][r].r, 2)) */ { sel.n = r; sel.type = ARC; sel.col = col; + distance = d; } } @@ -376,6 +384,7 @@ static void find_closest_box(double mx ,double my, int override_lock) double tmp; double ds = xctx->cadhalfdotsize; int i, c, r=-1, col = 0; + double d = distance; /* correction for very small boxes */ for(c=0;crect[c][i].x1, xctx->rect[c][i].y1, xctx->rect[c][i].x2, xctx->rect[c][i].y2); - if(tmp < distance) + if(tmp < d) { - r = i; distance = tmp;col = c; + r = i; d = tmp;col = c; } } } /* end for i */ } /* end for c */ - dbg(1, "find_closest_box(): distance=%.16g\n", distance); + dbg(1, "find_closest_box(): d=%.16g\n", d); if( r!=-1 && (override_lock || strboolcmp(get_tok_value(xctx->rect[col][r].prop_ptr, "lock", 0), "true"))) { sel.n = r; sel.type = xRECT; sel.col = col; + distance = d; } } @@ -408,6 +418,7 @@ static void find_closest_element(double mx, double my, int override_lock) { double tmp; int i, r=-1; + double d = distance; for(i = 0;i < xctx->instances; ++i) { dbg(1, "find_closest_element(): %s: %g %g %g %g\n", @@ -415,14 +426,15 @@ static void find_closest_element(double mx, double my, int override_lock) if( POINTINSIDE(mx, my, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2) ) { tmp=dist_from_rect(mx, my, xctx->inst[i].xx1, xctx->inst[i].yy1, xctx->inst[i].xx2, xctx->inst[i].yy2); - if(tmp < distance) + if(tmp < d) { - r = i; distance = tmp; + r = i; d = tmp; } dbg(2, "find_closest_element(): finding closest element, instances=%d, dist=%.16g\n", i, tmp); } } /* end for i */ if( r != -1 && (override_lock || strboolcmp(get_tok_value(xctx->inst[r].prop_ptr, "lock", 0), "true")) ) { + distance = d; sel.n = r; sel.type = ELEMENT; } } @@ -437,6 +449,7 @@ static void find_closest_text(double mx, double my) int customfont; #endif char *estr = NULL; + double d = distance; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; for(i=0;itexts; ++i) { @@ -459,13 +472,14 @@ static void find_closest_text(double mx, double my) #endif if(POINTINSIDE(mx, my, xx1, yy1, xx2, yy2)) { - r = i; distance = 0; - dbg(2, "find_closest_text(): finding closest text, texts=%d, dist=%.16g\n", i, distance); + r = i; d = 0; + dbg(2, "find_closest_text(): finding closest text, texts=%d, dist=%.16g\n", i, d); } } /* end for i */ - if( distance <= threshold && r!=-1) + if( d <= threshold && r!=-1) { sel.n = r; sel.type = xTEXT; + distance = d; } } diff --git a/src/make_sch_from_spice.awk b/src/make_sch_from_spice.awk index d009e19d..7913d15a 100755 --- a/src/make_sch_from_spice.awk +++ b/src/make_sch_from_spice.awk @@ -700,7 +700,7 @@ function print_sym(sym, template, format, subckt_name, sym_type, extra, dir, pin print "start print symbol: " sym - print "v {xschem version=3.4.6RC file_version=1.2}" > sym + print "v {xschem version=3.4.6 file_version=1.2}" > sym print "K {type=" sym_type > sym # print "format=\"@name @pinlist @symname " format_translate(template) "\"" > sym iii = format_translate(template, extra) diff --git a/src/make_sym.awk b/src/make_sym.awk index e74d1617..af0fca20 100755 --- a/src/make_sym.awk +++ b/src/make_sym.awk @@ -68,7 +68,7 @@ function beginfile(f) text_voffset=20 lab_voffset=4 ip=op=n_pin=0 - print "v {xschem version=3.4.6RC file_version=1.2}" > sym + print "v {xschem version=3.4.6 file_version=1.2}" > sym if(template !~/^{[ \t\n]*$/) { printf "%s", "K {type=subcircuit\nformat=\"@name @pinlist @symname\"\n" >sym printf "%s\n", "template=\"name=x1\"" >sym diff --git a/src/make_sym_from_spice.awk b/src/make_sym_from_spice.awk index 64bb3a36..2ca161e8 100755 --- a/src/make_sym_from_spice.awk +++ b/src/make_sym_from_spice.awk @@ -401,7 +401,7 @@ function print_sym(sym, template, format, subckt_name, sym_type, extra, dir, pin print "start print symbol: " sym - print "v {xschem version=3.4.6RC file_version=1.2}" > sym + print "v {xschem version=3.4.6 file_version=1.2}" > sym print "K {type=" sym_type > sym # print "format=\"@name @pinlist @symname " format_translate(template) "\"" > sym iii = format_translate(template, extra) diff --git a/src/make_sym_lcc.awk b/src/make_sym_lcc.awk index 910140cb..4df4b81c 100644 --- a/src/make_sym_lcc.awk +++ b/src/make_sym_lcc.awk @@ -61,7 +61,7 @@ function beginfile(f) text_voffset=10 lab_voffset=4 ip=op=n_pin=n_p=n_l=0 - print "v {xschem version=2.9.8 file_version=1.2}" > sym + print "v {xschem version=3.4.6 file_version=1.2}" > sym if(template=="") { printf "%s", "K {type=subcircuit\nformat=\"@name @pinlist @symname\"\n" >sym printf "%s\n", "template=\"name=x1\"" >sym diff --git a/src/netlist.c b/src/netlist.c index c39947e5..4180d46d 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -1040,7 +1040,8 @@ int shorted_instance(int i, int lvs_ignore) if(inst[i].ptr < 0) shorted = 0; else if(lvs_ignore) { if((inst[i].flags & LVS_IGNORE_SHORT) || (sym[inst[i].ptr].flags & LVS_IGNORE_SHORT) ) shorted = 1; - } else if(xctx->netlist_type == CAD_SPICE_NETLIST) { + } + if(xctx->netlist_type == CAD_SPICE_NETLIST) { if((inst[i].flags & SPICE_SHORT) || (sym[inst[i].ptr].flags & SPICE_SHORT) ) shorted = 1; } else if(xctx->netlist_type == CAD_VERILOG_NETLIST) { if((inst[i].flags & VERILOG_SHORT) || (sym[inst[i].ptr].flags & VERILOG_SHORT) ) shorted = 1; @@ -1703,8 +1704,8 @@ int sym_vs_sch_pins(int all) fprintf(errfp,"sym_vs_sch_pins(): WARNING: missing fields for LINE/BOX object, ignoring\n"); read_line(fd, 0); break; - } - load_ascii_string(&tmp, fd); + } + load_ascii_string(&tmp, fd); break; case 'P': if(fscanf(fd, "%d %d",&tmpi, &tmpi)<2) { diff --git a/src/psprint.c b/src/psprint.c index 07daae01..6ea4281a 100644 --- a/src/psprint.c +++ b/src/psprint.c @@ -859,27 +859,54 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho double xoffset, double yoffset) /* draws current layer only, should be called within */ { /* a "for(i=0;isym[xctx->inst[n].ptr].type; + lvs_ignore=tclgetboolvar("lvs_ignore"); if(xctx->inst[n].ptr == -1) return; - if( (layer != PINLAYER && !xctx->enable_layer[layer]) ) return; - if( (xctx->hide_symbols==1 && (xctx->inst[n].ptr+ xctx->sym)->prop_ptr && - !strcmp( (xctx->inst[n].ptr+ xctx->sym)->type, "subcircuit") ) || (xctx->hide_symbols == 2) ) { + if(layer == 0) { + xctx->inst[n].flags &= ~IGNORE_INST; /* clear bit */ + if( type && strcmp(type, "launcher") && strcmp(type, "logo") && + strcmp(type, "probe") && + strcmp(type, "architecture") && strcmp(type, "noconn")) { + if(skip_instance(n, 1, lvs_ignore)) { + xctx->inst[n].flags |= IGNORE_INST; + } + } + } + + if(shorted_instance(n, lvs_ignore)) { + c = PINLAYER; + what = NOW; + disabled = 2; + } + else if(xctx->inst[n].flags & IGNORE_INST) { + c = GRIDLAYER; + what = NOW; + disabled = 1; + } + if(xctx->inst[n].color != -10000) c = get_color(xctx->inst[n].color); + set_ps_colors(c); + if( (xctx->inst[n].flags & HIDE_INST) || + ((xctx->hide_symbols==1 && (xctx->inst[n].ptr+ xctx->sym)->prop_ptr && + !strcmp( (xctx->inst[n].ptr+ xctx->sym)->type, "subcircuit") )) || + (xctx->hide_symbols == 2) ) { hide = 1; } else { hide = 0; } - if(layer==0) { x1=X_TO_PS(xctx->inst[n].x1); @@ -891,8 +918,34 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho xctx->inst[n].flags|=1; return; } - else xctx->inst[n].flags&=~1; - + #if 0 + else if( + xctx->hilight_nets && /* if highlights... */ + c == 0 && /* we are not drawing highlighted inst */ + /* otherwise c > layer... */ + type && /* ... and type... */ + ( + ( /* ... and inst is hilighted ... */ + IS_LABEL_SH_OR_PIN(type) && xctx->inst[n].node && xctx->inst[n].node[0] && + bus_hilight_hash_lookup(xctx->inst[n].node[0], 0, XLOOKUP ) + ) || (/* !IS_LABEL_SH_OR_PIN(type) && */ (xctx->inst[n].color != -10000)) )) { + xctx->inst[n].flags|=1; /* ... then SKIP instance now and for following layers */ + return; + } + #endif + else if((xctx->inst[n].x2 - xctx->inst[n].x1) * xctx->mooz < 3 && + (xctx->inst[n].y2 - xctx->inst[n].y1) * xctx->mooz < 3) { + ps_filledrect(c, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 0, 0); + xctx->inst[n].flags|=1; + return; + } + else { + xctx->inst[n].flags&=~1; + } + if(hide) { + int color = (disabled==1) ? GRIDLAYER : (disabled == 2) ? PINLAYER : SYMLAYER; + ps_filledrect(color, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 2, 0); + } /* pdfmarks, only if doing hierarchy print and if symbol has a subcircuit */ if(what != 7) { char fname[PATH_MAX]; @@ -912,7 +965,7 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho } else if(xctx->inst[n].flags&1) { - dbg(1, "draw_symbol(): skippinginst %d\n", n); + dbg(1, "draw_symbol(): skipping inst %d\n", n); return; } flip = xctx->inst[n].flip; @@ -922,61 +975,81 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho x0=xctx->inst[n].x0 + xoffset; y0=xctx->inst[n].y0 + yoffset; symptr = (xctx->inst[n].ptr+ xctx->sym); - for(j=0;j< (xctx->inst[n].ptr+ xctx->sym)->lines[layer]; ++j) - { - line = ((xctx->inst[n].ptr+ xctx->sym)->line[layer])[j]; - ROTATION(rot, flip, 0.0,0.0,line.x1,line.y1,x1,y1); - ROTATION(rot, flip, 0.0,0.0,line.x2,line.y2,x2,y2); - ORDER(x1,y1,x2,y2); - ps_drawline(c, x0+x1, y0+y1, x0+x2, y0+y2, line.dash); - } - for(j=0;j< (xctx->inst[n].ptr+ xctx->sym)->polygons[layer]; ++j) - { - polygon = &((xctx->inst[n].ptr+ xctx->sym)->poly[layer])[j]; - { /* scope block so we declare some auxiliary arrays for coord transforms. 20171115 */ - int k, bezier; - double *x = my_malloc(_ALLOC_ID_, sizeof(double) * polygon->points); - double *y = my_malloc(_ALLOC_ID_, sizeof(double) * polygon->points); - for(k=0;kpoints; ++k) { - ROTATION(rot, flip, 0.0,0.0,polygon->x[k],polygon->y[k],x[k],y[k]); - x[k]+= x0; - y[k] += y0; - } - bezier = !strboolcmp(get_tok_value(polygon->prop_ptr, "bezier", 0), "true"); - ps_drawpolygon(c, NOW, x, y, polygon->points, polygon->fill, polygon->dash, bezier); - my_free(_ALLOC_ID_, &x); - my_free(_ALLOC_ID_, &y); - } - } - if((xctx->inst[n].ptr+ xctx->sym)->arcs[layer]) fprintf(fd, "NP\n"); /* newpath */ - for(j=0;j< (xctx->inst[n].ptr+ xctx->sym)->arcs[layer]; ++j) - { - double angle; - arc = ((xctx->inst[n].ptr+ xctx->sym)->arc[layer])[j]; - if(flip) { - angle = 270.*rot+180.-arc.b-arc.a; - } else { - angle = arc.a+rot*270.; + if( (layer != PINLAYER && !xctx->enable_layer[layer]) ) goto draw_texts; + + if(!hide) { + for(j=0;j< symptr->lines[layer]; ++j) + { + int dash; + line = &(symptr->line[layer])[j]; + dash = (disabled == 1) ? 3 : line->dash; + ROTATION(rot, flip, 0.0,0.0,line->x1,line->y1,x1,y1); + ROTATION(rot, flip, 0.0,0.0,line->x2,line->y2,x2,y2); + ORDER(x1,y1,x2,y2); + ps_drawline(c, x0+x1, y0+y1, x0+x2, y0+y2, dash); } - angle = fmod(angle, 360.); - if(angle<0.) angle+=360.; - ROTATION(rot, flip, 0.0,0.0,arc.x,arc.y,x1,y1); - ps_drawarc(c, arc.fill, x0+x1, y0+y1, arc.r, angle, arc.b, arc.dash); - } - if( xctx->enable_layer[layer] ) for(j=0;j< (xctx->inst[n].ptr+ xctx->sym)->rects[layer]; ++j) - { - rect = ((xctx->inst[n].ptr+ xctx->sym)->rect[layer])[j]; - ROTATION(rot, flip, 0.0,0.0,rect.x1,rect.y1,x1,y1); - ROTATION(rot, flip, 0.0,0.0,rect.x2,rect.y2,x2,y2); - RECTORDER(x1,y1,x2,y2); - if (rect.flags & 1024) /* image */ - { - ps_embedded_image(&rect, x0 + x1, y0 + y1, x0 + x2, y0 + y2, rot, flip); - continue; - } - ps_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, rect.dash, rect.fill); - } + for(j=0;j< symptr->polygons[layer]; ++j) + { + int dash; + int bezier; + polygon = &(symptr->poly[layer])[j]; + bezier = !strboolcmp(get_tok_value(polygon->prop_ptr, "bezier", 0), "true"); + dash = (disabled == 1) ? 3 : polygon->dash; + { /* scope block so we declare some auxiliary arrays for coord transforms. 20171115 */ + int k; + double *x = my_malloc(_ALLOC_ID_, sizeof(double) * polygon->points); + double *y = my_malloc(_ALLOC_ID_, sizeof(double) * polygon->points); + for(k=0;kpoints; ++k) { + ROTATION(rot, flip, 0.0,0.0,polygon->x[k],polygon->y[k],x[k],y[k]); + x[k]+= x0; + y[k] += y0; + } + ps_drawpolygon(c, NOW, x, y, polygon->points, polygon->fill, dash, bezier); + my_free(_ALLOC_ID_, &x); + my_free(_ALLOC_ID_, &y); + } + } + if(symptr->arcs[layer]) fprintf(fd, "NP\n"); /* newpath */ + for(j=0;j< symptr->arcs[layer]; ++j) + { + int dash; + double angle; + arc = &(symptr->arc[layer])[j]; + dash = (disabled == 1) ? 3 : arc->dash; + if(flip) { + angle = 270.*rot+180.-arc->b-arc->a; + } else { + angle = arc->a+rot*270.; + } + angle = fmod(angle, 360.); + if(angle<0.) angle+=360.; + ROTATION(rot, flip, 0.0,0.0,arc->x,arc->y,x1,y1); + ps_drawarc(c, arc->fill, x0+x1, y0+y1, arc->r, angle, arc->b, dash); + } + } /* if(!hide) */ + + if( (!hide && xctx->enable_layer[layer]) || + (hide && layer == PINLAYER && xctx->enable_layer[layer]) ) { + for(j=0;j< symptr->rects[layer]; ++j) + { + int dash; + rect = &(symptr->rect[layer])[j]; + dash = (disabled == 1) ? 3 : rect->dash; + ROTATION(rot, flip, 0.0,0.0,rect->x1,rect->y1,x1,y1); + ROTATION(rot, flip, 0.0,0.0,rect->x2,rect->y2,x2,y2); + RECTORDER(x1,y1,x2,y2); + if (layer == GRIDLAYER && rect->flags & 1024) /* image */ + { + ps_embedded_image(rect, x0 + x1, y0 + y1, x0 + x2, y0 + y2, rot, flip); + continue; + } + ps_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, dash, rect->fill); + } + } /* if( (!hide && xctx->enable_layer[layer]) || ... */ + + draw_texts: + if( !(xctx->inst[n].flags & HIDE_SYMBOL_TEXTS) && ( @@ -991,18 +1064,25 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho double xscale, yscale; get_sym_text_size(n, j, &xscale, &yscale); - text = (xctx->inst[n].ptr+ xctx->sym)->text[j]; + text = symptr->text[j]; /* if(xscale*FONTWIDTH* xctx->mooz<1) continue; */ if(!xctx->show_hidden_texts && (text.flags & (HIDE_TEXT | HIDE_TEXT_INSTANTIATED))) continue; if( hide && text.txt_ptr && strcmp(text.txt_ptr, "@symname") && strcmp(text.txt_ptr, "@name") ) continue; txtptr= translate(n, text.txt_ptr); ROTATION(rot, flip, 0.0,0.0,text.x0,text.y0,x1,y1); textlayer = c; - /* do not allow custom text color on PINLAYER hilighted instances */ - if( !(xctx->inst[n].color == -PINLAYER)) { - textlayer = (xctx->inst[n].ptr+ xctx->sym)->text[j].layer; - if(textlayer < 0 || textlayer >= cadlayers) textlayer = c; + /* do not allow custom text color on hilighted instances */ + if(disabled == 1) textlayer = GRIDLAYER; + else if(disabled == 2) textlayer = PINLAYER; + else if( xctx->inst[n].color == -10000) { + int lay; + get_sym_text_layer(n, j, &lay); + if(lay != -1) textlayer = lay; + else textlayer = symptr->text[j].layer; } + if(textlayer < 0 || textlayer >= cadlayers) textlayer = c; + if(textlayer != c) set_ps_colors(textlayer); + /* display PINLAYER colored instance texts even if PINLAYER disabled */ if(xctx->inst[n].color == -PINLAYER || xctx->enable_layer[textlayer]) { my_snprintf(ps_font_family, S(ps_font_name), "Helvetica"); @@ -1035,6 +1115,7 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho x0+x1, y0+y1, xscale, yscale); } } + if(textlayer != c) set_ps_colors(c); } } } @@ -1329,10 +1410,7 @@ void create_ps(char **psfile, int what, int fullzoom, int eps) /* bring outside previous for(c=0...) loop since ps_embedded_graph() calls ps_draw_symbol() */ for(c=0;cinstances; ++i) { - int color = c; - if(xctx->inst[i].color != -10000) color = get_color(xctx->inst[i].color); - set_ps_colors(color); - ps_draw_symbol(color, i,c,what,0,0,0.0,0.0); + ps_draw_symbol(c, i,c,what,0,0,0.0,0.0); } } prepare_netlist_structs(0); /* NEEDED: data was cleared by trim_wires() */ diff --git a/src/svgdraw.c b/src/svgdraw.c index 383f82ed..a6b8d885 100644 --- a/src/svgdraw.c +++ b/src/svgdraw.c @@ -546,7 +546,7 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot, double xoffset, double yoffset) /* draws current layer only, should be called within */ { /* a "for(i=0;isym[xctx->inst[n].ptr].type; + lvs_ignore=tclgetboolvar("lvs_ignore"); if(xctx->inst[n].ptr == -1) return; - if( (layer != PINLAYER && !xctx->enable_layer[layer]) ) return; - if( (xctx->hide_symbols==1 && (xctx->inst[n].ptr+ xctx->sym)->prop_ptr && - !strcmp( (xctx->inst[n].ptr+ xctx->sym)->type, "subcircuit") ) || (xctx->hide_symbols == 2) ) { + if(layer == 0) { + xctx->inst[n].flags &= ~IGNORE_INST; /* clear bit */ + if( type && strcmp(type, "launcher") && strcmp(type, "logo") && + strcmp(type, "probe") && + strcmp(type, "architecture") && strcmp(type, "noconn")) { + if(skip_instance(n, 1, lvs_ignore)) { + xctx->inst[n].flags |= IGNORE_INST; + } + } + } + + if(shorted_instance(n, lvs_ignore)) { + c = PINLAYER; + disabled = 2; + } + else if(xctx->inst[n].flags & IGNORE_INST) { + c = GRIDLAYER; + disabled = 1; + } + if(xctx->inst[n].color != -10000) c = get_color(xctx->inst[n].color); + + if( (xctx->inst[n].flags & HIDE_INST) || + ((xctx->hide_symbols==1 && (xctx->inst[n].ptr+ xctx->sym)->prop_ptr && + !strcmp( (xctx->inst[n].ptr+ xctx->sym)->type, "subcircuit") )) || + (xctx->hide_symbols == 2) ) { hide = 1; } else { hide = 0; } - if(layer==0) { x1=X_TO_SCREEN(xctx->inst[n].x1); x2=X_TO_SCREEN(xctx->inst[n].x2); @@ -576,9 +601,19 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot, xctx->inst[n].flags|=1; return; } + else if((xctx->inst[n].x2 - xctx->inst[n].x1) * xctx->mooz < 3 && + (xctx->inst[n].y2 - xctx->inst[n].y1) * xctx->mooz < 3) { + svg_filledrect(c, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 0, 0); + xctx->inst[n].flags|=1; + return; + } else { xctx->inst[n].flags&=~1; } + if(hide) { + int color = (disabled==1) ? GRIDLAYER : (disabled == 2) ? PINLAYER : SYMLAYER; + svg_filledrect(color, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 2, 0); + } } else if(xctx->inst[n].flags&1) { return; @@ -586,64 +621,85 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot, flip = xctx->inst[n].flip; if(tmp_flip) flip = !flip; rot = (xctx->inst[n].rot + rot ) & 0x3; + x0=xctx->inst[n].x0 + xoffset; y0=xctx->inst[n].y0 + yoffset; symptr = (xctx->inst[n].ptr+ xctx->sym); - for(j=0;j< symptr->lines[layer]; ++j) { - line = (symptr->line[layer])[j]; - ROTATION(rot, flip, 0.0,0.0,line.x1,line.y1,x1,y1); - ROTATION(rot, flip, 0.0,0.0,line.x2,line.y2,x2,y2); - ORDER(x1,y1,x2,y2); - svg_drawline(c, line.bus, x0+x1, y0+y1, x0+x2, y0+y2, line.dash); - } - for(j=0;j< symptr->polygons[layer]; ++j) { - polygon =&(symptr->poly[layer])[j]; - { /* scope block so we declare some auxiliary arrays for coord transforms. 20171115 */ - int k, bezier; - double *x = my_malloc(_ALLOC_ID_, sizeof(double) * polygon->points); - double *y = my_malloc(_ALLOC_ID_, sizeof(double) * polygon->points); - for(k=0;kpoints; ++k) { - ROTATION(rot, flip, 0.0,0.0,polygon->x[k],polygon->y[k],x[k],y[k]); - x[k]+= x0; - y[k] += y0; - } + + if( (layer != PINLAYER && !xctx->enable_layer[layer]) ) goto draw_texts; + + if(!hide) { + for(j=0;j< symptr->lines[layer]; ++j) { + int dash; + line = (symptr->line[layer])[j]; + dash = (disabled == 1) ? 3 : line.dash; + ROTATION(rot, flip, 0.0,0.0,line.x1,line.y1,x1,y1); + ROTATION(rot, flip, 0.0,0.0,line.x2,line.y2,x2,y2); + ORDER(x1,y1,x2,y2); + svg_drawline(c, line.bus, x0+x1, y0+y1, x0+x2, y0+y2, dash); + } + for(j=0;j< symptr->polygons[layer]; ++j) { + int dash; + int bezier; + polygon =&(symptr->poly[layer])[j]; bezier = !strboolcmp(get_tok_value(polygon->prop_ptr, "bezier", 0), "true"); - svg_drawpolygon(c, NOW, x, y, polygon->points, polygon->fill, polygon->dash, bezier); - my_free(_ALLOC_ID_, &x); - my_free(_ALLOC_ID_, &y); + dash = (disabled == 1) ? 3 : polygon->dash; + { /* scope block so we declare some auxiliary arrays for coord transforms. 20171115 */ + int k; + double *x = my_malloc(_ALLOC_ID_, sizeof(double) * polygon->points); + double *y = my_malloc(_ALLOC_ID_, sizeof(double) * polygon->points); + for(k=0;kpoints; ++k) { + ROTATION(rot, flip, 0.0,0.0,polygon->x[k],polygon->y[k],x[k],y[k]); + x[k]+= x0; + y[k] += y0; + } + svg_drawpolygon(c, NOW, x, y, polygon->points, polygon->fill, dash, bezier); + my_free(_ALLOC_ID_, &x); + my_free(_ALLOC_ID_, &y); + } } - } - for(j=0;j< symptr->arcs[layer]; ++j) { - double angle; - arc = (symptr->arc[layer])[j]; - if(flip) { - angle = 270.*rot+180.-arc.b-arc.a; - } else { - angle = arc.a+rot*270.; + for(j=0;j< symptr->arcs[layer]; ++j) { + int dash; + double angle; + arc = (symptr->arc[layer])[j]; + dash = (disabled == 1) ? 3 : arc.dash; + if(flip) { + angle = 270.*rot+180.-arc.b-arc.a; + } else { + angle = arc.a+rot*270.; + } + angle = fmod(angle, 360.); + if(angle<0.) angle+=360.; + ROTATION(rot, flip, 0.0,0.0,arc.x,arc.y,x1,y1); + svg_drawarc(c, arc.fill, x0+x1, y0+y1, arc.r, angle, arc.b, dash); } - angle = fmod(angle, 360.); - if(angle<0.) angle+=360.; - ROTATION(rot, flip, 0.0,0.0,arc.x,arc.y,x1,y1); - svg_drawarc(c, arc.fill, x0+x1, y0+y1, arc.r, angle, arc.b, arc.dash); - } + } /* if(!hide) */ - if( xctx->enable_layer[layer] ) for(j=0;j< symptr->rects[layer]; ++j) { - rect = &(symptr->rect[layer])[j]; - ROTATION(rot, flip, 0.0,0.0,rect->x1,rect->y1,x1,y1); - ROTATION(rot, flip, 0.0,0.0,rect->x2,rect->y2,x2,y2); - if(layer == GRIDLAYER && rect->flags & 1024) { - double xx1 = x0 + x1; - double yy1 = y0 + y1; - double xx2 = x0 + x2; - double yy2 = y0 + y2; - svg_embedded_image(rect, xx1, yy1, xx2, yy2, rot, flip); - } else { + if( (!hide && xctx->enable_layer[layer]) || + (hide && layer == PINLAYER && xctx->enable_layer[layer]) ) { + for(j=0;j< symptr->rects[layer]; ++j) + { + int dash; + rect = &(symptr->rect[layer])[j]; + dash = (disabled == 1) ? 3 : rect->dash; + ROTATION(rot, flip, 0.0,0.0,rect->x1,rect->y1,x1,y1); + ROTATION(rot, flip, 0.0,0.0,rect->x2,rect->y2,x2,y2); RECTORDER(x1,y1,x2,y2); - svg_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, rect->dash, rect->fill); + if(layer == GRIDLAYER && rect->flags & 1024) { + double xx1 = x0 + x1; + double yy1 = y0 + y1; + double xx2 = x0 + x2; + double yy2 = y0 + y2; + svg_embedded_image(rect, xx1, yy1, xx2, yy2, rot, flip); + continue; + } + svg_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, dash, rect->fill); } } + draw_texts: + if( !(xctx->inst[n].flags & HIDE_SYMBOL_TEXTS) && ( @@ -664,11 +720,17 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot, txtptr= translate(n, text.txt_ptr); ROTATION(rot, flip, 0.0,0.0,text.x0,text.y0,x1,y1); textlayer = c; - /* do not allow custom text color on PINLAYER hilighted instances */ - if( !(xctx->inst[n].color == PINLAYER)) { - textlayer = symptr->text[j].layer; - if(textlayer < 0 || textlayer >= cadlayers) textlayer = c; + /* do not allow custom text color on hilighted instances */ + if(disabled == 1) textlayer = GRIDLAYER; + else if(disabled == 2) textlayer = PINLAYER; + else if( xctx->inst[n].color == -10000) { + int lay; + get_sym_text_layer(n, j, &lay); + if(lay != -1) textlayer = lay; + else textlayer = symptr->text[j].layer; } + if(textlayer < 0 || textlayer >= cadlayers) textlayer = c; + /* display PINLAYER colored instance texts even if PINLAYER disabled */ if(xctx->inst[n].color == PINLAYER || xctx->enable_layer[textlayer]) { my_snprintf(svg_font_family, S(svg_font_family), tclgetvar("svg_font_name")); @@ -928,9 +990,7 @@ void svg_draw(void) xctx->poly[c][i].fill, xctx->poly[c][i].dash, bezier); } for(i=0;iinstances; ++i) { - color = c; - if(xctx->inst[i].color != -10000) color = get_color(xctx->inst[i].color); - svg_draw_symbol(color,i,c,0,0,0.0,0.0); + svg_draw_symbol(c,i,c,0,0,0.0,0.0); } } prepare_netlist_structs(0); /* NEEDED: data was cleared by trim_wires() */ diff --git a/src/symgen.awk b/src/symgen.awk index 236a0db4..dca7ed8d 100755 --- a/src/symgen.awk +++ b/src/symgen.awk @@ -393,7 +393,7 @@ function attrs(a) function header() { - print "v {xschem version=3.4.6RC file_version=1.2}" + print "v {xschem version=3.4.6 file_version=1.2}" } function round(n) diff --git a/src/token.c b/src/token.c index 40dc0565..f092bb74 100644 --- a/src/token.c +++ b/src/token.c @@ -3757,6 +3757,19 @@ const char *translate(int inst, const char* s) int sim_is_xyce; char *instname = NULL; + if(!s && inst == -1) { + if(result) my_free(_ALLOC_ID_, &result); + if(translated_tok) my_free(_ALLOC_ID_, &translated_tok); + if(get_sp_cur) { + regfree(get_sp_cur); + get_sp_cur = NULL; + } + } + + if(!s || !xctx || !xctx->inst) { + return empty; + } + if(!get_sp_cur) { get_sp_cur = my_malloc(_ALLOC_ID_, sizeof(regex_t)); /* @spice_get_current_param(...) or @spice_get_modelparam_param(...) */ @@ -3767,12 +3780,7 @@ const char *translate(int inst, const char* s) } sp_prefix = tclgetboolvar("spiceprefix"); - if(!s || !xctx || !xctx->inst) { - my_free(_ALLOC_ID_, &result); - my_free(_ALLOC_ID_, &translated_tok); - regfree(get_sp_cur); - return empty; - } + if(inst >= xctx->instances) { dbg(0, "translate(): instance number out of bounds: %d\n", inst); return empty; diff --git a/src/xinit.c b/src/xinit.c index e91347ce..9ad21557 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -646,6 +646,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->enable_drill = 0; xctx->prev_set_modify = -1; xctx->prev_crossx = xctx->prev_crossy = 0.0; + xctx->prev_m_crossx = xctx->prev_m_crossy = 0.0; xctx->prev_rubberx = xctx->prev_rubbery = 0.0; xctx->prev_gridx = xctx->prev_gridy = 0.0; xctx->prev_snapx = xctx->prev_snapy = 0.0; @@ -946,7 +947,7 @@ static void xwin_exit(void) clear_expandlabel_data(); get_sym_template(NULL, NULL); /* clear static data in function */ list_tokens(NULL, 0); /* clear static data in function */ - translate(0, NULL); /* clear static data in function */ + translate(-1, NULL); /* clear static data in function */ translate2(NULL, 0, NULL); /* clear static data in function */ translate3(NULL, 0, NULL, NULL, NULL); /* clear static data in function */ subst_token(NULL, NULL, NULL); /* clear static data in function */ diff --git a/src/xschem.h b/src/xschem.h index 41440ff4..8dad9125 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1050,7 +1050,8 @@ typedef struct { double xpan,ypan,xpan2,ypan2; double p_xx1,p_xx2,p_yy1,p_yy2; /* draw_crosshair */ - double prev_crossx, prev_crossy; + double prev_crossx, prev_crossy; /* previous closest net/pin found by draw_crosshair() */ + double prev_m_crossx, prev_m_crossy; /* previous snap mouse position processed by draw_crosshair() */ double prev_gridx, prev_gridy; double prev_snapx, prev_snapy; int closest_pin_found; diff --git a/src/xschem.tcl b/src/xschem.tcl index fa294625..5c21b990 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -4874,6 +4874,46 @@ proc add_lab_prefix {} { xschem merge $USER_CONF_DIR/.clipboard.sch } +# Create an xschem symbol from a list of in, out, inout pins. +# Example: +# create_symbol test.sym {CLK RST D} {Q QB} {VCC VSS} +# +proc create_symbol {name {in {}} {out {}} {inout {}}} { + set symname [file rootname $name].sym + set res [catch {open $symname {WRONLY CREAT EXCL}} fd] + if {$res} {puts $fd; return 0} ;# Error. Print reason and exit. + puts $fd {v {xschem version=3.4.6 file_version=1.2}} + puts $fd {K {type=subcircuit format="@name @pinlist @symname" template="name=X1"}} + set x -150 + set y 0 + foreach pin $in { ;# create all input pins on the left + puts $fd "B 5 [expr {$x - 2.5}] [expr {$y - 2.5}] [expr {$x + 2.5}] [expr {$y + 2.5}] {name=$pin dir=in}" + puts $fd "T {$pin} [expr {$x + 25}] [expr {$y - 6}] 0 0 0.2 0.2 {}" + puts $fd "L 4 $x $y [expr {$x + 20}] $y {}" + incr y 20 + } + set x 150 + set y 0 + foreach pin $out { ;# create all out pins on the top right + puts $fd "B 5 [expr {$x - 2.5}] [expr {$y - 2.5}] [expr {$x + 2.5}] [expr {$y + 2.5}] {name=$pin dir=out}" + puts $fd "T {$pin} [expr {$x - 25}] [expr {$y - 6}] 0 1 0.2 0.2 {}" + puts $fd "L 4 [expr {$x - 20}] $y $x $y {}" + incr y 20 + } + foreach pin $inout { ;# create all inout pins on the bottom right + puts $fd "B 5 [expr {$x - 2.5}] [expr {$y - 2.5}] [expr {$x + 2.5}] [expr {$y + 2.5}] {name=$pin dir=inout}" + puts $fd "T {$pin} [expr {$x - 25}] [expr {$y - 6}] 0 1 0.2 0.2 {}" + puts $fd "L 7 [expr {$x - 20}] $y $x $y {}" + incr y 20 + } + puts $fd "B 4 -130 -10 130 [expr {$y - 10}] {fill=0}" ;# symbol box + puts $fd "T {@symname} 0 [expr {($y - 20) / 2}] 0 0 0.3 0.3 {hcenter=1 vcenter=1}" ;#symbol name + puts $fd "T {@name} 130 -10 2 1 0.2 0.2 {}" ;# instance name + close $fd + puts "Created symbol ${symname}" + return 1 +} + proc make_symbol {name {ask {no}} } { global XSCHEM_SHAREDIR symbol_width set name [abs_sym_path $name ]