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 } {