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