2 note-column.cc -- implement Note_column
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 #include <math.h> // ceil
10 #include "axis-group-interface.hh"
11 #include "note-column.hh"
14 #include "paper-def.hh"
15 #include "group-interface.hh"
16 #include "staff-symbol-referencer.hh"
18 #include "note-head.hh"
19 #include "accidental-placement.hh"
22 TODO: figure out if we can prune this class. This is just an
23 annoying layer between (rest)collision & (note-head + stem)
27 Note_column::has_rests (Grob
*me
)
29 return unsmob_grob (me
->get_property ("rest"));
33 Note_column::shift_compare (Grob
*const &p1
, Grob
*const&p2
)
35 SCM s1
= p1
->get_property ("horizontal-shift");
36 SCM s2
= p2
->get_property ("horizontal-shift");
38 int h1
= (ly_number_p (s1
))? ly_scm2int (s1
) :0;
39 int h2
= (ly_number_p (s2
)) ? ly_scm2int (s2
):0;
44 Note_column::get_stem (Grob
*me
)
46 SCM s
= me
->get_property ("stem");
47 return unsmob_item (s
);
51 Note_column::head_positions_interval (Grob
*me
)
57 SCM h
= me
->get_property ("note-heads");
58 for (; ly_pair_p (h
); h
= ly_cdr (h
))
60 Grob
*se
= unsmob_grob (ly_car (h
));
62 int j
= Staff_symbol_referencer::get_rounded_position (se
);
63 iv
.unite (Slice (j
,j
));
69 Note_column::dir (Grob
* me
)
71 Grob
*stem
= unsmob_grob (me
->get_property ("stem"));
72 if (stem
&& Stem::has_interface (stem
))
73 return Stem::get_direction (stem
);
74 else if (ly_pair_p (me
->get_property ("note-heads")))
75 return (Direction
)sign (head_positions_interval (me
).center ());
77 programming_error ("Note column without heads and stem!");
83 Note_column::set_stem (Grob
*me
,Grob
* stem
)
85 me
->set_property ("stem", stem
->self_scm ());
86 me
->add_dependency (stem
);
87 Axis_group_interface::add_element (me
, stem
);
92 Note_column::get_rest (Grob
*me
)
94 return unsmob_grob (me
->get_property ("rest"));
98 Note_column::add_head (Grob
*me
,Grob
*h
)
101 if (Rest::has_interface (h
))
103 if (ly_pair_p (me
->get_property ("note-heads")))
106 me
->set_property ("rest", h
->self_scm ());
108 else if (Note_head::has_interface (h
))
110 if (unsmob_grob (me
->get_property ("rest")))
112 Pointer_group_interface::add_grob (me
, ly_symbol2scm ("note-heads"),h
);
116 me
->warning ("Can't have rests and note heads together on a stem.");
118 Axis_group_interface::add_element (me
, h
);
122 translate the rest symbols vertically by amount DY, but only if
123 they have no staff-position set.
126 Note_column::translate_rests (Grob
*me
, int dy
)
128 Grob
* r
= unsmob_grob (me
->get_property ("rest"));
129 if (r
&& !ly_number_p (r
->get_property ("staff-position")))
131 r
->translate_axis (dy
* Staff_symbol_referencer::staff_space (r
)/2.0, Y_AXIS
);
137 Note_column::set_dotcol (Grob
*me
,Grob
*d
)
139 Axis_group_interface::add_element (me
, d
);
146 Note_column::first_head (Grob
*me
)
148 Grob
* st
= get_stem (me
);
149 return st
? Stem::first_head (st
): 0;
154 Return the first Accidentals grob that we find in a note-head.
157 Note_column::accidentals (Grob
*me
)
159 SCM heads
= me
->get_property ("note-heads");
161 for (;ly_pair_p (heads
); heads
=ly_cdr (heads
))
163 Grob
* h
= unsmob_grob (ly_car (heads
));
164 acc
= h
? unsmob_grob (h
->get_property ("accidental-grob")) : 0;
172 if (Accidental_placement::has_interface (acc
->get_parent (X_AXIS
)))
173 return acc
->get_parent (X_AXIS
);
181 ADD_INTERFACE (Note_column
,"note-column-interface",
182 "Stem and noteheads combined",
183 "arpeggio note-heads rest-collision rest horizontal-shift stem accidentals force-hshift");