/*! \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; }
/*! \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); }
/*! \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; }
/*! \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; }