Ejemplo n.º 1
0
/*! \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;
}
Ejemplo n.º 2
0
/*! \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;
}
Ejemplo n.º 3
0
/*! \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);
}