2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1999--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
20 #include "spacing-spanner.hh"
25 #include "spacing-options.hh"
26 #include "international.hh"
29 #include "note-spacing.hh"
30 #include "output-def.hh"
31 #include "paper-column.hh"
32 #include "paper-score.hh"
33 #include "pointer-group-interface.hh"
34 #include "separation-item.hh"
35 #include "skyline-pair.hh"
36 #include "spaceable-grob.hh"
37 #include "spacing-interface.hh"
38 #include "staff-spacing.hh"
45 Spacing_spanner::get_columns (Grob *me_grob)
47 Spanner *me = dynamic_cast<Spanner *> (me_grob);
48 vector<Grob *> all (get_root_system (me)->used_columns ());
49 vsize start = binary_search (all, (Grob *)me->get_bound (LEFT),
50 &Paper_column::less_than);
51 vsize end = binary_search (all, (Grob *) me->get_bound (RIGHT),
52 &Paper_column::less_than);
54 all = vector<Grob *> (all.begin () + start,
55 all.begin () + end + 1);
59 MAKE_SCHEME_CALLBACK (Spacing_spanner, set_springs, 1);
61 Spacing_spanner::set_springs (SCM smob)
63 Spanner *me = unsmob<Spanner> (smob);
66 can't use get_system () ? --hwn.
68 Spacing_options options;
69 options.init_from_grob (me);
70 vector<Grob *> cols = Spacing_spanner::get_columns (me);
71 set_explicit_neighbor_columns (cols);
73 prune_loose_columns (me, &cols, &options);
74 set_implicit_neighbor_columns (cols);
75 generate_springs (me, cols, &options);
77 return SCM_UNSPECIFIED;
81 We want the shortest note that is also "common" in the piece, so we
82 find the shortest in each measure, and take the most frequently
85 This probably gives weird effects with modern music, where every
86 note has a different duration, but hey, don't write that kind of
90 MAKE_SCHEME_CALLBACK (Spacing_spanner, calc_common_shortest_duration, 1);
92 Spacing_spanner::calc_common_shortest_duration (SCM grob)
94 Spanner *me = unsmob<Spanner> (grob);
96 vector<Grob *> cols (get_columns (me));
101 vector<Rational> durations;
104 Rational shortest_in_measure;
105 shortest_in_measure.set_infinite (1);
107 for (vsize i = 0; i < cols.size (); i++)
109 if (Paper_column::is_musical (cols[i]))
111 Moment *when = unsmob<Moment> (cols[i]->get_property ("when"));
114 ignore grace notes for shortest notes.
116 if (when && when->grace_part_)
119 SCM st = cols[i]->get_property ("shortest-starter-duration");
120 Moment this_shortest = *unsmob<Moment> (st);
121 assert (this_shortest.to_bool ());
122 shortest_in_measure = min (shortest_in_measure, this_shortest.main_part_);
124 else if (!shortest_in_measure.is_infinity ()
125 && Paper_column::is_breakable (cols[i]))
128 for (; j < durations.size (); j++)
130 if (durations[j] > shortest_in_measure)
132 counts.insert (counts.begin () + j, 1);
133 durations.insert (durations.begin () + j, shortest_in_measure);
136 else if (durations[j] == shortest_in_measure)
143 if (durations.size () == j)
145 durations.push_back (shortest_in_measure);
146 counts.push_back (1);
149 shortest_in_measure.set_infinite (1);
153 vsize max_idx = VPOS;
155 for (vsize i = durations.size (); i--;)
157 if (counts[i] >= max_count)
160 max_count = counts[i];
164 SCM bsd = me->get_property ("base-shortest-duration");
165 Rational d = Rational (1, 8);
166 if (Moment *m = unsmob<Moment> (bsd))
170 d = min (d, durations[max_idx]);
172 return Moment (d).smobbed_copy ();
176 Spacing_spanner::generate_pair_spacing (Grob *me,
177 Paper_column *left_col, Paper_column *right_col,
178 Paper_column *after_right_col,
179 Spacing_options const *options)
181 if (Paper_column::is_musical (left_col))
183 if (!Paper_column::is_musical (right_col)
184 && (options->float_nonmusical_columns_ || to_boolean (right_col->get_property ("maybe-loose")))
186 && Paper_column::is_musical (after_right_col))
189 TODO: should generate rods to prevent collisions.
191 musical_column_spacing (me, left_col, after_right_col, options);
192 right_col->set_object ("between-cols", scm_cons (left_col->self_scm (),
193 after_right_col->self_scm ()));
196 musical_column_spacing (me, left_col, right_col, options);
198 if (Item *rb = right_col->find_prebroken_piece (LEFT))
199 musical_column_spacing (me, left_col, rb, options);
204 The case that the right part is broken as well is rather
205 rare, but it is possible, eg. with a single empty measure,
206 or if one staff finishes a tad earlier than the rest.
208 Item *lb = left_col->find_prebroken_piece (RIGHT);
209 Item *rb = right_col->find_prebroken_piece (LEFT);
211 if (left_col && right_col)
212 breakable_column_spacing (me, left_col, right_col, options);
215 breakable_column_spacing (me, lb, right_col, options);
218 breakable_column_spacing (me, left_col, rb, options);
221 breakable_column_spacing (me, lb, rb, options);
226 set_column_rods (vector<Grob *> const &cols, Real padding)
228 /* distances[i] will be the distance betwen cols[i-1] and cols[i], and
229 overhangs[j] the amount by which cols[0 thru j] extend beyond cols[j]
230 when each column is placed as far to the left as possible. */
231 vector<Real> distances (cols.size ());
232 vector<Real> overhangs (cols.size ());
234 for (vsize i = 0; i < cols.size (); i++)
236 Item *r = dynamic_cast<Item *> (cols[i]);
237 Item *rb = r->find_prebroken_piece (LEFT);
239 if (Separation_item::is_empty (r) && (!rb || Separation_item::is_empty (rb)))
242 Skyline_pair *skys = unsmob<Skyline_pair> (r->get_property ("horizontal-skylines"));
243 overhangs[i] = skys ? (*skys)[RIGHT].max_height () : 0.0;
245 if (0 == i) continue;
247 /* min rather than max because stickout will be negative if the right-hand column
248 sticks out a lot to the left */
249 Real stickout = min (skys ? (*skys)[LEFT].max_height () : 0.0,
250 Separation_item::conditional_skyline (r, cols[i - 1]).max_height ());
252 Real prev_distances = 0.0;
254 /* This is an inner loop and hence it is potentially quadratic. However, we only continue
255 as long as there is a rod to insert. Therefore, this loop will usually only execute
256 a constant number of times per iteration of the outer loop. */
257 for (vsize j = i; j--;)
259 if (overhangs[j] + padding <= prev_distances + distances[i] + stickout)
260 break; // cols[0 thru j] cannot reach cols[i]
262 Item *l = dynamic_cast<Item *> (cols[j]);
263 Item *lb = l->find_prebroken_piece (RIGHT);
265 Real dist = Separation_item::set_distance (l, r, padding);
266 distances[i] = max (distances[i], dist - prev_distances);
270 dist = Separation_item::set_distance (lb, r, padding);
271 // The left-broken version might reach more columns to the
272 // right than the unbroken version, by extending farther and/or
273 // nesting more closely;
274 if (j == i - 1) // check this, the first time we see each lb.
275 overhangs[j] = max (overhangs[j],
276 lb->extent (lb, X_AXIS)[RIGHT]
277 + distances[i] - dist);
280 Separation_item::set_distance (l, rb, padding);
282 Separation_item::set_distance (lb, rb, padding);
284 prev_distances += distances[j];
286 overhangs[i] = max (overhangs[i],
287 overhangs[i - 1] - distances[i]);
292 Spacing_spanner::generate_springs (Grob *me,
293 vector<Grob *> const &cols,
294 Spacing_options const *options)
296 Paper_column *prev = dynamic_cast<Paper_column *> (cols[0]);
297 for (vsize i = 1; i < cols.size (); i++)
299 Paper_column *col = dynamic_cast<Paper_column *> (cols[i]);
300 Paper_column *next = (i + 1 < cols.size ()) ? dynamic_cast<Paper_column *> (cols[i + 1]) : 0;
302 generate_pair_spacing (me, prev, col, next, options);
307 Real padding = robust_scm2double (prev->get_property ("padding"), 0.1);
308 set_column_rods (cols, padding);
312 Generate the space between two musical columns LEFT_COL and RIGHT_COL.
315 Spacing_spanner::musical_column_spacing (Grob *me,
318 Spacing_options const *options)
320 Spring spring = note_spacing (me, left_col, right_col, options);
322 if (options->stretch_uniformly_)
324 spring.set_min_distance (0.0);
325 spring.set_default_strength ();
329 vector<Spring> springs;
330 extract_grob_set (left_col, "spacing-wishes", wishes);
332 for (vsize i = 0; i < wishes.size (); i++)
334 Grob *wish = wishes[i];
335 if (Spacing_interface::left_column (wish) != left_col)
337 /* This shouldn't really happen, but the ancient music
338 stuff really messes up the spacing code, grrr
343 extract_grob_set (wish, "right-items", right_items);
344 bool found_matching_column = false;
345 for (vsize j = 0; j < right_items.size (); j++)
347 Item *it = dynamic_cast<Item *> (right_items[j]);
348 if (it && (right_col == it->get_column ()
349 || right_col->original () == it->get_column ()))
350 found_matching_column = true;
354 This is probably a waste of time in the case of polyphonic
356 if (found_matching_column && has_interface<Note_spacing> (wish))
358 Real inc = options->increment_;
359 Grob *gsp = unsmob<Grob> (left_col->get_object ("grace-spacing"));
360 if (gsp && Paper_column::when_mom (left_col).grace_part_)
362 Spacing_options grace_opts;
363 grace_opts.init_from_grob (gsp);
364 inc = grace_opts.increment_;
366 springs.push_back (Note_spacing::get_spacing (wish, right_col, spring, inc));
370 if (springs.empty ())
372 if (Paper_column::is_musical (right_col))
375 Min distance should be 0.0. If there are no spacing
376 wishes, we're probably dealing with polyphonic spacing
379 spring.set_min_distance (0.0);
383 spring = merge_springs (springs);
386 if (Paper_column::when_mom (right_col).grace_part_
387 && !Paper_column::when_mom (left_col).grace_part_)
390 Ugh. 0.8 is arbitrary.
396 TODO: make sure that the space doesn't exceed the right margin.
398 if (options->packed_)
401 In packed mode, pack notes as tight as possible. This makes
402 sense mostly in combination with ragged-right mode: the notes
403 are then printed at minimum distance. This is mostly useful
404 for ancient notation, but may also be useful for some flavours
405 of contemporary music. If not in ragged-right mode, lily will
406 pack as many bars of music as possible into a line, but the
407 line will then be stretched to fill the whole linewidth.
409 Note that we don't actually pack things as tightly as possible:
410 we don't allow the next column to begin before this one ends.
412 /* FIXME: the else clause below is the "right" thing to do,
413 but we can't do it because of all the empty columns that the
414 ligature-engravers leave lying around. In that case, the extent of
415 the column is incorrect because it includes note-heads that aren't
416 there. We get around this by only including the column extent if
417 the left-hand column is "genuine". This is a dirty hack and it
418 should be fixed in the ligature-engravers. --jneem
420 if (Paper_column::is_extraneous_column_from_ligature (left_col))
421 spring.set_distance (spring.min_distance ());
423 spring.set_distance (max (left_col->extent (left_col, X_AXIS)[RIGHT],
424 spring.min_distance ()));
426 spring.set_inverse_stretch_strength (1.0);
429 Spaceable_grob::add_spring (left_col, right_col, spring);
433 Check if COL fills the whole measure.
436 Spacing_spanner::fills_measure (Grob *me, Item *left, Item *col)
438 System *sys = get_root_system (me);
439 Item *next = sys->column (col->get_column ()->get_rank () + 1);
443 if (Paper_column::is_musical (next)
444 || Paper_column::is_musical (left)
445 || !Paper_column::is_musical (col)
446 || !Paper_column::is_used (next))
450 = Paper_column::when_mom (next) - Paper_column::when_mom (col);
452 Moment *len = unsmob<Moment> (left->get_property ("measure-length"));
457 Don't check for exact measure length, since ending measures are
458 often shortened due to pickups.
460 if (dt.main_part_ > len->main_part_ / Rational (2)
461 && (next->is_broken ()
462 || next->break_status_dir ()))
469 Read hints from L and generate springs.
472 Spacing_spanner::breakable_column_spacing (Grob *me, Item *l, Item *r,
473 Spacing_options const *options)
475 vector<Spring> springs;
478 Real full_measure_space = 0.0;
479 if (Paper_column::is_musical (r)
480 && l->break_status_dir () == CENTER
481 && fills_measure (me, l, r))
482 full_measure_space = robust_scm2double (l->get_property ("full-measure-extra-space"), 1.0);
484 Moment dt = Paper_column::when_mom (r) - Paper_column::when_mom (l);
486 if (dt == Moment (0, 0))
488 extract_grob_set (l, "spacing-wishes", wishes);
490 for (vsize i = 0; i < wishes.size (); i++)
492 Item *spacing_grob = dynamic_cast<Item *> (wishes[i]);
494 if (!spacing_grob || !has_interface<Staff_spacing> (spacing_grob))
498 column for the left one settings should be ok due automatic
501 assert (spacing_grob->get_column () == l);
503 springs.push_back (Staff_spacing::get_spacing (spacing_grob, r,
504 full_measure_space));
508 if (springs.empty ())
509 spring = standard_breakable_column_spacing (me, l, r, options);
511 spring = merge_springs (springs);
513 if (Paper_column::when_mom (r).grace_part_)
516 Correct for grace notes.
518 Ugh. The 0.8 is arbitrary.
523 if (options->stretch_uniformly_ && l->break_status_dir () != RIGHT)
525 spring.set_min_distance (0.0);
526 spring.set_default_strength ();
529 Spaceable_grob::add_spring (l, r, spring);
532 ADD_INTERFACE (Spacing_spanner,
533 "The space taken by a note is dependent on its duration."
534 " Doubling a duration adds @code{spacing-increment} to the"
535 " space. The most common shortest note gets"
536 " @code{shortest-duration-space}. Notes that are even shorter"
537 " are spaced proportonial to their duration.\n"
539 "Typically, the increment is the width of a black note head."
540 " In a piece with lots of 8th notes, and some 16th notes, the"
541 " eighth note gets a 2@tie{}note heads width (i.e., the space"
542 " following a note is a 1@tie{}note head width). A 16th note"
543 " is followed by 0.5 note head width. The quarter note is"
544 " followed by 3@tie{}NHW, the half by 4@tie{}NHW, etc.",
547 "average-spacing-wishes "
548 "base-shortest-duration "
549 "common-shortest-duration "
551 "shortest-duration-space "
553 "strict-grace-spacing "
554 "strict-note-spacing "
555 "uniform-stretching "