/*! \brief Return the bounds of the given GList of objects. * \par Given a list of objects, calcule the bounds coordinates. * \param [in] toplevel The TOPLEVEL structure. * \param [in] head The list of objects to look the bounds for. * \param [out] left pointer to the left coordinate of the object. * \param [out] top pointer to the top coordinate of the object. * \param [out] right pointer to the right coordinate of the object. * \param [out] bottom pointer to the bottom coordinate of the object. * \return If any bounds were found for the list of objects * \retval 0 No bounds were found * \retval 1 Bound was found */ int world_get_object_glist_bounds(TOPLEVEL *toplevel, const GList *head, int *left, int *top, int *right, int *bottom) { const GList *s_current=NULL; OBJECT *o_current=NULL; int rleft, rtop, rright, rbottom; int found = 0; s_current = head; /* Find the first object with bounds, and set the bounds variables, then expand as necessary */ while ( s_current != NULL ) { o_current = (OBJECT *) s_current->data; /* Sanity check */ g_return_val_if_fail ((o_current != NULL), found); if ( geda_object_calculate_visible_bounds( toplevel, o_current, &rleft, &rtop, &rright, &rbottom) ) { if ( found ) { *left = min( *left, rleft ); *top = min( *top, rtop ); *right = max( *right, rright ); *bottom = max( *bottom, rbottom ); } else { *left = rleft; *top = rtop; *right = rright; *bottom = rbottom; found = 1; } } s_current = g_list_next (s_current); } return found; }
/*! \brief Calculates the distance between the given point and the closest * point on an object within the complex object. * * \note When querying the distance to our child objects, we always * force treating them as solid filled. * We ignore the force_solid argument to this function. * * \param [in] toplevel The TOPLEVEL object. * \param [in] object The complex OBJECT. * \param [in] x The x coordinate of the given point. * \param [in] y The y coordinate of the given point. * \param [in] force_solid If true, force treating the object as solid. * \return The shortest distance from the object to the point. If the * distance cannot be calculated, this function returns a really large * number (G_MAXDOUBLE). With an invalid parameter, this function returns * G_MAXDOUBLE. */ double geda_complex_object_shortest_distance (TOPLEVEL *toplevel, OBJECT *object, int x, int y, int force_solid) { double shortest_distance = G_MAXDOUBLE; double distance; int found_line_bounds = 0; BOX line_bounds; GList *iter; g_return_val_if_fail (object->complex != NULL, G_MAXDOUBLE); for (iter = object->complex->prim_objs; iter != NULL; iter= g_list_next (iter)) { OBJECT *obj = iter->data; int left, top, right, bottom; /* Collect the bounds of any lines and arcs in the symbol */ if ((obj->type == OBJ_LINE || obj->type == OBJ_ARC) && geda_object_calculate_visible_bounds(toplevel, obj, &left, &top, &right, &bottom)) { if (found_line_bounds) { line_bounds.lower_x = min (line_bounds.lower_x, left); line_bounds.lower_y = min (line_bounds.lower_y, top); line_bounds.upper_x = max (line_bounds.upper_x, right); line_bounds.upper_y = max (line_bounds.upper_y, bottom); } else { line_bounds.lower_x = left; line_bounds.lower_y = top; line_bounds.upper_x = right; line_bounds.upper_y = bottom; found_line_bounds = 1; } } else { distance = geda_object_shortest_distance_full (toplevel, obj, x, y, TRUE); shortest_distance = min (shortest_distance, distance); } if (shortest_distance == 0.0) return shortest_distance; } if (found_line_bounds) { distance = geda_box_shortest_distance (&line_bounds, x, y, TRUE); shortest_distance = min (shortest_distance, distance); } return shortest_distance; }
/*! \brief Calculates the distance between the given point and the closest * point on the text. * * This function will calculate the distance to the text regardless * if the text is visible or not. * * \param [in] toplevel The TOPLEVEL object. * \param [in] object The text OBJECT. * \param [in] x The x coordinate of the given point. * \param [in] y The y coordinate of the given point. * \param [in] force_solid If true, force treating the object as solid. * \return The shortest distance from the object to the point. If the * distance cannot be calculated, this function returns a really large * number (G_MAXDOUBLE). With an invalid parameter, this funciton * returns G_MAXDOUBLE. */ double geda_text_object_shortest_distance (TOPLEVEL *toplevel, OBJECT *object, int x, int y, int force_solid) { int left, top, right, bottom; double dx, dy; g_return_val_if_fail (object->text != NULL, G_MAXDOUBLE); if (!geda_object_calculate_visible_bounds(toplevel, object, &left, &top, &right, &bottom)) return G_MAXDOUBLE; dx = MIN (x - left, right - x); dy = MIN (y - top, bottom - y); dx = MIN (dx, 0); dy = MIN (dy, 0); return hypot (dx, dy); }