2 staff-side.cc -- implement Staff_side_element
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include <math.h> // ceil.
11 #include "side-position-interface.hh"
12 #include "staff-symbol.hh"
15 #include "dimensions.hh"
16 #include "dimension-cache.hh"
17 #include "staff-symbol-referencer.hh"
19 Side_position_interface::Side_position_interface (Score_element
const *e
)
21 elt_l_
= (Score_element
*)e
;
26 Side_position_interface::add_support (Score_element
*e
)
28 SCM sup
= elt_l_
->get_elt_property ("side-support");
29 elt_l_
->set_elt_property ("side-support",
30 gh_cons (e
->self_scm_
,sup
));
36 Side_position_interface::get_direction () const
38 SCM d
= elt_l_
->get_elt_property ("direction");
40 return to_dir (d
) ? to_dir (d
) : DOWN
;
42 Direction relative_dir
= UP
;
43 SCM reldir
= elt_l_
->get_elt_property ("side-relative-direction"); // should use a lambda.
46 relative_dir
= to_dir (reldir
);
49 SCM other_elt
= elt_l_
->get_elt_property ("direction-source");
50 Score_element
* e
= unsmob_element(other_elt
);
53 return (Direction
)(relative_dir
* Side_position_interface (e
).get_direction ());
60 Callback that does the aligning.
63 Side_position_interface::side_position (Dimension_cache
const * c
)
65 Score_element
* me
= dynamic_cast<Score_element
*> (c
->element_l ());
68 Axis axis
= c
->axis ();
69 Score_element
*common
= me
->parent_l (axis
);
70 SCM support
= me
->get_elt_property ("side-support");
71 for (SCM s
= support
; s
!= SCM_EOL
; s
= gh_cdr (s
))
73 Score_element
* e
= unsmob_element ( gh_car (s
));
75 common
= common
->common_refpoint (e
, axis
);
78 for (SCM s
= support
; s
!= SCM_EOL
; s
= gh_cdr (s
))
81 Score_element
* e
= unsmob_element ( gh_car (s
));
84 Real coord
= e
->relative_coordinate (common
, axis
);
86 dim
.unite (coord
+ e
->extent (axis
));
95 Real off
= me
->parent_l (axis
)->relative_coordinate (common
, axis
);
98 Direction dir
= Side_position_interface (me
).get_direction ();
100 SCM pad
= me
->remove_elt_property ("padding");
101 if (gh_number_p (pad
))
103 off
+= gh_scm2double (pad
) * dir
;
105 Real total_off
= dim
[dir
] + off
;
107 if (fabs (total_off
) > 100 CM
)
108 programming_error ("Huh ? Improbable staff side dim.");
114 Side_position_interface::self_alignment (Dimension_cache
const *c
)
116 String
s ("self-alignment-");
117 Axis ax
= c
->axis ();
118 s
+= (ax
== X_AXIS
) ? "X" : "Y";
119 Score_element
*elm
= dynamic_cast<Score_element
*> (c
->element_l ());
120 SCM
align (elm
->get_elt_property (s
));
123 Direction d
= to_dir (align
);
124 Interval
ext(elm
->extent (ax
));
129 return - ext
.center ();
137 directed_round (Real f
, Direction d
)
146 Side_position_interface::quantised_position (Dimension_cache
const *c
)
148 Score_element
* me
= dynamic_cast<Score_element
*> (c
->element_l ());
149 Side_position_interface
s(me
);
150 Direction d
= s
.get_direction ();
151 Staff_symbol_referencer_interface
si (me
);
153 if (si
.has_interface_b ())
155 Real p
= si
.position_f ();
156 Real rp
= directed_round (p
, d
);
165 return (rp
- p
) * si
.staff_space () / 2.0;
171 Side_position_interface::aligned_side (Dimension_cache
const *c
)
173 Score_element
* me
= dynamic_cast<Score_element
*> (c
->element_l ());
174 Side_position_interface
s(me
);
175 Direction d
= s
.get_direction ();
176 Axis ax
= c
->axis ();
177 Real o
= side_position (c
);
179 Interval iv
= me
->extent (ax
);
185 SCM pad
= me
->get_elt_property ("padding");
186 if (gh_number_p (pad
))
187 o
+= d
*gh_scm2double (pad
) ;
196 Side_position_interface::set_axis (Axis a
)
198 // prop transparent ?
199 if (elt_l_
->get_elt_property ("side-support") == SCM_UNDEFINED
)
200 elt_l_
->set_elt_property ("side-support" ,SCM_EOL
);
202 elt_l_
->dim_cache_
[a
]->off_callbacks_
.push (aligned_side
);
207 Side_position_interface::set_quantised (Axis a
)
209 Dimension_cache
* c
= elt_l_
->dim_cache_
[a
];
211 c
->off_callbacks_
.push (quantised_position
);
215 Side_position_interface::get_axis () const
217 Dimension_cache
* c
= elt_l_
->dim_cache_
[X_AXIS
];
218 for (int i
=0 ; i
< c
->off_callbacks_
.size();i
++)
219 if (c
->off_callbacks_
[i
] == side_position
220 ||c
->off_callbacks_
[i
] == aligned_side
)
228 Side_position_interface::set_direction (Direction d
)
230 elt_l_
->set_elt_property ("direction", gh_int2scm (d
));
234 Side_position_interface::has_interface_b () const
236 return elt_l_
->get_elt_property ("side-support") != SCM_UNDEFINED
;
240 Side_position_interface::supported_b () const
242 SCM s
=elt_l_
->get_elt_property ("side-support");
243 return s
!= SCM_UNDEFINED
&& s
!= SCM_EOL
;