/*! \brief Create a copy of a path. * \par Function Description * This function creates a verbatim copy of the * object pointed by <B>o_current</B> describing a path. The new object * is added at the end of the list following the <B>list_tail</B> * parameter. * * \param [in] toplevel The TOPLEVEL object. * \param [in] o_current Line OBJECT to copy. * \return A new pointer to the end of the object list. */ OBJECT* geda_path_object_copy (TOPLEVEL *toplevel, OBJECT *o_current) { OBJECT *new_obj; char *path_string; path_string = s_path_string_from_path (o_current->path); new_obj = geda_path_object_new (toplevel, OBJ_PATH, o_current->color, path_string); g_free (path_string); /* copy the path 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; /* return the new tail of the object list */ return new_obj; }
/*! \brief Create and add circle OBJECT to list. * \par Function Description * This function creates a new object representing a circle. * * The circle is described by its center (<B>x</B>,<B>y</B>) and its radius * <B>radius</B>. * The <B>type</B> parameter must be equal to <B>OBJ_CIRCLE</B>. The <B>color</B> * corresponds to the color the box will be drawn with. * * The <B>OBJECT</B> structure is allocated with the #s_basic_new_object() * function. The structure describing the circle is allocated and initialized * with the parameters given to the function. * * Both the line type and the filling type are set to default values : solid * line type with a width of 0, and no filling. It can be changed after * with #o_set_line_options() and #o_set_fill_options(). * * \param [in] toplevel The TOPLEVEL object. * \param [in] type Must be OBJ_CIRCLE. * \param [in] color Circle line color. * \param [in] x Center x coordinate. * \param [in] y Center y coordinate. * \param [in] radius Radius of new circle. * \return A pointer to the new end of the object list. */ OBJECT *o_circle_new(TOPLEVEL *toplevel, char type, int color, int x, int y, int radius) { OBJECT *new_node; /* create the object */ new_node = s_basic_new_object(type, "circle"); new_node->color = color; new_node->circle = (CIRCLE *) g_malloc(sizeof(CIRCLE)); /* describe the circle with its center and radius */ new_node->circle->center_x = x; new_node->circle->center_y = y; new_node->circle->radius = radius; /* line type and filling initialized to default */ o_set_line_options(toplevel, new_node, END_NONE, TYPE_SOLID, 0, -1, -1); o_set_fill_options(toplevel, new_node, FILLING_HOLLOW, -1, -1, -1, -1, -1); /* compute the bounding box coords */ o_circle_recalc(toplevel, new_node); return new_node; }
/*! \brief Create a new path object. * \par Function Description * This function creates and returns a new OBJECT representing a path * using the path shape data stored in \a path_data. The \a * path_data is subsequently owned by the returned OBJECT. * * \see geda_path_object_new(). * * \param [in] toplevel The TOPLEVEL object. * \param [in] type Must be OBJ_PATH. * \param [in] color The path color. * \param [in] path_data The #PATH data structure to use. * \return A pointer to the new end of the object list. */ OBJECT* geda_path_object_new_take_path (TOPLEVEL *toplevel, char type, int color, PATH *path_data) { OBJECT *new_node; /* create the object */ new_node = s_basic_new_object (type, "path"); new_node->color = color; new_node->path = path_data; /* path type and filling initialized to default */ o_set_line_options (toplevel, new_node, DEFAULT_OBJECT_END, TYPE_SOLID, LINE_WIDTH, -1, -1); o_set_fill_options (toplevel, new_node, FILLING_HOLLOW, -1, -1, -1, -1, -1); /* compute bounding box */ new_node->w_bounds_valid_for = NULL; return new_node; }
/*! \brief Copy a box to a list. * \par Function Description * The function #geda_box_object_copy() creates a verbatim copy of the object * pointed by <B>o_current</B> describing a box. * * \param [in] toplevel The TOPLEVEL object. * \param [in] o_current BOX OBJECT to copy. * \return The new OBJECT */ OBJECT* geda_box_object_copy(TOPLEVEL *toplevel, OBJECT *o_current) { OBJECT *new_obj; /* A new box object is created with #geda_box_object_new(). * Values for its fields are default and need to be modified. */ new_obj = geda_box_object_new (toplevel, OBJ_BOX, o_current->color, 0, 0, 0, 0); /* * The dimensions of the new box are set with the ones of the original box. * The two boxes have the same line type and the same filling options. */ new_obj->box->upper_x = o_current->box->upper_x; new_obj->box->upper_y = o_current->box->upper_y; new_obj->box->lower_x = o_current->box->lower_x; new_obj->box->lower_y = o_current->box->lower_y; 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); new_obj->w_bounds_valid_for = NULL; /* new_obj->attribute = 0;*/ return new_obj; }
/*! \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 Create and add line OBJECT to list. * \par Function Description * This function creates a new object representing a line. * * The line is described by its two ends - <B>x1</B>,<B>y1</B> and * <B>x2</B>,<B>y2</B>. * The <B>type</B> parameter must be equal to #OBJ_LINE. * The <B>color</B> parameter corresponds to the color the box * will be drawn with. * * The #OBJECT structure is allocated with the #s_basic_new_object() * function. The structure describing the line is allocated and * initialized with the parameters given to the function. * * Both the line type and the filling type are set to default * values : solid line type with a width of 0, and no filling. * It can be changed after with the #o_set_line_options() and * #o_set_fill_options(). * * \param [in] toplevel The TOPLEVEL object. * \param [in] type Must be OBJ_LINE. * \param [in] color Circle line color. * \param [in] x1 Upper x coordinate. * \param [in] y1 Upper y coordinate. * \param [in] x2 Lower x coordinate. * \param [in] y2 Lower y coordinate. * \return A pointer to the new end of the object list. */ OBJECT *o_line_new(TOPLEVEL *toplevel, char type, int color, int x1, int y1, int x2, int y2) { OBJECT *new_node; /* create the object */ new_node = s_basic_new_object(type, "line"); new_node->color = color; new_node->line = (LINE *) g_malloc(sizeof(LINE)); /* describe the line with its two ends */ new_node->line->x[0] = x1; new_node->line->y[0] = y1; new_node->line->x[1] = x2; new_node->line->y[1] = y2; /* line type and filling initialized to default */ o_set_line_options(toplevel, new_node, DEFAULT_OBJECT_END, TYPE_SOLID, 0, -1, -1); o_set_fill_options(toplevel, new_node, FILLING_HOLLOW, -1, -1, -1, -1, -1); /* compute bounding box */ new_node->w_bounds_valid_for = NULL; return new_node; }
/*! \brief Create a BOX OBJECT * \par Function Description * This function creates a new object representing a box. * * The box is described by its upper left corner - <B>x1</B>, <B>y1</B> - and * its lower right corner - <B>x2</B>, <B>y2</B>. * The <B>type</B> parameter must be equal to <B>OBJ_BOX</B>. The <B>color</B> * corresponds to the color the box will be drawn with. * The <B>OBJECT</B> structure is allocated with the #s_basic_new_object() * function. The structure describing the box is allocated and initialized * with the parameters given to the function. * * Both the line type and the filling type are set to default values : solid * line type with a width of 0, and no filling. It can be changed after * with the #o_set_line_options() and #o_set_fill_options(). * * \param [in] toplevel The TOPLEVEL object. * \param [in] type Box type. * \param [in] color Box border color. * \param [in] x1 Upper x coordinate. * \param [in] y1 Upper y coordinate. * \param [in] x2 Lower x coordinate. * \param [in] y2 Lower y coordinate. * \return The new OBJECT */ OBJECT *o_box_new(TOPLEVEL *toplevel, char type, int color, int x1, int y1, int x2, int y2) { OBJECT *new_node; BOX *box; /* create the object */ new_node = s_basic_new_object(type, "box"); new_node->color = color; box = (BOX *) g_malloc(sizeof(BOX)); new_node->box = box; /* describe the box with its upper left and lower right corner */ box->upper_x = x1; box->upper_y = y1; box->lower_x = x2; box->lower_y = y2; /* line type and filling initialized to default */ o_set_line_options(toplevel, new_node, END_NONE, TYPE_SOLID, 0, -1, -1); o_set_fill_options(toplevel, new_node, FILLING_HOLLOW, -1, -1, -1, -1, -1); /* compute the bounding box */ o_box_recalc(toplevel, new_node); return new_node; }
/*! \brief Create a copy of a circle. * \par Function Description * The function #o_circle_copy() creates a verbatim copy of the object * pointed by <B>o_current</B> describing a circle. * * \param [in] toplevel The TOPLEVEL object. * \param [in] o_current Circle OBJECT to copy. * \return The new OBJECT */ OBJECT *o_circle_copy(TOPLEVEL *toplevel, OBJECT *o_current) { OBJECT *new_obj; /* A new circle object is created with #o_circle_new(). * Values for its fields are default and need to be modified. */ new_obj = o_circle_new (toplevel, OBJ_CIRCLE, o_current->color, 0, 0, 0); /* * The parameters of the new circle are set with the ones of the original * circle. The two circle have the same line type and the same filling * options. * * The bounding box coordinates are computed with * #o_circle_recalc(). */ /* modify */ new_obj->circle->center_x = o_current->circle->center_x; new_obj->circle->center_y = o_current->circle->center_y; new_obj->circle->radius = o_current->circle->radius; 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); o_circle_recalc(toplevel, new_obj); /* new_obj->attribute = 0;*/ return new_obj; }
/*! \brief create a new arc object * * The line and fill type of the created arc are set to default. * * \param [in] toplevel The TOPLEVEL object. * \param [in] color the color index of the arc * \param [in] center_x the x coordinate of the center * \param [in] center_y the y coordinate of the center * \param [in] radius the radius of the arc * \param [in] start_angle the starting angle in degrees * \param [in] sweep_angle the sweep angle in degrees * \return the new arc object */ GedaObject* geda_arc_object_new (TOPLEVEL *toplevel, gint color, gint center_x, gint center_y, gint radius, gint start_angle, gint sweep_angle) { GedaObject *new_node; new_node = s_basic_new_object (OBJ_ARC, "arc"); new_node->color = color; new_node->arc = geda_arc_new (); /*! \note * The ARC structure is initialized with the parameters. * A default initialization is performed for the line and * fill type to avoid misunderstanding. * * The functions relative to the use of the object are sets. */ /* World coordinates */ new_node->arc->x = center_x; new_node->arc->y = center_y; new_node->arc->radius = radius; /* must check the sign of start_angle, sweep_angle ... */ if(sweep_angle < 0) { start_angle = start_angle + sweep_angle; sweep_angle = -sweep_angle; } if(start_angle < 0) start_angle = 360 + start_angle; new_node->arc->start_angle = start_angle; new_node->arc->sweep_angle = sweep_angle; /* Default init */ o_set_line_options (toplevel, new_node, DEFAULT_OBJECT_END, TYPE_SOLID, LINE_WIDTH, -1, -1); o_set_fill_options(toplevel, new_node, FILLING_HOLLOW, -1, -1, -1, -1, -1); new_node->w_bounds_valid_for = NULL; /* new_node->graphical = arc; eventually */ return new_node; }
/*! \brief * \par Function Description * This function reads a formatted text buffer describing an arc * in the gEDA file format and initializes the corresponding object. * * Depending on the version of the file format the data extraction is * performed differently : currently pre-20000704 and 20000704 on one * hand and post-20000704 file format version on the other hand are supported. * The version is specified in string pointed by <B>fileformat_ver</B>. * * To get information on the various file formats have a * look to the fileformats.html document. * * The object is initialized with the functions #o_set_line_options() and #o_set_fill_options(). * The second one is only used to put initialize unused values for an arc as an arc can not be filled. * * The arc is allocated initialized with the function #o_arc_new(). * * A negative or null radius is not allowed. * * \param [in] toplevel The TOPLEVEL object. * \param [in] buf * \param [in] release_ver * \param [in] fileformat_ver * \return */ OBJECT *o_arc_read (TOPLEVEL *toplevel, char buf[], unsigned int release_ver, unsigned int fileformat_ver) { OBJECT *new_obj; char type; int x1, y1; int radius; int start_angle, end_angle; int color; int arc_width, arc_length, arc_space; int arc_type; int arc_end; /*! \note * Depending on the version of the file format used to describe this arc, * the buffer is parsed differently. The unknown parameters of the less * restrictive - the oldest - file format are set to common values */ if(release_ver <= VERSION_20000704) { sscanf(buf, "%c %d %d %d %d %d %d", &type, &x1, &y1, &radius, &start_angle, &end_angle, &color); arc_width = 0; arc_end = END_NONE; arc_type = TYPE_SOLID; arc_space = -1; arc_length= -1; } else { sscanf(buf, "%c %d %d %d %d %d %d %d %d %d %d %d", &type, &x1, &y1, &radius, &start_angle, &end_angle, &color, &arc_width, &arc_end, &arc_type, &arc_length, &arc_space); } /* Error check */ if (radius <= 0) { s_log_message (_("Found a zero radius arc [ %c %d, %d, %d, %d, %d, %d ]\n"), type, x1, y1, radius, start_angle, end_angle, 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; } /* Allocation and initialization */ new_obj = o_arc_new(toplevel, OBJ_ARC, color, x1, y1, radius, start_angle, end_angle); o_set_line_options(toplevel, new_obj, arc_end, arc_type, arc_width, arc_length, arc_space); o_set_fill_options(toplevel, new_obj, FILLING_HOLLOW, -1, -1, -1, -1, -1); return new_obj; }
/*! \brief * \par Function Description * The function creates a new OBJECT of type arc. * * The arc is defined by its center in parameters x and y. * The radius parameter specifies the radius of the arc. The start * angle is given by start_angle and the end angle by end_angle. * The line and fill type of the created arc are set to default. * * All dimensions are in world unit, except start_angle and * end_angle in degrees. * * A new object of type OBJECT is allocated. Its type and color * are initilized. The description of the arc characteristics * are stored in a new ARC structure. * * Now fixed for world coordinates. * * \param [in] toplevel The TOPLEVEL object. * \param [in] type * \param [in] color * \param [in] x * \param [in] y * \param [in] radius * \param [in] start_angle * \param [in] end_angle * \return */ OBJECT *o_arc_new(TOPLEVEL *toplevel, char type, int color, int x, int y, int radius, int start_angle, int end_angle) { OBJECT *new_node; new_node = s_basic_new_object(type, "arc"); new_node->color = color; new_node->arc = (ARC *) g_malloc(sizeof(ARC)); /*! \note * The ARC structure is initialized with the parameters. * A default initialization is performed for the line and * fill type to avoid misunderstanding. * * The functions relative to the use of the object are sets. */ /* World coordinates */ new_node->arc->x = x; new_node->arc->y = y; new_node->arc->width = 2 * radius; new_node->arc->height = 2 * radius; /* must check the sign of start_angle, end_angle ... */ if(end_angle < 0) { start_angle = start_angle + end_angle; end_angle = -end_angle; } if(start_angle < 0) start_angle = 360 + start_angle; new_node->arc->start_angle = start_angle; new_node->arc->end_angle = end_angle; /* Default init */ o_set_line_options(toplevel, new_node, o_get_line_end(toplevel->print_output_capstyle), TYPE_SOLID, 0, -1, -1); o_set_fill_options(toplevel, new_node, FILLING_HOLLOW, -1, -1, -1, -1, -1); o_arc_recalc(toplevel, new_node); /* new_node->graphical = arc; eventually */ return new_node; }
/*! \brief * \par Function Description * This function creates a new object representing an arc. * * The values of the <B>o_current</B> pointed OBJECT are then copied to the new object. * * The arc, the line options are initialized whereas the fill options are * initialized to passive values - as an arc can not be filled. * * \param [in] toplevel The TOPLEVEL object * \param [in] o_current * \return The new OBJECT */ OBJECT *o_arc_copy(TOPLEVEL *toplevel, OBJECT *o_current) { OBJECT *new_obj; new_obj = o_arc_new (toplevel, OBJ_ARC, o_current->color, o_current->arc->x, o_current->arc->y, o_current->arc->width / 2, o_current->arc->start_angle, o_current->arc->end_angle); 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, FILLING_HOLLOW, -1, -1, -1, -1, -1); return new_obj; }
/*! \brief Create and add circle OBJECT to list. * \par Function Description * This function creates a new object representing a circle. * * The circle is described by its center (<B>x</B>,<B>y</B>) and its radius * <B>radius</B>. * The <B>type</B> parameter must be equal to <B>OBJ_CIRCLE</B>. The <B>color</B> * corresponds to the color the box will be drawn with. * * The <B>OBJECT</B> structure is allocated with the #s_basic_new_object() * function. The structure describing the circle is allocated and initialized * with the parameters given to the function. * * Both the line type and the filling type are set to default values : solid * line type with a width of 0, and no filling. It can be changed after * with #o_set_line_options() and #o_set_fill_options(). * * \param [in] toplevel The TOPLEVEL object. * \param [in] color Circle line color. * \param [in] center_x Center x coordinate. * \param [in] center_y Center y coordinate. * \param [in] radius Radius of new circle. * \return A pointer to the new end of the object list. */ GedaObject* geda_circle_object_new (TOPLEVEL *toplevel, gint color, gint center_x, gint center_y, gint radius) { GedaObject *new_node; /* create the object */ new_node = s_basic_new_object (OBJ_CIRCLE, "circle"); new_node->color = color; new_node->circle = geda_circle_new (); /* describe the circle with its center and radius */ new_node->circle->center_x = center_x; new_node->circle->center_y = center_y; new_node->circle->radius = radius; /* line type and filling initialized to default */ o_set_line_options (toplevel, new_node, DEFAULT_OBJECT_END, TYPE_SOLID, LINE_WIDTH, -1, -1); o_set_fill_options (toplevel, new_node, FILLING_HOLLOW, -1, -1, -1, -1, -1); /* compute the bounding box coords */ new_node->w_bounds_valid_for = NULL; return new_node; }
/*! \brief Create a copy of a circle. * \par Function Description * The function #geda_circle_object_copy() creates a verbatim copy of the object * pointed by <B>o_current</B> describing a circle. * * \param [in] toplevel The TOPLEVEL object. * \param [in] o_current Circle OBJECT to copy. * \return The new OBJECT */ GedaObject* geda_circle_object_copy (TOPLEVEL *toplevel, const GedaObject *object) { GedaObject *new_obj; g_return_val_if_fail (object != NULL, NULL); g_return_val_if_fail (object->circle != NULL, NULL); g_return_val_if_fail (object->type == OBJ_CIRCLE, NULL); new_obj = geda_circle_object_new (toplevel, object->color, object->circle->center_x, object->circle->center_y, object->circle->radius); o_set_line_options (toplevel, new_obj, object->line_end, object->line_type, object->line_width, object->line_length, object->line_space); o_set_fill_options (toplevel, new_obj, object->fill_type, object->fill_width, object->fill_pitch1, object->fill_angle1, object->fill_pitch2, object->fill_angle2); new_obj->w_bounds_valid_for = NULL; /* new_obj->attribute = 0;*/ return new_obj; }
/*! \brief Create a BOX OBJECT * \par Function Description * This function creates a new object representing a box. * * The box is described by its upper left corner - <B>x1</B>, <B>y1</B> - and * its lower right corner - <B>x2</B>, <B>y2</B>. * The <B>type</B> parameter must be equal to <B>OBJ_BOX</B>. The <B>color</B> * corresponds to the color the box will be drawn with. * The <B>OBJECT</B> structure is allocated with the #s_basic_new_object() * function. The structure describing the box is allocated and initialized * with the parameters given to the function. * * Both the line type and the filling type are set to default values : solid * line type with a width of 0, and no filling. It can be changed after * with the #o_set_line_options() and #o_set_fill_options(). * * \param [in] toplevel The TOPLEVEL object. * \param [in] type Box type. * \param [in] color Box border color. * \param [in] x1 Upper x coordinate. * \param [in] y1 Upper y coordinate. * \param [in] x2 Lower x coordinate. * \param [in] y2 Lower y coordinate. * \return The new OBJECT */ OBJECT* geda_box_object_new (TOPLEVEL *toplevel, char type, int color, int x1, int y1, int x2, int y2) { OBJECT *new_node; BOX *box; /* create the object */ new_node = s_basic_new_object(type, "box"); new_node->color = color; box = geda_box_new (); new_node->box = box; /* describe the box with its upper left and lower right corner */ box->upper_x = x1; box->upper_y = y1; box->lower_x = x2; box->lower_y = y2; /* line type and filling initialized to default */ o_set_line_options (toplevel, new_node, DEFAULT_OBJECT_END, TYPE_SOLID, LINE_WIDTH, -1, -1); o_set_fill_options(toplevel, new_node, FILLING_HOLLOW, -1, -1, -1, -1, -1); /* compute the bounding box */ new_node->w_bounds_valid_for = NULL; return new_node; }
/*! \brief create a copy of an existing arc object * * \param [in] toplevel The TOPLEVEL object * \param [in] object the arc object to copy * \return The new arc object */ GedaObject* geda_arc_object_copy (TOPLEVEL *toplevel, const GedaObject *object) { GedaObject *new_object; g_return_val_if_fail (object != NULL, NULL); g_return_val_if_fail (object->arc != NULL, NULL); g_return_val_if_fail (object->type == OBJ_ARC, NULL); new_object = geda_arc_object_new (toplevel, object->color, object->arc->x, object->arc->y, object->arc->radius, object->arc->start_angle, object->arc->sweep_angle); o_set_line_options (toplevel, new_object, object->line_end, object->line_type, object->line_width, object->line_length, object->line_space); o_set_fill_options (toplevel, new_object, FILLING_HOLLOW, -1, -1, -1, -1, -1); return new_object; }
/*! \brief Create a box from a character string. * \par Function Description * This function gets the description of a box from the <B>*buf</B> character * string. * * 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 20000704 release * <DT>*</DT><DD>the file format used for the releases after 2000704. * </DL> * * \param [in] toplevel The TOPLEVEL object. * \param [in] buf Character string with box description. * \param [in] release_ver libgeda release version number. * \param [in] fileformat_ver libgeda file format version number. * \return The BOX OBJECT that was created, or NULL on error. */ OBJECT *o_box_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 width, height; int d_x1, d_y1; int d_x2, d_y2; int color; int box_width, box_space, box_length; int fill_width, angle1, pitch1, angle2, pitch2; int box_end; int box_type; int box_filling; if (release_ver <= VERSION_20000704) { /*! \note * The old geda file format, i.e. releases 20000704 and older, does not * handle the line type and the filling of the box object. They are set * to default. */ if (sscanf (buf, "%c %d %d %d %d %d\n", &type, &x1, &y1, &width, &height, &color) != 6) { g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse box object")); return NULL; } box_width = 0; box_end = END_NONE; box_type = TYPE_SOLID; box_length = -1; box_space = -1; box_filling = FILLING_HOLLOW; fill_width = 0; angle1 = -1; pitch1 = -1; angle2 = -1; pitch2 = -1; } else { /*! \note * The current line format to describe a box 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 %d %d %d %d %d %d\n", &type, &x1, &y1, &width, &height, &color, &box_width, &box_end, &box_type, &box_length, &box_space, &box_filling, &fill_width, &angle1, &pitch1, &angle2, &pitch2) != 17) { g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse box object")); return NULL; } } if (width == 0 || height == 0) { s_log_message (_("Found a zero width/height box [ %c %d %d %d %d %d ]\n"), type, x1, y1, width, height, 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; } /*! \note * A box is internally described by its lower right and upper left corner * whereas the line describe it with the lower left corner and the width * and height. * * A new object is allocated, initialized and added to the object list. * Its filling and line type are set according to the values of the field * on the line. */ /* upper left corner of the box */ d_x1 = x1; d_y1 = y1 + height; /* move box origin to top left */ /* lower right corner of the box */ d_x2 = x1 + width; /* end points of the box */ d_y2 = y1; /* create a new box */ new_obj = geda_box_object_new (toplevel, type, color, d_x1, d_y1, d_x2, d_y2); /* set its line options */ o_set_line_options (toplevel, new_obj, box_end, box_type, box_width, box_length, box_space); /* set its fill options */ o_set_fill_options (toplevel, new_obj, box_filling, fill_width, pitch1, angle1, pitch2, angle2); return new_obj; }
/*! \brief * \par Function Description * This function reads a formatted text buffer describing an arc * in the gEDA file format and initializes the corresponding object. * * Depending on the version of the file format the data extraction is * performed differently : currently pre-20000704 and 20000704 on one * hand and post-20000704 file format version on the other hand are supported. * The version is specified in string pointed by <B>fileformat_ver</B>. * * To get information on the various file formats have a * look to the fileformats.html document. * * The object is initialized with the functions #o_set_line_options() and #o_set_fill_options(). * The second one is only used to put initialize unused values for an arc as an arc can not be filled. * * The arc is allocated initialized with the function #geda_arc_object_new(). * * A negative or null radius is not allowed. * * \param [in] toplevel The TOPLEVEL object. * \param [in] buf * \param [in] release_ver * \param [in] fileformat_ver * \return The ARC OBJECT that was created, or NULL on error. */ OBJECT *o_arc_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 radius; int start_angle; int sweep_angle; int color; int arc_width, arc_length, arc_space; int arc_type; int arc_end; /*! \note * Depending on the version of the file format used to describe this arc, * the buffer is parsed differently. The unknown parameters of the less * restrictive - the oldest - file format are set to common values */ if(release_ver <= VERSION_20000704) { if (sscanf(buf, "%c %d %d %d %d %d %d", &type, &x1, &y1, &radius, &start_angle, &sweep_angle, &color) != 7) { g_set_error (err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse arc object")); return NULL; } arc_width = 0; arc_end = END_NONE; arc_type = TYPE_SOLID; arc_space = -1; arc_length= -1; } else { if (sscanf(buf, "%c %d %d %d %d %d %d %d %d %d %d %d", &type, &x1, &y1, &radius, &start_angle, &sweep_angle, &color, &arc_width, &arc_end, &arc_type, &arc_length, &arc_space) != 12) { g_set_error (err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse arc object")); return NULL; } } /* Error check */ if (radius <= 0) { s_log_message (_("Found a zero radius arc " "[ %1$c %2$d, %3$d, %4$d, %5$d, %6$d, %7$d ]"), type, x1, y1, radius, start_angle, sweep_angle, color); radius = 0; } if (color < 0 || color > MAX_COLORS) { s_log_message(_("Found an invalid color [ %1$s ]"), buf); s_log_message(_("Setting color to default color.")); color = DEFAULT_COLOR; } /* Allocation and initialization */ new_obj = geda_arc_object_new (toplevel, color, x1, y1, radius, start_angle, sweep_angle); o_set_line_options(toplevel, new_obj, (OBJECT_END) arc_end, (OBJECT_TYPE) arc_type, arc_width, arc_length, arc_space); o_set_fill_options(toplevel, new_obj, FILLING_HOLLOW, -1, -1, -1, -1, -1); return new_obj; }
/*! \brief Create path OBJECT from character string. * \par Function Description * This function creates a path OBJECT from the character string * <B>*buf</B> and a number of lines following that describing the * path, read from <B>*tb</B>. * * 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] first_line Character string with path description. * \param [in] tb Text buffer containing the path string. * \param [in] release_ver libgeda release version number. * \param [in] fileformat_ver libgeda file format version number. * \return A pointer to the new path object, or NULL on error; */ OBJECT *o_path_read (TOPLEVEL *toplevel, const char *first_line, TextBuffer *tb, unsigned int release_ver, unsigned int fileformat_ver, GError **err) { OBJECT *new_obj; char type; int color; int line_width, line_space, line_length; int line_end; int line_type; int fill_type, fill_width, angle1, pitch1, angle2, pitch2; int num_lines = 0; int i; char *string; GString *pathstr; /* * The current path format to describe a line is a space separated * list of characters and numbers in plain ASCII on a single path. * The meaning of each item is described in the file format documentation. */ /* Allocate enough space */ if (sscanf (first_line, "%c %d %d %d %d %d %d %d %d %d %d %d %d %d\n", &type, &color, &line_width, &line_end, &line_type, &line_length, &line_space, &fill_type, &fill_width, &angle1, &pitch1, &angle2, &pitch2, &num_lines) != 14) { g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse path object")); return NULL; } /* * Checks if the required color is valid. */ if (color < 0 || color > MAX_COLORS) { s_log_message (_("Found an invalid color [ %1$s ]"), first_line); s_log_message (_("Setting color to default color.")); color = DEFAULT_COLOR; } /* * A path is internally described by its two ends. A new object is * allocated, initialized and added to the list of objects. Its path * type is set according to the values of the fields on the path. */ pathstr = g_string_new (""); for (i = 0; i < num_lines; i++) { const gchar *line; line = s_textbuffer_next_line (tb); if (line == NULL) { g_set_error (err, EDA_ERROR, EDA_ERROR_PARSE, _("Unexpected end-of-file when reading path")); return NULL; } pathstr = g_string_append (pathstr, line); } /* retrieve the character string from the GString */ string = g_string_free (pathstr, FALSE); string = geda_string_remove_ending_newline (string); /* create a new path */ new_obj = geda_path_object_new (toplevel, type, color, string); g_free (string); /* set its line options */ o_set_line_options (toplevel, new_obj, (OBJECT_END) line_end, (OBJECT_TYPE) line_type, line_width, line_length, line_space); /* set its fill options */ o_set_fill_options (toplevel, new_obj, (OBJECT_FILLING) fill_type, fill_width, pitch1, angle1, pitch2, angle2); return new_obj; }
/*! \brief Create circle OBJECT from character string. * \par Function Description * The #o_circle_read() function gets from the character string <B>*buff</B> the * description of a circle. * * Depending on <B>*version</B>, the right file format is considered. * Currently two file format revisions are supported : * <DL> * <DT>*</DT><DD>the file format used until 2000704 release. * <DT>*</DT><DD>the file format used for the releases after 20000704. * </DL> * * \param [in] toplevel The TOPLEVEL object. * \param [in] buf Character string with circle description. * \param [in] release_ver libgeda release version number. * \param [in] fileformat_ver libgeda file format version number. * \return A pointer to the new circle object, or NULL on error. */ GedaObject* o_circle_read (TOPLEVEL *toplevel, const char buf[], unsigned int release_ver, unsigned int fileformat_ver, GError ** err) { GedaObject *new_obj; char type; int x1, y1; int radius; int color; int circle_width, circle_space, circle_length; int fill_width, angle1, pitch1, angle2, pitch2; int circle_end; int circle_type; int circle_fill; 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 of the box object. They are set * to default. */ if (sscanf(buf, "%c %d %d %d %d\n", &type, &x1, &y1, &radius, &color) != 5) { g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse circle object")); return NULL; } circle_width = 0; circle_end = END_NONE; circle_type = TYPE_SOLID; circle_length= -1; circle_space = -1; circle_fill = FILLING_HOLLOW; fill_width = 0; angle1 = -1; pitch1 = -1; angle2 = -1; pitch2 = -1; } else { /* * The current line format to describe a circle 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 %d %d %d %d %d\n", &type, &x1, &y1, &radius, &color, &circle_width, &circle_end, &circle_type, &circle_length, &circle_space, &circle_fill, &fill_width, &angle1, &pitch1, &angle2, &pitch2) != 16) { g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse circle object")); return NULL; } } if (radius <= 0) { s_log_message(_("Found a zero or negative radius circle [ %c %d %d %d %d ]\n"), type, x1, y1, radius, color); s_log_message (_("Setting radius to 0\n")); radius = 0; } 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 circle is internally described by its center and its radius. * * A new object is allocated, initialized and added to the object list. * Its filling and line type are set according to the values of the field * on the line. */ new_obj = geda_circle_object_new (toplevel, color, x1, y1, radius); o_set_line_options(toplevel, new_obj, circle_end, circle_type, circle_width, circle_length, circle_space); o_set_fill_options(toplevel, new_obj, circle_fill, fill_width, pitch1, angle1, pitch2, angle2); return new_obj; }
/*! \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; }