2 spacing-spanner.cc -- implement Spacing_spanner
4 source file of the GNU LilyPond music typesetter
6 (c) 1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "spacing-spanner.hh"
11 #include "score-column.hh"
12 #include "dimensions.hh"
13 #include "paper-def.hh"
16 #include "line-of-score.hh"
18 Spacing_spanner::Spacing_spanner ()
20 set_elt_property (break_helper_only_scm_sym, SCM_BOOL_T);
21 set_elt_property (transparent_scm_sym, SCM_BOOL_T);
25 Spacing_spanner::col_count () const
27 return pscore_l_->line_l_->cols_.size ();
31 Spacing_spanner::scol (int i)const
33 return dynamic_cast<Score_column*> (pscore_l_->line_l_->cols_[i]);
37 cut 'n paste from spring-spacer.cc
39 generate springs between columns.
44 * Spacing should take optical effects into account
46 The algorithm is partly taken from :
48 John S. Gourlay. ``Spacing a Line of Music,'' Technical Report
49 OSU-CISRC-10/87-TR35, Department of Computer and Information
50 Science, The Ohio State University, 1987.
54 Spacing_spanner::do_measure (int col1, int col2) const
56 for (int i =col1; i < col2; i++)
58 scol (i)->preprocess ();
63 shortest.set_infinite (1);
64 for (int i =col1; i < col2; i++)
66 if (scol(i)->musical_b ())
68 shortest = shortest <? scol(i)->shortest_starter_mom_;
72 Array<Spring> meas_springs;
75 UGR GUR URG. duplicate code for spacing generation.
77 for (int i= col1; i < col2; i++)
79 SCM hint = scol (i)->get_elt_property (extra_space_scm_sym);
80 if (hint != SCM_BOOL_F)
82 hint = SCM_CDR (hint);
85 s.item_l_drul_[LEFT] = scol (i);
86 s.item_l_drul_[RIGHT] = scol (i+1);
87 Real unbroken_dist = gh_scm2double (SCM_CDR(hint));
89 s.distance_f_ = unbroken_dist;
93 meas_springs.push (s);
96 Item * l = scol(i)->find_prebroken_piece (RIGHT);
97 Item * r = scol(i+1)->find_prebroken_piece (LEFT);
101 s.item_l_drul_[LEFT] = l;
102 s.item_l_drul_[RIGHT] = scol (i+1);
103 hint = l->get_elt_property (extra_space_scm_sym);
105 if (hint == SCM_BOOL_F)
107 programming_error ("No postbreak breakable spacing hint set.");
108 s.distance_f_= unbroken_dist;
111 s.distance_f_ = gh_scm2double (SCM_CDDR(hint));
114 space around barlines should not stretch very much.
117 meas_springs.push (s);
123 s.item_l_drul_[LEFT] = scol (i);
124 s.item_l_drul_[RIGHT] = r;
125 s.distance_f_ = unbroken_dist;
128 space around barlines should not stretch very much.
131 meas_springs.push (s);
137 s.item_l_drul_[LEFT] = l;
138 s.item_l_drul_[RIGHT] = r;
140 hint = l->get_elt_property (extra_space_scm_sym);
141 if (hint == SCM_BOOL_F)
143 programming_error ("No postbreak breakable spacing hint set.");
144 s.distance_f_= unbroken_dist;
147 s.distance_f_ = gh_scm2double (SCM_CDDR(hint));
150 space around barlines should not stretch very much.
153 meas_springs.push (s);
156 else if (!scol (i)->musical_b() && i+1 < col_count())
158 Real symbol_distance = scol (i)->extent (X_AXIS)[RIGHT] ;
159 Real durational_distance = 0;
160 Moment delta_t = scol (i+1)->when_mom () - scol (i)->when_mom () ;
162 ugh should use shortest_playing distance
166 Real k= paper_l()->arithmetic_constant (shortest);
167 durational_distance = paper_l()->length_mom_to_dist (delta_t,k);
169 symbol_distance += -scol (i+1)->extent(X_AXIS)[LEFT];
172 s.item_l_drul_[LEFT] = scol (i);
173 s.item_l_drul_[RIGHT] = scol (i+1);
174 s.distance_f_ = symbol_distance >? durational_distance;
175 meas_springs.push (s);
177 Item *l = s.item_l_drul_[LEFT]->find_prebroken_piece (RIGHT);
178 Item *r = s.item_l_drul_[RIGHT]->find_prebroken_piece (LEFT);
184 s.item_l_drul_[LEFT] =l ;
185 meas_springs.push (s);
191 s.item_l_drul_[RIGHT] = r;
192 s.item_l_drul_[LEFT] = l;
193 meas_springs.push (s);
199 for (int i=col1; i < col2; i++)
201 if (scol (i)->musical_b())
203 Moment shortest_playing_len = scol(i)->shortest_playing_mom_;
204 if (! shortest_playing_len)
206 warning (_f ("can't find a ruling note at %s",
207 scol (i)->when_mom ().str ()));
208 shortest_playing_len = 1;
212 warning (_f ("no minimum in measure at %s",
213 scol (i)->when_mom ().str ()));
216 Moment delta_t = scol (i+1)->when_mom () - scol (i)->when_mom ();
217 Real k= paper_l()->arithmetic_constant(shortest);
218 Real dist = paper_l()->length_mom_to_dist (shortest_playing_len, k);
219 dist *= (double)(delta_t / shortest_playing_len);
223 sp.distance_f_ = dist;
224 sp.item_l_drul_[LEFT] = scol (i);
225 sp.item_l_drul_[RIGHT] = scol (i+1);
227 meas_springs.push (sp);
231 advanced spacing here.
235 Item *r = sp.item_l_drul_[RIGHT]->find_prebroken_piece (LEFT);
240 sp.item_l_drul_[RIGHT] =r ;
241 meas_springs.push (sp);
249 Spacing_spanner::get_springs () const
251 Array<Spring> springs;
253 for (int i=1; i < col_count (); i++)
255 if (scol (i)->breakable_b ())
257 springs.concat (do_measure (last_break, i));