]> git.donarmstrong.com Git - lilypond.git/blob - lily/spacing-spanner.cc
release: 1.1.44
[lilypond.git] / lily / spacing-spanner.cc
1 /*   
2   spacing-spanner.cc --  implement Spacing_spanner
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "spacing-spanner.hh"
11 #include "score-column.hh"
12 #include "dimensions.hh"
13 #include "paper-def.hh"
14 #include "warn.hh"
15 #include "p-score.hh"
16 #include "line-of-score.hh"
17
18 Spacing_spanner::Spacing_spanner ()
19 {
20   set_elt_property (break_helper_only_scm_sym, SCM_BOOL_T);
21   set_elt_property (transparent_scm_sym, SCM_BOOL_T);
22 }
23
24 int
25 Spacing_spanner::col_count () const
26 {
27   return pscore_l_->line_l_->cols_.size ();
28 }
29
30 Score_column *
31 Spacing_spanner::scol (int i)const
32 {
33   return dynamic_cast<Score_column*> (pscore_l_->line_l_->cols_[i]);
34 }
35
36 /*
37   cut 'n paste from spring-spacer.cc
38  */
39 Array<Spring>
40 Spacing_spanner::do_measure (int col1, int col2) const
41 {
42   for (int i =col1; i < col2; i++)
43     {
44       scol (i)->preprocess ();
45       scol (i)->print ();
46     }
47
48   Moment shortest;
49   shortest.set_infinite (1);
50   for (int i =col1; i < col2; i++)
51     {
52       if (scol(i)->musical_b ())
53         {
54           shortest = shortest <? scol(i)->shortest_starter_mom_;
55         }
56     }
57
58   Array<Spring> meas_springs;
59
60   for (int i= col1; i < col2; i++)
61     {
62       if (!scol (i)->musical_b() && i+1 < col_count())
63         {
64           Real symbol_distance = scol (i)->extent (X_AXIS)[RIGHT] ;
65           Real durational_distance = 0;
66           Moment delta_t =  scol (i+1)->when_mom () - scol (i)->when_mom () ;
67           /*
68             ugh should use shortest_playing distance
69           */
70           if (delta_t)
71             {
72               Real k=  paper_l()->arithmetic_constant (shortest);
73               durational_distance =  paper_l()->length_mom_to_dist (delta_t,k);
74             }
75           symbol_distance += -scol (i+1)->extent(X_AXIS)[LEFT];
76
77           Spring s ;
78           s.item_l_drul_[LEFT] = scol (i);
79           s.item_l_drul_[RIGHT] = scol (i+1);
80           s.distance_f_ =  symbol_distance >? durational_distance;
81           meas_springs.push (s);
82
83           Item *l = s.item_l_drul_[LEFT]->find_prebroken_piece (RIGHT);
84           Item *r = s.item_l_drul_[RIGHT]->find_prebroken_piece (LEFT);
85           Spring sp_orig (s);
86           
87           if (l)
88             {
89               s = sp_orig;
90               s.item_l_drul_[LEFT] =l ;
91               meas_springs.push (s);
92             }
93
94           if (l && r)
95             {
96               s = sp_orig;
97               s.item_l_drul_[RIGHT] = r;
98               s.item_l_drul_[LEFT] = l;
99               meas_springs.push (s);
100             }
101           
102         }
103     }
104
105   for (int i=col1; i < col2; i++)
106     {
107       if (scol (i)->musical_b())
108         {
109           Moment shortest_playing_len = scol(i)->shortest_playing_mom_;
110           if (! shortest_playing_len)
111             {
112               warning (_f ("can't find a ruling note at %s", 
113                 scol (i)->when_mom ().str ()));
114               shortest_playing_len = 1;
115             }
116           if (! shortest)
117             {
118               warning (_f ("no minimum in measure at %s", 
119                       scol (i)->when_mom ().str ()));
120               shortest = 1;
121             }
122           Moment delta_t = scol (i+1)->when_mom () - scol (i)->when_mom ();
123           Real k=  paper_l()->arithmetic_constant(shortest);
124           Real dist = paper_l()->length_mom_to_dist (shortest_playing_len, k);
125           dist *= (double)(delta_t / shortest_playing_len);
126
127
128           Spring sp;
129           sp.distance_f_ =  dist;
130           sp.item_l_drul_[LEFT] = scol (i);
131           sp.item_l_drul_[RIGHT] = scol (i+1);
132
133           meas_springs.push (sp);
134
135           /*
136             UGH. TODO: more
137             advanced spacing here.
138            */
139           Spring sp_orig (sp);
140
141           Item *r =  sp.item_l_drul_[RIGHT]->find_prebroken_piece (LEFT);
142           
143           if (r)
144             {
145               sp = sp_orig;
146               sp.item_l_drul_[RIGHT] =r ;
147               meas_springs.push (sp);
148             }
149         }
150     }
151   return meas_springs;
152 }
153
154 Array<Spring>
155 Spacing_spanner::get_springs () const
156 {
157   Array<Spring> springs;
158   int last_break =0;
159   for (int i=1; i < col_count (); i++)
160     {
161       if (scol (i)->breakable_b ())
162         {
163           springs.concat (do_measure (last_break, i));
164           last_break  = i;
165         }
166     }
167   return springs;
168 }
169
170