]> git.donarmstrong.com Git - lilypond.git/blob - lily/tuplet-spanner.cc
release: 1.3.16
[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   /*
28     -> GUILE
29    */
30   parallel_beam_b_ = false;
31   set_elt_property ("beams", SCM_EOL);
32   set_elt_property ("columns", SCM_EOL);  
33 }
34
35 /*
36   TODO. 
37  */
38 Molecule*
39 Tuplet_spanner::do_brew_molecule_p () const
40 {
41   Molecule* mol_p = new Molecule;
42
43   // Default behaviour: number always, bracket when no beam!
44   bool bracket_visibility = !parallel_beam_b_;
45   bool number_visibility = true;
46   SCM visibility_sym =get_elt_property ("tuplet-visibility");
47   if (visibility_sym != SCM_UNDEFINED)
48     {
49       /*
50         ARG. Fixme.
51        */
52       
53       /* Property values:
54          0       show nothing
55          1       show number
56          2       show (number and bracket)-if-no-beam
57          3       show number, and bracket-if-no-beam
58          4       show number, and bracket
59       */
60       int value = gh_scm2int ((visibility_sym));
61       bracket_visibility = (value == 4 || (value > 1 && !parallel_beam_b_));
62       number_visibility = (value > 2 || value == 1 || 
63                            (value == 2 && !parallel_beam_b_));
64     }
65   
66   if (gh_pair_p (get_elt_property ("columns")))
67     {
68       Link_array<Note_column> column_arr=
69         Group_interface__extract_elements (this, (Note_column*)0, "columns");
70         
71       Real ncw = column_arr.top ()->extent(X_AXIS).length ();
72       Real w = spanner_length () + ncw;
73       Molecule num (lookup_l ()->text ("italic",
74                                        number_str_, paper_l ()));
75       num.align_to (X_AXIS, CENTER);
76       num.translate_axis (w/2, X_AXIS);
77       Real interline = paper_l ()->get_var ("interline");
78
79       Direction dir = directional_element (this).get ();
80       Real dy = column_arr.top ()->extent (Y_AXIS) [dir]
81         - column_arr[0]->extent (Y_AXIS) [dir];
82       num.align_to (Y_AXIS, CENTER);
83       num.translate_axis (dir * interline, Y_AXIS);
84         
85       num.translate_axis (dy/2, Y_AXIS);
86     
87       Real thick = paper_l ()->get_var ("tuplet_thick");
88       if (bracket_visibility)      
89         {
90           Real gap = paper_l () -> get_var ("tuplet_spanner_gap");
91         
92           mol_p->add_molecule (lookup_l ()->tuplet_bracket (dy, w, thick, gap, interline, dir));
93         }
94
95       if (number_visibility)
96         {
97           mol_p->add_molecule (num);
98         }
99       mol_p->translate_axis (dir * interline, Y_AXIS);
100     }
101   return mol_p;
102 }
103   
104 void
105 Tuplet_spanner::do_add_processing ()
106 {
107   if (gh_pair_p (get_elt_property ("columns")))
108     {
109       Link_array<Note_column> column_arr=
110         Group_interface__extract_elements (this, (Note_column*)0, "columns");
111       
112       set_bounds (LEFT, column_arr[0]);
113       set_bounds (RIGHT, column_arr.top ());  
114     }
115 }
116   
117 void
118 Tuplet_spanner::do_post_processing ()
119 {
120   Link_array<Note_column> column_arr=
121     Group_interface__extract_elements (this, (Note_column*)0, "columns");
122       
123
124   Direction d =   directional_element (this).get ();
125   if (!d)
126     {
127       d = UP;
128       directional_element (this).set (d);
129     }
130   
131   if (column_arr.size())
132     translate_axis (column_arr[0]->extent (Y_AXIS)[d], Y_AXIS);
133
134   
135   if (scm_ilength (get_elt_property ("beams")) == 1)
136     {
137       SCM bs = get_elt_property ("beams");
138       Score_element *b = unsmob_element (gh_car (bs));
139       Beam * beam_l = dynamic_cast<Beam*> (b);
140       if (!broken_b () 
141           && spanned_drul_[LEFT]->column_l () == beam_l->spanned_drul_[LEFT]->column_l ()
142           && spanned_drul_[RIGHT]->column_l () == beam_l->spanned_drul_[RIGHT]->column_l ())
143         parallel_beam_b_ = true;
144     }
145 }
146
147
148 Direction
149 Tuplet_spanner::get_default_dir () const
150 {
151   Direction d = UP;
152   SCM dir_sym =get_elt_property ("dir-forced");
153   if (gh_number_p (dir_sym))
154     {
155       d= (Direction) gh_scm2int (dir_sym);
156       if (d != CENTER)
157         return d;
158     }
159
160   for (SCM s = get_elt_property ("columns"); gh_pair_p (s); s = gh_cdr (s))
161     {
162       Score_element * sc = unsmob_element (gh_car (s));
163       Note_column * nc = dynamic_cast<Note_column*> (sc);
164       if (nc->dir () < 0) 
165         {
166           d = DOWN;
167           break;
168         }
169     }
170   
171   return d;
172 }
173
174 void
175 Tuplet_spanner::add_beam (Beam *b)
176 {
177   add_dependency (b);
178   Group_interface gi (this, "beams");
179   gi.add_element (b);
180 }
181
182 void
183 Tuplet_spanner::add_column (Note_column*n)
184 {
185   Group_interface gi (this, "columns");
186   gi.add_element (n);
187
188   add_dependency (n);
189 }
190
191