From b4c9fbc328f1e9681b0c582bae7be61a451a43d0 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Wed, 6 Oct 1999 10:57:49 +0200 Subject: [PATCH] patch::: 1.2.12.jcn1 pl 12.jcn1 - auto-knees, input/test/auto-knee.ly --- CHANGES | 3 ++ Documentation/GNUmakefile | 2 +- VERSION | 2 +- input/test/auto-knee.ly | 26 ++++++++++++ lily/auto-beam-engraver.cc | 10 ++++- lily/beam-engraver.cc | 10 ++++- lily/beam.cc | 84 ++++++++++++++++++++++++++++++++++++-- lily/include/beam.hh | 2 + lily/include/ly-symbols.hh | 2 + 9 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 input/test/auto-knee.ly diff --git a/CHANGES b/CHANGES index 762e19f241..4c8deed900 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +pl 12.jcn1 + - auto-knees, input/test/auto-knee.ly + pl 11.uu1 - changed debug init code. diff --git a/Documentation/GNUmakefile b/Documentation/GNUmakefile index 716212ddb6..74083082de 100644 --- a/Documentation/GNUmakefile +++ b/Documentation/GNUmakefile @@ -6,7 +6,7 @@ NAME = documentation SUBDIRS= user metadoc bibliography pictures topdocs ntweb STEPMAKE_TEMPLATES=documentation texinfo -README_TOP_FILES=NEWS DEDICATION TODO AIMS +README_TOP_FILES=NEWS DEDICATION TODO AIMS INFO_FILES = $(wildcard $(outdir)/$(package).info*) EXTRA_DIST_FILES = COPYRIGHT diff --git a/VERSION b/VERSION index 15ba9e3278..b14be88b79 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=2 PATCH_LEVEL=12 -MY_PATCH_LEVEL= +MY_PATCH_LEVEL=jcn1 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/input/test/auto-knee.ly b/input/test/auto-knee.ly new file mode 100644 index 0000000000..e6541ec2ef --- /dev/null +++ b/input/test/auto-knee.ly @@ -0,0 +1,26 @@ + +\score { + \notes \context PianoStaff < + \context Staff = "up" { + \autochange Staff \relative c' { + [c8 e'] [c' c,,] + \stemdown + c'8 c c g, + g8 d' d d + \stemup + b8 c d e + } + } + \context Staff = "down" { + \clef bass; + s1*2 + } + > + \paper{ + \translator{ + \StaffContext + autoKneeGap = "13.0"; + autoInterstaffKneeGap = "4.0"; + } + } +} diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index e72ffb29ab..28fc85fa65 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -203,8 +203,16 @@ Auto_beam_engraver::create_beam_p () /* urg, copied from Beam_engraver */ Scalar prop = get_property ("beamslopedamping", 0); if (prop.isnum_b ()) - beam_p->set_elt_property (damping_scm_sym, gh_int2scm( prop)); + beam_p->set_elt_property (damping_scm_sym, gh_int2scm(prop)); + prop = get_property ("autoKneeGap", 0); + if (prop.isnum_b ()) + beam_p->set_elt_property (auto_knee_gap_scm_sym, gh_int2scm(prop)); + + prop = get_property ("autoInterstaffKneeGap", 0); + if (prop.isnum_b ()) + beam_p->set_elt_property (auto_interstaff_knee_gap_scm_sym, gh_int2scm( prop)); + prop = get_property ("beamquantisation", 0); if (prop.isnum_b ()) beam_p->quantisation_ = (Beam::Quantisation)(int)prop; diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index d0a965e33a..b34d329d94 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -98,11 +98,19 @@ Beam_engraver::do_process_requests () beam_info_p_ = new Beaming_info_list; - + /* urg, must copy to Auto_beam_engraver too */ Scalar prop = get_property ("beamslopedamping", 0); if (prop.isnum_b ()) beam_p_->set_elt_property (damping_scm_sym, gh_int2scm( prop)); + prop = get_property ("autoKneeGap", 0); + if (prop.isnum_b ()) + beam_p_->set_elt_property (auto_knee_gap_scm_sym, gh_int2scm( prop)); + + prop = get_property ("autoInterstaffKneeGap", 0); + if (prop.isnum_b ()) + beam_p_->set_elt_property (auto_interstaff_knee_gap_scm_sym, gh_int2scm( prop)); + prop = get_property ("beamquantisation", 0); if (prop.isnum_b ()) beam_p_->quantisation_ = (Beam::Quantisation)(int)prop; diff --git a/lily/beam.cc b/lily/beam.cc index bb688749dd..92a92050a2 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -120,13 +120,73 @@ Beam::center () const si.stem_l_->staff_line_leading_f ()/2); } +/* + Simplistic auto-knees; only consider vertical gap between two + adjacent chords + */ +bool +Beam::auto_knee (SCM gap, bool interstaff_b) +{ + bool knee = false; + int knee_y = 0; + Real internote_f = stems_[0]->staff_line_leading_f ()/2; + if (gap != SCM_BOOL_F) + { + int auto_gap_i = gh_scm2int (SCM_CDR (gap)); + for (int i=1; i < stems_.size (); i++) + { + bool is_b = (bool)(sinfo_[i].interstaff_f_ - sinfo_[i-1].interstaff_f_); + int l_y = (int)(stems_[i-1]->chord_start_f () / internote_f) + + (int)sinfo_[i-1].interstaff_f_; + int r_y = (int)(stems_[i]->chord_start_f () / internote_f) + + (int)sinfo_[i].interstaff_f_; + int gap_i = r_y - l_y; + + /* + Forced stem directions are ignored. If you don't want auto-knees, + don't set, or unset autoKneeGap/autoInterstaffKneeGap. + */ + if ((abs (gap_i) >= auto_gap_i) && (!interstaff_b || is_b)) + { + knee_y = (r_y + l_y) / 2; + knee = true; + break; + } + } + } + if (knee) + { + for (int i=0; i < stems_.size (); i++) + { + int y = (int)(stems_[i]->chord_start_f () / internote_f) + + (int)sinfo_[i].interstaff_f_; + stems_[i]->dir_ = y < knee_y ? UP : DOWN; + stems_[i]->set_elt_property (dir_forced_scm_sym, SCM_BOOL_T); + } + } + return knee; +} + +bool +Beam::auto_knees () +{ + if (auto_knee (get_elt_property (auto_interstaff_knee_gap_scm_sym), true)) + return true; + + return auto_knee (get_elt_property (auto_knee_gap_scm_sym), false); +} + + void Beam::do_pre_processing () { + /* + urg: it seems that info on whether beam (voice) dir was forced + is being junked here? + */ if (!dir_) dir_ = get_default_dir (); - set_direction (dir_); } @@ -146,7 +206,25 @@ Beam::do_post_processing () { warning (_ ("beam with less than two stems")); set_elt_property (transparent_scm_sym, SCM_BOOL_T); - return ; + return; + } + set_steminfo (); + if (auto_knees ()) + { + /* + if auto-knee did its work, most probably stem directions + have changed, so we must recalculate all. + */ + dir_ = get_default_dir (); + set_direction (dir_); + + /* auto-knees used to only work for slope = 0 + anyway, should be able to set slope per beam + set_elt_property (damping_scm_sym, gh_int2scm(1000)); + */ + + sinfo_.clear (); + set_steminfo (); } calculate_slope (); set_stemlens (); @@ -323,6 +401,7 @@ Beam::set_steminfo () return; assert (multiple_i_); + int total_count_i = 0; int forced_count_i = 0; for (int i=0; i < stems_.size (); i++) @@ -374,7 +453,6 @@ Beam::set_steminfo () void Beam::calculate_slope () { - set_steminfo (); if (!sinfo_.size ()) slope_f_ = left_y_ = 0; else if (sinfo_[0].idealy_f_ == sinfo_.top ().idealy_f_) diff --git a/lily/include/beam.hh b/lily/include/beam.hh index 39f9b3b99b..145bbddce0 100644 --- a/lily/include/beam.hh +++ b/lily/include/beam.hh @@ -69,6 +69,8 @@ protected: Direction get_default_dir () const; void set_direction (Direction); void set_steminfo (); + bool auto_knee (SCM gap, bool interstaff_b); + bool auto_knees (); virtual void do_pre_processing (); virtual void do_post_processing (); diff --git a/lily/include/ly-symbols.hh b/lily/include/ly-symbols.hh index 0d929dd23e..521fa3d06e 100644 --- a/lily/include/ly-symbols.hh +++ b/lily/include/ly-symbols.hh @@ -18,6 +18,8 @@ DECLARE_LY_SYMBOL(alt_symbol); DECLARE_LY_SYMBOL(at_line_start); +DECLARE_LY_SYMBOL(auto_interstaff_knee_gap); +DECLARE_LY_SYMBOL(auto_knee_gap); DECLARE_LY_SYMBOL(bar_size); DECLARE_LY_SYMBOL(beam); DECLARE_LY_SYMBOL(beam_thickness); -- 2.39.5