/*! \brief draw rubbernet lines to the gc * \par Function Description * This function draws the rubbernets to the graphic context */ void o_net_draw_rubber(GSCHEM_TOPLEVEL *w_current) { int size = 0, w_magnetic_halfsize; if (w_current->toplevel->net_style == THICK) size = NET_WIDTH; gschem_cairo_set_source_color (w_current, x_color_lookup_dark (SELECT_COLOR)); if (w_current->magneticnet_mode) { if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1) { w_magnetic_halfsize = max (4 * size, WORLDabs (w_current, MAGNETIC_HALFSIZE)); gschem_cairo_arc (w_current, size, w_current->magnetic_wx, w_current->magnetic_wy, w_magnetic_halfsize, 0, 360); } } /* Primary line */ gschem_cairo_line (w_current, END_NONE, size, w_current->first_wx, w_current->first_wy, w_current->second_wx, w_current->second_wy); /* Secondary line */ gschem_cairo_line (w_current, END_NONE, size, w_current->second_wx, w_current->second_wy, w_current->third_wx, w_current->third_wy); gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, size, -1, -1); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void a_pan_mouse(GSCHEM_TOPLEVEL *w_current, int diff_x, int diff_y) { TOPLEVEL *toplevel = w_current->toplevel; double world_cx, world_cy; double page_cx, page_cy; #if DEBUG printf("a_pan_mouse(): diff_x=%d, diff_y=%d\n", diff_x, diff_y); #endif page_cx = (toplevel->page_current->left + toplevel->page_current->right) / 2.0; page_cy = (toplevel->page_current->top + toplevel->page_current->bottom) / 2.0; world_cx = page_cx - WORLDabs (w_current, diff_x); world_cy = page_cy + WORLDabs (w_current, diff_y); #if DEBUG printf(" world_cx=%f, world_cy=%f\n", world_cx, world_cy); #endif a_pan_general(w_current, world_cx, world_cy, 1, 0); }
/*! \brief find the closest possible location to connect to * \par Function Description * This function calculates the distance to all connectable objects * and searches the closest connection point. * It searches for pins, nets and busses. * * The connection point is stored in GSCHEM_TOPLEVEL->magnetic_wx and * GSCHEM_TOPLEVEL->magnetic_wy. If no connection is found. Both variables * are set to -1. */ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y) { TOPLEVEL *toplevel = w_current->toplevel; int x1, x2, y1, y2, min_x, min_y, w_magnetic_reach; double mindist, minbest, dist1, dist2; double weight, min_weight; int magnetic_reach = 0; OBJECT *o_current; OBJECT *o_magnetic = NULL; GList *objectlists, *iter1, *iter2; minbest = min_x = min_y = 0; min_weight = 0; /* max distance of all the different reaches */ magnetic_reach = max(MAGNETIC_PIN_REACH, MAGNETIC_NET_REACH); magnetic_reach = max(magnetic_reach, MAGNETIC_BUS_REACH); w_magnetic_reach = WORLDabs (w_current, magnetic_reach); /* get the objects of the tiles around the reach region */ x1 = w_x - w_magnetic_reach; y1 = w_y - w_magnetic_reach; x2 = w_x + w_magnetic_reach; y2 = w_y + w_magnetic_reach; objectlists = s_tile_get_objectlists(toplevel, x1, y1, x2, y2); for (iter1 = objectlists; iter1 != NULL; iter1 = g_list_next(iter1)) { for (iter2 = (GList*) iter1->data; iter2 != NULL; iter2 = g_list_next(iter2)) { o_current = (OBJECT*) iter2->data; if (!visible (w_current, o_current->w_left, o_current->w_top, o_current->w_right, o_current->w_bottom)) continue; /* skip invisible objects */ if (o_current->type == OBJ_PIN) { min_x = o_current->line->x[o_current->whichend]; min_y = o_current->line->y[o_current->whichend]; mindist = sqrt((double) (w_x - min_x)*(w_x - min_x) + (double) (w_y - min_y)*(w_y - min_y)); weight = mindist / MAGNETIC_PIN_WEIGHT; } else if (o_current->type == OBJ_NET || o_current->type == OBJ_BUS) { /* we have 3 possible points to connect: 2 endpoints and 1 midpoint point */ x1 = o_current->line->x[0]; y1 = o_current->line->y[0]; x2 = o_current->line->x[1]; y2 = o_current->line->y[1]; /* endpoint tests */ dist1 = sqrt((double) (w_x - x1)*(w_x - x1) + (double) (w_y - y1)*(w_y - y1)); dist2 = sqrt((double) (w_x - x2)*(w_x - x2) + (double) (w_y - y2)*(w_y - y2)); if (dist1 < dist2) { min_x = x1; min_y = y1; mindist = dist1; } else { min_x = x2; min_y = y2; mindist = dist2; } /* midpoint tests */ if ((x1 == x2) /* vertical net */ && ((y1 >= w_y && w_y >= y2) || (y2 >= w_y && w_y >= y1))) { if (abs(w_x - x1) < mindist) { mindist = abs(w_x - x1); min_x = x1; min_y = w_y; } } if ((y1 == y2) /* horitontal net */ && ((x1 >= w_x && w_x >= x2) || (x2 >= w_x && w_x >= x1))) { if (abs(w_y - y1) < mindist) { mindist = abs(w_y - y1); min_x = w_x; min_y = y1; } } if (o_current->type == OBJ_BUS) weight = mindist / MAGNETIC_BUS_WEIGHT; else /* OBJ_NET */ weight = mindist / MAGNETIC_NET_WEIGHT; } else { /* neither pin nor net or bus */ continue; } if (o_magnetic == NULL || weight < min_weight) { minbest = mindist; min_weight = weight; o_magnetic = o_current; w_current->magnetic_wx = min_x; w_current->magnetic_wy = min_y; } } } /* check whether we found an object and if it's close enough */ if (o_magnetic != NULL) { switch (o_magnetic->type) { case (OBJ_PIN): magnetic_reach = MAGNETIC_PIN_REACH; break; case (OBJ_NET): magnetic_reach = MAGNETIC_NET_REACH; break; case (OBJ_BUS): magnetic_reach = MAGNETIC_BUS_REACH; break; } if (minbest > WORLDabs (w_current, magnetic_reach)) { w_current->magnetic_wx = -1; w_current->magnetic_wy = -1; } } else { w_current->magnetic_wx = -1; w_current->magnetic_wy = -1; } g_list_free(objectlists); }