]> git.donarmstrong.com Git - lilypond.git/blob - lily/volta-spanner.cc
72ace70c4f1f1c30399b55cd848b790ef5de5be1
[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 #include "atom.hh"
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_p () const
37 {
38   Molecule* mol_p = new Molecule;
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_p;
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   Molecule volta; 
72
73   Atom *at = new Atom(gh_list (ly_symbol2scm ("volta"),
74                      gh_double2scm (h),
75                      gh_double2scm (w),
76                      gh_double2scm (t),
77                      gh_int2scm (no_vertical_start),
78                      gh_int2scm (no_vertical_end),
79                      SCM_UNDEFINED));
80
81   volta.dim_[Y_AXIS] = Interval (- h/2, h/2);
82   volta.dim_[X_AXIS] = Interval (0, w);
83   volta.add_atom (at->self_scm_);
84   
85   Molecule num (lookup_l ()->text ("volta",
86                                    ly_scm2string (get_elt_property("text")),
87                                    paper_l ()));
88   Real dy = bar_arr.top ()->extent (Y_AXIS) [UP] >? 
89      bar_arr[0]->extent (Y_AXIS) [UP];
90   dy += 2 * h;
91
92
93   /*
94     CODE DUPLICATION.
95     FIXME (see axis-group-elt, side-pos interface.)
96    */
97   for (int i = 0; i < note_column_arr.size (); i++)
98     dy = dy >? note_column_arr[i]->extent (Y_AXIS)[BIGGER];
99   dy -= h;
100
101   Molecule two (lookup_l ()->text ("volta", "2", paper_l ()));
102   Real gap = two.dim_.x ().length () / 2;
103   Offset off (num.dim_.x ().length () + gap, 
104               h / half_staff_space - gap);
105   num.translate (off);
106   mol_p->add_molecule (volta);
107   mol_p->add_molecule (num);
108   mol_p->translate (Offset (0, dy));
109   return mol_p;
110 }
111   
112 void
113 Volta_spanner::do_add_processing ()
114 {
115
116   Link_array<Bar> bar_arr
117     = Group_interface__extract_elements (this, (Bar*)0, "bars");
118
119   if (bar_arr.size ())
120     {
121       set_bounds (LEFT, bar_arr[0]);
122       set_bounds (RIGHT, bar_arr.top ());  
123     }
124 }
125
126 /*
127     Originally the following comment existed here
128     "in most cases, it's a lot better not no have height...",
129     but problems existed with collision between volta spanner
130     and above staff or lyrics for multi-staff music, so the proper
131     height is now being returned. Additional space should still
132     be added elsewhere so lyrics from above staff do not sit on
133     volta spanner. (Roy R. Rankin)
134 */
135 Interval
136 Volta_spanner::dim_callback (Dimension_cache const *c)
137 {
138   Volta_spanner * v = dynamic_cast<Volta_spanner*> (c->element_l ());
139   Real h = v->paper_l()->get_var ("volta_spanner_height") * 2.;
140   return Interval (0., h);
141 }
142
143 void
144 Volta_spanner::do_post_processing ()
145 {
146   Link_array<Bar> bar_arr
147     = Group_interface__extract_elements (this, (Bar*)0, "bars");
148   
149   if (bar_arr.size())
150     translate_axis (bar_arr[0]->extent (Y_AXIS)[UP], Y_AXIS);
151   translate_axis (get_broken_left_end_align (), X_AXIS);
152 }
153   
154 void
155 Volta_spanner::add_bar  (Bar* c)
156 {
157   Group_interface gi(this, "bars");
158   gi.add_element (c);
159
160   add_dependency (c);
161 }
162
163 void
164 Volta_spanner::add_column (Note_column* c)
165 {
166   Group_interface gi(this, "note-columns");
167   gi.add_element (c);
168
169   add_dependency (c);
170 }
171
172