From 3085ee6e9f67b0927797fc5e92249cd9d4ad0089 Mon Sep 17 00:00:00 2001 From: janneke Date: Thu, 25 Jul 2002 23:29:33 +0000 Subject: [PATCH] Fix to also work if some dirs are not set. For knees, set stems to their natural direction. Don't force stems of kneed beams to reach middle staff line. Recalculate beam position after deciding for a knee. --- ChangeLog | 17 +++++- lily/beam-quanting.cc | 4 +- lily/beam.cc | 134 ++++++++++++++++++++++-------------------- lily/stem.cc | 6 +- 4 files changed, 93 insertions(+), 68 deletions(-) diff --git a/ChangeLog b/ChangeLog index e44454bc01..0baf8ea00b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,24 @@ +2002-07-26 Jan Nieuwenhuizen + + * lily/beam.cc (knee_b): Fix to also work if some dirs are not + set. + + * lily/beam.cc (set_stem_directions): For knees, set stems to + their natural direction. + +2002-07-25 Jan Nieuwenhuizen + + * lily/stem.cc (calc_stem_info): Don't force stems of kneed beams + to reach middle staff line. + + * lily/beam.cc (consider_auto_knees): Recalculate beam position + after deciding for a knee. + 2002-07-26 Han-Wen * Documentation/user/internals.itely: move output-formats doco to WikiWiki. - 2002-07-25 Han-Wen * po/fr.po: update from TP diff --git a/lily/beam-quanting.cc b/lily/beam-quanting.cc index 890e7abe1f..6f5733f0d5 100644 --- a/lily/beam-quanting.cc +++ b/lily/beam-quanting.cc @@ -211,7 +211,7 @@ Beam::quanting (SCM smob) beam_count, ldir, rdir); } - + ; /* silly gdb thinks best_idx is inside for loop. */ for (int i = qscores.size (); i--;) if (qscores[i].demerits < reasonable_score) { @@ -223,7 +223,7 @@ Beam::quanting (SCM smob) qscores[i].yl, qscores[i].yr); } - + ; /* silly gdb thinks best_idx is inside for loop. */ int best_idx = best_quant_score_idx (qscores); me->set_grob_property ("positions", gh_cons (gh_double2scm (qscores[best_idx].yl), diff --git a/lily/beam.cc b/lily/beam.cc index dda0cf2c80..655e760322 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -484,75 +484,89 @@ Beam::set_stem_directions (Grob *me, Direction d) for (int i=0; i remove_grob_property ("dir-forced"); - if (!gh_boolean_p (force) || !gh_scm2bool (force)) - Directional_element_interface::set (s, d); + /* For knees, non-forced stems should probably have their + natural direction. In any case, when knee, beam direction is + foe. */ + if (knee_b(me)) + Stem::get_direction (s); // this actually sets it, if necessary + else + { + SCM force = s->remove_grob_property ("dir-forced"); + if (!gh_boolean_p (force) || !gh_scm2bool (force)) + Directional_element_interface::set (s, d); + } } } /* Simplistic auto-knees; only consider vertical gap between two adjacent chords. - `Forced' stem directions are ignored. If you don't want auto-knees, - don't set, or unset auto-knee-gap. */ + This may decide for a knee that's impossible to fit sane scoring + criteria (eg, stem lengths). We may need something smarter. */ void Beam::consider_auto_knees (Grob *me, Direction d) { SCM scm = me->get_grob_property ("auto-knee-gap"); - if (gh_number_p (scm)) - { - bool knee_b = false; - Real knee_y = 0; - Real staff_space = Staff_symbol_referencer::staff_space (me); - Real gap = gh_scm2double (scm) / staff_space; + if (!gh_number_p (scm)) + return; + + bool knee_b = false; + + Real staff_space = Staff_symbol_referencer::staff_space (me); + Real gap = gh_scm2double (scm) / staff_space; - Link_array stems= - Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems"); + Link_array stems= + Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems"); - Grob *common = common_refpoint_of_array (stems, me, Y_AXIS); - - int l = 0; - for (int i=1; i < stems.size (); i++) - { - if (!Stem::invisible_b (stems[i-1])) - l = i - 1; - if (Stem::invisible_b (stems[l])) - continue; - if (Stem::invisible_b (stems[i])) - continue; + Grob *common = common_refpoint_of_array (stems, me, Y_AXIS); + + int l = 0; + for (int r=1; r < stems.size (); r++) + { + if (!Stem::invisible_b (stems[r-1])) + l = r - 1; + Grob *right = stems[r]; + Grob *left = stems[l]; + if (Stem::invisible_b (left)) + continue; + if (Stem::invisible_b (right)) + continue; - Real left = Stem::extremal_heads (stems[l])[d] - ->relative_coordinate (common, Y_AXIS); - Real right = Stem::extremal_heads (stems[i])[-d] - ->relative_coordinate (common, Y_AXIS); + Real left_y = Stem::extremal_heads (left)[d] + ->relative_coordinate (common, Y_AXIS); + Real right_y = Stem::extremal_heads (right)[-d] + ->relative_coordinate (common, Y_AXIS); - Real dy = right - left; + Real dy = right_y - left_y; - if (abs (dy) >= gap) - { - knee_y = (right + left) / 2; - knee_b = true; - break; - } - } - - if (knee_b) + if (abs (dy) >= gap) { - for (int i=0; i < stems.size (); i++) + knee_b = true; + Direction knee_dir = (right_y > left_y ? UP : DOWN); + if (!Stem::invisible_b (left) + && left->get_grob_property ("dir-forced") != SCM_BOOL_T) { - Grob *s = stems[i]; - if (Stem::invisible_b (s) || - s->get_grob_property ("dir-forced") == SCM_BOOL_T) - continue; - Real y = Stem::extremal_heads (stems[i])[d] - ->relative_coordinate (common, Y_AXIS); + Directional_element_interface::set (left, knee_dir); + left->set_grob_property ("dir-forced", SCM_BOOL_T); - Directional_element_interface::set (s, y < knee_y ? UP : DOWN); - s->set_grob_property ("dir-forced", SCM_BOOL_T); + } + if (!Stem::invisible_b (right) + && stems[r]->get_grob_property ("dir-forced") != SCM_BOOL_T) + { + Directional_element_interface::set (right, -knee_dir); + right->set_grob_property ("dir-forced", SCM_BOOL_T); } } } + + if (knee_b) + { + me->set_grob_property ("knee", SCM_BOOL_T); + + for (int i=0; i < stems.size (); i++) + stems[i]->set_grob_property ("stem-info", SCM_EOL); + } } /* Set stem's shorten property if unset. @@ -1274,25 +1288,19 @@ Beam::rest_collision_callback (SCM element_smob, SCM axis) bool Beam::knee_b (Grob*me) { - SCM k= me->get_grob_property ("knee"); - if (gh_boolean_p(k)) + SCM k = me->get_grob_property ("knee"); + if (gh_boolean_p (k)) return gh_scm2bool (k); - Link_array stems= - Pointer_group_interface__extract_grobs (me, (Grob*)0, "stems"); - - Drul_array dirs_found(0,0); - - for (int i= 0; i < stems.size(); i++) - { - Grob*s = stems[i]; - dirs_found[Directional_element_interface::get(s)] = true; - - if (dirs_found[LEFT]&&dirs_found[RIGHT]) + bool knee = false; + int d = 0; + for (SCM s = me->get_grob_property ("stems"); gh_pair_p (s); s = ly_cdr (s)) + if (d != Directional_element_interface::get (unsmob_grob (ly_car (s)))) + { + knee = true; break; - } - - bool knee = dirs_found[LEFT]&&dirs_found[RIGHT]; + } + me->set_grob_property ("knee", gh_bool2scm (knee)); return knee; diff --git a/lily/stem.cc b/lily/stem.cc index 502ca9dc5c..fb0243ae45 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -836,10 +836,12 @@ Stem::calc_stem_info (Grob*me) Although this (additional) rule is probably correct, I expect that highest beam (UP) should also never be lower than middle staffline, just as normal stems. - + + Add: not for knees. Not sure if that's is a good thing. */ bool no_extend_b = to_boolean (me->get_grob_property ("no-stem-extend")); - if (!grace_b && !no_extend_b) + bool knee_b = to_boolean (beam->get_grob_property ("knee")); + if (!grace_b && !no_extend_b && !knee_b) { /* highest beam of (UP) beam must never be lower than middle staffline -- 2.39.5