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>
10 #include "staff-side.hh"
11 #include "staff-symbol.hh"
14 #include "dimensions.hh"
15 #include "dimension-cache.hh"
17 Side_position_interface::Side_position_interface (Score_element
*e
)
24 Side_position_interface::add_support (Score_element
*e
)
26 SCM sup
= elt_l_
->get_elt_property ("side-support");
27 elt_l_
->set_elt_property ("side-support",
28 gh_cons (e
->self_scm_
,sup
));
34 Side_position_interface::get_direction () const
36 SCM d
= elt_l_
->get_elt_property ("direction");
38 return to_dir (d
) ? to_dir (d
) : DOWN
;
40 Direction relative_dir
= UP
;
41 SCM reldir
= elt_l_
->get_elt_property ("side-relative-direction"); // should use a lambda.
44 relative_dir
= to_dir (reldir
);
47 SCM other_elt
= elt_l_
->get_elt_property ("direction-source");
48 Score_element
* e
= unsmob_element(other_elt
);
51 return relative_dir
* Side_position_interface (e
).get_direction ();
58 Callback that does the aligning.
61 Side_position_interface::side_position (Dimension_cache
const * c
)
63 Score_element
* me
= dynamic_cast<Score_element
*> (c
->element_l ());
66 Axis axis
= c
->axis ();
67 Score_element
*common
= me
->parent_l (axis
);
68 SCM support
= me
->get_elt_property ("side-support");
69 for (SCM s
= support
; s
!= SCM_EOL
; s
= gh_cdr (s
))
71 Score_element
* e
= unsmob_element ( gh_car (s
));
73 common
= common
->common_refpoint (e
, axis
);
76 for (SCM s
= support
; s
!= SCM_EOL
; s
= gh_cdr (s
))
79 Score_element
* e
= unsmob_element ( gh_car (s
));
82 Real coord
= e
->relative_coordinate (common
, axis
);
84 dim
.unite (coord
+ e
->extent (axis
));
93 Real off
= me
->parent_l (axis
)->relative_coordinate (common
, axis
);
96 Direction dir
= Side_position_interface (me
).get_direction ();
98 SCM pad
= me
->remove_elt_property ("padding");
99 if (pad
!= SCM_UNDEFINED
)
101 off
+= gh_scm2double (pad
) * dir
;
103 Real total_off
= dim
[dir
] + off
;
105 if (fabs (total_off
) > 100 CM
)
106 programming_error ("Huh ? Improbable staff side dim.");
112 Side_position_interface::self_alignment (Dimension_cache
const *c
)
114 String
s ("self-alignment-");
115 Axis ax
= c
->axis ();
116 s
+= (ax
== X_AXIS
) ? "X" : "Y";
117 Score_element
*elm
= dynamic_cast<Score_element
*> (c
->element_l ());
118 SCM
align (elm
->get_elt_property (s
));
121 Direction d
= to_dir (align
);
122 Interval
ext(elm
->extent (ax
));
127 return - ext
.center ();
135 directed_round (Real f
, Direction d
)
144 Side_position_interface::quantised_position (Dimension_cache
const *c
)
146 Score_element
* me
= dynamic_cast<Score_element
*> (c
->element_l ());
147 Side_position_interface
s(me
);
148 Direction d
= s
.get_direction ();
150 Staff_symbol_referencer
*ref
= dynamic_cast<Staff_symbol_referencer
*> (me
);
153 Real p
= ref
->position_f ();
154 Real rp
= directed_round (d
, p
);
163 return (rp
- p
) * ref
->staff_line_leading_f ();
169 Side_position_interface::aligned_side (Dimension_cache
const *c
)
171 Score_element
* me
= dynamic_cast<Score_element
*> (c
->element_l ());
172 Side_position_interface
s(me
);
173 Direction d
= s
.get_direction ();
174 Axis ax
= c
->axis ();
175 Real o
= side_position (c
);
177 Interval iv
= me
->extent (ax
);
183 SCM pad
= me
->get_elt_property ("padding");
184 if (gh_number_p (pad
))
185 o
+= d
*gh_scm2double (pad
) ;
194 Side_position_interface::set_axis (Axis a
)
196 // prop transparent ?
197 if (elt_l_
->get_elt_property ("side-support") == SCM_UNDEFINED
)
198 elt_l_
->set_elt_property ("side-support" ,SCM_EOL
);
200 elt_l_
->dim_cache_
[a
]->off_callbacks_
.push (aligned_side
);
205 Side_position_interface::set_quantised (Axis a
)
207 Dimension_cache
* c
= elt_l_
->dim_cache_
[a
];
208 for (int i
=0; i
< c
->off_callbacks_
.size (); i
++)
209 if (c
->off_callbacks_
[i
] == aligned_side
)
210 c
->off_callbacks_
[i
] = side_position
;
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::is_staff_side_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
;