diff --git a/XSchemWin/XSchemWin_cairo.vcxproj b/XSchemWin/XSchemWin_cairo.vcxproj index dd9b788b..f5563fad 100644 --- a/XSchemWin/XSchemWin_cairo.vcxproj +++ b/XSchemWin/XSchemWin_cairo.vcxproj @@ -122,8 +122,8 @@ false - $(VC_IncludePath);$(WindowsSDK_IncludePath);C:\myTcl86\include - $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\myTcl86\lib + $(VC_IncludePath);$(WindowsSDK_IncludePath);C:\myTcl86\include;cairo_win\cairo\src;cairo_win\projects\cairo\src; + $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\myTcl86\lib;cairo_win\projects\x64\Release;cairo_win\libs;cairo_win/freetype\objs\x64\Release Static $(VC_ExecutablePath_x64);$(CommonExecutablePath);D:\GnuWin32\bin XSchem @@ -218,7 +218,7 @@ true true true - tcl86t.lib;tk86t.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + cairo.lib;pixman.lib;zlib.lib;libpng.lib;freetype.lib;tcl86t.lib;tk86t.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) diff --git a/src/callback.c b/src/callback.c index c9ad1bbe..f7efaece 100644 --- a/src/callback.c +++ b/src/callback.c @@ -335,7 +335,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int } xval = G_X(xctx->mousex); - if(xctx->graph_sim_type == 3) xval = pow(10, xval); + if(gr->logx) xval = pow(10, xval); if(gr->unitx != 0) my_snprintf(sx, S(sx), "%.5g%c", gr->unitx * xval, gr->unitx_suffix); else @@ -672,9 +672,12 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int int ofs = 0; for(dset = 0 ; dset < xctx->graph_datasets; dset++) { for(i = ofs; i < ofs + xctx->graph_npoints[dset]; i++) { + double sweepval; + if(gr->logx) sweepval = log10(xctx->graph_values[sweep_idx][i]); + else sweepval = xctx->graph_values[sweep_idx][i]; if(dataset >= 0 && dataset != dset) continue; - if( xctx->graph_values[sweep_idx][i] < start || - xctx->graph_values[sweep_idx][i] > end) continue; + if( sweepval < start || + sweepval > end) continue; v = xctx->graph_values[j][i]; if(first || v < min) min = v; if(first || v > max) max = v; @@ -683,7 +686,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int ofs += xctx->graph_npoints[dset]; } } - } + } /* while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", &saven)) ) */ if(max == min) max += 0.01; min = floor_to_n_digits(min, 2); max = ceil_to_n_digits(max, 2); diff --git a/src/draw.c b/src/draw.c index 3bdaff9b..794cdf02 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1743,8 +1743,8 @@ static void draw_graph_bus_points(const char *ntok, int n_bits, SPICE_DATA **idx double s2 = DIG_SPACE; /* (DIG_NWAVES - DIG_SPACE) spacing between traces */ double c = (n_nodes - wcnt) * s1 * gr->gh - gr->gy1 * s2; /* trace baseline */ double c1 = c + gr->gh * 0.5 * s2; /* trace y-center, used for clipping */ - double lx1 = W_X(xctx->graph_values[sweep_idx][first]); - double lx2 = W_X(xctx->graph_values[sweep_idx][last]); + double lx1; + double lx2; double ylow = DW_Y(c + gr->gy2 * s2); /* swapped as xschem Y coordinates are top-bottom */ double yhigh = DW_Y(c + gr->gy1 * s2); char busval[1024], old_busval[1024]; @@ -1756,6 +1756,14 @@ static void draw_graph_bus_points(const char *ntok, int n_bits, SPICE_DATA **idx double vthh = gr->gy1 * 0.2 + gr->gy2 * 0.8; double vthl = gr->gy1 * 0.8 + gr->gy2 * 0.2; int hex_digits = ((n_bits - 1) >> 2) + 1; + + if(gr->logx) { + lx1 = W_X(log10(xctx->graph_values[sweep_idx][first])); + lx2 = W_X(log10(xctx->graph_values[sweep_idx][last])); + } else { + lx1 = W_X(xctx->graph_values[sweep_idx][first]); + lx2 = W_X(xctx->graph_values[sweep_idx][last]); + } if(c1 >= gr->ypos1 && c1 <=gr->ypos2) { set_thick_waves(1, wcnt, wave_col, gr); drawline(wave_col, NOW, lx1, ylow, lx2, ylow, 0); @@ -1764,7 +1772,11 @@ static void draw_graph_bus_points(const char *ntok, int n_bits, SPICE_DATA **idx /* calculate value of bus by adding all binary bits */ /* hex_digits = */ get_bus_value(n_bits, hex_digits, idx_arr, p, busval, vthl, vthh); - xval = W_X(xctx->graph_values[sweep_idx][p]); + if(gr->logx) { + xval = W_X(log10(xctx->graph_values[sweep_idx][p])); + } else { + xval = W_X(xctx->graph_values[sweep_idx][p]); + } /* used to draw bus value before 1st transition */ if(p == first) { my_strncpy(old_busval, busval, hex_digits+1); @@ -1864,13 +1876,13 @@ static void draw_graph_grid(Graph_ctx *gr) bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2); bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0); /* vertical grid lines */ - deltax = axis_increment(gr->gx1, gr->gx2, gr->divx, (xctx->graph_sim_type == 3)); + deltax = axis_increment(gr->gx1, gr->gx2, gr->divx, (gr->logx)); startx = axis_start(gr->gx1, deltax, gr->divx); for(j = -1;; j++) { /* start one interval before to allow sub grids at beginning */ wx = startx + j * deltax; if(gr->subdivx > 0) for(k = 1; k <=gr->subdivx; k++) { double subwx; - if(xctx->graph_sim_type == 3) { + if(gr->logx) { subwx = wx + deltax * log10(1.0 + (double)k * 9.0 / ((double)gr->subdivx + 1.0)); } else subwx = wx + deltax * (double)k / ((double)gr->subdivx + 1.0); @@ -1884,7 +1896,7 @@ static void draw_graph_grid(Graph_ctx *gr) drawline(GRIDLAYER, ADD, W_X(wx), W_Y(gr->gy2), W_X(wx), W_Y(gr->gy1), (int)dash_sizey); drawline(GRIDLAYER, ADD, W_X(wx), W_Y(gr->gy1), W_X(wx), W_Y(gr->gy1) + mark_size, 0); /* axis marks */ /* X-axis labels */ - if(xctx->graph_sim_type == 3) + if(gr->logx) draw_string(3, NOW, dtoa(pow(10, wx ) * gr->unitx), 0, 0, 1, 0, W_X(wx), gr->y2 + mark_size + 5 * gr->txtsizex, gr->txtsizex, gr->txtsizex); else @@ -1939,6 +1951,7 @@ void setup_graph_data(int i, const int flags, int skip, Graph_ctx *gr) /* default values */ gr->divx = gr->divy = 5; gr->subdivx = gr->subdivy = 0; + gr->logx = gr->logy = 0; gr->digital = 0; if(!skip) { @@ -1984,7 +1997,7 @@ void setup_graph_data(int i, const int flags, int skip, Graph_ctx *gr) gr->unitx_suffix = val[0]; gr->unitx = get_unit(val); val = get_tok_value(r->prop_ptr,"unity",0); - if(xctx->graph_sim_type == 3) { /* AC */ + if(gr->logx) { /* AC */ gr->unity_suffix = '1'; gr->unity = 1.0; } else { @@ -2001,6 +2014,10 @@ void setup_graph_data(int i, const int flags, int skip, Graph_ctx *gr) val = get_tok_value(r->prop_ptr,"divy",0); if(val[0]) gr->divy = atoi(val); if(gr->divy < 1) gr->divy = 1; + val = get_tok_value(r->prop_ptr,"logx",0); + if(val[0] == '1') gr->logx = 1; + val = get_tok_value(r->prop_ptr,"logy",0); + if(val[0] == '1') gr->logy = 1; val = get_tok_value(r->prop_ptr,"y1",0); if(val[0]) gr->gy1 = atof(val); val = get_tok_value(r->prop_ptr,"y2",0); @@ -2091,7 +2108,7 @@ static void draw_cursor(double active_cursorx, double other_cursorx, int cursor_ if(xx >= gr->x1 && xx <= gr->x2) { drawline(cursor_color, NOW, xx, gr->ry1, xx, gr->ry2, 1); - if(xctx->graph_sim_type == 3) active_cursorx = pow(10, active_cursorx); + if(gr->logx) active_cursorx = pow(10, active_cursorx); if(gr->unitx != 1.0) my_snprintf(tmpstr, S(tmpstr), "%.5g%c", gr->unitx * active_cursorx , gr->unitx_suffix); else @@ -2118,7 +2135,7 @@ static void draw_cursor_difference(Graph_ctx *gr) double yy = gr->ry2 - 1; double dtmp; double yline; - if(xctx->graph_sim_type == 3) return; + if(gr->logx) return; if(gr->unitx != 1.0) my_snprintf(tmpstr, S(tmpstr), "%.4g%c", gr->unitx * diffw , gr->unitx_suffix); else @@ -2169,7 +2186,7 @@ static void draw_graph_variables(int wcnt, int wave_color, int n_nodes, int swee my_strdup2(1155, &ntok_ptr, ntok); } - if(xctx->graph_sim_type == 3) { + if(gr->logx) { if(strstr(ntok_ptr, "ph(") == ntok_ptr || strstr(ntok_ptr, "_ph")) my_snprintf(tmpstr, S(tmpstr), "%s[Phase]", alias_ptr); else @@ -2442,7 +2459,10 @@ int calc_custom_data_yrange(int sweep_idx, const char *express, Graph_ctx *gr) prev_prev_x = prev_x = 0; last = ofs; for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) { - xx = gv[p]; + if(gr->logx) + xx = log10(gv[p]); + else + xx = gv[p]; wrap = (sweep_idx == 0 && cnt > 1 && XSIGN(xx - prev_x) != XSIGN(prev_x - prev_prev_x)); if(first != -1) { /* there is something to plot ... */ if(xx > end || xx < start || /* ... and we ran out of graph area ... */ @@ -2600,7 +2620,8 @@ void draw_graph(int i, const int flags, Graph_ctx *gr) prev_prev_x = prev_x = 0; last = ofs; for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) { - xx = gv[p]; + if(gr->logx) xx = log10(gv[p]); + else xx = gv[p]; wrap = (sweep_idx == 0 && cnt > 1 && XSIGN(xx - prev_x) != XSIGN(prev_x - prev_prev_x)); if(first != -1) { /* there is something to plot ... */ if(xx > end || xx < start || /* ... and we ran out of graph area ... */ diff --git a/src/save.c b/src/save.c index 8019fcae..b3b948d0 100644 --- a/src/save.c +++ b/src/save.c @@ -252,9 +252,9 @@ static void read_binary_block(FILE *fd) /* assign to xschem struct, memory aligned per variable, for cache locality */ if(ac) { for(v = 0; v < xctx->graph_nvars; v += 2) { /*AC analysis: calculate magnitude */ - if( v == 0 ) /* log scale x */ - xctx->graph_values[v][offset + p] = (float)log10(sqrt( tmp[v] * tmp[v] + tmp[v + 1] * tmp[v + 1])); - else /* dB */ + if( v == 0 ) /* sweep var */ + xctx->graph_values[v][offset + p] = (float)sqrt( tmp[v] * tmp[v] + tmp[v + 1] * tmp[v + 1]); + else /* magnitude */ /* avoid 0 for dB calculations */ if(tmp[v] == 0.0 && tmp[v + 1] == 0.0) xctx->graph_values[v][offset + p] = 1e-35f; else xctx->graph_values[v][offset + p] = @@ -822,6 +822,7 @@ int plot_raw_custom_data(int sweep_idx, int first, int last, const char *expr) double get_raw_value(int dataset, int idx, int point) { int i, ofs; + Graph_ctx *gr = &xctx->graph_struct; ofs = 0; if(xctx->graph_values) { if(dataset == -1) { @@ -832,7 +833,8 @@ double get_raw_value(int dataset, int idx, int point) ofs += xctx->graph_npoints[i]; } if(ofs + point < xctx->graph_allpoints) - return xctx->graph_values[idx][ofs + point]; + if(gr->logx && idx == 0) return log10(xctx->graph_values[idx][ofs + point]); + else return xctx->graph_values[idx][ofs + point]; } } return 0.0; diff --git a/src/scheduler.c b/src/scheduler.c index c1dd52ed..47a8a8b0 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -321,6 +321,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg "color=\"\"\n" "dataset=0\n" "unitx=u\n" + "logx=0\n" + "logy=0\n" ); xctx->need_reb_sel_arr=1; rebuild_selected_array(); diff --git a/src/xschem.h b/src/xschem.h index d6662154..07c509af 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -710,6 +710,7 @@ typedef struct { double txtsizelab, digtxtsizelab, txtsizey, txtsizex; int dataset; int hilight_wave[2]; /* [0] : graph index, [1] : wave index */ + int logx, logy; } Graph_ctx; typedef struct { diff --git a/src/xschem.tcl b/src/xschem.tcl index 052be978..cb40ec4c 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -1596,7 +1596,7 @@ proc update_div {graph_selected div} { proc graph_edit_properties {n} { global graph_bus graph_sort graph_digital graph_selected colors graph_sel_color - global graph_unlocked graph_schname + global graph_unlocked graph_schname graph_logx graph_logy xschem push_undo set geom {} @@ -1854,6 +1854,11 @@ proc graph_edit_properties {n} { .graphdialog.top.max insert 0 [xschem getprop rect 2 $graph_selected y2] # top3 frame + set graph_logx [xschem getprop rect 2 $graph_selected logx] + set graph_logy [xschem getprop rect 2 $graph_selected logy] + if { $graph_logx eq {} } { set graph_logx 0 } + if { $graph_logy eq {} } { set graph_logy 0 } + puts "graph_logx=$graph_logx , graph_selected=$graph_selected" checkbutton .graphdialog.top3.logx -padx 2 -text {Log X scale} -variable graph_logx \ -command { if { [xschem get schname] eq $graph_schname } {