From: fred Date: Tue, 26 Mar 2002 22:14:59 +0000 (+0000) Subject: lilypond-1.1.57 X-Git-Tag: release/1.5.59~2296 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=8f9585b9c115affed48b272d158796b46f6379c8;p=lilypond.git lilypond-1.1.57 --- diff --git a/NEWS b/NEWS index f2193e35fd..2a01616cca 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,31 @@ +pl 56.jcn3 + - slur de-hairification + * slurs always attached to noteheads, by default + * corrections for steep and high slurs + * snap to stem end when close + - bow/tie/slur dy/dx fix + +pl 56.hwn1 + - some spacing tweaks. + - bf: two repeats + alts after each other. +pl 56.jcn2 + - tie: bfs + even simpler + +pl 56.jcn1 + - bf: re-added \textflat,sharp to fix chords... + - bf: chord-modifier and mandatory dot: c-maj5 + - tutorial chord fixes + - tie fixes and boldifying: + * removed sloping (dy!=0) code + * use actual note-widths + * y[left] == y[right] + * follow OSU rules, I hope (from comments in text -- must check) + * undetermined direction -> down; inverse of stem + - bf: beam: undetermined direction -> up; like stem + - slur-symmetry fixes + - fix for \rhythm and seq_iter childs (still crude, but more effective) +********* + pl 55.uu1 - use GS' anti aliasing diff --git a/TODO b/TODO index 3939b22ad5..e95bd85eda 100644 --- a/TODO +++ b/TODO @@ -9,7 +9,6 @@ Most of the items are marked in the code as well Grep for TODO and ugh/ugr/urg. .* TODO before 1.2 -. * rename abc2ly mup2ly . * rename 'staff_line_leading' (who is being lead where?) to staff_space, interline; (or other meaningful name) and use throughout lily . * rename files to class-name: @@ -18,7 +17,29 @@ staff_space, interline; (or other meaningful name) and use throughout lily . * p-score . * engraver-group . * standardise(d) switches: -v, --version; -d, --debug, -. * Auto_beam debugging output (waarom/wanneer heb jij die weggehaald?) +. * Peter 1. Key signatures are no longer transposed with the rest + of + the music. + + \notes\transpose bes {\key D; d1 } + should produce no key signature (key C) + + 2. Crescendos and other dynamic markings that start inside a + \grace { } section are ignored. + + \notes \relative c' { fis4 r4 \grace { [g16 ( \< a16] } + ) b4 \! a8. g16} + + 3. Slurs that end within a grace section but start outside + are treated strangely. + a2 d,4 ( \grace { [e16 ) d16]} cis8 d + + + 4. Lyrics and grace sections don't go too well together. + The words are aligned with the main note, not the start of the + grace note. This is usually wrong, but is sometimes right. + + . * Auto_beam debugging output (waarom/wanneer heb jij die weggehaald?) . * Rename illegal to invalid . * Mats: @@ -51,11 +72,68 @@ staff_space, interline; (or other meaningful name) and use throughout lily - The paper11/13/26 files have to be updated. . * Grace_slur_engraver. +. * input/star-spangled-banner.ly: fold for lyrics? . * Break_req handling is silly (break_forbid () + \break fucks up.) . * hangOnClef with non-breakable clefs. . * do scaled fonts generally . * fix partial measures in meaningful way. +. * Michael + +- The two spacing bugs in the choral-1.ly I sent you earlier, small +GIFs attached for easy reference: #1: time meter and first note on the +line are too close; #2: last note on the line and next bar are too +close. + +- And I haven't got any feedback on this one, posted last week: + +Check out: + +\score { + \notes \relative c' { + \context Staff < + \context Voice = one { \stemdown c1 c4 } + \context Voice = two { \stemup d1 d4 } + > + } +} + +Notes are shifted as expected. Now check out: + +\score { + \notes \relative c' { + \context Staff < + \context Voice = one { \stemdown c1 } + \context Voice = two { \stemup d1 d4 } + > + } +} + +i.e. do + +- \context Voice = one { \stemdown c1 c4 } ++ \context Voice = one { \stemdown c1 } + +Now the chord collides with the note of the other voice! + . * relative mode for midi2ly +. * +Crescendi/diminuendi that cross a line break lose their vertical +position and all end up above the top staff line, see the +following example. + +---------------- +\score{ + \context StaffGroup < + \context Staff=s1 \notes\relative c'{ + c d e f | + g f e d | \break %% If this break is removed, it works fine + c d e f |} + \context Staff=s2 \notes\relative c'{ + c \< d e f | + g f e d | + c d e \! f |} + > +} . * uniformise recent feta contributions. . * bigger and fatter 4/4 C . * sort out directory stuff. @@ -81,6 +159,7 @@ GNU LilyPond 1.1.54. [/home/fred/usr/src/lilypond/scm/lily.scm] warning: can't find file: `init' . * indent = 0.0 with linewidth=-1.0 +. * collisions & accidentals. . * auto-beaming in input/test/spacing.ly. huh, snap niks van: gewone beam gaat wel goed. hoe kan abe nu invloed hebben op beam-creatie, stopt toch gewoon stokken in? @@ -107,7 +186,6 @@ invloed hebben op beam-creatie, stopt toch gewoon stokken in? . * Beam . * Stem . * Rhythmic_column and interaction stem/rhythmic_column/note_head/dots. -. * Slur . * Duration . * clef engraver . * parser @@ -562,3 +640,12 @@ hesitate to ask. (require 'allout) (outline-init 't) + ++ pl 56.jcn3 ++ - slur de-hairification ++ * slurs always attached to noteheads, by default ++ * corrections for steep and high slurs ++ * snap to stem end when close ++ - bow/tie/slur dy/dx fix ++ ++ diff --git a/input/star-spangled-banner.ly b/input/star-spangled-banner.ly index ef7324b2ca..b609d34d70 100644 --- a/input/star-spangled-banner.ly +++ b/input/star-spangled-banner.ly @@ -1,5 +1,5 @@ %{ -Converted from star.mup with the aid of mup-to-ly.py +Converted from star.mup with the aid of mup2ly.py http://www.Arkkra.com/doc/star.html http://www.Arkkra.com/doc/star.ps %} @@ -57,15 +57,20 @@ $staff2_voice_2 = \notes { g8. g16 fis4.()a,8 d8 e8 fis2 b8 b8 a4. a8 a,4 d2 s4 } -text = \lyrics - { Oh4 __ \repeat fold 2 { } +% hw: how does this work with new repeats? +textx = \lyrics { + Oh4 __ \repeat fold 2 { } \alternative { - { say.4 can you | see,2 by8. the16 dawn's4 ear- ly light2 What8 - so8 proud-4. ly8 we4 hailed,2 At8. the16 twi-4 light's last gleam- - ing. Whose8. broad16 } + { + say.4 can you | see,2 by8. the16 dawn's4 ear- ly light2 What8 + so8 proud-4. ly8 we4 hailed,2 At8. the16 twi-4 light's last gleam- + ing. Whose8. broad16 + } - { stripes4 and bright stars,2 through8. the16 per-4 il- ous fight,2 - O'er8 the8 ram-4. parts8 we4 watched,2 were8. so16 gal-4 lant- ly } + { + stripes4 and bright stars,2 through8. the16 per-4 il- ous fight,2 + O'er8 the8 ram-4. parts8 we4 watched,2 were8. so16 gal-4 lant- ly + } } stream-4 ing. And8. the16 rock-4 ets' red glare,2 the8 bombs8 burst-4 ing in air,2 gave4 proof4. through8 the4 night2 that8. @@ -74,6 +79,27 @@ text = \lyrics and8 the8 home4. of8 the4 brave.2 } +text = \lyrics { + Oh4 __ + %\alternative { + { + say.4 can you | see,2 by8. the16 dawn's4 ear- ly light2 What8 + so8 proud-4. ly8 we4 hailed,2 At8. the16 twi-4 light's last gleam- + ing. Whose8. broad16 + } + + %{ + stripes4 and bright stars,2 through8. the16 per-4 il- ous fight,2 + O'er8 the8 ram-4. parts8 we4 watched,2 were8. so16 gal-4 lant- ly + } + %} + stream-4 ing. And8. the16 rock-4 ets' red glare,2 the8 bombs8 + burst-4 ing in air,2 gave4 proof4. through8 the4 night2 that8. + our16 flag4 was still there,2 Oh4 say, does that star- span- + gled ban- ner yet wave,2 __ O'er8. the16 land2 __ of8 the8 free2 + and8 the8 home4. of8 the4 brave.2 +} + global = \notes { \time 3/4; \key D; diff --git a/lily/beam.cc b/lily/beam.cc index e523466d3c..43975b65dc 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1997--1999, 1998 Han-Wen Nienhuys + (c) 1997--1999 Han-Wen Nienhuys Jan Nieuwenhuizen */ @@ -194,27 +194,29 @@ Beam::get_default_dir () const wants to provide some real simple hands-on rules. We have our doubts, so we simply provide all sensible alternatives. + + If dir is not determined: up (see stem::get_default_dir ()) */ Dir_algorithm a = (Dir_algorithm)rint(paper_l ()->get_var ("beam_dir_algorithm")); switch (a) { case MAJORITY: - beamdir = (count[UP] > count[DOWN]) ? UP : DOWN; + beamdir = (count[UP] >= count[DOWN]) ? UP : DOWN; break; case MEAN: // mean center distance - beamdir = (total[UP] > total[DOWN]) ? UP : DOWN; + beamdir = (total[UP] >= total[DOWN]) ? UP : DOWN; break; default: case MEDIAN: // median center distance + if (!count[DOWN]) + beamdir = UP; if (!count[UP]) beamdir = DOWN; - else if (!count[DOWN]) - beamdir = UP; else - beamdir = (total[UP] / count[UP] > total[DOWN] / count[DOWN]) ? UP : DOWN; + beamdir = (total[UP] / count[UP] >= total[DOWN] / count[DOWN]) ? UP : DOWN; break; } return beamdir; diff --git a/lily/bow.cc b/lily/bow.cc index e5daab3c1b..a3ac0bf073 100644 --- a/lily/bow.cc +++ b/lily/bow.cc @@ -46,8 +46,6 @@ Bow::do_brew_molecule_p () const cout << "dy_f_r: " << dy_f_drul_[RIGHT] << endl; cout << "dy_f: " << dy_f_drul_[RIGHT] - dy_f_drul_[LEFT] << endl; } - a.translate (Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT])); - return new Molecule (a); } @@ -97,14 +95,11 @@ Bow::get_controls () const Array Bow::get_encompass_offset_arr () const { - Offset d (dx_f_drul_[RIGHT] - dx_f_drul_[LEFT], - dy_f_drul_[RIGHT] - dy_f_drul_[LEFT]); - d.x() += extent (X_AXIS). length (); - - Array notes; - notes.push (Offset (0, 0)); - notes.push (d); - - return notes; + Array offset_arr; + offset_arr.push (Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT])); + offset_arr.push (Offset (do_width ().length () + dx_f_drul_[RIGHT], + dy_f_drul_[RIGHT])); + + return offset_arr; } diff --git a/lily/encompass-info.cc b/lily/encompass-info.cc index 0271eba297..8dd95437d4 100644 --- a/lily/encompass-info.cc +++ b/lily/encompass-info.cc @@ -23,33 +23,28 @@ Encompass_info::Encompass_info () assert (0); } -Encompass_info::Encompass_info (Note_column const* note, Direction dir, Slur const* slur_l) +Encompass_info::Encompass_info (Note_column const* note_column, Direction dir, Slur const* slur_l) { interstaff_f_ = 0; - Paper_def* paper = note->paper_l (); - - // UGH - Real notewidth = paper->note_width () * 0.8; - - - Stem* stem_l = note->stem_l_; + Stem* stem_l = note_column->stem_l_; if (!stem_l) { - warning ("Slur over rest?"); - o_[X_AXIS] = note->hpos_f (); + warning (_ ("Slur over rest?")); + o_[X_AXIS] = note_column->hpos_f (); return; } - Real internote = stem_l-> staff_line_leading_f ()/2.; + o_[X_AXIS] = stem_l->hpos_f (); +#if 0 /* + Let's not do this; yields ugly assymetric slurs. + set o_[X_AXIS] to middle of notehead or on the exact position of stem, according to slur direction - */ - o_[X_AXIS] = stem_l->hpos_f (); - /* + stem_l->dir == dir ________ | | / \ @@ -58,18 +53,34 @@ Encompass_info::Encompass_info (Note_column const* note, Direction dir, Slur con */ + dx_f_drul_[d] = -d * spanned_drul_[d]->extent (X_AXIS).length (); + if (stem_l->dir_ != dir) - o_[X_AXIS] -= 0.5 * notewidth * stem_l->dir_; + o_[X_AXIS] -= 0.5 * stem_l->dir_ * note_column->extent (X_AXIS).length (); + +#else - o_[Y_AXIS] = stem_l->extent (Y_AXIS)[dir]; /* - leave a gap: slur mustn't touch head/stem + Instead; simply set x to middle of notehead */ - o_[Y_AXIS] += 2.5 * internote * dir; - if (stem_l->dir_ != dir) - o_[Y_AXIS] += 1.0 * internote * dir; + o_[X_AXIS] -= 0.5 * stem_l->dir_ * note_column->extent (X_AXIS).length (); + +#endif + + if (stem_l->dir_ == dir) + { + o_[Y_AXIS] = stem_l->extent (Y_AXIS)[dir]; + } + else + { + o_[Y_AXIS] = note_column->extent (Y_AXIS)[dir]; + } + /* + leave a gap: slur mustn't touch head/stem + */ + o_[Y_AXIS] += dir * slur_l->paper_l ()->get_var ("slur_y_free"); Dimension_cache *common = stem_l->common_group (slur_l, Y_AXIS); Align_element * align = dynamic_cast (common->element_l ()); @@ -82,7 +93,7 @@ Encompass_info::Encompass_info (Note_column const* note, Direction dir, Slur con interstaff_f_ = align->threshold_interval_[MIN]; Dimension_cache * slur_refpoint = slur_l->dim_cache_[Y_AXIS]; - Dimension_cache * note_refpoint = note->dim_cache_[Y_AXIS]; + Dimension_cache * note_refpoint = note_column->dim_cache_[Y_AXIS]; while (slur_refpoint->parent_l_ != common) slur_refpoint = slur_refpoint->parent_l_; diff --git a/lily/include/slur.hh b/lily/include/slur.hh index 5f634e700c..bf61df4b86 100644 --- a/lily/include/slur.hh +++ b/lily/include/slur.hh @@ -15,10 +15,6 @@ */ class Slur : public Bow { - bool broken_edge_b ( Direction dir) const; - bool normal_edge_b ( Direction dir) const; - Drul_array extrema () const; - public: Slur (); VIRTUAL_COPY_CONS(Score_element); diff --git a/lily/misc.cc b/lily/misc.cc index ae015bdbc1..3f1f2ad949 100644 --- a/lily/misc.cc +++ b/lily/misc.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1997--1999, 1998 Han-Wen Nienhuys + (c) 1997--1999 Han-Wen Nienhuys Jan Nieuwenhuizen */ diff --git a/lily/slur.cc b/lily/slur.cc index 827e9a0222..82aaa7e544 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -3,16 +3,14 @@ source file of the GNU LilyPond music typesetter - (c) 1996, 1997--1999, 1998 Han-Wen Nienhuys + (c) 1996, 1997--1999 Han-Wen Nienhuys Jan Nieuwenhuizen */ /* [TODO] - * URG: share code with tie - * begin and end should be treated as a Script. - * damping - * slur from notehead to stemend: c''()b'' + * begin and end should be treated as a/acknowledge Scripts. + * broken slur should have uniform trend */ #include "slur.hh" @@ -42,7 +40,6 @@ Slur::add_column (Note_column*n) else { encompass_arr_.push (n); - // n->stem_l_->slur_l_ = this; add_dependency (n); } } @@ -95,36 +92,6 @@ Note_column_compare (Note_column *const&n1 , Note_column* const&n2) return Item::left_right_compare (n1, n2); } -bool -Slur::broken_edge_b ( Direction dir) const -{ - return extrema ()[dir] != spanned_drul_[dir]; -} - -bool -Slur::normal_edge_b ( Direction dir) const -{ - Note_column *n = extrema ()[dir]; - return !broken_edge_b ( dir) - && n->stem_l_ - && n->stem_l_->get_elt_property (transparent_scm_sym) == SCM_BOOL_F - && n->head_l_arr_.size (); -} - -Drul_array -Slur::extrema ()const -{ - Drul_array extrema; - extrema[LEFT] = encompass_arr_[0]; - extrema[RIGHT] = encompass_arr_.top (); - return extrema; -} - -/* - TODO. - - Unhair this. - */ void Slur::do_post_processing () { @@ -132,237 +99,231 @@ Slur::do_post_processing () if (!dir_) dir_ = get_default_dir (); - Real interline_f = paper_l ()->get_realvar (interline_scm_sym); - Real internote_f = interline_f / 2; - // URG - Real notewidth_f = paper_l ()->note_width () * 0.8; - /* - [OSU]: slur and tie placement + Slur and tie placement [OSU] - slurs: - * x = center of head (upside-down: inner raakpunt stem) - d * gap + Slurs: + * x = centre of head - d * x_gap_f - * y = length < 5ss : horizontal raakpunt + d * 0.25 ss + TODO: + * y = length < 5ss : horizontal tangent + d * 0.25 ss y = length >= 5ss : y next interline - d * 0.25 ss - --> height <= 5 length ?? we use <= 3 length, now... */ - - Real gap_f = paper_l ()->get_var ("slur_x_gap"); + Real interline_f = paper_l ()->get_realvar (interline_scm_sym); + Real internote_f = interline_f / 2; + + Real x_gap_f = paper_l ()->get_var ("slur_x_gap"); + Real y_gap_f = paper_l ()->get_var ("slur_y_gap"); + + Drul_array note_column_drul; + note_column_drul[LEFT] = encompass_arr_[0]; + note_column_drul[RIGHT] = encompass_arr_.top (); - Direction d=LEFT; - + bool fix_broken_b = false; + Direction d = LEFT; do { - if (broken_edge_b (d)) + dx_f_drul_[d] = dy_f_drul_[d] = 0; + if ((note_column_drul[d] == spanned_drul_[d]) + && note_column_drul[d]->head_l_arr_.size () + && (note_column_drul[d]->stem_l_)) { - // ugh -- check if needed - dx_f_drul_[d] = -d - *(spanned_drul_[d]->extent (X_AXIS).length () - 0.5 * notewidth_f); - - // prebreak - if (d == RIGHT) + Stem* stem_l = note_column_drul[d]->stem_l_; + /* + side directly attached to note head; + no beam getting in the way + */ + if (((stem_l->get_elt_property (transparent_scm_sym) != SCM_BOOL_F) + || !((stem_l->dir_ == dir_) && (dir_ != d))) + && !((dir_ == stem_l->dir_) + && stem_l->beam_l_ && (stem_l->beams_i_drul_[-d] >= 1))) { - dx_f_drul_[LEFT] = spanned_drul_[LEFT]->extent (X_AXIS).length (); - - // urg -- check if needed - if (encompass_arr_.size () > 1) - dx_f_drul_[RIGHT] += notewidth_f; + dx_f_drul_[d] = spanned_drul_[d]->extent (X_AXIS).length () / 2; + dx_f_drul_[d] -= d * x_gap_f; + + if (stem_l->dir_ != dir_) + { + dy_f_drul_[d] = note_column_drul[d]->extent (Y_AXIS)[dir_]; + } + else + { + dy_f_drul_[d] = stem_l->chord_start_f () + + dir_ * internote_f; + } + dy_f_drul_[d] += dir_ * y_gap_f; } - } - /* - normal slur - */ - else if (normal_edge_b (d)) - { - Real notewidth_f = extrema ()[d]->extent (X_AXIS).length (); - dy_f_drul_[d] = (int)rint (extrema ()[d]->stem_l_-> extent (Y_AXIS)[dir_]); - dx_f_drul_[d] += 0.5 * notewidth_f - d * gap_f; - if (dir_ == extrema ()[d]->stem_l_->dir_) + /* + side attached to (visible) stem + */ + else { - if (dir_ == d) - dx_f_drul_[d] += 0.5 * dir_ * notewidth_f; + dx_f_drul_[d] = stem_l->hpos_f () + - spanned_drul_[d]->absolute_coordinate (X_AXIS); + /* + side attached to beamed stem + */ + if (stem_l->beam_l_ && (stem_l->beams_i_drul_[-d] >= 1)) + { + dy_f_drul_[d] = stem_l->extent (Y_AXIS)[dir_]; + dy_f_drul_[d] += dir_ * 2 * y_gap_f; + } + /* + side attached to notehead, with stem getting in the way + */ else - dx_f_drul_[d] += 0.25 * dir_ * notewidth_f; + { + dx_f_drul_[d] -= d * x_gap_f; + + dy_f_drul_[d] = stem_l->chord_start_f () + + dir_ * internote_f; + dy_f_drul_[d] += dir_ * y_gap_f; + } } } - else - { - Real notewidth_f = extrema ()[d]->extent (X_AXIS).length (); - dy_f_drul_[d] = (int)rint (extrema ()[d]->head_positions_interval () - [dir_]) * internote_f; - dx_f_drul_[d] += 0.5 * notewidth_f - d * gap_f; + /* + loose end + */ + else + { + dx_f_drul_[d] -= d * x_gap_f; + /* + broken: should get y from other piece, so that slur + continues up/down trend + + for now: be horizontal.. + */ + fix_broken_b = true; } - dy_f_drul_[d] += dir_ * interline_f; - if (extrema ()[d]->stem_l_ && (dir_ == extrema ()[d]->stem_l_->dir_)) - dy_f_drul_[d] -= dir_ * internote_f; - } - while (flip(&d) != LEFT); + } + while (flip (&d) != LEFT); - // now that both are set, do dependent - do - { - if (broken_edge_b (d)) - { - Direction u = d; - flip(&u); + if (fix_broken_b) + do { + if (dy_f_drul_[d]) + dy_f_drul_[-d] = dy_f_drul_[d]; + } + while (flip (&d) != LEFT); + + + /* + Now we've got a fine slur + Catch and correct some ugly cases + */ - // postbreak - if (d == LEFT) - dy_f_drul_[u] += dir_ * internote_f; + Real dx_f = do_width ().length () + dx_f_drul_[RIGHT] - dx_f_drul_[LEFT]; + Real dy_f = dy_f_drul_[RIGHT] - dy_f_drul_[LEFT]; + Real height_f = do_height ().length (); - dy_f_drul_[d] = dy_f_drul_[u]; - } - } - while (flip(&d) != LEFT); + Real height_damp_f = paper_l ()->get_var ("slur_height_damping"); + Real slope_damp_f = paper_l ()->get_var ("slur_slope_damping"); + Real ratio_f; + + + /* + Avoid too steep slurs. + */ + ratio_f = abs (dy_f / dx_f); + if (ratio_f > slope_damp_f) + { + Direction d = (Direction)(- dir_ * (sign (dy_f))); + if (!d) + d = LEFT; + dy_f_drul_[d] += dir_ * (ratio_f - slope_damp_f) * dx_f; + } /* - Slur should follow line of music + Avoid too high slurs */ - if (normal_edge_b (LEFT) - && normal_edge_b (RIGHT) - && (extrema ()[LEFT]->stem_l_ != extrema ()[RIGHT]->stem_l_)) + ratio_f = abs (height_f / dx_f); + if (ratio_f > height_damp_f) { - Real note_dy = extrema ()[RIGHT]->stem_l_->head_positions ()[dir_] - - extrema ()[LEFT]->stem_l_->head_positions ()[dir_]; - Real dy = dy_f_drul_[RIGHT] - dy_f_drul_[LEFT]; + Direction d = (Direction)(- dir_ * (sign (dy_f))); + if (!d) + d = LEFT; + dy_f_drul_[d] += dir_ * height_f * height_damp_f; /* - Should we always follow note-heads, (like a tie)? - For now, only if the note_dy != slur_dy, we'll do - slur_dy := note_dy * factor. - */ - if (sign (dy) != sign (note_dy)) + if y positions at same height, correct both ends + */ + if (abs (dy_f / dx_f ) < slope_damp_f) { - Real damp_f = paper_l ()->get_var ("slur_slope_follow_music_factor"); - Real realdy = note_dy * damp_f; - Direction adjust_dir = (Direction)(- dir_ * sign (realdy)); - if (!adjust_dir) - adjust_dir = -dir_; - /* - adjust only if no beam gets in the way - */ - if (!extrema ()[adjust_dir]->stem_l_->beam_l_ - || (adjust_dir == extrema ()[adjust_dir]->stem_l_->dir_) - || (extrema ()[adjust_dir]->stem_l_->beams_i_drul_[-adjust_dir] < 1)) - { - dy_f_drul_[adjust_dir] = dy_f_drul_[-adjust_dir] - + 2 * adjust_dir * realdy; - Real dx = notewidth_f / 2; - if (adjust_dir != extrema ()[adjust_dir]->stem_l_->dir_) - dx /= 2; - dx_f_drul_[adjust_dir] -= adjust_dir * dx; - } + dy_f_drul_[-d] += dir_ * height_f * height_damp_f; } } /* - Avoid too steep slurs. - */ - Real damp_f = paper_l ()->get_var ("slur_slope_damping"); - Offset d_off = Offset (dx_f_drul_[RIGHT] - dx_f_drul_[LEFT], - dy_f_drul_[RIGHT] - dy_f_drul_[LEFT]); - d_off[X_AXIS] += extent (X_AXIS).length (); - - Real ratio_f = abs (d_off[Y_AXIS] / d_off[X_AXIS]); - if (ratio_f > damp_f) - dy_f_drul_[(Direction)(- dir_ * sign (d_off[Y_AXIS]))] += - dir_ * (ratio_f - damp_f) * d_off[X_AXIS]; + If, after correcting, we're close to stem-end... + */ + Real snap_f = paper_l ()->get_var ("slur_snap_to_stem"); + do + { + if ((note_column_drul[d] == spanned_drul_[d]) + && (note_column_drul[d]->stem_l_) + && (note_column_drul[d]->stem_l_->dir_ == dir_) + && (abs (note_column_drul[d]->stem_l_->extent (Y_AXIS)[dir_] + - dy_f_drul_[d]) <= snap_f)) + { + /* + attach to stem-end + */ + Stem* stem_l = note_column_drul[d]->stem_l_; + dx_f_drul_[d] = stem_l->hpos_f () + - spanned_drul_[d]->absolute_coordinate (X_AXIS); + dy_f_drul_[d] = stem_l->extent (Y_AXIS)[dir_]; + dy_f_drul_[d] += dir_ * 2 * y_gap_f; + } + } + while (flip (&d) != LEFT); } Array Slur::get_encompass_offset_arr () const { - Real notewidth = paper_l ()->note_width () * 0.8; - Real gap = paper_l ()->get_var ("slur_x_gap"); - - /* - urg. Calcs done wrt the leftmost note. Fixme. - - Calcs ignore possibility of pre/postbreak. - - - */ - - Offset left = Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT]); - left[X_AXIS] += encompass_arr_[0]->stem_l_->hpos_f (); - - Real internote = encompass_arr_[0]->stem_l_->staff_line_leading_f ()/2.0; - - /* - - i don't understand these two, but *must* for symmetry - look at encompass array: - lilypond -D input/test/slur-symmetry*.ly - lilypond -D input/test/sleur.ly - - do_post_processing should have calculated these into - dx_f_drul_[], no?? - - */ - - if (dir_ != encompass_arr_[0]->stem_l_->dir_) - left[X_AXIS] += - 0.5 * notewidth * encompass_arr_[0]->stem_l_->dir_ - + gap; - else if (encompass_arr_[0]->stem_l_->dir_ == UP) - left[X_AXIS] -= notewidth; - - if ((dir_ == encompass_arr_[0]->stem_l_->dir_) - && (encompass_arr_[0]->stem_l_->dir_ == DOWN)) - left[Y_AXIS] -= internote * encompass_arr_[0]->stem_l_->dir_; - /* */ - - Offset d = Offset (dx_f_drul_[RIGHT] - dx_f_drul_[LEFT], - dy_f_drul_[RIGHT] - dy_f_drul_[LEFT]); - d[X_AXIS] += extent (X_AXIS).length (); + Array offset_arr; + Offset origin (absolute_coordinate (X_AXIS), 0); int first = 1; - int last = encompass_arr_.size () - 1; + int last = encompass_arr_.size () - 2; - - Array notes; - notes.push (Offset (0,0)); - - // prebreak - if (broken_edge_b (RIGHT)) - last++; - else - { - Encompass_info info (encompass_arr_.top (), dir_, this); - d[Y_AXIS] += info.interstaff_f_; - } - - // postbreak - if (broken_edge_b (LEFT)) + /* + left is broken edge + */ + if (encompass_arr_[0] != spanned_drul_[LEFT]) { first--; - /* - interstaff postbreak: slur begins at height of last note - */ - Encompass_info info (encompass_arr_[0], dir_, this); - notes[0][Y_AXIS] += info.interstaff_f_; } - else + Encompass_info left_info (encompass_arr_[0], dir_, this); + offset_arr.push (Offset (0, left_info.interstaff_f_)); + + /* + right is broken edge + */ + if (encompass_arr_.top () != spanned_drul_[RIGHT]) { - Encompass_info info (encompass_arr_[0], dir_, this); - notes[0][Y_AXIS] += info.interstaff_f_; + last++; } - for (int i = first; i < last; i++) + for (int i = first; i <= last; i++) { Encompass_info info (encompass_arr_[i], dir_, this); - notes.push (info.o_ - left); + offset_arr.push (info.o_ - origin); } - /* - interstaff prebreak: slur ends at height of last note - */ - if (broken_edge_b (RIGHT)) - d[Y_AXIS] = notes.top ()[Y_AXIS]; + offset_arr.push (Offset (do_width ().length (), 0)); - notes.push (d); +#if 1 + offset_arr[0] += Offset (dx_f_drul_[LEFT], dy_f_drul_[LEFT]); + offset_arr.top () += Offset (dx_f_drul_[RIGHT], dy_f_drul_[RIGHT]); +#else + /* + check non-disturbed slur + FIXME: ends off by a tiny bit!! + */ + offset_arr[0] += Offset (0, dy_f_drul_[LEFT]); + offset_arr.top () += Offset (0, dy_f_drul_[RIGHT]); +#endif - return notes; + return offset_arr; } diff --git a/lily/spanner.cc b/lily/spanner.cc index 17ca378449..9fbd9b8226 100644 --- a/lily/spanner.cc +++ b/lily/spanner.cc @@ -41,7 +41,6 @@ Spanner::break_into_pieces () } Link_array break_points = pscore_l_->broken_col_range (left,right); - Link_array broken_into_l_arr; break_points.insert (left,0); break_points.push (right); diff --git a/ly/params.ly b/ly/params.ly index afc68d5ab7..47b28f061e 100644 --- a/ly/params.ly +++ b/ly/params.ly @@ -87,17 +87,23 @@ beam_steep_slope = 0.2 / 1.0; % OSU: suggested gap = ss / 5; slur_x_gap = \interline / 5.0; +slur_y_gap = 0.25 * \interline; +slur_y_free = 0.75 * \interline; slur_x_minimum = 3.0 * \interline; % slope damping: keep dy/dx < slur_slope_damping -slur_slope_damping = 0.6; - -% dy_slur := dy_music * factor -slur_slope_follow_music_factor = 0.8; +slur_slope_damping = 0.3; +% height damping: keep h/dx < slur_height_damping +slur_height_damping = 0.5; +% snap to stem if slur ends closer to stem than +slur_snap_to_stem = 1.5 * \interline; tie_x_minimum = \slur_x_minimum; +% OSU: tie gap == slur gap tie_x_gap = \slur_x_gap; -tie_slope_damping = 0.8; +tie_y_gap = 0.25 * \interline; +% length of a tie that's a staffspace high +tie_staffspace_length = 4.0 * \interline; % ugh: rename to bow (in bezier.cc and fonts.doc too...) % slur_thickness = 1.8 * \staffline; @@ -180,6 +186,8 @@ postBreakPadding = 0.0; stemSpacingCorrection = 0.5*\interline; +% relative strength of space following time signature, +non_musical_space_strength = 4.0;