X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fnote-spacing.cc;h=a894be25394c9a41ba44a5db8870e79e686c574b;hb=5d84bfad4626892bcffd05adcced53c8a2329047;hp=9a71c00a598b9bee8aa42cf8de12769fb6d0470e;hpb=3f8a827aad721ed546b823e3f9f2605f61b90e20;p=lilypond.git diff --git a/lily/note-spacing.cc b/lily/note-spacing.cc index 9a71c00a59..a894be2539 100644 --- a/lily/note-spacing.cc +++ b/lily/note-spacing.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 2001--2011 Han-Wen Nienhuys + Copyright (C) 2001--2015 Han-Wen Nienhuys LilyPond is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,17 +31,17 @@ #include "separation-item.hh" #include "spacing-interface.hh" #include "staff-spacing.hh" +#include "staff-symbol-referencer.hh" #include "stem.hh" #include "warn.hh" /* - TODO: detect hshifts due to collisions, and account for them in - spacing? + Adjust the ideal and minimum distance between note columns, + based on the notehead size, skylines, and optical illusions. */ - Spring Note_spacing::get_spacing (Grob *me, Item *right_col, - Real base_space, Real increment) + Spring base, Real increment) { vector note_columns = Spacing_interface::left_note_columns (me); Real left_head_end = 0; @@ -49,7 +49,7 @@ Note_spacing::get_spacing (Grob *me, Item *right_col, for (vsize i = 0; i < note_columns.size (); i++) { SCM r = note_columns[i]->get_object ("rest"); - Grob *g = unsmob_grob (r); + Grob *g = unsmob (r); Grob *col = note_columns[i]->get_column (); if (!g) @@ -72,16 +72,12 @@ Note_spacing::get_spacing (Grob *me, Item *right_col, The main factor that determines the amount of space is the width of the note head (or the rest). For example, a quarter rest gets almost 0.5 ss less horizontal space than a note. - - The other parts of a note column (eg. flags, accidentals, etc.) don't get - the full amount of space. We give them half the amount of space, but then - adjust things so there are no collisions. */ + Real ideal = base.distance () - increment + left_head_end; Drul_array skys = Spacing_interface::skylines (me, right_col); - Real distance = skys[LEFT].distance (skys[RIGHT]); + Real distance = skys[LEFT].distance (skys[RIGHT], robust_scm2double (right_col->get_property ("skyline-vertical-padding"), 0.0)); Real min_dist = max (0.0, distance); - Real min_desired_space = left_head_end + (min_dist - left_head_end + base_space - increment) / 2; - Real ideal = base_space - increment + left_head_end; + base.set_min_distance (min_dist); /* If we have a NonMusical column on the right, we measure the ideal distance to the bar-line (if present), not the start of the column. */ @@ -94,24 +90,21 @@ Note_spacing::get_spacing (Grob *me, Item *right_col, Bar_line::non_empty_barline); if (bar) + ideal -= bar->extent (right_col, X_AXIS)[LEFT]; + else { - Real shift = bar->extent (right_col, X_AXIS)[LEFT]; - ideal -= shift; - min_desired_space -= max (shift, 0.0); + /* Measure ideal distance to the right side of the NonMusical column + but keep at least half the gap we would have had to a note */ + Real min_desired_space = (ideal + min_dist) / 2.0; + ideal -= right_col->extent (right_col, X_AXIS)[RIGHT]; + ideal = max (ideal, min_desired_space); } - else - ideal -= right_col->extent (right_col, X_AXIS)[RIGHT]; } - ideal = max (ideal, min_desired_space); - stem_dir_correction (me, right_col, increment, &ideal, &min_desired_space); + stem_dir_correction (me, right_col, increment, &ideal); - /* TODO: grace notes look bad when things are stretched. Should we increase - their stretch strength? */ - Spring ret (max (0.0, ideal), min_dist); - ret.set_inverse_compress_strength (max (0.0, ideal - min_desired_space)); - ret.set_inverse_stretch_strength (max (0.1, base_space - increment)); - return ret; + base.set_distance (max (0.0, ideal)); + return base; } static Real @@ -205,7 +198,7 @@ same_direction_correction (Grob *note_spacing, Drul_array head_posns) void Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, Real increment, - Real *space, Real *fixed) + Real *space) { Drul_array stem_dirs (CENTER, CENTER); Drul_array stem_posns; @@ -221,8 +214,6 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, Interval bar_xextent; Interval bar_yextent; - Direction d = LEFT; - bool acc_right = false; Grob *bar = Spacing_interface::extremal_break_aligned_grob (me, RIGHT, @@ -231,13 +222,13 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, if (bar && dynamic_cast (bar)->get_column () == rcolumn) bar_yextent = Staff_spacing::bar_y_positions (bar); - do + for (LEFT_and_RIGHT (d)) { vector const &items (ly_scm2link_array (props [d])); for (vsize i = 0; i < items.size (); i++) { Item *it = dynamic_cast (items[i]); - if (!Note_column::has_interface (it)) + if (!has_interface (it)) continue; if (d == RIGHT && it->get_column () != rcolumn) continue; @@ -273,22 +264,12 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, Interval hp = Stem::head_positions (stem); if (!hp.is_empty ()) { - Real chord_start = hp[stem_dir]; - - /* - can't look at stem-end-position, since that triggers - beam slope computations. - */ - Real stem_end = hp[stem_dir] - + stem_dir * robust_scm2double (stem->get_property ("length"), 7); - - stem_posns[d] = Interval (min (chord_start, stem_end), - max (chord_start, stem_end)); + Real ss = Staff_symbol_referencer::staff_space (stem); + stem_posns[d] = stem->pure_y_extent (stem, 0, INT_MAX) * (2 / ss); head_posns[d].unite (hp); } } } - while (flip (&d) != LEFT); Real correction = 0.0; @@ -321,7 +302,6 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, && !acc_right) correction = same_direction_correction (me, head_posns); - *fixed += correction; *space += correction; /* there used to be a correction for bar_xextent () here, but