]> git.donarmstrong.com Git - lilypond.git/blob - lily/note-column.cc
2d20c48a190229032bb98897a24f6bccb28794ea
[lilypond.git] / lily / note-column.cc
1 /*
2   note-column.cc -- implement Note_column
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8 #include <math.h>               // ceil
9
10 #include "axis-group-interface.hh"
11 #include "note-column.hh"
12 #include "stem.hh"
13 #include "debug.hh"
14 #include "paper-def.hh"
15 #include "group-interface.hh"
16 #include "staff-symbol-referencer.hh"
17
18 bool
19 Note_column::rest_b () const
20 {
21   return unsmob_element (get_elt_pointer ("rest"));
22 }
23
24 int
25 Note_column::shift_compare (Note_column *const &p1, Note_column*const&p2)
26 {
27   SCM s1 = p1->get_elt_property ("horizontal-shift");
28   SCM s2 = p2->get_elt_property ("horizontal-shift");
29
30   int h1 = (gh_number_p (s1))?  gh_scm2int (s1) :0;
31   int h2 = (gh_number_p (s2)) ? gh_scm2int (s2):0;
32   return h1 - h2;
33 }
34
35 Note_column::Note_column( SCM s)
36   : Item (s)
37 {
38   set_elt_pointer ("note-heads", SCM_EOL);  
39   Axis_group_interface (this).set_interface ();
40   Axis_group_interface (this).set_axes (X_AXIS, Y_AXIS);
41   Group_interface (this, "interfaces").add_thing (ly_symbol2scm ("Note_column"));
42 }
43
44 Stem *
45 Note_column::stem_l () const
46 {
47   SCM s = get_elt_pointer ("stem");
48   return dynamic_cast<Stem*> (unsmob_element (s));
49 }
50
51   
52 Slice
53 Note_column::head_positions_interval(Score_element *me)
54 {
55   Slice  iv;
56
57   iv.set_empty ();
58
59   SCM h = me->get_elt_pointer ("note-heads");
60   for (; gh_pair_p (h); h = gh_cdr (h))
61     {
62       Score_element *se = unsmob_element (gh_car (h));
63       Staff_symbol_referencer_interface si (se); 
64       
65       int j = int (si.position_f ());
66       iv.unite (Slice (j,j));
67     }
68   return iv;
69 }
70
71 Direction
72 Note_column::static_dir (Score_element*  me)
73 {
74   Score_element *stem = unsmob_element (me->get_elt_pointer ("stem"));
75   if (dynamic_cast<Stem*> (stem))
76     return dynamic_cast<Stem*> (stem)->get_direction ();
77   else if (gh_pair_p (me->get_elt_pointer ("note-heads")))
78     return (Direction)sign (head_positions_interval (me).center ());
79
80   programming_error ("Note column without heads and stem!");
81   return CENTER;
82 }
83
84
85 Direction
86 Note_column::dir () const
87 {
88   return static_dir ((Score_element*) this);
89 }
90
91 void
92 Note_column::set_stem (Score_element * stem_l)
93 {
94   set_elt_pointer ("stem", stem_l->self_scm_);
95
96   add_dependency (stem_l);
97   Axis_group_interface (this).add_element (stem_l);
98 }
99
100 void
101 Note_column::add_head (Score_element *h)
102 {
103   if (to_boolean (h->get_elt_property ("rest-interface")))
104     {
105       this->set_elt_pointer ("rest", h->self_scm_);
106     }
107   else if (to_boolean (h->get_elt_property ("note-head-interface")))
108     {
109       Pointer_group_interface gi (this, "note-heads");
110       gi.add_element (h);
111     }
112   Axis_group_interface (this).add_element (h);
113 }
114
115 /**
116   translate the rest symbols vertically by amount DY_I.
117  */
118 void
119 Note_column::translate_rests (int dy_i)
120 {
121   Score_element * r = unsmob_element (get_elt_pointer ("rest"));
122   if (r)
123     {
124       Staff_symbol_referencer_interface si (r);
125       r->translate_axis (dy_i * si.staff_space ()/2.0, Y_AXIS);
126     }
127 }
128
129
130 void
131 Note_column::set_dotcol (Score_element *d)
132 {
133   Axis_group_interface (this).add_element (d);
134 }
135
136
137
138 Interval
139 Note_column::rest_dim () const
140 {
141   Score_element * r = unsmob_element (get_elt_pointer ("rest"));
142   return r->extent (Y_AXIS);
143 }
144
145 Rhythmic_head*
146 Note_column::first_head () const
147 {
148   Stem * st = stem_l ();
149   return st?  st->first_head (): 0; 
150 }