From 5707b18abaa20a8dd5cfaa06e06859bb6e3e333a Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Thu, 30 Dec 2021 15:45:38 +0100 Subject: [PATCH] wave view: added cursors for delay/time measurements --- src/callback.c | 282 +++++++++++++--------- src/draw.c | 419 ++++++++++++++++++++------------- src/xinit.c | 2 + src/xschem.h | 18 +- xschem_library/rom8k/rom8k.sch | 53 +++-- 5 files changed, 467 insertions(+), 307 deletions(-) diff --git a/src/callback.c b/src/callback.c index 651ab5ea..f08fa2fd 100644 --- a/src/callback.c +++ b/src/callback.c @@ -21,26 +21,25 @@ */ #include "xschem.h" -static int waves_selected(int state) + +static int waves_selected(int event, int key, int state, int button) { - int n, c, i; + int i; int is_inside = 0; - xRect *r; - rebuild_selected_array(); if(state & Mod1Mask) return 0; - if(xctx->ui_state & (STARTMOVE | STARTCOPY) ) return 0; - if(!(xctx->ui_state & SELECTION) || !xctx->lastsel) return 0; - for(i=0; ilastsel; i++) { - c = xctx->sel_array[i].col; - if(xctx->sel_array[i].type == xRECT && c == GRIDLAYER) { - n = xctx->sel_array[i].n; - r = &xctx->rect[c][n]; - if(r->flags != 1) return 0; - if( (xctx->ui_state & GRAPHPAN) || - POINTINSIDE(xctx->mousex, xctx->mousey, r->x1, r->y1, r->x2, r->y2) ) { - is_inside = 1; - } - } else return 0; + if(event == MotionNotify && (state & Button2Mask)) return 0; + if(event == ButtonPress && button == Button2) return 0; + if(event == ButtonRelease && button == Button2) return 0; + if(xctx->ui_state & STARTSELECT) return 0; + + for(i=0; i< xctx->rects[GRIDLAYER]; i++) { + xRect *r; + r = &xctx->rect[GRIDLAYER][i]; + if(!(r->flags & 1) ) continue; + if( (xctx->ui_state & GRAPHPAN) || + POINTINSIDE(xctx->mousex, xctx->mousey, r->x1, r->y1, r->x2, r->y2) ) { + is_inside = 1; + } } return is_inside; } @@ -183,6 +182,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int int need_redraw = 0; double delta_threshold = 0.25; int dataset = 0; + double zoom_m = 0.5; #if HAS_CAIRO==1 cairo_save(xctx->cairo_ctx); cairo_save(xctx->cairo_save_ctx); @@ -190,60 +190,110 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int cairo_select_font_face(xctx->cairo_save_ctx, "Sans-Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); #endif + /* determine if mouse pointer is below xaxis or left of yaxis in some graph */ - if( (event == ButtonPress || event == MotionNotify) && !(xctx->ui_state & GRAPHPAN) ) { - if(state & (Button1Mask | Button3Mask)) { + if( event == KeyPress || event == ButtonPress || event == MotionNotify ) { + if( + ( + (event == ButtonPress && (button == Button1 || button == Button3)) || + (event == MotionNotify && (state & (Button1Mask | Button3Mask))) + ) && + !(xctx->ui_state & GRAPHPAN) + ) { xctx->ui_state |= GRAPHPAN; xctx->mx_double_save = xctx->mousex_snap; xctx->my_double_save = xctx->mousey_snap; } - for(i=0; ilastsel; i++) { - - c = xctx->sel_array[i].col; + for(i=0; i < xctx->rects[GRIDLAYER]; i++) { /* process only graph boxes */ - if(xctx->sel_array[i].type == xRECT && c == GRIDLAYER) { - xRect *r; - n = xctx->sel_array[i].n; - r = &xctx->rect[GRIDLAYER][n]; - if( POINTINSIDE(xctx->mousex_snap, xctx->mousey_snap, r->x1, r->y1, r->x2, r->y2)) { - val = get_tok_value(r->prop_ptr,"x1",0); - if(val[0]) wx1 = atof(val); - val = get_tok_value(r->prop_ptr,"y1",0); - if(val[0]) wy1 = atof(val); - val = get_tok_value(r->prop_ptr,"x2",0); - if(val[0]) wx2 = atof(val); - val = get_tok_value(r->prop_ptr,"y2",0); - if(val[0]) wy2 = atof(val); - val = get_tok_value(r->prop_ptr,"digital",0); - if(val[0]) digital = atof(val); - calc_graph_area(GRIDLAYER, n, digital, &x1, &y1, &x2, &y2, &marginx, &marginy); - cx = (x2 - x1) / (wx2 - wx1); - dx = x1 - wx1 * cx; - cy = (y1 - y2) / (wy2 - wy1); - dy = y2 - wy1 * cy; - if(xctx->mousex_snap < W_X(wx1)) { - xctx->graph_left = 1; - } else { - xctx->graph_left = 0; - } - if(xctx->mousey_snap > W_Y(wy1)) { - xctx->graph_bottom = 1; - } else { - xctx->graph_bottom = 0; - } - xctx->graph_master = n; - if(state & ControlMask) xctx->graph_flags |= 1; - else xctx->graph_flags &= ~1; - break; + xRect *r; + r = &xctx->rect[GRIDLAYER][i]; + if(!(r->flags & 1) ) continue; + /* check if this is the master graph (the one containing the mouse pointer) */ + if( POINTINSIDE(xctx->mousex_snap, xctx->mousey_snap, r->x1, r->y1, r->x2, r->y2)) { + val = get_tok_value(r->prop_ptr,"x1",0); + if(val[0]) wx1 = atof(val); + else wx1 = 0; + val = get_tok_value(r->prop_ptr,"y1",0); + if(val[0]) wy1 = atof(val); + else wy1 = 0; + val = get_tok_value(r->prop_ptr,"x2",0); + if(val[0]) wx2 = atof(val); + else wx2 = 1e-6; + val = get_tok_value(r->prop_ptr,"y2",0); + if(val[0]) wy2 = atof(val); + else wy2 = 5; + val = get_tok_value(r->prop_ptr,"digital",0); + if(val[0]) digital = atoi(val); + else digital = 0; + calc_graph_area(GRIDLAYER, i, digital, &x1, &y1, &x2, &y2, &marginx, &marginy); + cx = (x2 - x1) / (wx2 - wx1); + dx = x1 - wx1 * cx; + cy = (y1 - y2) / (wy2 - wy1); + dy = y2 - wy1 * cy; + if(xctx->mousex_snap < W_X(wx1)) { + xctx->graph_left = 1; + } else { + xctx->graph_left = 0; } - } + if(xctx->mousey_snap > W_Y(wy1)) { + xctx->graph_bottom = 1; + } else { + xctx->graph_bottom = 0; + } + xctx->graph_master = i; + if(xctx->lastsel == 1 && + xctx->sel_array[0].type == xRECT && + xctx->sel_array[0].col == GRIDLAYER && + xctx->sel_array[0].n == i ) { + xctx->graph_unlock_x = 1; + } else { + xctx->graph_unlock_x = 0; + } + zoom_m = (xctx->mousex - x1) / ( x2 - x1); + + + if(event == ButtonPress && button == Button1) { + if( (xctx->graph_flags & 2) && fabs(xctx->mousex - W_X(xctx->graph_cursor1_x)) < 10) { + xctx->graph_flags |= 16; /* move cursor1 */ + } + if( (xctx->graph_flags & 4) && fabs(xctx->mousex - W_X(xctx->graph_cursor2_x)) < 10) { + xctx->graph_flags |= 32; /* move cursor2 */ + } + } + + + + /* x-cursor set */ + if((key == 'a') ) { + xctx->graph_flags ^= 2; + need_redraw = 1; + xctx->graph_flags |= 1; /* apply to all graphs */ + if(xctx->graph_flags & 2) xctx->graph_cursor1_x = G_X(xctx->mousex); + } + else if((key == 'b') ) { + xctx->graph_flags ^= 4; + need_redraw = 1; + xctx->graph_flags |= 1; /* apply to all graphs */ + if(xctx->graph_flags & 4) xctx->graph_cursor2_x = G_X(xctx->mousex); + } + else if(state & ControlMask) xctx->graph_flags |= 1; + else xctx->graph_flags &= ~1; + + break; + } /* if( POINTINSIDE(...) */ } } + if(!xctx->graph_unlock_x) xctx->graph_flags |= 1; + /* lock x-axis to working graph when moving/zooming multiple graphs */ val = get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr,"x1",0); if(val[0]) wx1 = atof(val); + else wx1 = 0; val = get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr,"x2",0); if(val[0]) wx2 = atof(val); + else wx2 = 1e-6; + for(i=0; i< ((xctx->graph_flags & 1) ? xctx->rects[GRIDLAYER] : xctx->lastsel); i++) { c = (xctx->graph_flags & 1) ? GRIDLAYER : xctx->sel_array[i].col; /* process only graph boxes */ @@ -254,17 +304,23 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int if(r->flags != 1) continue; val = get_tok_value(r->prop_ptr,"divx",0); if(val[0]) divx = atoi(val); + else divx = 4; val = get_tok_value(r->prop_ptr,"divy",0); if(val[0]) divy = atoi(val); + else divy = 4; val = get_tok_value(r->prop_ptr,"y1",0); if(val[0]) wy1 = atof(val); + else wy1 = 0; val = get_tok_value(r->prop_ptr,"y2",0); if(val[0]) wy2 = atof(val); + else wy2 = 5; val = get_tok_value(r->prop_ptr,"dataset",0); if(val[0]) dataset = atoi(val); + else dataset = 0; if(dataset >= xctx->graph_datasets) dataset = xctx->graph_datasets - 1; val = get_tok_value(r->prop_ptr,"digital",0); - if(val[0]) digital = atof(val); + if(val[0]) digital = atoi(val); + else digital = 0; calc_graph_area(GRIDLAYER, n, digital, &x1, &y1, &x2, &y2, &marginx, &marginy); /* cache coefficients for faster graph coord transformations */ cx = (x2 - x1) / (wx2 - wx1); @@ -272,7 +328,18 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int cy = (y1 - y2) / (wy2 - wy1); dy = y2 - wy1 * cy; dbg(1, "%g %g %g %g - %d %d\n", wx1, wy1, wx2, wy2, divx, divy); - if(event == MotionNotify && (state & Button1Mask) && !xctx->graph_bottom) { + + /* move cursor1 */ + if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) { + xctx->graph_cursor1_x = G_X(xctx->mousex); + need_redraw = 1; + } + /* move cursor2 */ + else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 32 )) { + xctx->graph_cursor2_x = G_X(xctx->mousex); + need_redraw = 1; + } + else if(event == MotionNotify && (state & Button1Mask) && !xctx->graph_bottom) { double delta; if(xctx->graph_left) { if(n == xctx->graph_master) { @@ -290,8 +357,8 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int } } } else { - delta = (wx2 - wx1) / divx; - delta_threshold = 0.05; + delta = (wx2 - wx1); + delta_threshold = 0.02; if(fabs(xctx->mx_double_save - xctx->mousex_snap) > fabs(cx * delta) * delta_threshold) { xx1 = wx1 + (xctx->mx_double_save - xctx->mousex_snap) / cx; xx2 = wx2 + (xctx->mx_double_save - xctx->mousex_snap) / cx; @@ -323,8 +390,8 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int need_redraw = 1; } } else { - delta = (wx2 - wx1) / divx; - delta_threshold = 1.0; + delta = (wx2 - wx1); + delta_threshold = 0.02; xx1 = wx1 - delta * delta_threshold; xx2 = wx2 - delta * delta_threshold; my_snprintf(s, S(s), "%g", xx1); @@ -352,8 +419,8 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int need_redraw = 1; } } else { - delta = (wx2 - wx1) / divx; - delta_threshold = 1.0; + delta = (wx2 - wx1); + delta_threshold = 0.02; xx1 = wx1 - delta * delta_threshold; xx2 = wx2 - delta * delta_threshold; my_snprintf(s, S(s), "%g", xx1); @@ -378,8 +445,8 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int need_redraw = 1; } } else { - delta = (wx2 - wx1) / divx; - delta_threshold = 1.0; + delta = (wx2 - wx1); + delta_threshold = 0.02; xx1 = wx1 + delta * delta_threshold; xx2 = wx2 + delta * delta_threshold; my_snprintf(s, S(s), "%g", xx1); @@ -407,8 +474,8 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int need_redraw = 1; } } else { - delta = (wx2 - wx1) / divx; - delta_threshold = 1.0; + delta = (wx2 - wx1); + delta_threshold = 0.02; xx1 = wx1 + delta * delta_threshold; xx2 = wx2 + delta * delta_threshold; my_snprintf(s, S(s), "%g", xx1); @@ -435,13 +502,9 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int need_redraw = 1; } } else { - double m = G_X(xctx->mousex); - double a = m - wx1; - double b = wx2 -m; - double delta = (wx2 - wx1); - double var = delta * 0.2; - xx2 = wx2 + var * b / delta; - xx1 = wx1 - var * a / delta; + double var = 0.2 * (wx2 -wx1); + xx2 = wx2 + var * zoom_m; + xx1 = wx1 - var * (1 - zoom_m); my_snprintf(s, S(s), "%g", xx1); my_strdup(1399, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s)); my_snprintf(s, S(s), "%g", xx2); @@ -464,13 +527,9 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int need_redraw = 1; } } else { - double m = G_X(xctx->mousex); - double a = m - wx1; - double b = wx2 -m; - double delta = (wx2 - wx1); - double var = delta * 0.2; - xx2 = wx2 + var * b / delta; - xx1 = wx1 - var * a / delta; + double var = 0.2 * (wx2 -wx1); + xx2 = wx2 + var * zoom_m; + xx1 = wx1 - var * (1 - zoom_m); my_snprintf(s, S(s), "%g", xx1); my_strdup(1418, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s)); my_snprintf(s, S(s), "%g", xx2); @@ -495,13 +554,9 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int need_redraw = 1; } } else { - double m = G_X(xctx->mousex); - double a = m - wx1; - double b = wx2 -m; - double delta = (wx2 - wx1); - double var = delta * 0.2; - xx2 = wx2 - var * b / delta; - xx1 = wx1 + var * a / delta; + double var = 0.2 * (wx2 - wx1);; + xx2 = wx2 - var * zoom_m; + xx1 = wx1 + var * (1 - zoom_m); my_snprintf(s, S(s), "%g", xx1); my_strdup(1449, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s)); my_snprintf(s, S(s), "%g", xx2); @@ -525,13 +580,9 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int need_redraw = 1; } } else { - double m = G_X(xctx->mousex); - double a = m - wx1; - double b = wx2 -m; - double delta = (wx2 - wx1); - double var = delta * 0.2; - xx2 = wx2 - var * b / delta; - xx1 = wx1 + var * a / delta; + double var = 0.2 * (wx2 -wx1); + xx2 = wx2 - var * zoom_m; + xx1 = wx1 + var * (1 - zoom_m); my_snprintf(s, S(s), "%g", xx1); my_strdup(1445, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s)); my_snprintf(s, S(s), "%g", xx2); @@ -601,6 +652,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int } else if(event == ButtonRelease && button != Button3) { xctx->ui_state &= ~GRAPHPAN; + xctx->graph_flags &= ~(16 | 32); /* clear move cursor flags */ } else if(event == ButtonRelease && button == Button3) { double tmp; @@ -616,7 +668,9 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int need_redraw = 1; } } /* if(xctx->sel_array[i].type == xRECT && c == 2) */ - if(need_redraw) draw_graph(GRIDLAYER, n, 1); /* draw data in each graph box */ + if(need_redraw) { + draw_graph(GRIDLAYER, n, 1 + 8 + (xctx->graph_flags & 6) ); /* draw data in each graph box */ + } } /* for(i=0; ilastsel; i++) */ draw_selection(xctx->gc[SELLAYER], 0); #if HAS_CAIRO==1 @@ -765,7 +819,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, break; case MotionNotify: - if( waves_selected(state)) { + if( waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } @@ -1197,7 +1251,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } if(key==XK_Right) /* left */ { - if(waves_selected(state)) { + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } @@ -1208,7 +1262,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } if(key==XK_Left) /* right */ { - if(waves_selected(state)) { + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } @@ -1219,7 +1273,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } if(key==XK_Down) /* down */ { - if(waves_selected(state)) { + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } @@ -1230,7 +1284,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } if(key==XK_Up) /* up */ { - if(waves_selected(state)) { + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } @@ -1341,6 +1395,10 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, if(key=='a' && state == 0) /* make symbol */ { if(xctx->semaphore >= 2) break; + if(waves_selected(event, key, state, button)) { + waves_callback(event, mx, my, key, button, aux, state); + break; + } tcleval("tk_messageBox -type okcancel -parent [xschem get topwindow] " "-message {do you want to make symbol view ?}"); if(strcmp(tclresult(),"ok")==0) @@ -1889,6 +1947,10 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, if(key=='b' && state==0) /* merge schematic */ { if(xctx->semaphore >= 2) break; + if(waves_selected(event, key, state, button)) { + waves_callback(event, mx, my, key, button, aux, state); + break; + } merge_file(0, ""); /* 2nd parameter not used any more for merge 25122002 */ break; } @@ -1973,7 +2035,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } if(key=='f' && state == 0 ) /* full zoom */ { - if(waves_selected(state)) { + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } @@ -1997,7 +2059,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, break; case ButtonPress: /* end operation */ dbg(1, "callback(): ButtonPress ui_state=%ld state=%d\n",xctx->ui_state,state); - if(waves_selected(state)) { + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } @@ -2137,21 +2199,21 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } } else if(button==Button5 && state == 0 ) { - if(waves_selected(state)) { + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } view_unzoom(CADZOOMSTEP); } else if(button==Button4 && state == 0 ) { - if(waves_selected(state)) { + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } view_zoom(CADZOOMSTEP); } else if(button==Button4 && (state & ShiftMask) && !(state & Button2Mask)) { - if(waves_selected(state)) { + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } @@ -2160,7 +2222,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, redraw_w_a_l_r_p_rubbers(); } else if(button==Button5 && (state & ShiftMask) && !(state & Button2Mask)) { - if(waves_selected(state)) { + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } @@ -2382,7 +2444,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, } /* button==Button1 */ break; case ButtonRelease: - if(waves_selected(state)) { + if(waves_selected(event, key, state, button)) { waves_callback(event, mx, my, key, button, aux, state); break; } diff --git a/src/draw.c b/src/draw.c index 4d1b7ed3..932d51ab 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1642,7 +1642,7 @@ int read_rawfile(const char *f) dbg(0, "read_rawfile(): must clear current raw file before loading new\n"); return 0; } - fd = fopen(f, "r"); + fd = fopen(f, fopen_read_mode); if(fd) { if((res = read_dataset(fd)) == 1) { dbg(0, "Raw file data read\n"); @@ -1693,8 +1693,8 @@ void calc_graph_area(int c, int i, int digital, double *x1, double *y1,double *x /* set margins */ tmp = rw * 0.1; *marginx = tmp < 30 ? 30 : tmp; - tmp = rh * 0.15; - *marginy = tmp < 15 ? 15 : tmp; + tmp = rh * 0.09; + *marginy = tmp < 30 ? 30 : tmp; /* calculate graph bounding box (container - margin) * This is the box where plot is done */ @@ -1916,13 +1916,14 @@ static void draw_graph_grid( double cx, double cy, double dx, double dy, /* graph to xschem matrix transform */ int divx, int divy, int subdivx, int subdivy, /* axis major/minor grids */ double unitx, double unity, /* unit conversion (p, u, m, k, M, G) */ - int digital) /* set to 1 for digital plot */ + int digital, /* set to 1 for digital plot */ + double *txtsizex) /* txtsizex needed in caller too */ { double deltax, startx, deltay, starty, wx,wy, dash_sizex, dash_sizey, w, h; int j, k; char lab[30]; - double tmp, txtsizex, txtsizey; - double mark_size = marginx/20.0; + double tmp, txtsizey; + double mark_size = marginy/10.0; w = (x2 - x1); h = (y2 - y1); @@ -1933,9 +1934,9 @@ static void draw_graph_grid( tmp = marginy * 0.02; if(tmp < txtsizey) txtsizey = tmp; - txtsizex = w / divx * 0.0033; - tmp = marginy * 0.0083; - if(tmp < txtsizex) txtsizex = tmp; + *txtsizex = w / divx * 0.0033; + tmp = marginy * 0.0063; + if(tmp < *txtsizex) *txtsizex = tmp; /* calculate dash length for grid lines */ dash_sizex = 1.5 * xctx->mooz; @@ -1945,11 +1946,15 @@ static void draw_graph_grid( dash_sizey = dash_sizey > 2.0 ? 2.0 : dash_sizey; if(dash_sizey <= 1.0) dash_sizey = 1.0; + /* clipping everything outside container area */ /* background */ filledrect(0, NOW, rx1, ry1, rx2, ry2); /* graph bounding box */ drawrect(GRIDLAYER, NOW, rx1, ry1, rx2, ry2, 2); + bbox(START, 0.0, 0.0, 0.0, 0.0); + bbox(ADD, rx1, ry1, rx2, ry2); + bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0); /* vertical grid lines */ deltax = axis_increment(wx1, wx2, divx); startx = axis_start(wx1, deltax, divx); @@ -1968,7 +1973,7 @@ static void draw_graph_grid( drawline(GRIDLAYER, ADD, W_X(wx), W_Y(wy1), W_X(wx), W_Y(wy1) + mark_size, 0); /* axis marks */ /* X-axis labels */ my_snprintf(lab, S(lab), "%g", wx * unitx); - draw_string(3, NOW, lab, 0, 0, 1, 0, W_X(wx), y2 + mark_size + 20 * txtsizex, txtsizex, txtsizex); + draw_string(3, NOW, lab, 0, 0, 1, 0, W_X(wx), y2 + mark_size + 5 * *txtsizex, *txtsizex, *txtsizex); } /* first and last vertical box delimiters */ drawline(GRIDLAYER, ADD, W_X(wx1), W_Y(wy2), W_X(wx1), W_Y(wy1), 0); @@ -1991,7 +1996,7 @@ static void draw_graph_grid( drawline(GRIDLAYER, ADD, W_X(wx1) - mark_size, W_Y(wy), W_X(wx1), W_Y(wy), 0); /* axis marks */ /* Y-axis labels */ my_snprintf(lab, S(lab), "%g", wy * unity); - draw_string(3, NOW, lab, 0, 1, 0, 1, x1 - mark_size - 20 * txtsizey, W_Y(wy), txtsizey, txtsizey); + draw_string(3, NOW, lab, 0, 1, 0, 1, x1 - mark_size - 5 * txtsizey, W_Y(wy), txtsizey, txtsizey); } } /* first and last horizontal box delimiters */ @@ -2003,8 +2008,21 @@ static void draw_graph_grid( * swap order of wy1 and wy2 since grap y orientation is opposite to xorg orientation */ if(wx1 <= 0 && wx2 >= 0) drawline(GRIDLAYER, ADD, W_X(0), W_Y(wy2), W_X(0), W_Y(wy1), 0); drawline(GRIDLAYER, END, 0.0, 0.0, 0.0, 0.0, 0); + bbox(END, 0.0, 0.0, 0.0, 0.0); + + } +/* flags: + * 1: do final XCopyArea (copy 2nd buffer areas to screen) + * If draw_graph_all() is called from draw() no need to do XCopyArea, as draw() does it already. + * This makes drawing faster and removes a 'tearing' effect when moving around. + * 2: draw x-cursor1 + * 4: draw x-cursor2 + * 8: all drawing, if not set do only XCopyArea / x-cursor if specified + * 16: move cursor1 + * 32: move cursor2 + */ void draw_graph(int c, int i, int flags) { /* container box */ @@ -2014,16 +2032,16 @@ void draw_graph(int c, int i, int flags) /* graph coordinate, some defaults */ int digital = 0; int dig_max_waves = 10; /* max waves that can be stacked, then vertical pan can be used to view more */ - double wx1 = -2e-6; - double wy1 = -1; - double wx2 = 8e-6; - double wy2 = 4; + double wx1 = 0; + double wy1 = 0; + double wx2 = 1e-6; + double wy2 = 5; double marginx = 20; /* will be recalculated later */ double marginy = 20; /* will be recalculated later */ /* coefficients for graph to container coordinate transformations W_X() and W_Y()*/ double cx, dx, cy, dy; - int divx = 10; - int divy = 5; + int divx = 4; + int divy = 4; int subdivx = 0; int subdivy = 0; double unitx = 1.0; @@ -2033,7 +2051,7 @@ void draw_graph(int c, int i, int flags) int wave_color = 5; const char *val; char *node = NULL, *color = NULL, *sweep = NULL; - double txtsizelab, digtxtsizelab, tmp; + double txtsizelab, digtxtsizelab, txtsizex, tmp; Int_hashentry *entry; int sweep_idx = 0; int n_nodes; /* number of variables to display in a single graph */ @@ -2044,6 +2062,7 @@ void draw_graph(int c, int i, int flags) char *bus_msb = NULL; int wcnt = 0; int dataset = -1; + /* container (embedding rectangle) coordinates */ rx1 = r->x1; ry1 = r->y1; @@ -2080,6 +2099,7 @@ void draw_graph(int c, int i, int flags) val = get_tok_value(r->prop_ptr,"dig_max_waves",0); if(val[0]) dig_max_waves = atoi(val); } + /* plot single dataset */ val = get_tok_value(r->prop_ptr,"dataset",0); if(val[0]) dataset = atoi(val); @@ -2097,150 +2117,223 @@ void draw_graph(int c, int i, int flags) cy = (y1 - y2) / (wy2 - wy1); dy = y2 - wy1 * cy; - /* graph box, gridlines and axes */ - draw_graph_grid(rx1, ry1, rx2, ry2, x1, y1, x2, y2, marginx, marginy, - wx1, wy1, wx2, wy2, cx, cy, dx, dy, - divx, divy, subdivx, subdivy, unitx, unity, digital); - - /* get data to plot */ - my_strdup2(1389, &node, get_tok_value(r->prop_ptr,"node",0)); - my_strdup2(1390, &color, get_tok_value(r->prop_ptr,"color",0)); - my_strdup2(1407, &sweep, get_tok_value(r->prop_ptr,"sweep",0)); - nptr = node; - cptr = color; - sptr = sweep; - n_nodes = count_items(node, " \t\n"); - /* process each node given in "node" attribute, get also associated color/sweep var if any*/ - while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) { - if(strstr(ntok, ",")) { - my_strdup2(1452, &bus_msb, find_nth(ntok, ',', 2)); - } - ctok = my_strtok_r(cptr, " ", &savec); - stok = my_strtok_r(sptr, " ", &saves); - nptr = cptr = sptr = NULL; - dbg(1, "ntok=%s ctok=%s\n", ntok, ctok? ctok: "NULL"); - if(ctok && ctok[0]) wave_color = atoi(ctok); - if(stok && stok[0]) { - sweep_idx = get_raw_index(stok); - if( sweep_idx == -1) { - sweep_idx = 0; + /* draw stuff */ + if(flags & 8) { + /* graph box, gridlines and axes */ + draw_graph_grid(rx1, ry1, rx2, ry2, x1, y1, x2, y2, marginx, marginy, + wx1, wy1, wx2, wy2, cx, cy, dx, dy, + divx, divy, subdivx, subdivy, unitx, unity, digital, &txtsizex); + + /* get data to plot */ + my_strdup2(1389, &node, get_tok_value(r->prop_ptr,"node",0)); + my_strdup2(1390, &color, get_tok_value(r->prop_ptr,"color",0)); + my_strdup2(1407, &sweep, get_tok_value(r->prop_ptr,"sweep",0)); + nptr = node; + cptr = color; + sptr = sweep; + n_nodes = count_items(node, " \t\n"); + /* process each node given in "node" attribute, get also associated color/sweep var if any*/ + while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) { + if(strstr(ntok, ",")) { + my_strdup2(1452, &bus_msb, find_nth(ntok, ',', 2)); } - } - /* clipping everything outside container area */ - bbox(START, 0.0, 0.0, 0.0, 0.0); - bbox(ADD, rx1, ry1, rx2, ry2); - bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0); - /* draw sweep variable(s) on x-axis */ - if(wcnt == 0 || (stok && stok[0])) { - if(xctx->graph_values) stok = xctx->graph_names[sweep_idx]; - if(unitx != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", stok ? stok : "" , unitx_suffix); - else my_snprintf(tmpstr, S(tmpstr), "%s", stok ? stok : ""); - draw_string(wave_color, NOW, tmpstr, 2, 1, 0, 0, - rx1 + 2 + rw / n_nodes * wcnt, ry2-1, txtsizelab, txtsizelab); - } - /* draw node labels in graph */ - if(bus_msb) { - if(unity != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", find_nth(ntok, ',', 1), unity_suffix); - else my_snprintf(tmpstr, S(tmpstr), "%s",find_nth(ntok, ',', 1)); - } else { - if(unity != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", ntok, unity_suffix); - else my_snprintf(tmpstr, S(tmpstr), "%s", ntok); - } - if(digital) { - /* int n = n_nodes > dig_max_waves ? dig_max_waves : n_nodes; */ - int n = dig_max_waves; - double xt = x1 - 10 * txtsizelab; - double delta_div_n = (wy2 - wy1) / n; - double yt = delta_div_n * (double)wcnt; - - if(yt <= wy2 && yt >= wy1) { - draw_string(wave_color, NOW, tmpstr, 2, 0, 0, 0, xt, W_Y(yt), digtxtsizelab, digtxtsizelab); + ctok = my_strtok_r(cptr, " ", &savec); + stok = my_strtok_r(sptr, " ", &saves); + nptr = cptr = sptr = NULL; + dbg(1, "ntok=%s ctok=%s\n", ntok, ctok? ctok: "NULL"); + if(ctok && ctok[0]) wave_color = atoi(ctok); + if(stok && stok[0]) { + sweep_idx = get_raw_index(stok); + if( sweep_idx == -1) { + sweep_idx = 0; + } } - } else { - draw_string(wave_color, NOW, tmpstr, 0, 0, 0, 0, rx1 + rw / n_nodes * wcnt, ry1, txtsizelab, txtsizelab); - } - bbox(END, 0.0, 0.0, 0.0, 0.0); - /* quickly find index number of ntok variable to be plotted */ - entry = int_hash_lookup(xctx->raw_table, bus_msb ? bus_msb : ntok, 0, XLOOKUP); - if(xctx->graph_values && entry) { - int p, dset, ofs; - int poly_npoints; - int v; - int first; - double xx; - double start; - double end; - double *xarr = NULL, *yarr = NULL; - - /* clipping everything outside graph area */ + /* clipping everything outside container area */ bbox(START, 0.0, 0.0, 0.0, 0.0); - bbox(ADD,x1, y1, x2, y2); - bbox(SET, 0.0, 0.0, 0.0, 0.0); - - ofs = 0; - v = entry->value; - start = (wx1 <= wx2) ? wx1 : wx2; - end = (wx1 <= wx2) ? wx2 : wx1; - /* loop through all datasets found in raw file */ - for(dset = 0 ; dset < xctx->graph_datasets; dset++) { - if(dataset == -1 || dset == dataset) { - double prev_x; - first = -1; - poly_npoints = 0; - my_realloc(1401, &xarr, xctx->graph_npoints[dset] * sizeof(double)); - my_realloc(1402, &yarr, xctx->graph_npoints[dset] * sizeof(double)); - /* Process "npoints" simulation items - * p loop split repeated 2 timed (for x and y points) to preserve cache locality */ - for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) { - xx = xctx->graph_values[sweep_idx][p]; - if(xx > end || (sweep_idx == 0 && (p > ofs && fabs(xx) < fabs(prev_x))) ) { - if(first != -1) { - /* get y-axis points */ - if(bus_msb) { - if(digital) { - draw_graph_bus_points(ntok, first, p, cx, dx, cy, dy, wave_color, - sweep_idx, digital, dig_max_waves, wcnt, n_nodes, wy1, wy2); - } - } else { - draw_graph_points(v, first, p, cy, dy, xarr, yarr, wave_color, - digital, dig_max_waves, wcnt, n_nodes, wy1, wy2); - } - poly_npoints = 0; - first = -1; - } - } - if(xx >= start && xx <= end) { - if(first == -1) first = p; - /* Build poly x array. Translate from graph coordinates to {x1,y1} - {x2, y2} world. */ - xarr[poly_npoints] = W_X(xx); - poly_npoints++; - } - prev_x = xx; - } - if(first != -1) { - /* get y-axis points */ - if(bus_msb) { - if(digital) { - draw_graph_bus_points(ntok, first, p, cx, dx, cy, dy, wave_color, - sweep_idx, digital, dig_max_waves, wcnt, n_nodes, wy1, wy2); - } - } else { - draw_graph_points(v, first, p, cy, dy, xarr, yarr, wave_color, - digital, dig_max_waves, wcnt, n_nodes, wy1, wy2); - } - } - } /* if(dataset == -1 || dset == dataset) */ - - /* offset pointing to next dataset */ - ofs += xctx->graph_npoints[dset]; - } /* for(dset...) */ - my_free(1403, &xarr); - my_free(1404, &yarr); + bbox(ADD, rx1, ry1, rx2, ry2); + bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0); + /* draw sweep variable(s) on x-axis */ + if(wcnt == 0 || (stok && stok[0])) { + if(xctx->graph_values) stok = xctx->graph_names[sweep_idx]; + if(unitx != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", stok ? stok : "" , unitx_suffix); + else my_snprintf(tmpstr, S(tmpstr), "%s", stok ? stok : ""); + draw_string(wave_color, NOW, tmpstr, 2, 1, 0, 0, + rx1 + 2 + rw / n_nodes * wcnt, ry2-1, txtsizelab, txtsizelab); + } + /* draw node labels in graph */ + if(bus_msb) { + if(unity != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", find_nth(ntok, ',', 1), unity_suffix); + else my_snprintf(tmpstr, S(tmpstr), "%s",find_nth(ntok, ',', 1)); + } else { + if(unity != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", ntok, unity_suffix); + else my_snprintf(tmpstr, S(tmpstr), "%s", ntok); + } + if(digital) { + /* int n = n_nodes > dig_max_waves ? dig_max_waves : n_nodes; */ + int n = dig_max_waves; + double xt = x1 - 10 * txtsizelab; + double delta_div_n = (wy2 - wy1) / n; + double yt = delta_div_n * (double)wcnt; + + if(yt <= wy2 && yt >= wy1) { + draw_string(wave_color, NOW, tmpstr, 2, 0, 0, 0, xt, W_Y(yt), digtxtsizelab, digtxtsizelab); + } + } else { + draw_string(wave_color, NOW, tmpstr, 0, 0, 0, 0, rx1 + rw / n_nodes * wcnt, ry1, txtsizelab, txtsizelab); + } bbox(END, 0.0, 0.0, 0.0, 0.0); - }/* if(entry) */ - wcnt++; - if(bus_msb) my_free(1453, &bus_msb); - } /* while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) */ + /* quickly find index number of ntok variable to be plotted */ + entry = int_hash_lookup(xctx->raw_table, bus_msb ? bus_msb : ntok, 0, XLOOKUP); + if(xctx->graph_values && entry) { + int p, dset, ofs; + int poly_npoints; + int v; + int first; + double xx; + double start; + double end; + double *xarr = NULL, *yarr = NULL; + + /* clipping everything outside graph area */ + bbox(START, 0.0, 0.0, 0.0, 0.0); + bbox(ADD,x1, y1, x2, y2); + bbox(SET, 0.0, 0.0, 0.0, 0.0); + + ofs = 0; + v = entry->value; + start = (wx1 <= wx2) ? wx1 : wx2; + end = (wx1 <= wx2) ? wx2 : wx1; + /* loop through all datasets found in raw file */ + for(dset = 0 ; dset < xctx->graph_datasets; dset++) { + if(dataset == -1 || dset == dataset) { + double prev_x; + first = -1; + poly_npoints = 0; + my_realloc(1401, &xarr, xctx->graph_npoints[dset] * sizeof(double)); + my_realloc(1402, &yarr, xctx->graph_npoints[dset] * sizeof(double)); + /* Process "npoints" simulation items + * p loop split repeated 2 timed (for x and y points) to preserve cache locality */ + for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) { + xx = xctx->graph_values[sweep_idx][p]; + if(xx > end || (sweep_idx == 0 && (p > ofs && fabs(xx) < fabs(prev_x))) ) { + if(first != -1) { + /* get y-axis points */ + if(bus_msb) { + if(digital) { + draw_graph_bus_points(ntok, first, p, cx, dx, cy, dy, wave_color, + sweep_idx, digital, dig_max_waves, wcnt, n_nodes, wy1, wy2); + } + } else { + draw_graph_points(v, first, p, cy, dy, xarr, yarr, wave_color, + digital, dig_max_waves, wcnt, n_nodes, wy1, wy2); + } + poly_npoints = 0; + first = -1; + } + } + if(xx >= start && xx <= end) { + if(first == -1) first = p; + /* Build poly x array. Translate from graph coordinates to {x1,y1} - {x2, y2} world. */ + xarr[poly_npoints] = W_X(xx); + poly_npoints++; + } + prev_x = xx; + } + if(first != -1) { + /* get y-axis points */ + if(bus_msb) { + if(digital) { + draw_graph_bus_points(ntok, first, p, cx, dx, cy, dy, wave_color, + sweep_idx, digital, dig_max_waves, wcnt, n_nodes, wy1, wy2); + } + } else { + draw_graph_points(v, first, p, cy, dy, xarr, yarr, wave_color, + digital, dig_max_waves, wcnt, n_nodes, wy1, wy2); + } + } + } /* if(dataset == -1 || dset == dataset) */ + + /* offset pointing to next dataset */ + ofs += xctx->graph_npoints[dset]; + } /* for(dset...) */ + my_free(1403, &xarr); + my_free(1404, &yarr); + bbox(END, 0.0, 0.0, 0.0, 0.0); + }/* if(entry) */ + wcnt++; + if(bus_msb) my_free(1453, &bus_msb); + } /* while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) */ + my_free(1391, &node); + my_free(1392, &color); + my_free(1408, &sweep); + } + if(flags & 2) { /* cursor1 */ + double xx = W_X(xctx->graph_cursor1_x); + double tx1, ty1, tx2, ty2; + int tmp; + double txtsize = txtsizex; + + int flip = (xctx->graph_cursor2_x > xctx->graph_cursor1_x) ? 0 : 1; + int xoffs = flip ? 2 : -2; + if(xx >= x1 && xx <= x2) { + drawline(3, NOW, xx, ry1, xx, ry2, 1); + if(unitx != 1.0) + my_snprintf(tmpstr, S(tmpstr), "%.4g%c", unitx * xctx->graph_cursor1_x , unitx_suffix); + else + my_snprintf(tmpstr, S(tmpstr), "%.4g", xctx->graph_cursor1_x); + text_bbox(tmpstr, txtsize, txtsize, 2, flip, 0, 0, xx + xoffs, ry2-1, &tx1, &ty1, &tx2, &ty2, &tmp, &tmp); + filledrect(0, NOW, tx1, ty1, tx2, ty2); + draw_string(3, NOW, tmpstr, 2, flip, 0, 0, xx + xoffs, ry2-1, txtsize, txtsize); + } + } + if(flags & 4) { /* cursor2 */ + double xx = W_X(xctx->graph_cursor2_x); + double tx1, ty1, tx2, ty2; + int tmp; + double txtsize = txtsizex; + int flip = (xctx->graph_cursor2_x > xctx->graph_cursor1_x) ? 1 : 0; + int xoffs = flip ? 2 : -2; + if(xx >= x1 && xx <= x2) { + drawline(3, NOW, xx, ry1, xx, ry2, 1); + if(unitx != 1.0) + my_snprintf(tmpstr, S(tmpstr), "%.4g%c", unitx * xctx->graph_cursor2_x , unitx_suffix); + else + my_snprintf(tmpstr, S(tmpstr), "%.4g", xctx->graph_cursor2_x); + text_bbox(tmpstr, txtsize, txtsize, 2, flip, 0, 0, xx + xoffs, ry2-1, &tx1, &ty1, &tx2, &ty2, &tmp, &tmp); + filledrect(0, NOW, tx1, ty1, tx2, ty2); + draw_string(3, NOW, tmpstr, 2, flip, 0, 0, xx + xoffs, ry2-1, txtsize, txtsize); + + } + } + if((flags & 6) == 6) { /* difference between cursors */ + int tmp; + double txtsize = txtsizex; + double tx1, ty1, tx2, ty2; + double aa = W_X(xctx->graph_cursor1_x); + double a = CLIP(aa, x1, x2); + double bb = W_X(xctx->graph_cursor2_x); + double b = CLIP(bb, x1, x2); + double diff = fabs(b - a); + double diffw = fabs(xctx->graph_cursor2_x - xctx->graph_cursor1_x); + double xx = ( a + b ) / 2.0; + double yy = ry2 - 1; + double tmpd; + double yline; + if(unitx != 1.0) + my_snprintf(tmpstr, S(tmpstr), "%.4g%c", unitx * diffw , unitx_suffix); + else + my_snprintf(tmpstr, S(tmpstr), "%.4g", diffw); + text_bbox(tmpstr, txtsize, txtsize, 2, 0, 1, 0, xx, yy, &tx1, &ty1, &tx2, &ty2, &tmp, &tmp); + if( tx2 - tx1 < diff ) { + draw_string(3, NOW, tmpstr, 2, 0, 1, 0, xx, yy, txtsize, txtsize); + if( a > b) { + tmpd = a; a = b; b = tmpd; + } + yline = (ty1 + ty2) / 2.0; + if( tx1 - a > 4.0) drawline(3, NOW, a + 2, yline, tx1 - 2, yline, 1); + if( b - tx2 > 4.0) drawline(3, NOW, tx2 + 2, yline, b - 2, yline, 1); + } + } if(flags & 1) { bbox(START, 0.0, 0.0, 0.0, 0.0); bbox(ADD, rx1, ry1, rx2, ry2); @@ -2251,16 +2344,10 @@ void draw_graph(int c, int i, int flags) } bbox(END, 0.0, 0.0, 0.0, 0.0); } - my_free(1391, &node); - my_free(1392, &color); - my_free(1408, &sweep); } -/* fill graph boxes with data from ngspice simulations */ /* flags: - * 1: do final XCopyArea (copy 2nd buffer areas to screen) - * If draw_graph_all() is called from draw() no need to do XCopyArea, as draw() does it already. - * This makes drawing faster and removes a 'tearing' effect when moving around. + * see draw_graph() */ void draw_graph_all(int flags) { @@ -2337,7 +2424,7 @@ void draw(void) xctx->areaw, xctx->areah); dbg(1, "draw(): window: %d %d %d %d\n",xctx->areax1, xctx->areay1, xctx->areax2, xctx->areay2); drawgrid(); - draw_graph_all(0); + draw_graph_all((xctx->graph_flags & 6) + 8); /* xctx->graph_flags for cursors */ x1 = X_TO_XSCHEM(xctx->areax1); y1 = Y_TO_XSCHEM(xctx->areay1); x2 = X_TO_XSCHEM(xctx->areax2); diff --git a/src/xinit.c b/src/xinit.c index 258a7c05..687a64d8 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -428,6 +428,8 @@ void alloc_xschem_data(const char *top_path) xctx->graph_npoints = NULL; xctx->graph_datasets = 0; xctx->graph_master = 0; + xctx->graph_cursor1_x = 0; + xctx->graph_unlock_x = 0; xctx->graph_flags = 0; xctx->graph_bottom = 0; xctx->graph_left = 0; diff --git a/src/xschem.h b/src/xschem.h index e497bfd6..182d52a6 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -313,10 +313,13 @@ extern char win_temp_dir[PATH_MAX]; #define IS_PIN(type) (!(strcmp(type,"ipin") && strcmp(type,"opin") && strcmp(type,"iopin"))) -#define X_TO_SCREEN(x) ( floor(((x)+xctx->xorigin)* xctx->mooz) ) -#define Y_TO_SCREEN(y) ( floor(((y)+xctx->yorigin)* xctx->mooz) ) -#define X_TO_XSCHEM(x) ((x)*xctx->zoom -xctx->xorigin) -#define Y_TO_XSCHEM(y) ((y)*xctx->zoom -xctx->yorigin) +/* floor not needed? screen coordinates always positive <<<< */ +/* #define X_TO_SCREEN(x) ( floor(((x)+xctx->xorigin)* xctx->mooz) ) */ +/* #define Y_TO_SCREEN(y) ( floor(((y)+xctx->yorigin)* xctx->mooz) ) */ +#define X_TO_SCREEN(x) ( ((x) + xctx->xorigin) * xctx->mooz ) +#define Y_TO_SCREEN(y) ( ((y) + xctx->yorigin) * xctx->mooz ) +#define X_TO_XSCHEM(x) ( (x) * xctx->zoom - xctx->xorigin ) +#define Y_TO_XSCHEM(y) ( (y) * xctx->zoom - xctx->yorigin ) /* given a dest_string of size 'size', allocate space to make sure it can * hold 'add' characters */ @@ -827,7 +830,12 @@ typedef struct { int graph_nvars; int *graph_npoints; int graph_datasets; - int graph_flags; /* 1: zoom / pan all graphs even if only one selected */ + double graph_cursor1_x; + double graph_cursor2_x; + int graph_unlock_x; + int graph_flags; /* 1: zoom / pan all graphs even if only one selected + * 2: x-axis cursor1 + * 4: x-axis cursor2 */ int graph_master; /* graph where mouse operations are started, used to lock x-axis */ int graph_bottom; /* graph where mouse operations are started, used to lock x-axis */ int graph_left; /* graph where mouse operations are started, used to lock x-axis */ diff --git a/xschem_library/rom8k/rom8k.sch b/xschem_library/rom8k/rom8k.sch index 53912021..da14c2f5 100644 --- a/xschem_library/rom8k/rom8k.sch +++ b/xschem_library/rom8k/rom8k.sch @@ -28,12 +28,12 @@ L 8 1180 -160 1180 -120 {} L 8 1180 -120 1300 -120 {} L 8 820 -120 950 -120 {} B 2 1840 -420 2890 -280 {flags=1 -y1 = 0 -y2 = 1 +y1 = -0.0039 +y2 = 0.87 divy = 3 subdivy=1 -x1=1.22237e-07 -x2=1.80069e-07 divx=10 +x1=2.44096e-07 +x2=3.3487e-07 divx=10 node=" v(ldbl[0]) v(ldbl[16]) v(ldbl[32]) v(ldbl[1]) v(ldbl[17]) v(ldbl[33]) @@ -42,15 +42,15 @@ v(ldbl[2]) v(ldbl[18]) v(ldbl[34]) color="8 9 10 11 12 13 14 15 16 17 18" unitx=n} B 2 1840 -1090 2890 -880 {flags=1 digital=0 -y1 = -0.0120424 -y2 = 1.50796 +y1 = -0.021 +y2 = 1.5 subdivy=1 divy = 4 -x1=1.22237e-07 -x2=1.80069e-07 +x1=2.44096e-07 +x2=3.3487e-07 divx=10 subdivx=4 -node="v(ldcp) v(ldyms[4]) v(ldyms[5]) v(ldyms[6]) v(ldyms[7])" +node="v(ldcp) v(ldyms[4]) v(ldyms[5]) v(ldyms[6]) v(ldymsref)" color="6 12 13 14 15" unitx=n} B 2 1840 -280 2890 -120 {flags=1 @@ -59,8 +59,8 @@ y2 = 1.6 divy = 3 subdivy=0 subdivx = 1 -x1=1.22237e-07 -x2=1.80069e-07 divx=10 +x1=2.44096e-07 +x2=3.3487e-07 divx=10 node=" v(ldwl[0]) v(ldwl[1]) v(ldwl[2]) v(ldwl[3]) v(ldwl[4]) v(ldwl[5]) v(ldwl[6]) v(ldwl[16]) @@ -69,22 +69,22 @@ color="4 5 4 5 4 5 4 5 4 5 4 5" unitx=n } B 2 1840 -120 2890 -20 {flags=1 -y1 = 0 +y1 = -0.021 y2 = 0.9 divy = 1 -x1=1.22237e-07 -x2=1.80069e-07 divx=10 +x1=2.44096e-07 +x2=3.3487e-07 divx=10 node="v(ldymsref)" color=3 unitx=n subdivy=4} B 2 1840 -880 2890 -420 {flags=1 digital=1 dig_max_waves=12 -y1 = -0.0811982 -y2 = 1.4188 +y1 = -0.024 +y2 = 1.6 divy = 1 -x1=1.22237e-07 -x2=1.80069e-07 -divx=10 +x1=2.44096e-07 +x2=3.3487e-07 +divx=12 subdivx=4 node=" v(lden) v(ldprech) @@ -102,15 +102,16 @@ v(ldcp) color="4 15 4 15 4 15 4 15 4 15 4 15 4 15 4 15 4 15 4 15 4 15" unitx=n } -B 2 1840 -1270 2890 -1090 {flags=1 -y1 = -0.0479717 -y2 = 1.55203 +B 2 1840 -1280 2890 -1090 {flags=1 +y1 = -0.022 +y2 = 1.6 divy = 4 -x1=1.22237e-07 -x2=1.80069e-07 +x1=2.44096e-07 +x2=3.3487e-07 divx=8 -node="v(xsa[0].ldqi) v(xsa[0].ldqib) v(xsa[0].ldsali)" -color="16 8 15"} +unitx=n +node="v(xsa[0].ldqib) v(xsa[5].ldqib) v(xsa[0].ldsali) v(xctrl.ldq_b)" +color="4 4 5 12 "} B 7 950 -250 980 -80 {} B 7 1150 -250 1180 -80 {} B 21 10 -970 240 -750 {}