]> git.donarmstrong.com Git - lilypond.git/blob - lily/volta-spanner.cc
9ea8b7a2c7ed547c3b48c25960a6c8ee0caa0c20
[lilypond.git] / lily / volta-spanner.cc
1 /*
2   volta-spanner.cc -- implement Volta_spanner
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--2000 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9
10 #include "box.hh"
11 #include "debug.hh"
12 #include "lookup.hh"
13 #include "molecule.hh"
14 #include "note-column.hh"
15 #include "paper-column.hh"
16 #include "bar.hh"
17 #include "paper-def.hh"
18 #include "volta-spanner.hh"
19 #include "stem.hh"
20 #include "dimension-cache.hh"
21 #include "group-interface.hh"
22
23 Volta_spanner::Volta_spanner ()
24 {
25   dim_cache_ [Y_AXIS]->set_callback (dim_callback);
26   set_elt_property ("bars", SCM_EOL);
27   set_elt_property ("note-columns", SCM_EOL);
28 }
29
30 /*
31   FIXME: too complicated.
32  */
33 Molecule*
34 Volta_spanner::do_brew_molecule_p () const
35 {
36   Molecule* mol_p = new Molecule;
37
38   Link_array<Bar> bar_arr
39     = Group_interface__extract_elements (this, (Bar*)0, "bars");
40
41   if (!bar_arr.size ())
42     return mol_p;
43
44   Link_array<Score_element> note_column_arr
45     = Group_interface__extract_elements (this, (Score_element*)0, "note-columns");
46   
47   bool no_vertical_start = false;
48   bool no_vertical_end = to_boolean (get_elt_property ("last-volta"));
49   Spanner *orig_span =  dynamic_cast<Spanner*> (original_l_);
50   if (orig_span && (orig_span->broken_into_l_arr_[0] != (Spanner*)this))
51     no_vertical_start = true;
52   if (orig_span && (orig_span->broken_into_l_arr_.top () != (Spanner*)this))
53     no_vertical_end = true;
54
55 #if 0
56   // FIXME
57   if (bar_arr.top ()->get_elt_property (type_str_.length_i () > 1)
58     no_vertical_end = false;
59 #endif
60
61   Real staff_space = paper_l ()->get_var ("interline");
62   Real half_staff_space = staff_space/2;
63   Real t = paper_l ()->get_var ("volta_thick");
64
65   Real dx = half_staff_space;
66   Real w = spanner_length() - dx - get_broken_left_end_align ();
67   Real h = paper_l()->get_var ("volta_spanner_height");
68   Molecule volta (lookup_l ()->volta (h, w, t, no_vertical_start, no_vertical_end));
69
70   
71   Molecule num (lookup_l ()->text ("volta",
72                                    ly_scm2string (get_elt_property("text")),
73                                    paper_l ()));
74   Real dy = bar_arr.top ()->extent (Y_AXIS) [UP] >? 
75      bar_arr[0]->extent (Y_AXIS) [UP];
76   dy += 2 * h;
77
78
79   /*
80     CODE DUPLICATION.
81     FIXME (see axis-group-elt, side-pos interface.)
82    */
83   for (int i = 0; i < note_column_arr.size (); i++)
84     dy = dy >? note_column_arr[i]->extent (Y_AXIS)[BIGGER];
85   dy -= h;
86
87   Molecule two (lookup_l ()->text ("number", "2", paper_l ()));
88   Real gap = two.dim_.x ().length () / 2;
89   Offset off (num.dim_.x ().length () + gap, 
90               h / half_staff_space - gap);
91   num.translate (off);
92   mol_p->add_molecule (volta);
93   mol_p->add_molecule (num);
94   mol_p->translate (Offset (0, dy));
95   return mol_p;
96 }
97   
98 void
99 Volta_spanner::do_add_processing ()
100 {
101
102   Link_array<Bar> bar_arr
103     = Group_interface__extract_elements (this, (Bar*)0, "bars");
104
105   if (bar_arr.size ())
106     {
107       set_bounds (LEFT, bar_arr[0]);
108       set_bounds (RIGHT, bar_arr.top ());  
109     }
110 }
111
112 /*
113     Originally the following comment existed here
114     "in most cases, it's a lot better not no have height...",
115     but problems existed with collision between volta spanner
116     and above staff or lyrics for multi-staff music, so the proper
117     height is now being returned. Additional space should still
118     be added elsewhere so lyrics from above staff do not sit on
119     volta spanner. (Roy R. Rankin)
120 */
121 Interval
122 Volta_spanner::dim_callback (Dimension_cache const *c)
123 {
124   Volta_spanner * v = dynamic_cast<Volta_spanner*> (c->element_l ());
125   Real h = v->paper_l()->get_var ("volta_spanner_height") * 2.;
126   return Interval (0., h);
127 }
128
129 void
130 Volta_spanner::do_post_processing ()
131 {
132   Link_array<Bar> bar_arr
133     = Group_interface__extract_elements (this, (Bar*)0, "bars");
134   
135   if (bar_arr.size())
136     translate_axis (bar_arr[0]->extent (Y_AXIS)[UP], Y_AXIS);
137   translate_axis (get_broken_left_end_align (), X_AXIS);
138 }
139   
140 void
141 Volta_spanner::add_bar  (Bar* c)
142 {
143   Group_interface gi(this, "bars");
144   gi.add_element (c);
145
146   add_dependency (c);
147 }
148
149 void
150 Volta_spanner::add_column (Note_column* c)
151 {
152   Group_interface gi(this, "note-columns");
153   gi.add_element (c);
154
155   add_dependency (c);
156 }
157
158