X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fnote-spacing.cc;h=73faa02100bd0ea2782c2f4cc5e6e0a2c34ac8c2;hb=1dbfe58548c0dbea3a09c94eb03113aaaaa73c75;hp=90db07a7e82ab1159a3804c4308b3f9bccc21fcb;hpb=ac6c83f047635535d0481a15654c13e776334dc6;p=lilypond.git diff --git a/lily/note-spacing.cc b/lily/note-spacing.cc index 90db07a7e8..73faa02100 100644 --- a/lily/note-spacing.cc +++ b/lily/note-spacing.cc @@ -1,27 +1,38 @@ /* - note-spacing.cc -- implement Note_spacing + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 2001--2011 Han-Wen Nienhuys - (c) 2001--2007 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ #include "note-spacing.hh" +#include "accidental-placement.hh" #include "bar-line.hh" #include "directional-element-interface.hh" #include "grob-array.hh" -#include "paper-column.hh" #include "moment.hh" #include "note-column.hh" -#include "warn.hh" -#include "stem.hh" +#include "output-def.hh" +#include "paper-column.hh" +#include "pointer-group-interface.hh" #include "separation-item.hh" #include "spacing-interface.hh" #include "staff-spacing.hh" -#include "accidental-placement.hh" -#include "output-def.hh" -#include "pointer-group-interface.hh" +#include "stem.hh" +#include "warn.hh" /* TODO: detect hshifts due to collisions, and account for them in @@ -32,29 +43,29 @@ Spring Note_spacing::get_spacing (Grob *me, Item *right_col, Real base_space, Real increment) { - vector note_columns = Spacing_interface::left_note_columns (me); + vector note_columns = Spacing_interface::left_note_columns (me); Real left_head_end = 0; for (vsize i = 0; i < note_columns.size (); i++) { - SCM r = note_columns[i]->get_object ("rest"); - Grob *g = unsmob_grob (r); - Grob *col = note_columns[i]->get_column (); - - if (!g) - g = Note_column::first_head (note_columns[i]); - - /* - Ugh. If Stem is switched off, we don't know what the - first note head will be. - */ - if (g) - { - if (g->common_refpoint (col, X_AXIS) != col) - programming_error ("Note_spacing::get_spacing (): Common refpoint incorrect"); - else - left_head_end = g->extent (col, X_AXIS)[RIGHT]; - } + SCM r = note_columns[i]->get_object ("rest"); + Grob *g = unsmob_grob (r); + Grob *col = note_columns[i]->get_column (); + + if (!g) + g = Note_column::first_head (note_columns[i]); + + /* + Ugh. If Stem is switched off, we don't know what the + first note head will be. + */ + if (g) + { + if (g->common_refpoint (col, X_AXIS) != col) + programming_error ("Note_spacing::get_spacing (): Common refpoint incorrect"); + else + left_head_end = g->extent (col, X_AXIS)[RIGHT]; + } } /* @@ -80,7 +91,7 @@ Note_spacing::get_spacing (Grob *me, Item *right_col, { Grob *bar = Pointer_group_interface::find_grob (right_col, ly_symbol2scm ("elements"), - Bar_line::has_interface); + Bar_line::non_empty_barline); if (bar) { @@ -108,7 +119,7 @@ knee_correction (Grob *note_spacing, Grob *right_stem, Real increment) { Real note_head_width = increment; Grob *head = right_stem ? Stem::support_head (right_stem) : 0; - Grob *rcolumn = dynamic_cast (head)->get_column (); + Grob *rcolumn = dynamic_cast (head)->get_column (); Interval head_extent; if (head) @@ -153,44 +164,43 @@ same_direction_correction (Grob *note_spacing, Drul_array head_posns) { /* Correct for the following situation: - + X X | | | | | X | | | | ======== - + ^ move the center one to the left. - - + + this effect seems to be much more subtle than the stem-direction stuff (why?), and also does not scale with the difference in stem length. - + */ Interval hp = head_posns[LEFT]; hp.intersect (head_posns[RIGHT]); if (!hp.is_empty ()) return 0; - + Direction lowest = (head_posns[LEFT][DOWN] > head_posns[RIGHT][UP]) ? RIGHT : LEFT; - + Real delta = head_posns[-lowest][DOWN] - head_posns[lowest][UP]; Real corr = robust_scm2double (note_spacing->get_property ("same-direction-correction"), 0); - + return (delta > 1) ? -lowest * corr : 0; } +/* + Correct for optical illusions. See [Wanske] p. 138. The combination + up-stem + down-stem should get extra space, the combination + down-stem + up-stem less. -/** - Correct for optical illusions. See [Wanske] p. 138. The combination - up-stem + down-stem should get extra space, the combination - down-stem + up-stem less. - - TODO: have to check whether the stems are in the same staff. + TODO: have to check whether the stems are in the same staff. */ void Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, @@ -213,26 +223,30 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, Direction d = LEFT; + bool acc_right = false; + Grob *bar = Spacing_interface::extremal_break_aligned_grob (me, RIGHT, rcolumn->break_status_dir (), &bar_xextent); - if (bar && dynamic_cast (bar)->get_column () == rcolumn) + if (bar && dynamic_cast (bar)->get_column () == rcolumn) bar_yextent = Staff_spacing::bar_y_positions (bar); do { - vector const &items (ly_scm2link_array (props [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)) continue; + if (d == RIGHT && it->get_column () != rcolumn) + continue; /* - don't correct if accidentals are sticking out of the right side. + Find accidentals which are sticking out of the right side. */ - if (d == RIGHT && Note_column::accidentals (it)) - return; + if (d == RIGHT) + acc_right = acc_right || Note_column::accidentals (it); Grob *stem = Note_column::get_stem (it); @@ -265,8 +279,8 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, 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); + 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)); @@ -300,7 +314,12 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, correction *= 0.5; } } - else if (stem_dirs[LEFT] * stem_dirs[RIGHT] == 1) + /* + Only apply same direction correction if there are no + accidentals sticking out of the right hand side. + */ + else if (stem_dirs[LEFT] * stem_dirs[RIGHT] == 1 + && !acc_right) correction = same_direction_correction (me, head_posns); *space += correction;