]> git.donarmstrong.com Git - lilypond.git/blob - lily/tuplet-spanner.cc
release: 1.3.18
[lilypond.git] / lily / tuplet-spanner.cc
1 /*
2   plet-spanner.cc -- implement Tuplet_spanner
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--1999 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "beam.hh"
10 #include "box.hh"
11 #include "debug.hh"
12 #include "lookup.hh"
13 #include "molecule.hh"
14 #include "paper-column.hh"
15 #include "paper-def.hh"
16 #include "tuplet-spanner.hh"
17 #include "stem.hh"
18 #include "note-column.hh"
19 #include "dimensions.hh"
20 #include "group-interface.hh"
21 #include "directional-element-interface.hh"
22
23
24
25 Tuplet_spanner::Tuplet_spanner ()
26 {
27   set_elt_property ("beams", SCM_EOL);
28   set_elt_property ("columns", SCM_EOL);  
29 }
30
31 /*
32   TODO. 
33  */
34 Molecule*
35 Tuplet_spanner::do_brew_molecule_p () const
36 {
37   Molecule* mol_p = new Molecule;
38
39   // Default behaviour: number always, bracket when no beam!
40   bool par_beam = to_boolean (get_elt_property ("parallel-beam"));
41   bool bracket_visibility = !par_beam;
42   bool number_visibility = true;
43   SCM visibility_sym =get_elt_property ("tuplet-visibility");
44   if (gh_number_p (visibility_sym))
45     {
46       /*
47         ARG. Fixme.
48        */
49       
50       /* Property values:
51          0       show nothing
52          1       show number
53          2       show (number and bracket)-if-no-beam
54          3       show number, and bracket-if-no-beam
55          4       show number, and bracket
56       */
57       int value = gh_scm2int ((visibility_sym));
58       bracket_visibility = (value == 4 || (value > 1 && !par_beam));
59       number_visibility = (value > 2 || value == 1 || 
60                            (value == 2 && !par_beam));
61     }
62   
63   if (gh_pair_p (get_elt_property ("columns")))
64     {
65       Link_array<Note_column> column_arr=
66         Group_interface__extract_elements (this, (Note_column*)0, "columns");
67         
68       Real ncw = column_arr.top ()->extent(X_AXIS).length ();
69       Real w = spanner_length () + ncw;
70
71
72       Real staff_space = paper_l ()->get_var ("interline");
73       
74
75       Direction dir = directional_element (this).get ();
76       Real dy = column_arr.top ()->extent (Y_AXIS) [dir]
77             - column_arr[0]->extent (Y_AXIS) [dir];
78       
79
80       SCM number = get_elt_property ("text");
81       if (gh_string_p (number))
82         {
83
84           Molecule
85             num (lookup_l ()->text ("italic",
86                                     ly_scm2string (number), paper_l ()));
87           num.align_to (X_AXIS, CENTER);
88           num.translate_axis (w/2, X_AXIS);
89           num.align_to (Y_AXIS, CENTER);
90           num.translate_axis (dir * staff_space, Y_AXIS);
91         
92           num.translate_axis (dy/2, Y_AXIS);
93
94           mol_p->add_molecule (num);
95         }
96       
97       Real thick = paper_l ()->get_var ("tuplet_thick");
98       if (bracket_visibility)      
99         {
100           Real gap = paper_l () -> get_var ("tuplet_spanner_gap");
101         
102           mol_p->add_molecule (lookup_l ()->tuplet_bracket (dy, w, thick, gap, staff_space, dir));
103         }
104
105       mol_p->translate_axis (dir * staff_space, Y_AXIS);
106     }
107   return mol_p;
108 }
109   
110 void
111 Tuplet_spanner::do_add_processing ()
112 {
113   if (gh_pair_p (get_elt_property ("columns")))
114     {
115       Link_array<Note_column> column_arr=
116         Group_interface__extract_elements (this, (Note_column*)0, "columns");
117       
118       set_bounds (LEFT, column_arr[0]);
119       set_bounds (RIGHT, column_arr.top ());  
120     }
121 }
122   
123 void
124 Tuplet_spanner::do_post_processing ()
125 {
126   Link_array<Note_column> column_arr=
127     Group_interface__extract_elements (this, (Note_column*)0, "columns");
128       
129
130   Direction d =   directional_element (this).get ();
131   if (!d)
132     {
133       d = UP;
134       directional_element (this).set (d);
135     }
136   
137   if (column_arr.size())
138     translate_axis (column_arr[0]->extent (Y_AXIS)[d], Y_AXIS);
139
140   
141   if (scm_ilength (get_elt_property ("beams")) == 1)
142     {
143       SCM bs = get_elt_property ("beams");
144       Score_element *b = unsmob_element (gh_car (bs));
145       Beam * beam_l = dynamic_cast<Beam*> (b);
146       if (!broken_b () 
147           && spanned_drul_[LEFT]->column_l () == beam_l->spanned_drul_[LEFT]->column_l ()
148           && spanned_drul_[RIGHT]->column_l () == beam_l->spanned_drul_[RIGHT]->column_l ())
149         set_elt_property ("parallel-beam", SCM_BOOL_T);
150     }
151 }
152
153
154 Direction
155 Tuplet_spanner::get_default_dir () const
156 {
157   Direction d = UP;
158   SCM dir_sym =get_elt_property ("dir-forced");
159   if (gh_number_p (dir_sym))
160     {
161       d= (Direction) gh_scm2int (dir_sym);
162       if (d != CENTER)
163         return d;
164     }
165
166   for (SCM s = get_elt_property ("columns"); gh_pair_p (s); s = gh_cdr (s))
167     {
168       Score_element * sc = unsmob_element (gh_car (s));
169       Note_column * nc = dynamic_cast<Note_column*> (sc);
170       if (nc->dir () < 0) 
171         {
172           d = DOWN;
173           break;
174         }
175     }
176   
177   return d;
178 }
179
180 void
181 Tuplet_spanner::add_beam (Beam *b)
182 {
183   add_dependency (b);
184   Group_interface gi (this, "beams");
185   gi.add_element (b);
186 }
187
188 void
189 Tuplet_spanner::add_column (Note_column*n)
190 {
191   Group_interface gi (this, "columns");
192   gi.add_element (n);
193
194   add_dependency (n);
195 }
196
197