1 /* Lepton EDA library
2 * Copyright (C) 1998-2010 Ales Hvezda
3 * Copyright (C) 1998-2016 gEDA Contributors
4 * Copyright (C) 2017-2021 Lepton EDA Contributors
5 *
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.
10 *
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.
15 *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <math.h>
24
25 #include "liblepton_priv.h"
26
27
28 /*! \brief Test if object is a bus pin object.
29 *
30 * \param [in] object The object to test.
31 * \return TRUE, if the object is bus pin, otherwise FALSE.
32 */
33 gboolean
lepton_pin_object_is_bus_pin(const LeptonObject * object)34 lepton_pin_object_is_bus_pin (const LeptonObject *object)
35 {
36 g_return_val_if_fail (lepton_object_is_pin (object), FALSE);
37
38 return (object->pin_type == PIN_TYPE_BUS);
39 }
40
41
42 /*! \brief Test if object is a net pin object.
43 *
44 * \param [in] object The object to test.
45 * \return TRUE, if the object is net pin, otherwise FALSE.
46 */
47 gboolean
lepton_pin_object_is_net_pin(const LeptonObject * object)48 lepton_pin_object_is_net_pin (const LeptonObject *object)
49 {
50 g_return_val_if_fail (lepton_object_is_pin (object), FALSE);
51
52 return (object->pin_type == PIN_TYPE_NET);
53 }
54
55
56 /*! \file pin_object.c
57 * \brief functions for the pin object
58 */
59
60 /*! \brief Calculate the bounds of a pin
61 *
62 * On failure, this function sets the bounds to empty.
63 *
64 * \param [in] object The pin object
65 * \param [out] bounds The bounds of the pin
66 */
67 void
lepton_pin_object_calculate_bounds(const LeptonObject * object,LeptonBounds * bounds)68 lepton_pin_object_calculate_bounds (const LeptonObject *object,
69 LeptonBounds *bounds)
70 {
71 gint expand;
72 gint width;
73
74 lepton_bounds_init (bounds);
75
76 g_return_if_fail (lepton_object_is_pin (object));
77 g_return_if_fail (object->line != NULL);
78
79 lepton_line_calculate_bounds (object->line, bounds);
80
81 width = lepton_pin_object_get_width (object);
82
83 expand = ceil (0.5 * G_SQRT2 * width);
84
85 /* This isn't strictly correct, but a 1st order approximation */
86 lepton_bounds_expand (bounds, bounds, expand, expand);
87 }
88
89 /*! \brief Get the width to draw the pin
90 *
91 * On failure, this function returns PIN_WIDTH_NET.
92 *
93 * \param [in] object The pin object
94 * \return The line width to draw the pin
95 */
96 gint
lepton_pin_object_get_width(const LeptonObject * object)97 lepton_pin_object_get_width (const LeptonObject *object)
98 {
99 gint width = PIN_WIDTH_NET;
100
101 g_return_val_if_fail (lepton_object_is_pin (object), PIN_WIDTH_NET);
102
103 switch (object->pin_type)
104 {
105 case PIN_TYPE_NET:
106 width = PIN_WIDTH_NET;
107 break;
108
109 case PIN_TYPE_BUS:
110 width = PIN_WIDTH_BUS;
111 break;
112
113 default:
114 g_warning ("lepton_pin_object_calculate_bounds: invalid pin_type");
115 }
116
117 return width;
118 }
119
120 /*! \brief get the position of a whichend of the pin object
121 * \par Function Description
122 * This function gets the position of the whichend side of a pin object.
123 *
124 * \param [in] object The object to get the position.
125 * \param [out] x pointer to the x-position
126 * \param [out] y pointer to the y-position
127 * \return TRUE if successfully determined the position, FALSE otherwise
128 */
129 gboolean
lepton_pin_object_get_position(const LeptonObject * object,gint * x,gint * y)130 lepton_pin_object_get_position (const LeptonObject *object,
131 gint *x,
132 gint *y)
133 {
134 g_return_val_if_fail (lepton_object_is_pin (object), FALSE);
135 g_return_val_if_fail (object->line != NULL, FALSE);
136 g_return_val_if_fail (object->whichend >= 0, FALSE);
137 g_return_val_if_fail (object->whichend < 2, FALSE);
138
139 if (x != NULL) {
140 *x = object->line->x[object->whichend];
141 }
142
143 if (y != NULL) {
144 *y = object->line->y[object->whichend];
145 }
146
147 return TRUE;
148 }
149
150 /*! \brief Get the x coordinate of first endpoint
151 *
152 * The coordinate properties are broken out individually to make it easier for
153 * the GUI. This way, the GUI does not need as many adapters to interface to
154 * a line boxed type.
155 *
156 * \param [in] object The line
157 * \return The x coordinate for the first endpoint
158 */
159 gint
lepton_pin_object_get_x0(const LeptonObject * object)160 lepton_pin_object_get_x0 (const LeptonObject *object)
161 {
162 g_return_val_if_fail (lepton_object_is_pin (object), 0);
163 g_return_val_if_fail (object->line != NULL, 0);
164
165 return object->line->x[0];
166 }
167
168 /*! \brief Get the x coordinate of second endpoint
169 *
170 * The coordinate properties are broken out individually to make it easier for
171 * the GUI. This way, the GUI does not need as many adapters to interface to
172 * a line boxed type.
173 *
174 * \param [in] object The line
175 * \return The x coordinate for the second endpoint
176 */
177 gint
lepton_pin_object_get_x1(const LeptonObject * object)178 lepton_pin_object_get_x1 (const LeptonObject *object)
179 {
180 g_return_val_if_fail (lepton_object_is_pin (object), 0);
181 g_return_val_if_fail (object->line != NULL, 0);
182
183 return object->line->x[1];
184 }
185
186 /*! \brief Get the y coordinate of first endpoint
187 *
188 * The coordinate properties are broken out individually to make it easier for
189 * the GUI. This way, the GUI does not need as many adapters to interface to
190 * a line boxed type.
191 *
192 * \param [in] object The line
193 * \return The y coordinate for the first endpoint
194 */
195 gint
lepton_pin_object_get_y0(const LeptonObject * object)196 lepton_pin_object_get_y0 (const LeptonObject *object)
197 {
198 g_return_val_if_fail (lepton_object_is_pin (object), 0);
199 g_return_val_if_fail (object->line != NULL, 0);
200
201 return object->line->y[0];
202 }
203
204 /*! \brief Get the y coordinate of second endpoint
205 *
206 * The coordinate properties are broken out individually to make it easier for
207 * the GUI. This way, the GUI does not need as many adapters to interface to
208 * a line boxed type.
209 *
210 * \param [in] object The line
211 * \return The y coordinate for the second endpoint
212 */
213 gint
lepton_pin_object_get_y1(const LeptonObject * object)214 lepton_pin_object_get_y1 (const LeptonObject *object)
215 {
216 g_return_val_if_fail (lepton_object_is_pin (object), 0);
217 g_return_val_if_fail (object->line != NULL, 0);
218
219 return object->line->y[1];
220 }
221
222 /*! \brief Set the x coordinate of first endpoint
223 *
224 * The coordinate properties are broken out individually to make it easier for
225 * the GUI. This way, the GUI does not need as many adapters to interface to
226 * a line boxed type.
227 *
228 * \param [in,out] object The line
229 * \param [in] x The new x coordinate for the first endpoint
230 */
231 void
lepton_pin_object_set_x0(LeptonObject * object,gint x)232 lepton_pin_object_set_x0 (LeptonObject *object,
233 gint x)
234 {
235 g_return_if_fail (lepton_object_is_pin (object));
236 g_return_if_fail (object->line != NULL);
237
238 object->line->x[0] = x;
239 }
240
241 /*! \brief Set the x coordinate of second endpoint
242 *
243 * The coordinate properties are broken out individually to make it easier for
244 * the GUI. This way, the GUI does not need as many adapters to interface to
245 * a line boxed type.
246 *
247 * \param [in,out] object The line
248 * \param [in] x The new x coordinate for the second endpoint
249 */
250 void
lepton_pin_object_set_x1(LeptonObject * object,gint x)251 lepton_pin_object_set_x1 (LeptonObject *object,
252 gint x)
253 {
254 g_return_if_fail (lepton_object_is_pin (object));
255 g_return_if_fail (object->line != NULL);
256
257 object->line->x[1] = x;
258 }
259
260 /*! \brief Set the y coordinate of first endpoint
261 *
262 * The coordinate properties are broken out individually to make it easier for
263 * the GUI. This way, the GUI does not need as many adapters to interface to
264 * a line boxed type.
265 *
266 * \param [in,out] object The line
267 * \param [in] y The new y coordinate for the first endpoint
268 */
269 void
lepton_pin_object_set_y0(LeptonObject * object,gint y)270 lepton_pin_object_set_y0 (LeptonObject *object,
271 gint y)
272 {
273 g_return_if_fail (lepton_object_is_pin (object));
274 g_return_if_fail (object->line != NULL);
275
276 object->line->y[0] = y;
277 }
278
279 /*! \brief Set the y coordinate of second endpoint
280 *
281 * The coordinate properties are broken out individually to make it easier for
282 * the GUI. This way, the GUI does not need as many adapters to interface to
283 * a line boxed type.
284 *
285 * \param [in,out] object The line
286 * \param [in] y The new y coordinate for the second endpoint
287 */
288 void
lepton_pin_object_set_y1(LeptonObject * object,gint y)289 lepton_pin_object_set_y1 (LeptonObject *object,
290 gint y)
291 {
292 g_return_if_fail (lepton_object_is_pin (object));
293 g_return_if_fail (object->line != NULL);
294
295 object->line->y[1] = y;
296 }
297
298 /*! \brief create a new pin object
299 * \par Function Description
300 * This function creates and returns a new pin object.
301 *
302 * \param [in] color The color of the pin
303 * \param [in] x1 x-coord of the first point
304 * \param [in] y1 y-coord of the first point
305 * \param [in] x2 x-coord of the second point
306 * \param [in] y2 y-coord of the second point
307 * \param [in] pin_type type of pin (PIN_TYPE_NET or PIN_TYPE_BUS)
308 * \param [in] whichend The connectable end of the pin
309 * \return A new pin LeptonObject
310 */
311 LeptonObject*
lepton_pin_object_new(int color,int x1,int y1,int x2,int y2,int pin_type,int whichend)312 lepton_pin_object_new (int color,
313 int x1,
314 int y1,
315 int x2,
316 int y2,
317 int pin_type,
318 int whichend)
319 {
320 LeptonObject *new_node;
321
322 new_node = lepton_object_new (OBJ_PIN, "pin");
323 lepton_object_set_color (new_node, color);
324
325 new_node->line = lepton_line_new ();
326
327 new_node->line->x[0] = x1;
328 new_node->line->y[0] = y1;
329 new_node->line->x[1] = x2;
330 new_node->line->y[1] = y2;
331
332 lepton_pin_object_set_type (new_node, pin_type);
333
334 new_node->whichend = whichend;
335
336 return new_node;
337 }
338
339 /*! \brief Create a new net pin object.
340 * \par Function Description
341 * This function creates and returns a new net pin object.
342 *
343 * \param [in] color The color of the pin.
344 * \param [in] x1 X-coord of the first point.
345 * \param [in] y1 Y-coord of the first point.
346 * \param [in] x2 X-coord of the second point.
347 * \param [in] y2 Y-coord of the second point.
348 * \param [in] whichend The connectible end of the pin.
349 * \return A new pin LeptonObject
350 */
351 LeptonObject*
lepton_pin_object_new_net_pin(int color,int x1,int y1,int x2,int y2,int whichend)352 lepton_pin_object_new_net_pin (int color,
353 int x1,
354 int y1,
355 int x2,
356 int y2,
357 int whichend)
358 {
359 return lepton_pin_object_new (color, x1, y1, x2, y2, PIN_TYPE_NET, whichend);
360 }
361
362
363 /*! \brief Create a new bus pin object.
364 * \par Function Description
365 * This function creates and returns a new bus pin object.
366 *
367 * \param [in] color The color of the pin.
368 * \param [in] x1 X-coord of the first point.
369 * \param [in] y1 Y-coord of the first point.
370 * \param [in] x2 X-coord of the second point.
371 * \param [in] y2 Y-coord of the second point.
372 * \param [in] whichend The connectible end of the pin.
373 * \return A new pin LeptonObject
374 */
375 LeptonObject*
lepton_pin_object_new_bus_pin(int color,int x1,int y1,int x2,int y2,int whichend)376 lepton_pin_object_new_bus_pin (int color,
377 int x1,
378 int y1,
379 int x2,
380 int y2,
381 int whichend)
382 {
383 return lepton_pin_object_new (color, x1, y1, x2, y2, PIN_TYPE_BUS, whichend);
384 }
385
386 /*! \brief read a pin object from a char buffer
387 * \par Function Description
388 * This function reads a pin object from the buffer \a buf.
389 * If the pin object was read successfully, a new pin object is
390 * allocated and appended to the \a object_list.
391 *
392 * \param [in] buf a text buffer (usually a line of a schematic file)
393 * \param [in] release_ver The release number gEDA
394 * \param [in] fileformat_ver a integer value of the file format
395 * \return The object list, or NULL on error.
396 */
397 LeptonObject*
lepton_pin_object_read(const char buf[],unsigned int release_ver,unsigned int fileformat_ver,GError ** err)398 lepton_pin_object_read (const char buf[],
399 unsigned int release_ver,
400 unsigned int fileformat_ver,
401 GError **err)
402 {
403 LeptonObject *new_obj;
404 char type;
405 int x1, y1;
406 int x2, y2;
407 int color;
408 int pin_type;
409 int whichend;
410
411 if (release_ver <= VERSION_20020825) {
412 if (sscanf (buf, "%c %d %d %d %d %d\n", &type, &x1, &y1, &x2, &y2, &color) != 6) {
413 g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse pin object"));
414 return NULL;
415 }
416 pin_type = PIN_TYPE_NET;
417 whichend = -1;
418 } else {
419 if (sscanf (buf, "%c %d %d %d %d %d %d %d\n", &type, &x1, &y1, &x2, &y2,
420 &color, &pin_type, &whichend) != 8) {
421 g_set_error(err, EDA_ERROR, EDA_ERROR_PARSE, _("Failed to parse pin object"));
422 return NULL;
423 }
424 }
425
426 if (whichend == -1) {
427 g_message (_("Found a pin which did not have the whichend field set.\n"
428 "Verify and correct manually."));
429 } else if (whichend < -1 || whichend > 1) {
430 g_message (_("Found an invalid whichend on a pin (reseting to zero): %d"),
431 whichend);
432 whichend = 0;
433 }
434
435 if (!color_id_valid (color)) {
436 g_message (_("Found an invalid color [ %1$s ]"), buf);
437 g_message (_("Setting color to default color."));
438 color = default_color_id();
439 }
440
441 new_obj = lepton_pin_object_new (color,
442 x1,
443 y1,
444 x2,
445 y2,
446 pin_type,
447 whichend);
448
449 return new_obj;
450 }
451
452 /*! \brief Create a string representation of the pin object
453 *
454 * This function takes a pin \a object and returns a string
455 * according to the file format definition.
456 *
457 * On failure, this function returns NULL.
458 *
459 * The caller must free the returned string when no longer needed using
460 * g_free().
461 *
462 * \param [in] object a pin object
463 * \return a string representation of the pin object
464 */
465 gchar*
lepton_pin_object_to_buffer(const LeptonObject * object)466 lepton_pin_object_to_buffer (const LeptonObject *object)
467 {
468 g_return_val_if_fail (lepton_object_is_pin (object), NULL);
469 g_return_val_if_fail (object->line != NULL, NULL);
470
471 return g_strdup_printf ("%c %d %d %d %d %d %d %d",
472 lepton_object_get_type (object),
473 lepton_pin_object_get_x0 (object),
474 lepton_pin_object_get_y0 (object),
475 lepton_pin_object_get_x1 (object),
476 lepton_pin_object_get_y1 (object),
477 lepton_object_get_color (object),
478 object->pin_type,
479 object->whichend);
480 }
481
482 /*! \brief move a pin object
483 * \par Function Description
484 * This function changes the position of a pin \a object.
485 *
486 * \param [ref] object The pin LeptonObject to be moved
487 * \param [in] dx The x-distance to move the object
488 * \param [in] dy The y-distance to move the object
489 */
490 void
lepton_pin_object_translate(LeptonObject * object,int dx,int dy)491 lepton_pin_object_translate (LeptonObject *object,
492 int dx,
493 int dy)
494 {
495 g_return_if_fail (lepton_object_is_pin (object));
496 g_return_if_fail (object->line != NULL);
497
498 /* Update world coords */
499 object->line->x[0] = object->line->x[0] + dx;
500 object->line->y[0] = object->line->y[0] + dy;
501 object->line->x[1] = object->line->x[1] + dx;
502 object->line->y[1] = object->line->y[1] + dy;
503 }
504
505 /*! \brief create a copy of a pin object
506 * \par Function Description
507 * This function creates a copy of the pin object \a o_current.
508 *
509 * \param [in] o_current The object that is copied
510 * \return a new pin object
511 */
512 LeptonObject*
lepton_pin_object_copy(LeptonObject * o_current)513 lepton_pin_object_copy (LeptonObject *o_current)
514 {
515 LeptonObject *new_obj;
516
517 g_return_val_if_fail (lepton_object_is_pin (o_current), NULL);
518 g_return_val_if_fail (o_current->line != NULL, NULL);
519
520 new_obj = lepton_pin_object_new (lepton_object_get_color (o_current),
521 o_current->line->x[0],
522 o_current->line->y[0],
523 o_current->line->x[1],
524 o_current->line->y[1],
525 o_current->pin_type,
526 o_current->whichend);
527
528 return new_obj;
529 }
530
531 /*! \brief rotate a pin object around a centerpoint
532 * \par Function Description
533 * This function rotates a pin \a object around the point
534 * (\a world_centerx, \a world_centery).
535 *
536 * \param [in] world_centerx x-coord of the rotation center
537 * \param [in] world_centery y-coord of the rotation center
538 * \param [in] angle The angle to rotat the pin object
539 * \param [in] object The pin object
540 * \note only steps of 90 degrees are allowed for the \a angle
541 */
542 void
lepton_pin_object_rotate(int world_centerx,int world_centery,int angle,LeptonObject * object)543 lepton_pin_object_rotate (int world_centerx,
544 int world_centery,
545 int angle,
546 LeptonObject *object)
547 {
548 int newx, newy;
549
550 g_return_if_fail (lepton_object_is_pin (object));
551 g_return_if_fail (object->line != NULL);
552
553 if (angle == 0)
554 return;
555
556 /* translate object to origin */
557 lepton_pin_object_translate (object, -world_centerx, -world_centery);
558
559 lepton_point_rotate_90 (object->line->x[0],
560 object->line->y[0],
561 angle,
562 &newx,
563 &newy);
564
565 object->line->x[0] = newx;
566 object->line->y[0] = newy;
567
568 lepton_point_rotate_90 (object->line->x[1],
569 object->line->y[1],
570 angle,
571 &newx,
572 &newy);
573
574 object->line->x[1] = newx;
575 object->line->y[1] = newy;
576
577 lepton_pin_object_translate (object, world_centerx, world_centery);
578 }
579
580 /*! \brief mirror a pin object horizontaly at a centerpoint
581 * \par Function Description
582 * This function mirrors a pin \a object horizontaly at the point
583 * (\a world_centerx, \a world_centery).
584 *
585 * \param [in] world_centerx x-coord of the mirror position
586 * \param [in] world_centery y-coord of the mirror position
587 * \param [in] object The pin object
588 */
589 void
lepton_pin_object_mirror(int world_centerx,int world_centery,LeptonObject * object)590 lepton_pin_object_mirror (int world_centerx,
591 int world_centery,
592 LeptonObject *object)
593 {
594 g_return_if_fail (lepton_object_is_pin (object));
595 g_return_if_fail (object->line != NULL);
596
597 /* translate object to origin */
598 lepton_pin_object_translate (object, -world_centerx, -world_centery);
599
600 object->line->x[0] = -object->line->x[0];
601
602 object->line->x[1] = -object->line->x[1];
603
604 lepton_pin_object_translate (object, world_centerx, world_centery);
605 }
606
607 /*! \brief modify one point of a pin object
608 * \par Function Description
609 * This function modifies one point of a pin \a object. The point
610 * is specified by the \a whichone variable and the new coordinate
611 * is (\a x, \a y).
612 *
613 * \param object The pin LeptonObject to modify
614 * \param x new x-coord of the pin point
615 * \param y new y-coord of the pin point
616 * \param whichone pin point to modify
617 *
618 */
619 void
lepton_pin_object_modify(LeptonObject * object,int x,int y,int whichone)620 lepton_pin_object_modify (LeptonObject *object,
621 int x,
622 int y,
623 int whichone)
624 {
625 g_return_if_fail (lepton_object_is_pin (object));
626 g_return_if_fail (object->line != NULL);
627 g_return_if_fail (object->whichend >= 0);
628 g_return_if_fail (object->whichend < 2);
629
630 object->line->x[whichone] = x;
631 object->line->y[whichone] = y;
632 }
633
634 /*! \brief guess the whichend of pins of object list
635 * \par Function Description
636 * This function determines the whichend of the pins in the \a object_list.
637 * In older libgeda file format versions there was no information about the
638 * active end of pins.
639 * This function calculates the bounding box of all pins in the object list.
640 * The side of the pins that are closer to the boundary of the box are
641 * set as active ends of the pins.
642 *
643 * \param object_list list of LeptonObjects
644 * \param force_boundingbox Use the whole symbol bounding box to
645 * find pin connection points.
646 */
647 void
lepton_pin_object_update_whichend(GList * object_list,gboolean force_boundingbox)648 lepton_pin_object_update_whichend (GList *object_list,
649 gboolean force_boundingbox)
650 {
651 LeptonObject *o_current;
652 GList *iter;
653 GList *pin_list = NULL;
654 int top = 0, left = 0;
655 int right = 0, bottom = 0;
656 int d1, d2, d3, d4;
657 int min0, min1;
658 int min0_whichend, min1_whichend;
659
660 /* No objects, nothing to update. */
661 if (object_list == NULL) return;
662
663 for (iter = object_list;
664 iter != NULL;
665 iter = g_list_next (iter)) {
666 o_current = (LeptonObject *)iter->data;
667 if (lepton_object_is_pin (o_current))
668 {
669 pin_list = g_list_prepend (pin_list, o_current);
670 }
671 }
672
673 /* No pins, nothing to update. */
674 if (pin_list == NULL) return;
675
676 if (force_boundingbox) {
677 /* Include text objects since we need full bounds. */
678 world_get_object_glist_bounds (object_list,
679 /* Never consider hidden text. */
680 FALSE,
681 &left,
682 &top,
683 &right,
684 &bottom);
685 } else {
686 /* Only look at the pins to calculate symbol bounds. */
687 world_get_object_glist_bounds (pin_list,
688 FALSE,
689 &left,
690 &top,
691 &right,
692 &bottom);
693 }
694
695 iter = pin_list;
696 while (iter != NULL) {
697 o_current = (LeptonObject *)iter->data;
698 /* Determine which end of the pin is on or nearest the boundary */
699 if (o_current->whichend == -1) {
700 if (o_current->line->y[0] == o_current->line->y[1]) {
701 /* horizontal */
702
703 d1 = abs(o_current->line->x[0] - left);
704 d2 = abs(o_current->line->x[1] - left);
705 d3 = abs(o_current->line->x[0] - right);
706 d4 = abs(o_current->line->x[1] - right);
707
708 if (d1 <= d2) {
709 min0 = d1;
710 min0_whichend = 0;
711 } else {
712 min0 = d2;
713 min0_whichend = 1;
714 }
715
716 if (d3 <= d4) {
717 min1 = d3;
718 min1_whichend = 0;
719 } else {
720 min1 = d4;
721 min1_whichend = 1;
722 }
723
724 if (min0 <= min1) {
725 o_current->whichend = min0_whichend;
726 } else {
727 o_current->whichend = min1_whichend;
728 }
729
730 } else if (o_current->line->x[0] == o_current->line->x[1]) {
731 /* vertical */
732
733 d1 = abs(o_current->line->y[0] - top);
734 d2 = abs(o_current->line->y[1] - top);
735 d3 = abs(o_current->line->y[0] - bottom);
736 d4 = abs(o_current->line->y[1] - bottom);
737
738 if (d1 <= d2) {
739 min0 = d1;
740 min0_whichend = 0;
741 } else {
742 min0 = d2;
743 min0_whichend = 1;
744 }
745
746 if (d3 <= d4) {
747 min1 = d3;
748 min1_whichend = 0;
749 } else {
750 min1 = d4;
751 min1_whichend = 1;
752 }
753
754 if (min0 <= min1) {
755 o_current->whichend = min0_whichend;
756 } else {
757 o_current->whichend = min1_whichend;
758 }
759 }
760 }
761 iter = g_list_next (iter);
762 }
763
764 g_list_free (pin_list);
765 }
766
767
768 /*! \brief Sets the type, and corresponding width of a pin
769 *
770 * \par Function Description
771 * Sets the pin's type and width to a particular style.
772 *
773 * \param [in] o_current The pin LeptonObject being modified
774 * \param [in] pin_type The new type of this pin
775 */
776 void
lepton_pin_object_set_type(LeptonObject * o_current,int pin_type)777 lepton_pin_object_set_type (LeptonObject *o_current,
778 int pin_type)
779 {
780 g_return_if_fail (lepton_object_is_pin (o_current));
781
782 lepton_object_emit_pre_change_notify (o_current);
783 switch (pin_type) {
784 default:
785 g_critical ("lepton_pin_object_set_type: Got invalid pin type %1$i\n", pin_type);
786 /* Fall through */
787 case PIN_TYPE_NET:
788 lepton_object_set_stroke_width (o_current, PIN_WIDTH_NET);
789 o_current->pin_type = PIN_TYPE_NET;
790 break;
791 case PIN_TYPE_BUS:
792 lepton_object_set_stroke_width (o_current, PIN_WIDTH_BUS);
793 o_current->pin_type = PIN_TYPE_BUS;
794 break;
795 }
796 lepton_object_emit_change_notify (o_current);
797 }
798