Beispiel #1
0
/*! \brief Create a copy of a line.
 *  \par Function Description
 *  This function creates a verbatim copy of the
 *  object pointed by <B>o_current</B> describing a line.
 *
 *  \param [in]  toplevel  The TOPLEVEL object.
 *  \param [in]  o_current  Line OBJECT to copy.
 *  \return The new OBJECT
 */
OBJECT *o_line_copy(TOPLEVEL *toplevel, OBJECT *o_current)
{
  OBJECT *new_obj;

  /* A new line object is created with #o_line_new().
   * Values for its fields are default and need to be modified. */
  new_obj = o_line_new (toplevel, OBJ_LINE, o_current->color,
                        o_current->line->x[0], o_current->line->y[0],
                        o_current->line->x[1], o_current->line->y[1]);

  /*
   * The coordinates of the ends of the new line are set with the ones
   * of the original line. The two lines have the sale line type and
   * filling options.
   */

  /* copy the line type and filling options */
  o_set_line_options(toplevel, new_obj, o_current->line_end,
		     o_current->line_type, o_current->line_width,
		     o_current->line_length, o_current->line_space);
  o_set_fill_options(toplevel, new_obj,
		     o_current->fill_type, o_current->fill_width,
		     o_current->fill_pitch1, o_current->fill_angle1,
		     o_current->fill_pitch2, o_current->fill_angle2);
  
  /* calc the bounding box */
  o_current->w_bounds_valid_for = NULL;
  
  /* new_obj->attribute = 0;*/

  /* return the new tail of the object list */
  return new_obj;
}
Beispiel #2
0
/*! \brief End the input of a line.
 *  \par Function Description
 *  This function ends the process of interactively adding a line to the
 *  current sheet.
 *
 *  It first erases the last temporary line displayed, calculates the
 *  corresponding world coordinates of the two ends of the line and finally
 *  adds a new initialized line object to the list of object of the current
 *  sheet.
 *
 *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
 *  \param [in] w_x        (unused)
 *  \param [in] w_y        (unused)
 */
void o_line_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  OBJECT *new_obj;

  g_assert( w_current->inside_action != 0 );

  /* Don't bother.. the real object is invalidated, its in the same place */
  /* o_line_invalidate_rubber (w_current); */
  w_current->rubber_visible = 0;

  /* don't allow zero length lines */
  if ( (w_current->first_wx == w_current->second_wx) &&
       (w_current->first_wy == w_current->second_wy) ) {
    return;
  }

  /* create the line object and draw it */
  new_obj = o_line_new (toplevel, OBJ_LINE, GRAPHIC_COLOR,
                        w_current->first_wx, w_current->first_wy,
                        w_current->second_wx, w_current->second_wy);
  s_page_append (toplevel, toplevel->page_current, new_obj);

  toplevel->page_current->CHANGED=1;
  o_undo_savestate(w_current, UNDO_ALL);
}
Beispiel #3
0
/*! \brief
 *  \par Function Description
 *
 */
OBJECT *o_complex_new(TOPLEVEL *toplevel,
		      char type,
		      int color, int x, int y, int angle,
		      int mirror, const CLibSymbol *clib,
		      const gchar *basename,
		      int selectable)
{
  OBJECT *new_node=NULL;
  OBJECT *new_prim_obj;
  GList *prim_objs;
  GList *iter;
  int loaded_normally = FALSE;

  gchar *buffer = NULL;

  new_node = s_basic_new_object(type, "complex");

  if (clib != NULL) {
    new_node->complex_basename = g_strdup (s_clib_symbol_get_name (clib));
  } else {
    new_node->complex_basename = g_strdup (basename);
  }


  new_node->complex_embedded = FALSE;
  new_node->color = color;
  new_node->selectable = selectable;

  new_node->complex = (COMPLEX *) g_malloc(sizeof(COMPLEX));
  new_node->complex->angle = angle;
  new_node->complex->mirror = mirror;
  new_node->complex->x = x;
  new_node->complex->y = y;

  prim_objs = NULL;

  /* get the symbol data */
  if (clib != NULL) {
    buffer = s_clib_symbol_get_data (clib);
  }

  if (clib == NULL || buffer == NULL) {

    char *not_found_text = NULL;
    int left, right, top, bottom;
    int x_offset, y_offset;

    /* filename was NOT found */
    loaded_normally = FALSE;

    /* Put placeholder into object list.  Changed by SDB on
     * 1.19.2005 to fix problem that symbols were silently
     * deleted by gattrib when RC files were messed up.  */
    new_node->type = OBJ_PLACEHOLDER;

    /* Mark the origin of the missing component */
    new_prim_obj = o_line_new(toplevel, OBJ_LINE,
                           DETACHED_ATTRIBUTE_COLOR,
                           x - 50, y, x + 50, y);
    prim_objs = g_list_append (prim_objs, new_prim_obj);
    new_prim_obj = o_line_new(toplevel, OBJ_LINE,
                           DETACHED_ATTRIBUTE_COLOR,
                           x, y + 50, x, y - 50); 
    prim_objs = g_list_append (prim_objs, new_prim_obj);

    /* Add some useful text */
    not_found_text = 
      g_strdup_printf (_("Component not found:\n %s"),
		       new_node->complex_basename);
    new_prim_obj = o_text_new(toplevel,
                           OBJ_TEXT, DETACHED_ATTRIBUTE_COLOR, 
                           x + NOT_FOUND_TEXT_X, 
                           y + NOT_FOUND_TEXT_Y, LOWER_LEFT, 0, 
                           not_found_text, 8,
                           VISIBLE, SHOW_NAME_VALUE);
    prim_objs = g_list_append (prim_objs, new_prim_obj);
    g_free(not_found_text);

    /* figure out where to put the hazard triangle */
    world_get_text_bounds (toplevel, new_prim_obj, &left, &top, &right, &bottom);
    x_offset = (right - left) / 4;
    y_offset = bottom - top + 100;  /* 100 is just an additional offset */

    /* add hazard triangle */
    new_prim_obj = o_line_new(toplevel, OBJ_LINE,
                           DETACHED_ATTRIBUTE_COLOR,
                           x + NOT_FOUND_TEXT_X + x_offset, 
                           y + NOT_FOUND_TEXT_Y + y_offset, 
                           x + NOT_FOUND_TEXT_X + x_offset + 600, 
                           y + NOT_FOUND_TEXT_Y + y_offset); 
    o_set_line_options(toplevel, new_prim_obj, END_ROUND, TYPE_SOLID,
                       50, -1, -1);
    prim_objs = g_list_append (prim_objs, new_prim_obj);
    new_prim_obj = o_line_new(toplevel, OBJ_LINE,
                           DETACHED_ATTRIBUTE_COLOR,
                           x + NOT_FOUND_TEXT_X + x_offset, 
                           y + NOT_FOUND_TEXT_Y + y_offset, 
                           x + NOT_FOUND_TEXT_X + x_offset + 300, 
                           y + NOT_FOUND_TEXT_Y + y_offset + 500); 
    o_set_line_options(toplevel, new_prim_obj, END_ROUND, TYPE_SOLID,
                       50, -1, -1);
    prim_objs = g_list_append (prim_objs, new_prim_obj);
    new_prim_obj = o_line_new(toplevel, OBJ_LINE,
                           DETACHED_ATTRIBUTE_COLOR,
                           x + NOT_FOUND_TEXT_X + x_offset + 300, 
                           y + NOT_FOUND_TEXT_Y + y_offset + 500, 
                           x + NOT_FOUND_TEXT_X + x_offset + 600, 
                           y + NOT_FOUND_TEXT_Y + y_offset); 
    o_set_line_options(toplevel, new_prim_obj, END_ROUND, TYPE_SOLID,
                       50, -1, -1);
    prim_objs = g_list_append (prim_objs, new_prim_obj);
    new_prim_obj = o_text_new(toplevel,
                           OBJ_TEXT, DETACHED_ATTRIBUTE_COLOR, 
                           x + NOT_FOUND_TEXT_X + x_offset + 270, 
                           y + NOT_FOUND_TEXT_Y + y_offset + 90, 
                           LOWER_LEFT, 0, "!", 18,
                           VISIBLE, SHOW_NAME_VALUE);
    prim_objs = g_list_append (prim_objs, new_prim_obj);

  } else {

    /* filename was found */
    loaded_normally = TRUE;

    /* add connections till translated */
    prim_objs = o_read_buffer (toplevel, prim_objs, buffer, -1, new_node->complex_basename);

    g_free (buffer);

  }

  /* do not mirror/rotate/translate/connect the primitive objects if the
   * component was not loaded via o_read 
   */
  if (loaded_normally == TRUE) {
    if (mirror) {
      o_glist_mirror_world (toplevel, 0, 0, prim_objs);
    }

    o_glist_rotate_world (toplevel, 0, 0, angle, prim_objs);
    o_glist_translate_world (toplevel, x, y, prim_objs);
  }

  new_node->complex->prim_objs = prim_objs;

  /* set the parent field now */
  for (iter = prim_objs; iter != NULL; iter = g_list_next (iter)) {
    OBJECT *tmp = iter->data;
    tmp->parent = new_node;
  }

  o_complex_recalc(toplevel, new_node);

  return new_node;
}
Beispiel #4
0
/*! \brief Create line OBJECT from character string.
 *  \par Function Description
 *  This function creates a line OBJECT from the character string
 *  <B>*buf</B> the description of a box.
 *
 *  The function returns a pointer on the new last element, that is
 *  the added line object.
 *
 *  Depending on <B>*version</B>, the correct file format is considered.
 *  Currently two file format revisions are supported :
 *  <DL>
 *    <DT>*</DT><DD>the file format used until 20010704 release.
 *    <DT>*</DT><DD>the file format used for the releases after 20010704.
 *  </DL>
 *
 *  \param [in]  toplevel       The TOPLEVEL object.
 *  \param [in]  buf             Character string with line description.
 *  \param [in]  release_ver     libgeda release version number.
 *  \param [in]  fileformat_ver  libgeda file format version number.
 *  \return A pointer to the new line object, or NULL on error.
 */
OBJECT *o_line_read (TOPLEVEL *toplevel, const char buf[],
                     unsigned int release_ver, unsigned int fileformat_ver, GError ** err)
{
  OBJECT *new_obj;
  char type;
  int x1, y1;
  int x2, y2;
  int line_width, line_space, line_length;
  int line_end;
  int line_type;
  int color;

  if (release_ver <= VERSION_20000704) {
    /*
     * The old geda file format, i.e. releases 20000704 and older, does
     * not handle the line type and the filling - here filling is irrelevant.
     * They are set to default.
     */
    if (sscanf (buf, "%c %d %d %d %d %d\n", &type,
		&x1, &y1, &x2, &y2, &color) != 6) {
      g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse line object"));
      return NULL;
    }

    line_width = 0;
    line_end   = END_NONE;
    line_type  = TYPE_SOLID;
    line_length= -1;
    line_space = -1;
  } else {
    /*
     * The current line format to describe a line is a space separated
     * list of characters and numbers in plain ASCII on a single line.
     * The meaning of each item is described in the file format documentation.
     */
      if (sscanf (buf, "%c %d %d %d %d %d %d %d %d %d %d\n", &type,
		  &x1, &y1, &x2, &y2, &color,
		  &line_width, &line_end, &line_type, &line_length, &line_space) != 11) {
        g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse line object"));
        return NULL;
      }
  }

  /*
   * Null length line are not allowed. If such a line is detected a
   * message is issued.
   *
   * It also checks is the required color is valid.
   */
  if (x1 == x2 && y1 == y2) {
    s_log_message (_("Found a zero length line [ %c %d %d %d %d %d ]\n"),
                   type, x1, y1, x2, y2, color);
  }

  if (color < 0 || color > MAX_COLORS) {
    s_log_message (_("Found an invalid color [ %s ]\n"), buf);
    s_log_message (_("Setting color to default color\n"));
    color = DEFAULT_COLOR;
  }

  /*
   * A line is internally described by its two ends. A new object is
   * allocated, initialized and added to the list of objects. Its line
   * type is set according to the values of the fields on the line.
   */
  /* create and add the line to the list */
  new_obj = o_line_new (toplevel, type, color, x1, y1, x2, y2);
  /* set its line options */
  o_set_line_options (toplevel, new_obj,
                      line_end, line_type, line_width, line_length,
                      line_space);
  /* filling is irrelevant for line, just set to default */
  o_set_fill_options (toplevel, new_obj,
                      FILLING_HOLLOW, -1, -1, -1, -1, -1);

  return new_obj;
}