From dafef223123bb629eab05e53c443c6e6d20e9481 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 22 May 2006 14:06:28 +0000 Subject: [PATCH] * input/regression/beam-single-stem.ly: new file. * lily/stem.cc (set_beaming): use #f as signaling value for beamcount 0. * lily/beam-engraver.cc (typeset_beam): set right bound if unset. * lily/beam.cc (set_beaming): read clip-edges property. (calc_direction): don't suicide for single stem. * lily/beaming-info.cc (best_splitpoint_index): take bool* argument, remove 1<<15 hack. Remove clip_edges() * lily/hairpin.cc (print): only do padding for nonmusical bounds --- ChangeLog | 13 ++++++ input/regression/beam-single-stem.ly | 17 ++++++++ lily/auto-beam-engraver.cc | 9 ++-- lily/beam-engraver.cc | 40 +++++++++++++----- lily/beam.cc | 32 +++++++------- lily/beaming-info.cc | 63 ++++++++++++++++++---------- lily/hairpin.cc | 3 +- lily/include/beaming.hh | 15 +++++-- lily/measure-grouping-engraver.cc | 27 ++++++++---- lily/stem.cc | 8 +++- scm/define-grob-properties.scm | 1 + scm/define-grobs.scm | 3 +- 12 files changed, 162 insertions(+), 69 deletions(-) create mode 100644 input/regression/beam-single-stem.ly diff --git a/ChangeLog b/ChangeLog index f62b454c90..af201e791b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2006-05-22 Han-Wen Nienhuys + * input/regression/beam-single-stem.ly: new file. + + * lily/stem.cc (set_beaming): use #f as signaling value for + beamcount 0. + + * lily/beam-engraver.cc (typeset_beam): set right bound if unset. + + * lily/beam.cc (set_beaming): read clip-edges property. + (calc_direction): don't suicide for single stem. + + * lily/beaming-info.cc (best_splitpoint_index): take bool* + argument, remove 1<<15 hack. Remove clip_edges() + * lily/hairpin.cc (print): only do padding for nonmusical bounds 2006-05-21 Graham Percival diff --git a/input/regression/beam-single-stem.ly b/input/regression/beam-single-stem.ly new file mode 100644 index 0000000000..8749d41390 --- /dev/null +++ b/input/regression/beam-single-stem.ly @@ -0,0 +1,17 @@ +\header { + + texidoc = "Single stem beams are also allowed. For such beams, + clip-edges is switched off automatically." + +} +\version "2.9.6" + +\relative c' { + d16[] + \set stemRightBeamCount = #0 + d32[] +} + +\layout { + ragged-right = ##t +} diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index a70755bc33..03795dc9a0 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -211,14 +211,12 @@ Auto_beam_engraver::begin_beam () } stems_ = new vector; - grouping_ = new Beaming_info_list; + grouping_ = make_beaming_info_list (context ()); beam_settings_ = updated_grob_properties (context (), ly_symbol2scm ("Beam")); beam_start_moment_ = now_mom (); beam_start_location_ = robust_scm2moment (get_property ("measurePosition"), Moment (0)); - subdivide_beams_ = ly_scm2bool (get_property ("subdivideBeams")); - beat_length_ = robust_scm2moment (get_property ("beatLength"), Moment (1, 4)); } void @@ -260,7 +258,10 @@ Auto_beam_engraver::typeset_beam () { if (finished_beam_) { - finished_grouping_->beamify (beat_length_, subdivide_beams_); + if (!finished_beam_->get_bound (RIGHT)) + finished_beam_->set_bound (RIGHT, finished_beam_->get_bound (LEFT)); + + finished_grouping_->beamify (); Beam::set_beaming (finished_beam_, finished_grouping_); finished_beam_ = 0; diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index eb6284380a..7f89b9ed98 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -145,8 +145,7 @@ Beam_engraver::process_music () beam_start_location_ = mp; beam_start_mom_ = now_mom (); - beam_info_ = new Beaming_info_list; - + beam_info_ = make_beaming_info_list (context ()); /* urg, must copy to Auto_beam_engraver too */ } } @@ -156,7 +155,10 @@ Beam_engraver::typeset_beam () { if (finished_beam_) { - finished_beam_info_->beamify (beat_length_, subdivide_beams_); + if (!finished_beam_->get_bound (RIGHT)) + finished_beam_->set_bound (RIGHT, finished_beam_->get_bound (LEFT)); + + finished_beam_info_->beamify (); Beam::set_beaming (finished_beam_, finished_beam_info_); delete finished_beam_info_; @@ -173,9 +175,6 @@ Beam_engraver::start_translation_timestep () if (beam_) { set_melisma (true); - - subdivide_beams_ = to_boolean (get_property ("subdivideBeams")); - beat_length_ = robust_scm2moment (get_property ("beatLength"), Moment (1, 4)); } } @@ -277,12 +276,21 @@ ADD_ACKNOWLEDGER (Beam_engraver, stem); ADD_ACKNOWLEDGER (Beam_engraver, rest); ADD_TRANSLATOR (Beam_engraver, - /* doc */ "Handles Beam events by engraving Beams. If omitted, then notes will be " + /* doc */ + + "Handles Beam events by engraving Beams. If omitted, then notes will be " "printed with flags instead of beams.", + /* create */ "Beam", /* accept */ "beam-event", - /* read */ "beamMelismaBusy beatLength subdivideBeams", - /* write */ "forbidBreak"); + + /* read */ + "beamMelismaBusy " + "beatLength " + "subdivideBeams " + , + /* write */ + "forbidBreak"); class Grace_beam_engraver : public Beam_engraver { @@ -314,12 +322,22 @@ Grace_beam_engraver::valid_end_point () ADD_ACKNOWLEDGER (Grace_beam_engraver, stem); ADD_ACKNOWLEDGER (Grace_beam_engraver, rest); + ADD_TRANSLATOR (Grace_beam_engraver, - /* doc */ "Handles Beam events by engraving Beams. If omitted, then notes will " + + /* doc */ + + "Handles Beam events by engraving Beams. If omitted, then notes will " "be printed with flags instead of beams. Only engraves beams when we " " are at grace points in time. ", + /* create */ "Beam", /* accept */ "beam-event", - /* read */ "beamMelismaBusy beatLength allowBeamBreak subdivideBeams", + /* read */ + "beamMelismaBusy " + "beatLength " + "allowBeamBreak " + "subdivideBeams " + , /* write */ ""); diff --git a/lily/beam.cc b/lily/beam.cc index 1a4e0e3661..497957b465 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -133,24 +133,17 @@ Beam::calc_direction (SCM smob) For a beam that only has one stem, we try to do some disappearance magic: we revert the flag, and move on to The Eternal Engraving Fields. */ - Direction d = CENTER; + Direction dir = CENTER; int count = visible_stem_count (me); if (count < 2) { extract_grob_set (me, "stems", stems); - if (stems.size () == 1) + if (stems.size () == 0) { - me->warning (_ ("removing beam with less than two stems")); - - stems[0]->set_object ("beam", SCM_EOL); + me->warning (_ ("removing beam with no stems")); me->suicide (); - return SCM_UNSPECIFIED; - } - else if (stems.size () == 0) - { - me->suicide (); return SCM_UNSPECIFIED; } else @@ -160,24 +153,24 @@ Beam::calc_direction (SCM smob) /* ugh: stems[0] case happens for chord tremolo. */ - d = to_dir ((stem ? stem : stems[0])->get_property ("default-direction")); + dir = to_dir ((stem ? stem : stems[0])->get_property ("default-direction")); } } if (count >= 1) { - if (!d) - d = get_default_dir (me); + if (!dir) + dir = get_default_dir (me); consider_auto_knees (me); } - if (d) + if (dir) { - set_stem_directions (me, d); + set_stem_directions (me, dir); } - return scm_from_int (d); + return scm_from_int (dir); } @@ -1217,6 +1210,12 @@ Beam::set_beaming (Grob *me, Beaming_info_list const *beaming) && Stem::is_invisible (stem)) count = min (count, beaming->infos_.at (i).beam_count_drul_[-d]); + if ( ((i == 0 && d == LEFT) + || (i == stems.size ()-1 && d == RIGHT)) + && stems.size () > 1 + && to_boolean (me->get_property ("clip-edges"))) + count = 0; + Stem::set_beaming (stem, count, d); } } @@ -1445,6 +1444,7 @@ ADD_INTERFACE (Beam, "beamed-stem-shorten " "beaming " "break-overshoot " + "clip-edges " "concaveness " "damping " "details " diff --git a/lily/beaming-info.cc b/lily/beaming-info.cc index 417a20372c..0e66b2b681 100644 --- a/lily/beaming-info.cc +++ b/lily/beaming-info.cc @@ -7,6 +7,7 @@ */ #include "beaming.hh" +#include "context.hh" Beaming_info::Beaming_info () { @@ -22,11 +23,10 @@ Beaming_info::Beaming_info (Moment m, int i) beam_count_drul_[RIGHT] = i; } -const int at_beat = 1 << 15; // WTF is this. - int -Beaming_info_list::best_splitpoint_index (Moment &beat_length, - bool subdivide) const +Beaming_info_list::best_splitpoint_index (Moment beat_length, + bool subdivide_beams, + bool *at_beat_subdivide) const { int min_denominator = INT_MAX; int min_index = -1; @@ -37,7 +37,7 @@ Beaming_info_list::best_splitpoint_index (Moment &beat_length, beat_pos = infos_[i].start_moment_ / beat_length; int den = beat_pos.den (); if (infos_[i].beam_count_drul_[LEFT] == infos_[i - 1].beam_count_drul_[RIGHT] - && !subdivide) + && !subdivide_beams) den *= 2; if (den < min_denominator) @@ -47,7 +47,9 @@ Beaming_info_list::best_splitpoint_index (Moment &beat_length, } } - return min_index | (min_denominator == 1 && subdivide ? at_beat : 0); + *at_beat_subdivide = (min_denominator == 1 && subdivide_beams); + + return min_index; } int @@ -63,16 +65,37 @@ Beaming_info_list::beam_extend_count (Direction d) const } void -Beaming_info_list::beamify (Moment &beat_length, bool subdivide) +Beaming_info_list::beamify () +{ + bool subdivide_beams = to_boolean (context_->get_property ("subdivideBeams")); + Moment beat_length = robust_scm2moment (context_->get_property ("beatLength"), Moment (1, 4)); + + beamify (beat_length, subdivide_beams); +} + + + +Beaming_info_list * +make_beaming_info_list (Context *context) +{ + Beaming_info_list *l = new Beaming_info_list; + l->context_ = context; + return l; +} + + +void +Beaming_info_list::beamify (Moment beat_length, + bool subdivide_beams) { if (infos_.size () <= 1) return; - Drul_array splits; + + Drul_array splits (*this, *this); - int m = best_splitpoint_index (beat_length, subdivide); - bool split = subdivide && (m & at_beat); - m = m & ~at_beat; + bool split = false; + int m = best_splitpoint_index (beat_length, subdivide_beams, &split); splits[LEFT].infos_ = vector (infos_.begin (), infos_.begin () + m); @@ -83,7 +106,7 @@ Beaming_info_list::beamify (Moment &beat_length, bool subdivide) do { - splits[d].beamify (beat_length, subdivide); + splits[d].beamify (beat_length, subdivide_beams); } while (flip (&d) != LEFT); @@ -102,22 +125,20 @@ Beaming_info_list::beamify (Moment &beat_length, bool subdivide) infos_.insert (infos_.end (), splits[RIGHT].infos_.begin (), splits[RIGHT].infos_.end ()); - - clip_edges (); } + + void Beaming_info_list::add_stem (Moment m, int b) { infos_.push_back (Beaming_info (m, b)); } -void -Beaming_info_list::clip_edges () + +Beaming_info_list::Beaming_info_list () { - if (infos_.size ()) - { - infos_[0].beam_count_drul_[LEFT] = 0; - infos_.back ().beam_count_drul_[RIGHT] = 0; - } + context_ = 0; } + + diff --git a/lily/hairpin.cc b/lily/hairpin.cc index 37337d45bc..4b9c215e2e 100644 --- a/lily/hairpin.cc +++ b/lily/hairpin.cc @@ -164,7 +164,8 @@ Hairpin::print (SCM smob) else { x_points[d] = e[d]; - if (me->get_bound (d)->is_non_musical ()) + Item *bound = me->get_bound (d); + if (bound->is_non_musical (bound)) x_points[d] -= d * padding; } } diff --git a/lily/include/beaming.hh b/lily/include/beaming.hh index 32a9ed4c82..bb4bc7e1c0 100644 --- a/lily/include/beaming.hh +++ b/lily/include/beaming.hh @@ -11,6 +11,7 @@ #include "std-vector.hh" #include "moment.hh" +#include "lily-proto.hh" struct Beaming_info { @@ -18,8 +19,9 @@ struct Beaming_info Drul_array beam_count_drul_; Beaming_info (Moment, int); - int count (Direction d); Beaming_info (); + + int count (Direction d); }; /* @@ -29,12 +31,17 @@ struct Beaming_info struct Beaming_info_list { vector infos_; + Context *context_; + Beaming_info_list (); + int beam_extend_count (Direction) const; - int best_splitpoint_index (Moment &beat_length, bool subdivide) const; - void beamify (Moment &beat_length, bool subdivide); + int best_splitpoint_index (Moment, bool, bool *split) const; + void beamify (); + void beamify (Moment, bool); void add_stem (Moment d, int beams); - void clip_edges (); }; +Beaming_info_list *make_beaming_info_list (Context *); + #endif /* BEAMING_HH */ diff --git a/lily/measure-grouping-engraver.cc b/lily/measure-grouping-engraver.cc index fc6e2ed7ee..126e32ec5f 100644 --- a/lily/measure-grouping-engraver.cc +++ b/lily/measure-grouping-engraver.cc @@ -66,12 +66,12 @@ Measure_grouping_engraver::process_music () Moment *measpos = unsmob_moment (get_property ("measurePosition")); Rational mp = measpos->main_part_; - Moment *beatlen = unsmob_moment (get_property ("beatLength")); - Rational bl = beatlen->main_part_; + Moment *beatlen_mom = unsmob_moment (get_property ("beatLength")); + Rational beat_length = beatlen_mom->main_part_; Rational where (0); for (SCM s = grouping; scm_is_pair (s); - where += Rational ((int) scm_to_int (scm_car (s))) * bl, + where += Rational ((int) scm_to_int (scm_car (s))) * beat_length, s = scm_cdr (s)) { int grouplen = scm_to_int (scm_car (s)); @@ -86,7 +86,7 @@ Measure_grouping_engraver::process_music () grouping_ = make_spanner ("MeasureGrouping", SCM_EOL); grouping_->set_bound (LEFT, unsmob_grob (get_property ("currentMusicalColumn"))); - stop_grouping_mom_ = now.main_part_ + Rational (grouplen - 1) * bl; + stop_grouping_mom_ = now.main_part_ + Rational (grouplen - 1) * beat_length; get_global_context ()->add_moment_to_process (Moment (stop_grouping_mom_)); if (grouplen == 3) @@ -107,8 +107,17 @@ Measure_grouping_engraver::Measure_grouping_engraver () ADD_ACKNOWLEDGER (Measure_grouping_engraver, note_column); ADD_TRANSLATOR (Measure_grouping_engraver, - /* doc */ "Creates MeasureGrouping to indicate beat subdivision.", - /* create */ "MeasureGrouping", - /* accept */ "", - /* read */ "beatGrouping beatLength measurePosition currentMusicalColumn", - /* write */ ""); + /* doc */ + "Creates MeasureGrouping to indicate beat subdivision.", + /* create */ + "MeasureGrouping", + /* accept */ + "", + /* read */ + "beatLength " + "currentMusicalColumn " + "measurePosition " + "beatGrouping " + , + /* write */ + ""); diff --git a/lily/stem.cc b/lily/stem.cc index 1be8f59855..3b00da28cf 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); } diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index d59d4661c9..5bcffdd929 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -368,6 +368,7 @@ Y axis.") (shorten-pair ,number-pair? "The lengths to shorten a text-spanner on both sides, for example a pedal bracket") + (clip-edges ,boolean? "Allow outward pointing beamlets at the edges of beams?") (common-shortest-duration ,ly:moment? "The most common shortest note length. This is used in spacing. Enlarging this will set the score tighter.") diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 128849f988..304360f4f1 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -268,7 +268,8 @@ (shorten . ,ly:beam::calc-stem-shorten) (beaming . ,ly:beam::calc-beaming) (stencil . ,ly:beam::print) - + (clip-edges . #t) + ;; TODO: should be in SLT. (thickness . 0.48) ; in staff-space (neutral-direction . ,DOWN) -- 2.39.5