From fefbd922d50f08a87b885e46b9e9c08d04ec7429 Mon Sep 17 00:00:00 2001 From: Chayan Deb Date: Fri, 24 Jan 2025 14:40:29 +0530 Subject: [PATCH] [Bugfix - Snap Cursor]: Fully removed the bug from commit 0a0ef22. Solved by introducing breaking change in 'find_closest_net_or_symbol_pin()' function defined in 'src/xschem.h' and implemented in 'src/findnet.c'. The function now returns a boolean value indicating if the search yielded any valid results, instead of returning nothing (void). --- src/callback.c | 57 ++++++++++++++++++++++++++++++++++++++------------ src/findnet.c | 7 ++++++- src/xinit.c | 1 + src/xschem.h | 4 +++- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/callback.c b/src/callback.c index 6a2b3339..f3a64f41 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1479,15 +1479,46 @@ void draw_snap_cursor(int what) if(!xctx->mouse_inside) return; xctx->draw_pixmap = 0; xctx->draw_window = 1; + double prev_x = xctx->prev_snapx; + double prev_y = xctx->prev_snapy; if(what != 2) { if(fix_broken_tiled_fill || !_unix) { - MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0); - } else { - double prev_x = xctx->prev_snapx; - double prev_y = xctx->prev_snapy; - double points_x[5] = {prev_x, prev_x+snapcursor_size, prev_x, prev_x-snapcursor_size, prev_x}; - double points_y[5] = {prev_y-snapcursor_size, prev_y, prev_y+snapcursor_size, prev_y, prev_y-snapcursor_size}; - drawtemppolygon(xctx->gctiled, NOW, points_x, points_y, 5, 0); + /*MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], 0, 0, xctx->xrect[0].width, xctx->xrect[0].height, 0, 0);*/ + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], + (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, + 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, + (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size); + MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0], + (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, + 4 * INT_WIDTH(xctx->lw) + 4 * snapcursor_size, + (int)X_TO_SCREEN(prev_x) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size, + (int)Y_TO_SCREEN(prev_y) - 2 * INT_WIDTH(xctx->lw) - snapcursor_size); + } else { + draw_xhair_line(xctx->gctiled, snapcursor_size, + X_TO_SCREEN(prev_x), + Y_TO_SCREEN(prev_y) - snapcursor_size, + X_TO_SCREEN(prev_x) + snapcursor_size, + Y_TO_SCREEN(prev_y)); + draw_xhair_line(xctx->gctiled, snapcursor_size, + X_TO_SCREEN(prev_x) + snapcursor_size, + Y_TO_SCREEN(prev_y), + X_TO_SCREEN(prev_x), + Y_TO_SCREEN(prev_y) + snapcursor_size); + draw_xhair_line(xctx->gctiled, snapcursor_size, + X_TO_SCREEN(prev_x), + Y_TO_SCREEN(prev_y) + snapcursor_size, + X_TO_SCREEN(prev_x) - snapcursor_size, + Y_TO_SCREEN(prev_y)); + draw_xhair_line(xctx->gctiled, snapcursor_size, + X_TO_SCREEN(prev_x) - snapcursor_size, + Y_TO_SCREEN(prev_y), + X_TO_SCREEN(prev_x), + Y_TO_SCREEN(prev_y) - snapcursor_size); } } if(what != 1) { @@ -1496,11 +1527,8 @@ void draw_snap_cursor(int what) x = xctx->prev_snapx; y = xctx->prev_snapy; } else { /* Only search for nearest pin if the grid-snap-point has changed */ - find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); + xctx->closest_pin_found = find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); } - /*double points_x[5] = {x, x+snapcursor_size, x, x-snapcursor_size, x};*/ - /*double points_y[5] = {y-snapcursor_size, y, y+snapcursor_size, y, y-snapcursor_size};*/ - /*drawpolygon(xctx->crosshair_layer, NOW, points_x, points_y, 5, 0, 0, 0);*/ draw_xhair_line(xctx->gc[xctx->crosshair_layer], snapcursor_size, X_TO_SCREEN(x), Y_TO_SCREEN(y) - snapcursor_size, @@ -4250,8 +4278,11 @@ int rstate; /* (reduced state, without ShiftMask) */ if(tclgetboolvar("persistent_command") && xctx->last_command) { if(xctx->last_command == STARTLINE) start_line(xctx->mousex_snap, xctx->mousey_snap); if(xctx->last_command == STARTWIRE){ - if(tclgetboolvar("snap_cursor") && (xctx->prev_snapx == xctx->mousex_snap && xctx->prev_snapy == xctx->mousey_snap) - && (xctx->ui_state & STARTWIRE)){ + if(tclgetboolvar("snap_cursor") + && (xctx->prev_snapx == xctx->mousex_snap + && xctx->prev_snapy == xctx->mousey_snap) + && (xctx->ui_state & STARTWIRE) + && xctx->closest_pin_found){ new_wire(PLACE|END, xctx->mousex_snap, xctx->mousey_snap); xctx->ui_state &= ~STARTWIRE; } diff --git a/src/findnet.c b/src/findnet.c index 852e72bb..cc9801e1 100644 --- a/src/findnet.c +++ b/src/findnet.c @@ -185,7 +185,7 @@ static void find_closest_line(double mx, double my) /* snap wire to closest pin or net endpoint (if it is inside the current screen viewport) */ /* use spatial hash table iterators to avoid O(N) */ -void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) +int find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) { double x1, y1, x2, y2; Iterator_ctx ctx; @@ -193,6 +193,7 @@ void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) Wireentry *wireptr; double curr_dist = DBL_MAX; double xx, yy, dist, min_dist_x = xctx->mousex_snap, min_dist_y = xctx->mousey_snap; + int found_net_or_pin = 0; x1 = X_TO_XSCHEM(xctx->areax1); y1 = Y_TO_XSCHEM(xctx->areay1); @@ -218,6 +219,7 @@ void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) curr_dist = dist; min_dist_x = xx; min_dist_y = yy; + found_net_or_pin = 1; } } } @@ -236,6 +238,7 @@ void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) curr_dist = dist; min_dist_x = xx; min_dist_y = yy; + found_net_or_pin = 1; } xx = wire[i].x2; yy = wire[i].y2; @@ -245,11 +248,13 @@ void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) curr_dist = dist; min_dist_x = xx; min_dist_y = yy; + found_net_or_pin = 1; } } *x = min_dist_x; *y = min_dist_y; + return found_net_or_pin; } #if 0 diff --git a/src/xinit.c b/src/xinit.c index acb456ef..2fcb25f7 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -648,6 +648,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->prev_crossx = xctx->prev_crossy = 0.0; xctx->prev_gridx = xctx->prev_gridy = 0.0; xctx->prev_snapx = xctx->prev_snapy = 0.0; + xctx->closest_pin_found = 0; xctx->mouse_inside = 0; xctx->pending_fullzoom = 0; my_strncpy(xctx->hiersep, ".", S(xctx->hiersep)); diff --git a/src/xschem.h b/src/xschem.h index 23d9d254..de5b5f2a 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1051,6 +1051,7 @@ typedef struct { double prev_crossx, prev_crossy; double prev_gridx, prev_gridy; double prev_snapx, prev_snapy; + int closest_pin_found; int mouse_inside; /* set_modify */ int prev_set_modify; @@ -1397,7 +1398,8 @@ extern int callback(const char *winpath, int event, int mx, int my, KeySym key, int button, int aux, int state); extern void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h); extern Selected find_closest_obj(double mx,double my, int override_lock); -extern void find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y); +/*extern void find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y);*/ +extern int find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y); extern void drawline(int c, int what, double x1,double y1,double x2,double y2, int dash, void *ct); extern void draw_xhair_line(GC gc, int size, double linex1, double liney1, double linex2, double liney2);