1 ;;; gEDA - GPL Electronic Design Automation
2 ;;; gschem - gEDA Schematic Capture
3 ;;; Copyright (C) 1998-2010 Ales Hvezda
4 ;;; Copyright (C) 1998-2020 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., 51 Franklin Street, Fifth Floor, Boston,
19 ;;; MA 02111-1301 USA.
21 (use-modules (ice-9 regex)
24 ;; --------------------------------------------------------------------------
26 ;; Code to place new text attributes automatically
27 ;; written by Carlos Nieves Onega starts here.
30 ; Copyright (C) 2006 Carlos Nieves Onega
32 ; Given a bound, defined as a list of the form ( (x1 x2) (y1 y2) ) with:
33 ; - (x1, y1): bottom left corner.
34 ; - (x2, y2): upper right corner.
36 ; - The minimum x value if point is "min-x".
37 ; - The maximum x value if point is "max-x".
38 ; - The minimum y value if point is "min-y".
39 ; - The maximum y value if point is "max-y".
40 (define get-point-of-bound
42 (if (string=? point "min-x")
43 (min (car (car bound))
45 (if (string=? point "max-x")
46 (max (car (car bound))
48 (if (string=? point "min-y")
49 (min (car (cdr bound))
51 (if (string=? point "max-y")
52 (max (car (cdr bound))
55 "get-point-of-bound : Unknown point to get: "
59 ; This function returns the pin direction of the pin object parameter.
60 ; It returns a one character string: "^", "v", "<" or ">". The arrow
61 ; points the pin's end, which is NOT the active connection end.
62 ; This function takes care of the pin's whichend property: if it's 1,
63 ; then the pin ends should be reversed.
64 (define get-pin-direction
66 (let* ( (pin-ends (get-pin-ends pin))
67 (pin-beginning (car pin-ends))
68 (pin-end (cdr pin-ends)) )
70 (if (eq? (car pin-beginning) (car pin-end) )
71 (if (<= (cdr pin-beginning) (cdr pin-end))
72 ; The x coords are equal. The pin is vertical.
75 (if (<= (car pin-beginning) (car pin-end))
76 ; The x coords are not equal. The pin is horizontal.
80 ; This function returns the net direction of the net object parameter.
81 ; It returns a string :
83 ; "<>": horizontal net
84 (define get-net-connection-sides
86 (let ( (bounds (get-object-bounds object (list "all") (list)))
89 (if (or (char=? (get-object-type object) OBJ_NET)
90 (char=? (get-object-type object) OBJ_BUS))
91 (let ( ; Get the net bounds without the attribute
92 (min-x (get-point-of-bound "min-x" bounds))
93 (max-x (get-point-of-bound "max-x" bounds))
94 (min-y (get-point-of-bound "min-y" bounds))
95 (max-y (get-point-of-bound "max-y" bounds))
97 ; Line's width needs to be considered here.
98 (if (eq? (- max-x min-x) (get-line-width object))
99 ; If the x bounds are the same, this is a vertical segment.
101 (if (eq? (- max-y min-y) (get-line-width object))
102 ; If the y bounds are, this is a horizontal segment.
104 ; X or Y bounds are not the same. We don't know.
106 (display "Warning: get-net-connection-sides: Can't guess net direction.\n")
111 ; This is not a OBJ_NET object. Return an empty list.
119 ; This function returns a list with the end coordinate of the pins,
120 ; if they are in the desired side.
121 ; - desired_side: is a one character string: "^", "v", "<" or ">".
122 ; - coordinate: is a one character string:
123 ; - "B" if the pin beginnings are desired.
124 ; - "E" if the pin ends are desired.
125 (define get-bound-of-pins
126 (lambda (desired_side coordinate pins)
127 (if (eq? (length pins) 0)
129 (let* ( (pin (car pins))
130 (pin-ends (get-pin-ends pin))
131 (pin-beginning (car pin-ends))
132 (pin-end (cdr pin-ends))
135 (if (string=? (get-pin-direction pin) desired_side)
136 (if (string=? coordinate "B")
137 (cons (car pin-beginning)
139 (get-bound-of-pins desired_side
142 (if (string=? coordinate "E")
143 (cons (cdr pin-beginning)
145 (get-bound-of-pins desired_side
148 (error (string-append
149 "get-bound-of-pin : Unknown coordinate: "
151 (get-bound-of-pins desired_side coordinate (cdr pins))))
155 ; This function returns the bounds of the pins in the given side of the object
156 ; The side is a one character string: "^", "v", "<" or ">". The arrow
157 ; points the pin's end, which is NOT the active connection end.
158 (define get-bounds-of-pins-in-side
159 (lambda (object desired_side)
160 (let* ( (pins (get-object-pins object))
161 (pins-beginning (get-bound-of-pins desired_side "B" pins))
162 (pins-beginning-sorted (if (eq? (length pins-beginning) 0)
164 (stable-sort pins-beginning <)))
165 (pins-end (get-bound-of-pins desired_side "E" pins))
166 (pins-end-sorted (if (eq? (length pins-end) 0)
168 (stable-sort pins-end <)))
171 (if (or (eq? (length pins-beginning-sorted) 0)
172 (eq? (length pins-end-sorted) 0))
174 (let* ( (min-x (car pins-beginning-sorted))
175 (max-x (list-ref pins-beginning-sorted
176 (- (length pins-beginning-sorted) 1)))
177 (min-y (car pins-end-sorted))
178 (max-y (list-ref pins-end-sorted
179 (- (length pins-end-sorted) 1))))
180 (cons (cons min-x max-x) (cons min-y max-y)))
184 ; This function returns the bounds of the pins in the given side of the object
185 ; The side is a one character string: "^", "v", "<" or ">". The arrow
186 ; points the pin's end, which is NOT the active connection end.
187 (define get-bounds-of-pins-with-attribs-in-side
188 (lambda (object desired_side)
189 (define get-bound-of-list-of-pins-with-attribs
190 (lambda (bounds desired-side pin-list)
194 (let* ( (pin (car pin-list))
195 (pin-direction (get-pin-direction pin))
196 (pin-bounds (get-object-bounds pin (list) (list)))
201 (if (string=? pin-direction desired-side)
205 (set! old-bounds pin-bounds)
207 (if (not (null? pin-bounds))
210 (min (get-point-of-bound
214 (max (get-point-of-bound
217 "max-x" old-bounds)))
219 (min (get-point-of-bound
223 (max (get-point-of-bound
226 "max-y" old-bounds))))))))
227 (get-bound-of-list-of-pins-with-attribs
228 new-bounds desired-side (cdr pin-list))
231 (get-bound-of-list-of-pins-with-attribs
234 (get-object-pins object))
237 ; Check if a point (x,y) if inside a region with the given bounds.
238 ; - bounds is a list of the form ( (x1 x2) (y1 y2) ) with:
239 ; - (x1, y1): bottom left corner.
240 ; - (x2, y2): upper right corner.
241 ; Return true if the point is inside the region, or false otherwise.
242 (define inside-region
244 (let* ( (right (get-point-of-bound "max-x" bounds))
245 (left (get-point-of-bound "min-x" bounds))
246 (top (get-point-of-bound "max-y" bounds))
247 (bottom (get-point-of-bound "min-y" bounds))
248 (collision (and (>= x left) (<= x right) (<= y top) (>= y bottom)))
253 ; Chech if two regions are overlapping.
254 ; Each bound is defined as a list of the form ( (x1 x2) (y1 y2) ) with:
255 ; - (x1, y1): bottom left corner.
256 ; - (x2, y2): upper right corner.
257 ; Return true if the regions are overlapping, or false otherwise.
258 (define check-collision-of-bounds
259 (lambda (bounds1 bounds2)
260 (let* ( (bounds1_x1 (get-point-of-bound "min-x" bounds1))
261 (bounds1_x2 (get-point-of-bound "max-x" bounds1))
262 (bounds1_y1 (get-point-of-bound "min-y" bounds1))
263 (bounds1_y2 (get-point-of-bound "max-y" bounds1))
265 (bounds2_x1 (get-point-of-bound "min-x" bounds2))
266 (bounds2_x2 (get-point-of-bound "max-x" bounds2))
267 (bounds2_y1 (get-point-of-bound "min-y" bounds2))
268 (bounds2_y2 (get-point-of-bound "max-y" bounds2))
272 (or (inside-region bounds1 bounds2_x1 bounds2_y1)
273 (inside-region bounds1 bounds2_x2 bounds2_y2)
274 (inside-region bounds1 bounds2_x1 bounds2_y2)
275 (inside-region bounds1 bounds2_x2 bounds2_y1)
277 (inside-region bounds2 bounds1_x1 bounds1_y1)
278 (inside-region bounds2 bounds1_x2 bounds1_y2)
279 (inside-region bounds2 bounds1_x1 bounds1_y2)
280 (inside-region bounds2 bounds1_x2 bounds1_y1)
282 ; horizontal bounds or region 1 are within
283 ; horizontal bounds of region 2 and
284 ; vertical bounds of region 1 are within
285 ; vertical bounds of region 2
286 (and (< bounds1_x1 bounds2_x1)
287 (< bounds1_x1 bounds2_x2)
288 (> bounds1_x2 bounds2_x1)
289 (> bounds1_x2 bounds2_x2)
290 (> bounds1_y1 bounds2_y1)
291 (< bounds1_y2 bounds2_y2))
293 ; horizontal bounds or region 2 are within
294 ; horizontal bounds of region 1 and
295 ; vertical bounds of region 2 are within
296 ; vertical bounds of region 1
297 (and (< bounds2_x1 bounds1_x1)
298 (< bounds2_x1 bounds1_x2)
299 (> bounds2_x2 bounds1_x1)
300 (> bounds2_x2 bounds1_x2)
301 (> bounds2_y1 bounds1_y1)
302 (< bounds2_y2 bounds1_y2)))))))
304 ; Chech if the attribute bounds may overlap the net conections of
306 ; Each bound is defined as a list of the form ( (x1 x2) (y1 y2) ) with:
307 ; - (x1, y1): bottom left corner.
308 ; - (x2, y2): upper right corner.
309 ; Return true if the regions are overlapping, or false otherwise.
310 (define check-overlapping-of-pin-connections
311 (lambda (pins-bounds pin-direction attrib-bounds spacing)
312 (let* ( (pins-min-x (get-point-of-bound "min-x" pins-bounds))
313 (pins-max-x (get-point-of-bound "max-x" pins-bounds))
314 (pins-min-y (get-point-of-bound "min-y" pins-bounds))
315 (pins-max-y (get-point-of-bound "max-y" pins-bounds))
316 (attrib-min-x (get-point-of-bound "min-x" attrib-bounds))
317 (attrib-max-x (get-point-of-bound "max-x" attrib-bounds))
318 (attrib-min-y (get-point-of-bound "min-y" attrib-bounds))
319 (attrib-max-y (get-point-of-bound "max-y" attrib-bounds)) )
320 (if (string=? pin-direction "^")
321 (and (>= pins-min-y attrib-max-y)
322 (check-collision-of-bounds
323 ; Calcule the collision as if the attribute has the same
324 ; vertical coordinates as the pins (including spacing).
325 (cons (cons attrib-min-x attrib-max-x)
326 (cons pins-min-y pins-max-y))
327 (cons (cons (- pins-min-x spacing) (+ pins-max-x spacing))
328 (cons pins-min-y pins-max-y)) ) )
329 (if (string=? pin-direction "v")
330 (and (<= pins-max-y attrib-min-y)
331 (check-collision-of-bounds
332 ; Calcule the collision as if the attribute has the same
333 ; vertical coordinates as the pins (including spacing).
334 (cons (cons attrib-min-x attrib-max-x)
335 (cons pins-min-y pins-max-y))
336 (cons (cons (- pins-min-x spacing) (+ pins-max-x spacing))
337 (cons pins-min-y pins-max-y)) ) )
338 (if (string=? pin-direction "<")
339 (and (<= pins-max-x attrib-min-x)
340 (check-collision-of-bounds
341 ; Calcule the collision as if the attribute has
342 ; the same horizontal coordinates as the pins
343 ; (including spacing).
344 (cons (cons pins-min-x pins-max-x)
345 (cons attrib-min-y attrib-max-y))
346 (cons (cons pins-min-x
348 (cons (- pins-min-y spacing)
349 (+ pins-max-y spacing)) ) ) )
350 (if (string=? pin-direction ">")
351 (and (>= pins-min-x attrib-max-x)
352 (check-collision-of-bounds
353 ; Calcule the collision as if the attribute has
354 ; the same horizontal coordinates as the pins
355 ; (including spacing).
356 (cons (cons pins-min-x pins-max-x)
357 (cons attrib-min-y attrib-max-y))
358 (cons (cons pins-min-x
360 (cons (- pins-min-y spacing)
361 (+ pins-max-y spacing)) ) ) )
362 (error (string-append
363 "check-overlapping-of-pin-connections : Unknown pin-direction: "
364 pin-direction)))))))))
367 ; Given a coordinate, snap it to the nearest point in the grid.
368 (define snap-coord-to-grid
370 (if (> autoplace-attributes-grid 0)
372 (inexact->exact (* (floor (/ coord
373 autoplace-attributes-grid))
374 autoplace-attributes-grid))
375 (inexact->exact (* (ceiling (/ coord
376 autoplace-attributes-grid))
377 autoplace-attributes-grid)))
381 ; Given the new desired bounds of an object's attribute,
382 ; calcule the new bounds so the new position don't overlap with pins
384 ; Returns the new bounds of the attribute.
385 (define adjust-pos-to-avoid-collision
386 (lambda (new-attrib-bounds object move-direction spacing)
387 (let* ( (pin-directions-list (list ">" "<" "v" "^"))
388 (pin-directions-list-index 0)
389 (new-attrib-bounds-adjusted new-attrib-bounds)
392 ; For each pin-direction in the pin-directions-list, make a 2 pass loop.
393 ; The first one checks the attribute bounds with the pin bounds (without
394 ; attributes like pinname, pinnumber,...), and taking care of not overlap
395 ; the pin connections side, so the nets connecting to the pins don't
396 ; overlap the attribute.
397 ; The second one checks the attribute bounds with the pin bounds,
398 ; this time including all the pin attributes.
399 (while (<= pin-directions-list-index (- (length pin-directions-list) 1))
400 (let* ( (pin-direction (list-ref pin-directions-list
401 pin-directions-list-index))
404 (get-bounds-of-pins-in-side object pin-direction)
405 (get-bounds-of-pins-with-attribs-in-side
406 object pin-direction)))
411 (if (not (null? pins-bounds))
413 (check-overlapping-of-pin-connections
416 new-attrib-bounds-adjusted
418 (check-collision-of-bounds
419 new-attrib-bounds-adjusted
423 ; Calcule the offset for vertical pins.
424 (if (or (string=? pin-direction "^")
425 (string=? pin-direction "v") )
427 (if (string-index move-direction #\<)
429 (- (- (get-point-of-bound
432 2 (get-point-of-bound
434 new-attrib-bounds-adjusted)
436 spacing )) ;; add spacing
437 (if (string-index move-direction #\>)
439 (+ (- (get-point-of-bound
444 new-attrib-bounds-adjusted)
448 ; If the offset is zero, there is probably
449 ; an overlap with pin connections, so add
450 ; one grid spacing to the offset.
452 (if (string-index move-direction #\<)
454 autoplace-attributes-grid))
456 autoplace-attributes-grid))
459 ; Snap the offset to the grid.
460 (set! x_offset (snap-coord-to-grid x_offset))
462 ; Set the new attrib bounds.
463 (set! new-attrib-bounds-adjusted
464 (cons (cons (+ (get-point-of-bound
466 new-attrib-bounds-adjusted)
468 (+ (get-point-of-bound
470 new-attrib-bounds-adjusted)
472 (cons (get-point-of-bound
474 new-attrib-bounds-adjusted)
477 new-attrib-bounds-adjusted))))
479 ; Calcule the offset for horizontal pins.
480 (if (or (string=? pin-direction "<")
481 (string=? pin-direction ">") )
483 (if (string-index move-direction #\^)
486 (+ (- (get-point-of-bound
491 new-attrib-bounds-adjusted)
494 (if (string-index move-direction #\v)
497 (- (- (get-point-of-bound
502 new-attrib-bounds-adjusted))
505 ; If the offset is zero, there is probably
506 ; an overlap with pin connections, so add
507 ; one grid spacing to the offset.
509 (if (string-index move-direction #\v)
511 autoplace-attributes-grid))
513 autoplace-attributes-grid))
516 ; Snap the offset to the grid.
518 (snap-coord-to-grid y_offset))
520 ; Set the new attrib bounds.
521 (set! new-attrib-bounds-adjusted
523 (cons (get-point-of-bound
525 new-attrib-bounds-adjusted)
528 new-attrib-bounds-adjusted))
529 (cons (+ (get-point-of-bound
531 new-attrib-bounds-adjusted)
533 (+ (get-point-of-bound
535 new-attrib-bounds-adjusted)
540 (error "adjust-pos-to-avoid-collision: Wrong pin-direction format")
544 ; Update the index and pass number for the next loop.
545 (if (not (eq? pass 1))
547 (set! pin-directions-list-index
548 (+ pin-directions-list-index 1))
550 (set! pass (+ pass 1)))
553 new-attrib-bounds-adjusted
557 ; This function gets the reference point of an object.
558 ; The position string is the reference to return. It has the format:
559 ; "horizontal vertical", where:
560 ; - "horizontal" is one of the following: "Left", "Middle", "Right".
561 ; - "vertical" is one of the following: "Lower", "Middle", "Upper".
562 ; Example: "Lower Right".
563 (define (get-reference object position-string)
564 (if (not (string-index position-string #\ ))
565 (error "get-reference : Wrong reference format"))
566 (let* ( (object-type (get-object-type object))
567 ; Get the object bounds:
568 ; - If it's a pin: including everything.
569 ; - otherwise: without attributes neither pins.
570 (bounds (if (char=? object-type OBJ_PIN)
571 (get-object-bounds object (list "all") (list))
572 (get-object-bounds object (list "all")
573 (list (list->string (list OBJ_PIN)))))
575 (horiz-bounds (car bounds))
576 (vertical-bounds (cdr bounds))
577 (space-pos (string-index position-string #\ ))
578 (vertical-string (substring position-string 0 space-pos))
579 (horiz-string (substring position-string (+ space-pos 1)))
580 (horiz-pos (if (string=? horiz-string "Left")
581 (min (car horiz-bounds) (cdr horiz-bounds))
582 (if (string=? horiz-string "Middle")
583 (ceiling (/ (+ (car horiz-bounds)
584 (cdr horiz-bounds)) 2))
585 (if (string=? horiz-string "Right")
586 (max (car horiz-bounds) (cdr horiz-bounds))
587 (error (string-append
588 "get-reference : Unknown reference (horizontal): "
590 (vertical-pos (if (string=? vertical-string "Lower")
591 (min (car vertical-bounds) (cdr vertical-bounds))
592 (if (string=? vertical-string "Middle")
593 (ceiling (/ (+ (car vertical-bounds)
594 (cdr vertical-bounds)) 2))
595 (if (string=? vertical-string "Upper")
596 (max (car vertical-bounds)
597 (cdr vertical-bounds))
598 (error (string-append
599 "get-reference : Unknown reference (vertical): "
600 vertical-string)))))) )
601 (cons horiz-pos vertical-pos)))
604 ; Given a matching pattern and a list, return false if no member of the list
605 ; matches the pattern, or true if any does.
606 (define (list-string-match matching-pattern attributes_list)
607 (if (null? attributes_list)
609 (if (list? attributes_list)
610 (if (string-match matching-pattern (car attributes_list))
612 (list-string-match matching-pattern (cdr attributes_list)))
613 (if (string-match matching-pattern attributes_list)
618 ; Given an object and an attribute matching pattern, this function checks
619 ; if the object attributes match the pattern.
620 ; The attributes_list has the form ( [attribute-name attribute-pattern]* )
621 (define (check-object-attributes object attributes_list)
622 (if (null? attributes_list)
624 (if (< (length attributes_list) 2)
625 (error (string-append "check-object-attributes: Odd number in attributes list."))
626 (let* ( (attribute-name (car attributes_list))
627 (attribute-pattern (car (cdr attributes_list)))
628 (attribute-values (if (string=? attribute-name
632 (list (get-object-type object))))
633 (get-attrib-value-by-attrib-name
634 object attribute-name)))
637 (if (null? attribute-values)
639 (if (list-string-match attribute-pattern attribute-values)
640 (check-object-attributes object
641 (cdr (cdr attributes_list)))
653 ; This function sets the default parameters of each attribute,
654 ; provided it is specified in the default-position-of-text-attributes.
655 ; It gets the attrib name from the attribute and sets
656 ; the text properties as specified in default-position-of-text-attributes.
657 (define (set-default-position object attribute direction defaults)
660 (let* ( (attrib-name-value (get-attribute-name-value attribute))
661 (attrib-name (car attrib-name-value)) ; Attribute name
662 (default-def (car defaults)) ; Default definition
663 (def-attrib-name (list-ref default-def ; Default attrib name
664 def-attrib-name-pos))
665 (def-direction (list-ref default-def ; Default direction
666 def-direction-pos)) )
667 ; Check if the attribute's name and direction matches.
668 (if (and (string=? attrib-name def-attrib-name)
669 (string=? def-direction
671 (check-object-attributes object
672 (list-ref default-def ; attrib match
675 ; It matches, so change the text parameters
676 (let* ( (ref (get-reference object (list-ref default-def
678 (new-alignment (list-ref default-def
680 (new-angle (list-ref default-def
682 (new-color (list-ref default-def
684 (new-x (+ (list-ref default-def
687 (new-y (+ (list-ref default-def
690 (attrib-move-dir (list-ref default-def def-move-pos))
691 (attrib-spacing (abs (list-ref default-def
693 (new-attrib-bounds (calcule-new-attrib-bounds attribute
698 (new-attrib-bounds-adjusted
699 (adjust-pos-to-avoid-collision new-attrib-bounds
704 (if (null? new-attrib-bounds-adjusted)
706 (- (get-point-of-bound "min-x"
707 new-attrib-bounds-adjusted)
708 (get-point-of-bound "min-x" new-attrib-bounds))))
710 (if (null? new-attrib-bounds-adjusted)
712 (- (get-point-of-bound "min-y"
713 new-attrib-bounds-adjusted)
714 (get-point-of-bound "min-y" new-attrib-bounds))))
716 (set-attribute-text-properties! attribute
718 -1 ; keep previous size
723 (if (not (= new-color -1))
724 (set-object-color! attribute
730 (set-default-position object attribute direction
731 (cdr defaults)) ; process the rest
733 ) ; End of definition of set-default-position
735 ; This function processes the attribute list and calls
736 ; set-default-position for each attribute
737 (define autoplace-text
738 (lambda (object direction attrib-list)
739 (if (not (eq? (length attrib-list) 0))
741 (set-default-position object (car attrib-list) direction
742 default-position-of-text-attributes)
743 (autoplace-text object direction (cdr attrib-list))
744 )))) ; End of definition of autoplace-pin-text
747 ; Autoplace the attributes of the given pin object.
748 (define (autoplace-pin-attributes pin)
749 (let ((pin-direction (get-pin-direction pin))
750 (attribute-list (get-object-attributes pin)) )
751 (autoplace-text pin pin-direction attribute-list)))
754 ; Get the pin directions of the given list of pins.
755 ; It returns a list with all the pin directions of the pins.
756 (define get-pin-directions
758 (if (eq? (length pins) 0)
760 (cons (get-pin-direction (car pins))
761 (get-pin-directions (cdr pins))))))
763 ; Get the connection sides where there are pins.
764 ; The parameter pin-directions is a list with the directions of
765 ; all the pins. (As given by get-pin-directions).
766 ; It returns a string with the sides where there are pins.
767 ; It is needed that the return value doesn't depend on the order of the pins.
768 ; (Notice the arrow always points to the inside of the symbol).
769 ; Examples of return values: "<>^v", "<>", "^v".
770 (define get-connection-sides
771 (lambda (pin-directions)
772 (define (check-side side-list pin-directions)
773 (if (eq? (length side-list) 0)
775 (if (member (car side-list) pin-directions)
776 (string-append (car side-list)
777 (check-side (cdr side-list) pin-directions))
778 (check-side (cdr side-list) pin-directions))))
779 (check-side (list "<" ">" "^" "v") pin-directions)))
781 ; Autoplace the attributes of the given object.
782 ; This function gets some info of the object and calls autoplace-text.
783 (define (autoplace-object-attributes object)
784 (let* ((pin-list (get-object-pins object))
785 (pin-directions (get-pin-directions pin-list))
786 (connection-sides (if (or (char=? (get-object-type object)
788 (char=? (get-object-type object)
790 (get-net-connection-sides object)
791 (get-connection-sides pin-directions)))
792 (attribute-list (get-object-attributes object)) )
793 (autoplace-text object connection-sides attribute-list)))
797 ;; Code to place new text attributes automatically
798 ;; written by Carlos Nieves Onega ends here.
800 ;; --------------------------------------------------------------------------