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