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