コード例 #1
0
ファイル: geda_object.c プロジェクト: gareth8118/geda-gaf
/*! \brief Get an object's parent PAGE.
 *
 * \par Function Description
 * Returns the PAGE structure which owns \a object. If \a object is
 * not currently associated with a PAGE, returns NULL. If \a object is
 * part of a compound object, recurses upward.
 *
 * \param [in] toplevel  The TOPLEVEL structure.
 * \param [in] object    The OBJECT for which to retrieve the parent PAGE.
 * \return The PAGE which owns \a object or NULL.
 *
 * \sa s_page_append_object() s_page_append() s_page_remove()
 */
PAGE *
o_get_page (TOPLEVEL *toplevel, OBJECT *object)
{
  if (object->parent != NULL) {
    return o_get_page (toplevel, object->parent);
  }
  return object->page;
}
コード例 #2
0
ファイル: o_basic.c プロジェクト: pardo-bsso/geda-gaf
/*! \brief Get an object's parent PAGE, or fall back to global current page.
 *
 * \par Function Description
 * If set, returns the PAGE structure which owns \a object.  If \a
 * object does not have a parent page set, returns the global current
 * page from \a toplevel.  If the object parent page is inconsistent
 * with the global current page, a critical-level error message is
 * emitted.
 *
 * \warning This function is primarily intended to assist in the
 * migration of code from using the TOPLEVEL current page to using the
 * o_get_page().  It should not be used in new code.
 *
 * \deprecated Use o_get_page() in new code.
 *
 * \param [in] toplevel  The TOPLEVEL structure.
 * \param [in] object    The OBJECT for which to retrieve the parent PAGE.
 * \return The PAGE which owns \a object, the global current PAGE, or NULL.
 */
PAGE *
o_get_page_compat (TOPLEVEL *toplevel, OBJECT *object) {
  PAGE *page = o_get_page (toplevel, object);
  if (page != toplevel->page_current) {
    g_critical ("o_get_page_compat: OBJECT.page = %p, TOPLEVEL.page_current = %p",
                page, toplevel->page_current);
    return toplevel->page_current;
  } else {
    return page;
  }
}
コード例 #3
0
ファイル: o_net_basic.c プロジェクト: fvila/geda-gaf
/*! \brief try to consolidate a net object
 *  \par Function Description
 *  This function tries to consolidate a net with any other object
 *  that is connected to the current \a object.
 *  
 *  \param toplevel   The TOPLEVEL object
 *  \param object     The object to consolidate
 *  \return 0 if no consolidation was possible, -1 otherwise
 *
 */
static int o_net_consolidate_segments (TOPLEVEL *toplevel, OBJECT *object)
{
  int object_orient;
  int other_orient;
  GList *c_current;
  CONN *conn;
  OBJECT *other_object;
  PAGE *page;
  int changed = 0;

  g_return_val_if_fail ((toplevel != NULL), 0);
  g_return_val_if_fail ((object != NULL), 0);
  g_return_val_if_fail ((object->type == OBJ_NET), 0);

  /* It's meaningless to do anything here if the object isn't in a page. */
  page = o_get_page (toplevel, object);
  g_return_val_if_fail ((page != NULL), 0);

  object_orient = o_net_orientation(object);

  c_current = object->conn_list;
  while(c_current != NULL) {
    conn = (CONN *) c_current->data;
    other_object = conn->other_object;

    /* only look at end points which have a valid end on the other side */
    if (other_object != NULL && conn->type == CONN_ENDPOINT &&
        conn->other_whichone != -1 && conn->whichone != -1 &&
        o_net_consolidate_nomidpoint(object, conn->x, conn->y) ) {

      if (other_object->type == OBJ_NET) {
        other_orient = o_net_orientation(other_object);

        /* - both objects have the same orientation (either vert or horiz) */
        /* - it's not the same object */
        if (object_orient == other_orient &&
            object->sid != other_object->sid &&
            other_orient != NEITHER) {

#if DEBUG
          printf("consolidating %s to %s\n", object->name, other_object->name);
#endif

          o_net_consolidate_lowlevel(object, other_object, other_orient);

          changed++;
          if (other_object->selected == TRUE ) {
            o_selection_remove (toplevel, page->selection_list, other_object);

            /* If we're consolidating with a selected object,
             * ensure we select the resulting object.
             */
            if (object->selected == FALSE) {
              o_selection_add (toplevel, page->selection_list, object);
            }
          }

          s_delete_object (toplevel, other_object);
          o_net_recalc(toplevel, object);
          s_tile_update_object(toplevel, object);
          s_conn_update_object (toplevel, object);
          return(-1);
        }
      }
      
    }

    c_current = g_list_next (c_current);
  }

  return(0);
}
コード例 #4
0
ファイル: o_misc.c プロジェクト: jaredcasper/geda-gaf
/*! \brief Update a component.
 *
 * \par Function Description
 * Updates \a o_current to the latest version of the symbol available
 * in the symbol library, while preserving any attributes set in the
 * current schematic. On success, returns the new OBJECT which
 * replaces \a o_current on the page; \a o_current is deleted. On
 * failure, returns NULL, and \a o_current is left unchanged.
 *
 * \param [in]     w_current The GSCHEM_TOPLEVEL object.
 * \param [in,out] o_current The OBJECT to be updated.
 *
 * \return the new OBJECT that replaces \a o_current.
 */
OBJECT *
o_update_component (GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  OBJECT *o_new;
  PAGE *page;
  GList *new_attribs;
  GList *old_attribs;
  GList *iter;
  const CLibSymbol *clib;

  g_return_val_if_fail (o_current != NULL, NULL);
  g_return_val_if_fail (o_current->type == OBJ_COMPLEX, NULL);
  g_return_val_if_fail (o_current->complex_basename != NULL, NULL);

  page = o_get_page (toplevel, o_current);

  /* This should be replaced with API to invalidate only the specific
   * symbol name we want to update */
  s_clib_flush_symbol_cache ();
  clib = s_clib_get_symbol_by_name (o_current->complex_basename);

  if (clib == NULL) {
    s_log_message (_("Could not find symbol [%s] in library. Update failed.\n"),
                   o_current->complex_basename);
    return NULL;
  }

  /* Unselect the old object. */
  o_selection_remove (toplevel, page->selection_list, o_current);

  /* Create new object and set embedded */
  o_new = o_complex_new (toplevel, OBJ_COMPLEX, DEFAULT_COLOR,
                         o_current->complex->x,
                         o_current->complex->y,
                         o_current->complex->angle,
                         o_current->complex->mirror,
                         clib, o_current->complex_basename,
                         1);
  if (o_complex_is_embedded (o_current)) {
    o_embed (toplevel, o_new);
  }

  new_attribs = o_complex_promote_attribs (toplevel, o_new);

  /* Cull any attributes from new COMPLEX that are already attached to
   * old COMPLEX. Note that the new_attribs list is kept consistent by
   * setting GList data pointers to NULL if their OBJECTs are
   * culled. At the end, the new_attribs list is updated by removing
   * all list items with NULL data. This is slightly magic, but
   * works. */
  for (iter = new_attribs; iter != NULL; iter = g_list_next (iter)) {
    OBJECT *attr_new = iter->data;
    gchar *name;
    gchar *value;

    g_assert (attr_new->type == OBJ_TEXT);

    o_attrib_get_name_value (attr_new, &name, NULL);

    value = o_attrib_search_attached_attribs_by_name (o_current, name, 0);
    if (value != NULL) {
      o_attrib_remove (toplevel, &o_new->attribs, attr_new);
      s_delete_object (toplevel, attr_new);
      iter->data = NULL;
    }

    g_free (name);
    g_free (value);
  }
  new_attribs = g_list_remove_all (new_attribs, NULL);

  /* Detach attributes from old OBJECT and attach to new OBJECT */
  old_attribs = g_list_copy (o_current->attribs);
  o_attrib_detach_all (toplevel, o_current);
  o_attrib_attach_list (toplevel, old_attribs, o_new, 1);
  g_list_free (old_attribs);

  /* Add new attributes to page */
  s_page_append_list (toplevel, page, new_attribs);

  /* Update pinnumbers for current slot */
  s_slot_update_object (toplevel, o_new);

  /* Replace old OBJECT with new OBJECT */
  s_page_replace (toplevel, page, o_current, o_new);
  s_delete_object (toplevel, o_current);

  /* Select new OBJECT */
  o_selection_add (toplevel, page->selection_list, o_new);

  /* mark the page as modified */
  toplevel->page_current->CHANGED = 1;
  o_undo_savestate (w_current, UNDO_ALL);

  return o_new;
}
コード例 #5
0
ファイル: s_tile.c プロジェクト: fvila/geda-gaf
/*! \brief add a line object to the tiles
 *  \par Function Description
 *  This function takes a single line object and adds it to
 *  every tile that is touched by the line. 
 *  It also adds all tiles that are touched by the object to 
 *  the objects tile list.
 *  \param toplevel The TOPLEVEL structure
 *  \param object The line OBJECT to add
 */
static void s_tile_add_line_object (TOPLEVEL *toplevel, OBJECT *object)
{
  TILE *t_current;
  PAGE *p_current;
  GList *found;
  int i, j;
  int v, w;
  double x1, y1, x2, y2;
  double bottom;
  double m, b;
  double x_size, y_size;
  double x, y;
  int start, end;

#if DEBUG  
  printf("name: %s\n", object->name);
#endif

  g_return_if_fail (object != NULL);
  g_return_if_fail (object->line != NULL);

  p_current = o_get_page (toplevel, object);

  if (p_current == NULL) {
    return;
  }
  
  x_size = (double) toplevel->init_right / (double) MAX_TILES_X;
  y_size = (double) toplevel->init_bottom / (double) MAX_TILES_Y;

  x1 = (int) (object->line->x[0] / x_size);
  x2 = (int) (object->line->x[1] / x_size);
  y1 = (int) (object->line->y[0] / y_size);
  y2 = (int) (object->line->y[1] / y_size);

  bottom = x2 - x1;

  if (bottom != 0.0) {
    m = (double) (y2 - y1) / bottom;
    b = y1 - m * x1;

    start = min((int) x1, (int) x2);
    end = max((int) x1, (int) x2);
    for (i = start; i <= end; i++) {
      x = i;
      y = m * x + b;
      if (floor(y) != ceil(y)) {

        v = (int) x;
        w = (int) floor(y);
        if (v < 0 || w < 0 || v > MAX_TILES_X-1 || w > MAX_TILES_Y-1) {
          return;
        }
        /* g_assert(v < MAX_TILES_X && w < MAX_TILES_Y && v >= 0 && w >= 0); */
        t_current = &p_current->world_tiles[v][w];
        found = g_list_find(t_current->objects, object);

        if (!found) {
          /*printf("%d %d\n", v, w);*/
          t_current->objects = g_list_append(t_current->objects,
                                             object);
          object->tiles = g_list_append(object->tiles, t_current);
        }

        v = (int) x;
        w = (int) ceil(y);
        if (v < 0 || w < 0 || v > MAX_TILES_X-1 || w > MAX_TILES_Y-1) {
          return;
        }
        /*g_assert(v < MAX_TILES_X && w < MAX_TILES_Y && v >= 0 && w >= 0);*/
        t_current = &p_current->world_tiles[v][w];
        found = g_list_find(t_current->objects, object);

        if (!found) {
          /*printf("%d %d\n", v, w);*/
          t_current->objects = g_list_append(t_current->objects,
                                             object);
          object->tiles = g_list_append(object->tiles, t_current);
        }

      } else {
        v = (int) x;
        w = (int) floor(y);
        if (v < 0 || w < 0 || v > MAX_TILES_X-1 || w > MAX_TILES_Y-1) {
          return;
        }
        /*g_assert(v < MAX_TILES_X && w < MAX_TILES_Y && v >= 0 && w >= 0);*/
        t_current = &p_current->world_tiles[v][w];
        found = g_list_find(t_current->objects, object);

        if (!found) {
          /*printf("%d %d\n", v, w);*/
          t_current->objects = g_list_append(t_current->objects,
                                             object);
          object->tiles = g_list_append(object->tiles, t_current);
        }
      }
    }

    if (m != 0.0) {
      start = min((int) y1, (int) y2);
      end = max((int) y1, (int) y2);
      for (j = start; j <= end; j++) {
        y = j;
        x = (y - b) / m;
        if (floor(x) != ceil(x)) {
          w = (int) y;
          v = (int) floor(x);
          if (v < 0 || w < 0 || v > MAX_TILES_X-1 || w > MAX_TILES_Y-1) {
            return;
          }
          /*g_assert(v < MAX_TILES_X && w < MAX_TILES_Y &&
            v >= 0 && w >= 0);*/
          t_current = &p_current->world_tiles[v][w];
          found = g_list_find(t_current->objects, object);

          if (!found) {
            /*printf("%d %d\n", v, w);*/
            t_current->objects =
              g_list_append(t_current->objects, object);
            object->tiles = g_list_append(object->tiles, t_current);
          }

          w = (int) y;
          v = (int) ceil(x);
          if (v < 0 || w < 0 || v > MAX_TILES_X-1 || w > MAX_TILES_Y-1) {
            return;
          }
          /* g_assert(v < MAX_TILES_X && w < MAX_TILES_Y &&
             v >= 0 && w >= 0);*/
          t_current = &p_current->world_tiles[v][w];
          found = g_list_find(t_current->objects, object);

          if (!found) {
            /*printf("%d %d\n", v, w);*/
            t_current->objects =
              g_list_append(t_current->objects, object);
            object->tiles = g_list_append(object->tiles, t_current);
          }

        } else {
          w = (int) y;
          v = (int) floor(x);
          if (v < 0 || w < 0 || v > MAX_TILES_X-1 || w > MAX_TILES_Y-1) {
            return;
          }
          /*g_assert(v < MAX_TILES_X && w < MAX_TILES_Y &&
            v >= 0 && w >= 0);*/
          t_current = &p_current->world_tiles[v][w];
          found = g_list_find(t_current->objects, object);

          if (!found) {
            /*printf("%d %d\n", v, w);*/
            t_current->objects =
              g_list_append(t_current->objects, object);
            object->tiles = g_list_append(object->tiles, t_current);
          }
        }
      }
    }
  } else {
    start = min((int) y1, (int) y2);
    end = max((int) y1, (int) y2);
    for (j = start; j <= end; j++) {

      y = j;
      x = x1;
      v = (int) x;
      w = (int) y;
      if (v < 0 || w < 0 || v > MAX_TILES_X-1 || w > MAX_TILES_Y-1) {
        return;
      }
      /*g_assert(v < MAX_TILES_X && w < MAX_TILES_Y &&
        v >= 0 && w >= 0);*/
      t_current = &p_current->world_tiles[v][w];
      found = g_list_find(t_current->objects, object);

      if (!found) {
        /*printf("%d %d\n", v, w);*/
        t_current->objects = g_list_append(t_current->objects,
                                           object);
        object->tiles = g_list_append(object->tiles, t_current);
      }

    }
  }
}