1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
3 * Copyright (C) 1998-2007 Ales Hvezda
4 * Copyright (C) 1998-2007 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21 /*! \file o_bus_basic.c
22 * \brief functions for the bus object
29 #include "libgeda_priv.h"
31 #ifdef HAVE_LIBDMALLOC
35 /*! Default setting for bus draw function. */
36 void (*bus_draw_func
)() = NULL
;
38 /*! \brief calculate and return the boundaries of a bus object
39 * \par Function Description
40 * This function calculates the object boundaries of a bus \a object.
42 * \param [in] toplevel The TOPLEVEL object.
43 * \param [in] object a bus object
44 * \param [out] left the left world coord
45 * \param [out] top the top world coord
46 * \param [out] right the right world coord
47 * \param [out] bottom the bottom world coord
49 void world_get_bus_bounds(OBJECT
*object
, int *left
, int *top
,
50 int *right
, int *bottom
)
52 world_get_line_bounds(object
, left
, top
, right
, bottom
);
55 OBJECT
*o_bus_new_at_xy(TOPLEVEL
*toplevel
, char type
, int color
, int x
, int y
)
57 OBJECT
*bus
= o_line_new_at_xy(toplevel
, type
, color
, x
, y
);
62 /*! \brief create a new bus object
63 * \par Function Description
64 * This function creates and returns a new bus object.
66 * \param [in] toplevel The TOPLEVEL object.
67 * \param [in] type The OBJECT type (usually OBJ_BUS)
68 * \param [in] color The color of the bus
69 * \param [in] x1 x-coord of the first point
70 * \param [in] y1 y-coord of the first point
71 * \param [in] x2 x-coord of the second point
72 * \param [in] y2 y-coord of the second point
73 * \param [in] bus_ripper_direction direction of the bus rippers
74 * \return A new bus OBJECT
76 OBJECT
*o_bus_new(TOPLEVEL
*toplevel
,
78 int x1
, int y1
, int x2
, int y2
,
79 int bus_ripper_direction
)
83 new_node
= o_bus_new_at_xy(toplevel
, type
, color
, x1
, y1
);
85 s_basic_move_grip(new_node
, GRIP_1
, x1
, y1
);
86 s_basic_move_grip(new_node
, GRIP_2
, x2
, y2
);
88 new_node
->bus_ripper_direction
= bus_ripper_direction
;
90 o_bus_recalc(new_node
);
95 /*! \brief recalc the visual properties of a bus object
96 * \par Function Description
97 * This function updates the visual coords of the \a o_current object.
99 * \param [in] toplevel The TOPLEVEL object.
100 * \param [in] o_current a bus object.
102 void o_bus_recalc(OBJECT
*o_current
)
104 int left
, right
, top
, bottom
;
106 if (o_current
== NULL
) {
110 if (o_current
->line
== NULL
) {
114 world_get_bus_bounds(o_current
, &left
, &top
, &right
, &bottom
);
116 o_current
->w_left
= left
;
117 o_current
->w_top
= top
;
118 o_current
->w_right
= right
;
119 o_current
->w_bottom
= bottom
;
120 o_current
->w_bounds_valid
= TRUE
;
123 /*! \brief read a bus object from a char buffer
124 * \par Function Description
125 * This function reads a bus object from the buffer \a buf.
127 * \param [in] toplevel The TOPLEVEL object
128 * \param [in] buf a text buffer (usually a line of a schematic file)
129 * \param [in] release_ver The release number gEDA
130 * \param [in] fileformat_ver a integer value of the file format
131 * \return The object list
133 OBJECT
*o_bus_read(TOPLEVEL
*toplevel
, char buf
[],
134 unsigned int release_ver
, unsigned int fileformat_ver
)
145 if(release_ver
<= VERSION_20020825
) {
146 sscanf(buf
, "%c %d %d %d %d %d\n", &type
, &x1
, &y1
, &x2
, &y2
, &color
);
149 sscanf(buf
, "%c %d %d %d %d %d %d\n", &type
, &x1
, &y1
, &x2
, &y2
, &color
,
158 if (x1
== x2
&& y1
== y2
) {
159 s_log_message(_("Found a zero length bus [ %c %d %d %d %d %d ]\n"),
160 type
, x1
, y1
, x2
, y2
, color
);
163 if (toplevel
->override_bus_color
!= -1) {
164 color
= toplevel
->override_bus_color
;
167 if (color
< 0 || color
> MAX_COLORS
) {
168 s_log_message(_("Found an invalid color [ %s ]\n"), buf
);
169 s_log_message(_("Setting color to WHITE\n"));
173 if (ripper_dir
< -1 || ripper_dir
> 1) {
174 s_log_message(_("Found an invalid bus ripper direction [ %s ]\n"), buf
);
175 s_log_message(_("Resetting direction to neutral (no direction)\n"));
179 new_obj
= o_bus_new(toplevel
, type
, color
,
180 d_x1
, d_y1
, d_x2
, d_y2
, ripper_dir
);
185 /*! \brief Create a string representation of the bus object
186 * \par Function Description
187 * This function takes a bus \a object and return a string
188 * according to the file format definition.
190 * \param [in] object a bus OBJECT
191 * \return the string representation of the bus OBJECT
193 char *o_bus_save(OBJECT
*object
)
199 s_basic_get_grip(object
, GRIP_1
, &x1
, &y1
);
200 s_basic_get_grip(object
, GRIP_2
, &x2
, &y2
);
202 /* Use the right color */
203 if (object
->saved_color
== -1) {
204 color
= object
->color
;
206 color
= object
->saved_color
;
209 buf
= g_strdup_printf("%c %d %d %d %d %d %d", object
->type
,
210 x1
, y1
, x2
, y2
, color
, object
->bus_ripper_direction
);
214 /*! \brief move a bus object
215 * \par Function Description
216 * This function changes the position of a bus \a object.
218 * \param [in] dx The x-distance to move the object
219 * \param [in] dy The y-distance to move the object
220 * \param [in] object The bus OBJECT to be moved
222 void o_bus_translate_world(int dx
, int dy
, OBJECT
*object
)
226 if (object
== NULL
) printf("btw NO!\n");
228 s_basic_get_grip(object
, GRIP_1
, &x1
, &y1
);
229 s_basic_get_grip(object
, GRIP_2
, &x2
, &y2
);
231 /* Update world coords */
232 s_basic_move_grip(object
, GRIP_1
, x1
+ dx
, y1
+ dy
);
233 s_basic_move_grip(object
, GRIP_2
, x2
+ dx
, y2
+ dy
);
235 /* Update bounding box */
236 o_bus_recalc(object
);
239 /*! \brief create a copy of a bus object
240 * \par Function Description
241 * This function creates a copy of the bus object \a o_current.
243 * \param [in] toplevel The TOPLEVEL object
244 * \param [in] o_current The object that is copied
245 * \return a new bus object
247 OBJECT
*o_bus_copy(TOPLEVEL
*toplevel
, OBJECT
*o_current
)
253 if (o_current
->saved_color
== -1) {
254 color
= o_current
->color
;
256 color
= o_current
->saved_color
;
259 s_basic_get_grip(o_current
, GRIP_1
, &x1
, &y1
);
260 s_basic_get_grip(o_current
, GRIP_2
, &x2
, &y2
);
262 /* make sure you fix this in pin and bus as well */
263 /* still doesn't work... you need to pass in the new values */
264 /* or don't update and update later */
265 /* I think for now I'll disable the update and manually update */
266 new_obj
= o_bus_new(toplevel
, OBJ_BUS
, color
, x1
, y1
, x2
, y2
,
267 o_current
->bus_ripper_direction
);
269 /* XXX What is the purpose of this? It seems redundant. */
270 s_basic_move_grip(new_obj
, GRIP_1
, x1
, y1
);
271 s_basic_move_grip(new_obj
, GRIP_2
, x2
, y2
);
276 /*! \brief postscript print command for a bus object
277 * \par Function Description
278 * This function writes the postscript command of the bus object \a o_current
279 * into the FILE \a fp points to.
281 * \param [in] toplevel The TOPLEVEL object
282 * \param [in] fp pointer to a FILE structure
283 * \param [in] o_current The OBJECT to print
284 * \param [in] origin_x x-coord of the postscript origin
285 * \param [in] origin_y y-coord of the postscript origin
287 void o_bus_print(TOPLEVEL
*toplevel
, FILE *fp
, OBJECT
*o_current
,
288 int origin_x
, int origin_y
)
294 if (o_current
== NULL
) {
295 printf("got null in o_bus_print\n");
299 if (toplevel
->print_color
) {
300 f_print_set_color(fp
, o_current
->color
);
304 if (toplevel
->bus_style
== THICK
) {
305 bus_width
= BUS_WIDTH
;
308 s_basic_get_grip(o_current
, GRIP_1
, &x1
, &y1
);
309 s_basic_get_grip(o_current
, GRIP_2
, &x2
, &y2
);
311 fprintf(fp
, "%d %d %d %d %d line\n",
312 x1
- origin_x
, y1
- origin_y
,
313 x2
- origin_x
, y2
- origin_y
,
318 /*! \brief rotate a bus object around a centerpoint
319 * \par Function Description
320 * This function rotates a bus \a object around the point
321 * (\a world_centerx, \a world_centery).
323 * \param [in] world_centerx x-coord of the rotation center
324 * \param [in] world_centery y-coord of the rotation center
325 * \param [in] angle The angle to rotate the bus object
326 * \param [in] object The bus object
327 * \note only steps of 90 degrees are allowed for the \a angle
329 void o_bus_rotate_world(int world_centerx
, int world_centery
, int angle
,
338 /* translate object to origin */
339 o_bus_translate_world(-world_centerx
, -world_centery
, object
);
341 s_basic_get_grip(object
, GRIP_1
, &x1
, &y1
);
342 s_basic_get_grip(object
, GRIP_2
, &x2
, &y2
);
344 rotate_point_90(x1
, y1
, angle
, &newx
, &newy
);
345 s_basic_move_grip(object
, GRIP_1
, newx
, newy
);
347 rotate_point_90(x2
, y2
, angle
, &newx
, &newy
);
348 s_basic_move_grip(object
, GRIP_2
, newx
, newy
);
350 o_bus_translate_world(world_centerx
, world_centery
, object
);
353 /*! \brief mirror a bus object horizontally at a centerpoint
354 * \par Function Description
355 * This function mirrors a bus \a object horizontally at the point
356 * (\a world_centerx, \a world_centery).
358 * \param [in] world_centerx x-coord of the mirror position
359 * \param [in] world_centery y-coord of the mirror position
360 * \param [in] object The bus object
362 void o_bus_mirror_world(int world_centerx
, int world_centery
, OBJECT
*object
)
366 s_basic_get_grip(object
, GRIP_1
, &x1
, &y1
);
367 s_basic_get_grip(object
, GRIP_2
, &x2
, &y2
);
369 /* translate object to origin */
370 o_bus_translate_world(-world_centerx
, -world_centery
, object
);
372 s_basic_move_grip(object
, GRIP_1
, -x1
, y1
);
373 s_basic_move_grip(object
, GRIP_2
, -x2
, y2
);
375 o_bus_translate_world(world_centerx
, world_centery
, object
);
378 /*! \brief modify one point of a bus object
379 * \par Function Description
380 * This function modifies one point of a bus \a object. The point
381 * is specified by the \a whichone variable and the new coordinate
384 * \param toplevel The TOPLEVEL object
385 * \param object The bus OBJECT to modify
386 * \param x new x-coord of the bus point
387 * \param y new y-coord of the bus point
388 * \param whichone bus point to modify
390 void o_bus_modify(TOPLEVEL
*toplevel
, OBJECT
*object
,
391 int x
, int y
, int whichone
)
393 s_basic_move_grip(object
, whichone
, x
, y
);
395 o_bus_recalc(object
);