]> git.donarmstrong.com Git - lilypond.git/blob - lily/volta-spanner.cc
release: 1.3.17
[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--1999 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   last_b_ = false;
26   dim_cache_ [Y_AXIS]->set_callback (dim_callback);
27   set_elt_property ("bars", SCM_EOL);
28   set_elt_property ("note-columns", SCM_EOL);
29 }
30
31 Molecule*
32 Volta_spanner::do_brew_molecule_p () const
33 {
34   Molecule* mol_p = new Molecule;
35
36   Link_array<Bar> bar_arr
37     = Group_interface__extract_elements (this, (Bar*)0, "bars");
38
39   if (!bar_arr.size ())
40     return mol_p;
41
42   Link_array<Score_element> note_column_arr
43     = Group_interface__extract_elements (this, (Score_element*)0, "note-columns");
44   
45   bool no_vertical_start = false;
46   bool no_vertical_end = last_b_;
47   Spanner *orig_span =  dynamic_cast<Spanner*> (original_l_);
48   if (orig_span && (orig_span->broken_into_l_arr_[0] != (Spanner*)this))
49     no_vertical_start = true;
50   if (orig_span && (orig_span->broken_into_l_arr_.top () != (Spanner*)this))
51     no_vertical_end = true;
52   if (bar_arr.top ()->type_str_.length_i () > 1)
53     no_vertical_end = false;
54
55   Real staff_space = paper_l ()->get_var ("interline");
56   Real half_staff_space = staff_space/2;
57   Real t = paper_l ()->get_var ("volta_thick");
58
59   Real dx = half_staff_space;
60   Real w = spanner_length() - dx - get_broken_left_end_align ();
61   Real h = paper_l()->get_var ("volta_spanner_height");
62   Molecule volta (lookup_l ()->volta (h, w, t, no_vertical_start, no_vertical_end));
63
64   
65   Molecule num (lookup_l ()->text ("volta", number_str_, paper_l ()));
66   Real dy = bar_arr.top ()->extent (Y_AXIS) [UP] > 
67      bar_arr[0]->extent (Y_AXIS) [UP];
68   dy += 2 * h;
69
70   for (int i = 0; i < note_column_arr.size (); i++)
71     dy = dy >? note_column_arr[i]->extent (Y_AXIS)[BIGGER];
72   dy -= h;
73
74   Molecule two (lookup_l ()->text ("number", "2", paper_l ()));
75   Real gap = two.dim_.x ().length () / 2;
76   Offset off (num.dim_.x ().length () + gap, 
77               h / half_staff_space - gap);
78   num.translate (off);
79   mol_p->add_molecule (volta);
80   mol_p->add_molecule (num);
81   mol_p->translate (Offset (0, dy));
82   return mol_p;
83 }
84   
85 void
86 Volta_spanner::do_add_processing ()
87 {
88
89   Link_array<Bar> bar_arr
90     = Group_interface__extract_elements (this, (Bar*)0, "bars");
91
92   if (bar_arr.size ())
93     {
94       set_bounds (LEFT, bar_arr[0]);
95       set_bounds (RIGHT, bar_arr.top ());  
96     }
97 }
98
99 /*
100     Originally the following comment existed here
101     "in most cases, it's a lot better not no have height...",
102     but problems existed with collision between volta spanner
103     and above staff or lyrics for multi-staff music, so the proper
104     height is now being returned. Additional space should still
105     be added elsewhere so lyrics from above staff do not sit on
106     volta spanner. (Roy R. Rankin)
107 */
108 Interval
109 Volta_spanner::dim_callback (Dimension_cache const *c)
110 {
111   Volta_spanner * v = dynamic_cast<Volta_spanner*> (c->element_l ());
112   Real h = v->paper_l()->get_var ("volta_spanner_height") * 2.;
113   return Interval (0., h);
114 }
115
116 void
117 Volta_spanner::do_post_processing ()
118 {
119
120   Link_array<Bar> bar_arr
121     = Group_interface__extract_elements (this, (Bar*)0, "bars");
122   
123   if (bar_arr.size())
124     translate_axis (bar_arr[0]->extent (Y_AXIS)[UP], Y_AXIS);
125   translate_axis (get_broken_left_end_align (), X_AXIS);
126 }
127
128
129   
130 void
131 Volta_spanner::add_bar  (Bar* c)
132 {
133   Group_interface gi(this, "bars");
134   gi.add_element (c);
135
136   add_dependency (c);
137 }
138
139 void
140 Volta_spanner::add_column (Note_column* c)
141 {
142   Group_interface gi(this, "note-columns");
143   gi.add_element (c);
144
145   add_dependency (c);
146 }
147
148