X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fstem.cc;h=69e7a15ce6328f59d356daed30c4c77cf303afe1;hb=3ee0df13c3fe001cef0bef15adcbadfb2c394fd8;hp=8a59a4909cf777997280b98ca6481fc3909e28a1;hpb=6faae8735988dec671fcf8a67a4e09a0b74325eb;p=lilypond.git diff --git a/lily/stem.cc b/lily/stem.cc index 8a59a4909c..69e7a15ce6 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -48,8 +48,12 @@ Stem::set_beaming (Grob *me, int beam_count, Direction d) } SCM lst = index_get_cell (pair, d); - for (int i = 0; i < beam_count; i++) - lst = scm_cons (scm_from_int (i), lst); + if (beam_count) + for (int i = 0; i < beam_count; i++) + lst = scm_cons (scm_from_int (i), lst); + else + lst = SCM_BOOL_F; + index_set_cell (pair, d, lst); } @@ -61,7 +65,9 @@ Stem::get_beaming (Grob *me, Direction d) return 0; SCM lst = index_get_cell (pair, d); - return scm_ilength (lst); + + int len = scm_ilength (lst); + return max (len, 0); } Interval @@ -174,12 +180,6 @@ Stem::extremal_heads (Grob *me) return exthead; } -static int -integer_compare (int const &a, int const &b) -{ - return a - b; -} - /* The positions, in ascending order. */ vector Stem::note_head_positions (Grob *me) @@ -195,7 +195,7 @@ Stem::note_head_positions (Grob *me) ps.push_back (p); } - vector_sort (ps, integer_compare); + vector_sort (ps, less ()); return ps; } @@ -221,6 +221,32 @@ Stem::is_invisible (Grob *me) && scm_to_int (me->get_property ("duration-log")) >= 1); } +MAKE_SCHEME_CALLBACK (Stem, pure_height, 3) +SCM +Stem::pure_height (SCM smob, SCM start, SCM end) +{ + (void) start; + (void) end; + + + Grob *me = unsmob_grob (smob); + Real ss = Staff_symbol_referencer::staff_space (me); + Real len = scm_to_double (calc_length (smob)) * ss / 2; + Direction dir = get_grob_direction (me); + + Interval iv; + Interval hp = head_positions (me); + if (dir == UP) + iv = Interval (0, len); + else + iv = Interval (-len, 0); + + if (!hp.is_empty ()) + iv.translate (hp[dir] * ss / 2); + + return ly_interval2scm (iv); +} + MAKE_SCHEME_CALLBACK (Stem, calc_stem_end_position, 1) SCM Stem::calc_stem_end_position (SCM smob) @@ -230,6 +256,11 @@ Stem::calc_stem_end_position (SCM smob) if (!head_count (me)) return scm_from_double (0.0); + if (Grob *beam = get_beam (me)) + { + (void) beam->get_property ("quantized-positions"); + return me->get_property ("stem-end-position"); + } Real ss = Staff_symbol_referencer::staff_space (me); int durlog = duration_log (me); @@ -335,17 +366,21 @@ Stem::calc_length (SCM smob) + 2 * t_flag->extent (t_flag, Y_AXIS).length () / ss; + /* We don't want to add the whole extent of the flag because the trem + and the flag can overlap partly. beam_translation gives a good + approximation */ if (durlog >= 3) - { - Interval flag_ext = flag (me).extent (Y_AXIS); - if (!flag_ext.is_empty ()) - minlen += 2 * flag_ext.length () / ss; - - /* The clash is smaller for down stems (since the tremolo is - angled up.) */ - if (dir == DOWN) - minlen -= 1.0; - } + { + Real beam_trans = Stem_tremolo::get_beam_translation (t_flag); + /* the obvious choice is (durlog - 2) here, but we need a bit more space. */ + minlen += 2 * (durlog - 1.5) * beam_trans; + + /* up-stems need even a little more space to avoid collisions. This + needs to be in sync with the tremolo positioning code in + Stem_tremolo::print */ + if (dir == UP) + minlen += beam_trans; + } length = max (length, minlen + 1.0); } @@ -369,7 +404,7 @@ Stem::calc_positioning_done (SCM smob) extract_grob_set (me, "note-heads", ro_heads); vector heads (ro_heads); - vector_sort (heads, compare_position); + vector_sort (heads, position_less); Direction dir = get_grob_direction (me); if (dir < 0) @@ -384,12 +419,25 @@ Stem::calc_positioning_done (SCM smob) dir = UP; set_grob_direction (me, dir); } - + + bool is_harmonic_centered = false; + for (vsize i = 0; i < heads.size (); i++) + is_harmonic_centered = is_harmonic_centered + || heads[i]->get_property ("style") == ly_symbol2scm ("harmonic"); + is_harmonic_centered = is_harmonic_centered && is_invisible (me); + Real w = hed->extent (hed, X_AXIS)[dir]; for (vsize i = 0; i < heads.size (); i++) - heads[i]->translate_axis (w - heads[i]->extent (heads[i], X_AXIS)[dir], - X_AXIS); + { + Real amount = w - heads[i]->extent (heads[i], X_AXIS)[dir]; + if (is_harmonic_centered) + amount = + hed->extent (hed, X_AXIS).linear_combination (CENTER) + - heads[i]->extent (heads[i], X_AXIS).linear_combination (CENTER); + + heads[i]->translate_axis (amount, X_AXIS); + } bool parity = true; Real lastpos = Real (Staff_symbol_referencer::get_position (heads[0])); for (vsize i = 1; i < heads.size (); i++) @@ -645,6 +693,8 @@ SCM Stem::print (SCM smob) { Grob *me = unsmob_grob (smob); + Grob *beam = get_beam (me); + Stencil mol; Direction d = get_grob_direction (me); @@ -658,7 +708,6 @@ Stem::print (SCM smob) = to_boolean (me->get_property ("avoid-note-head")) ? last_head (me) : first_head (me); - Grob *beam = get_beam (me); if (!lh && !stemlet) return SCM_EOL; @@ -798,7 +847,6 @@ Stem::get_stem_info (Grob *me) return si; } -/* TODO: add extra space for tremolos! */ MAKE_SCHEME_CALLBACK(Stem, calc_stem_info, 1); SCM Stem::calc_stem_info (SCM smob) @@ -847,6 +895,13 @@ Stem::calc_stem_info (SCM smob) * staff_space * length_fraction; + Real height_of_my_trem = 0.0; + Grob *trem = unsmob_grob (me->get_object ("tremolo-flag")); + if (trem) + height_of_my_trem = trem->extent (trem, Y_AXIS).length () + /* hack a bit of space around the trem. */ + + beam_translation; + /* UGH It seems that also for ideal minimum length, we must use the maximum beam count (for this direction): @@ -859,6 +914,7 @@ Stem::calc_stem_info (SCM smob) Real ideal_minimum_length = ideal_minimum_free + height_of_my_beams + + height_of_my_trem /* stem only extends to center of beam */ - 0.5 * beam_thickness; @@ -908,18 +964,11 @@ Stem::calc_stem_info (SCM smob) * staff_space * length_fraction; - Real minimum_length = minimum_free + Real minimum_length = max (minimum_free, height_of_my_trem) + height_of_my_beams /* stem only extends to center of beam */ - 0.5 * beam_thickness; - if (Grob *tremolo = unsmob_grob (me->get_object ("tremolo-flag"))) - { - Interval y_ext = tremolo->extent (tremolo, Y_AXIS); - y_ext.widen (0.5); // FIXME. Should be tunable? - minimum_length = max (minimum_length, y_ext.length ()); - } - ideal_y *= my_dir; Real minimum_y = note_start + minimum_length; Real shortest_y = minimum_y * my_dir; @@ -974,6 +1023,7 @@ ADD_INTERFACE (Stem, "stem-interface", "french-beaming " "length " "length-fraction " + "max-beam-connect " "neutral-direction " "no-stem-extend " "note-heads "