X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fnote-spacing.cc;h=3c6fca58036d673c9bf1e905b6e407b5f5e32cd3;hb=5d7a663ab5450018118c99fc48263c18f2df52dc;hp=95ba49aa64a7a271f06dd4261dddb62ace9e0cbf;hpb=91efee074adda04245d08c45af153eab5ac6bd34;p=lilypond.git diff --git a/lily/note-spacing.cc b/lily/note-spacing.cc index 95ba49aa64..3c6fca5803 100644 --- a/lily/note-spacing.cc +++ b/lily/note-spacing.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 2001--2002 Han-Wen Nienhuys + (c) 2001--2003 Han-Wen Nienhuys */ @@ -17,7 +17,8 @@ #include "stem.hh" #include "separation-item.hh" #include "staff-spacing.hh" - +#include "accidental-placement.hh" +#include "paper-def.hh" void Note_spacing::get_spacing (Grob *me, Item* right_col, @@ -49,13 +50,13 @@ Note_spacing::get_spacing (Grob *me, Item* right_col, if (!it) continue; - Item *it_col = it->column_l (); + Item *it_col = it->get_column (); if (d == RIGHT && right_col != it_col) continue; if (Separation_item::has_interface (it)) { - extents[d].unite (Separation_item::my_width (it)); + extents[d].unite (Separation_item::width (it)); continue; } @@ -66,6 +67,10 @@ Note_spacing::get_spacing (Grob *me, Item* right_col, if (!g) g = Note_column::first_head (it); + /* + Ugh. If Stem is switched off, we don't know what the + first note head will be. + */ if (g) left_head_wid = g->extent(it_col, X_AXIS); } @@ -78,11 +83,16 @@ Note_spacing::get_spacing (Grob *me, Item* right_col, accs = Note_column::accidentals (it->get_parent (X_AXIS)); if (accs) - extents[d].unite (accs->extent (it_col, X_AXIS)); + { + Interval v = + Accidental_placement::get_relevant_accidental_extent (accs, it_col, me); + + extents[d].unite (v); + } } } - if (extents[d].empty_b ()) + if (extents[d].is_empty ()) extents[d] = Interval (0,0); } while (flip (&d) != LEFT); @@ -94,35 +104,57 @@ Note_spacing::get_spacing (Grob *me, Item* right_col, What is sticking out of the note head (eg. a flag), doesn't get the full amount of space. + + FIXED also includes the left part of the right object. */ - *fixed = left_head_wid.empty_b () ? increment : left_head_wid[RIGHT]; - *space = (base_space - increment) + *fixed + - (extents[LEFT][RIGHT] - left_head_wid[RIGHT])/ 2; - ; + *fixed = + (left_head_wid.is_empty () ? increment : + /* + Size of the head: + */ + (left_head_wid[RIGHT]+ - if (*space - *fixed < 2 * ((- extents[RIGHT][LEFT]) >? 0)) + /* + What's sticking out of the head, eg. a flag: + */ + (extents[LEFT][RIGHT] - left_head_wid[RIGHT])/2)) + + /* + What is sticking out of the right note: + */ + + (extents[RIGHT].is_empty () ? 0.0 : - extents[RIGHT][LEFT] / 2); + + /* + We don't do complicated stuff: (base_space - increment) is the + normal amount of white, which also determines the amount of + stretch. Upon (extreme) stretching, notes with accidentals should + stretch as much as notes without accidentals. + */ + *space = (base_space - increment) + *fixed ; + + if (Item::breakable_b (right_col) + || right_col->original_) { /* - - What's sticking out at the left of the right side has less - influence. We only take it into account if there is not enough - space. + This is for the situation - this sucks: this criterion is discontinuous; FIXME. - */ - *space += 0.5 * (( -extents[RIGHT][LEFT]) >? 0); + rest | 3/4 (eol) + + */ + *space += -extents[RIGHT][LEFT]; + *fixed += -extents[RIGHT][LEFT]; } - + stem_dir_correction (me, right_col, increment, space, fixed); } Item * Note_spacing::left_column (Grob *me) { - if (me->immutable_property_alist_ == SCM_EOL) + if (!me->live()) return 0; - return dynamic_cast (me)->column_l (); + return dynamic_cast (me)->get_column (); } /* @@ -136,10 +168,7 @@ prune RIGHT-ITEMS. Item * Note_spacing::right_column (Grob*me) { - /* - ugh. should have generic is_live() method? - */ - if (me->immutable_property_alist_ == SCM_EOL) + if (!me->live()) return 0; SCM right = me->get_grob_property ("right-items"); @@ -150,8 +179,8 @@ Note_spacing::right_column (Grob*me) { Item * ri = unsmob_item (gh_car (s)); - Item * col = ri->column_l (); - int rank = Paper_column::rank_i (col); + Item * col = ri->get_column (); + int rank = Paper_column::get_rank (col); if (rank < min_rank) { @@ -169,7 +198,7 @@ Note_spacing::right_column (Grob*me) SCM newright = SCM_EOL; for (SCM s = right ; gh_pair_p (s) ; s =gh_cdr (s)) { - if (unsmob_item (gh_car (s))->column_l () == mincol) + if (unsmob_item (gh_car (s))->get_column () == mincol) newright = gh_cons (gh_car (s), newright); } @@ -179,7 +208,7 @@ Note_spacing::right_column (Grob*me) if (!mincol) { /* - int r = Paper_column::rank_i (dynamic_cast(me)->column_l ()); + int r = Paper_column::get_rank (dynamic_cast(me)->get_column ()); programming_error (_f("Spacing wish column %d has no right item.", r)); */ @@ -209,14 +238,14 @@ Note_spacing::stem_dir_correction (Grob*me, Item * rcolumn, me->get_grob_property ("right-items")); Drul_array beams_drul(0,0); - Real correction = 0.0; + Drul_array stems_drul(0,0); stem_dirs[LEFT] = stem_dirs[RIGHT] = CENTER; Interval intersect; Interval bar_xextent; Interval bar_yextent; - bool correct = true; + bool correct_stem_dirs = true; Direction d = LEFT; bool acc_right = false; @@ -229,18 +258,18 @@ Note_spacing::stem_dir_correction (Grob*me, Item * rcolumn, if (d == RIGHT) acc_right = acc_right || Note_column::accidentals (it); - Grob *stem = Note_column::stem_l (it); + Grob *stem = Note_column::get_stem (it); - if (!stem) + if (!stem || !stem->live ()) { if (d == RIGHT && Separation_item::has_interface (it)) { - if (it->column_l () != rcolumn) + if (it->get_column () != rcolumn) { it = it->find_prebroken_piece (rcolumn->break_status_dir ()); } - Grob *last = Staff_spacing::extremal_break_aligned_grob (it, LEFT, &bar_xextent); + Grob *last = Separation_item::extremal_break_aligned_grob (it, LEFT, &bar_xextent); if (last) bar_yextent = Staff_spacing::bar_y_positions (last); @@ -253,16 +282,19 @@ Note_spacing::stem_dir_correction (Grob*me, Item * rcolumn, if(Stem::invisible_b (stem)) { - return ; + correct_stem_dirs = false; + continue; } - beams_drul[d] = Stem::beam_l (stem); + stems_drul[d] = stem; + beams_drul[d] = Stem::get_beam (stem); Direction sd = Stem::get_direction (stem); if (stem_dirs[d] && stem_dirs[d] != sd) { - return ; + correct_stem_dirs = false; + continue; } stem_dirs[d] = sd; @@ -271,14 +303,11 @@ Note_spacing::stem_dir_correction (Grob*me, Item * rcolumn, hanging from the note. */ if (d == LEFT - && Stem::duration_log (stem) > 2 && !Stem::beam_l (stem)) + && Stem::duration_log (stem) > 2 && !Stem::get_beam (stem)) { - - return; + correct_stem_dirs = false; } - - Interval hp = Stem::head_positions (stem); Real chord_start = hp[sd]; Real stem_end = Stem::stem_end_position (stem); @@ -292,54 +321,77 @@ Note_spacing::stem_dir_correction (Grob*me, Item * rcolumn, /* don't correct if accidentals are sticking out of the right side. - */ if (acc_right) return ; - if (!bar_yextent.empty_b()) + Real correction = 0.0; + + if (!bar_yextent.is_empty ()) { stem_dirs[RIGHT] = - stem_dirs[LEFT]; stem_posns[RIGHT] = bar_yextent; } - if (correct &&stem_dirs[LEFT] *stem_dirs[RIGHT] == -1) + if (correct_stem_dirs && stem_dirs[LEFT] *stem_dirs[RIGHT] == -1) { if (beams_drul[LEFT] && beams_drul[LEFT] == beams_drul[RIGHT]) { + /* this is a knee: maximal correction. */ - - correction = increment* stem_dirs[LEFT]; - *fixed += increment* stem_dirs[LEFT]; + Real note_head_width = increment; + Grob * st = stems_drul[RIGHT]; + Grob * head = st ? Stem::support_head (st) : 0; + + Interval head_extent; + if (head) + { + head_extent = head->extent (rcolumn, X_AXIS); + + if (!head_extent.is_empty ()) + note_head_width = head_extent[RIGHT]; + + if (st) + { + Real thick = Stem::thickness (st); + + note_head_width -= thick; + } + } + + correction = note_head_width* stem_dirs[LEFT]; + correction *= robust_scm2double (me->get_grob_property ("knee-spacing-correction"), 0); + *fixed += correction; } else { intersect = stem_posns[LEFT]; intersect.intersect(stem_posns[RIGHT]); - correct = correct && !intersect.empty_b (); + correct_stem_dirs = correct_stem_dirs && !intersect.is_empty (); - if (!correct) - return; - - correction = abs (intersect.length ()); + if (correct_stem_dirs) + { + correction =abs (intersect.length ()); - /* - Ugh. 7 is hardcoded. - */ - correction = (correction/7) get_grob_property ("stem-spacing-correction")); - - if (!bar_yextent.empty_b()) + /* + Ugh. 7 is hardcoded. + */ + correction = (correction/7) get_grob_property ("stem-spacing-correction"), 0); + } + + if (!bar_yextent.is_empty ()) { correction *= 0.5; } } } - else if (correct && stem_dirs[LEFT] *stem_dirs[RIGHT] == UP) + else if (correct_stem_dirs && stem_dirs[LEFT] *stem_dirs[RIGHT] == UP) { /* Correct for the following situation: @@ -363,23 +415,25 @@ Note_spacing::stem_dir_correction (Grob*me, Item * rcolumn, Interval hp = head_posns[LEFT]; hp.intersect (head_posns[RIGHT]); - if (!hp.empty_b()) + if (!hp.is_empty ()) return ; Direction lowest = (head_posns[LEFT][DOWN] > head_posns[RIGHT][UP]) ? RIGHT : LEFT; Real delta = head_posns[-lowest][DOWN] - head_posns[lowest][UP] ; - Real corr = gh_scm2double (me->get_grob_property ("stem-spacing-correction")); + Real corr = robust_scm2double (me->get_grob_property ("stem-spacing-correction"), 0); corr = (delta <= 1) ? 0.0 : 0.25; correction= -lowest * corr ; } - if (!bar_xextent.empty_b()) - correction += - bar_xextent[LEFT]; - *space += correction; + + /* there used to be a correction for bar_xextent() here, but + it's unclear what that was good for ? + */ + } @@ -387,5 +441,5 @@ Note_spacing::stem_dir_correction (Grob*me, Item * rcolumn, ADD_INTERFACE (Note_spacing,"note-spacing-interface", "", - "left-items right-items stem-spacing-correction"); + "left-items right-items stem-spacing-correction knee-spacing-correction");