From 830a24bb572c9a7226379f6a170a08565751a0d5 Mon Sep 17 00:00:00 2001 From: Lukas Pietsch Date: Sun, 1 Mar 2015 20:00:45 +0100 Subject: [PATCH 5/5] Support for flagged semiminims in mensural notation. New grob property "hollow-duration-min" to set the cutoff level between hollow and black notes, and corresponding behavior of flags/beams. --- input/regression/flagged-seminimim.ly | 42 +++++++++++++++++++++++++++++++++++ lily/beam-engraver.cc | 11 +++++++-- lily/flag.cc | 7 ++++++ lily/note-head.cc | 1 + lily/stem-engraver.cc | 7 +++++- scm/define-grob-properties.scm | 1 + scm/define-grobs.scm | 1 + scm/output-lib.scm | 16 ++++++++++--- 8 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 input/regression/flagged-seminimim.ly diff --git a/input/regression/flagged-seminimim.ly b/input/regression/flagged-seminimim.ly new file mode 100644 index 0000000..e6e612c --- /dev/null +++ b/input/regression/flagged-seminimim.ly @@ -0,0 +1,42 @@ +\header { + + texidoc = "In mensural notation (and some early modern notation), crotchets + may be displayed as hollow notes with flags or beams, + and/or quavers as hollow notes with two flags. The grob properties + NoteHead.hollow-duration-min and Stem.hollow-duration-min determine the + duration level up to which noteheads are hollow and beyond which flag + count is normal." + +} + +\version "2.19.2" + +\score { + << + \new Staff \relative g' { + \cadenzaOn + \override Stem.hollow-duration-min = #1 + \override NoteHead.hollow-duration-min = #1 + g1^0_"hollow-duration-min=1" g2^1 g4^2 g8^3 g16^4 \bar "|" g4 g4 g8[ g8] g16[ g16] + } + \new Staff \relative g' { + \cadenzaOn + \override Stem.hollow-duration-min = #2 + \override NoteHead.hollow-duration-min = #2 + g1_"hollow-duration-min=2" g2 g4 g8 g16 \bar "|" g4[ g4] g8[ g8] g16[ g16] + } + \new Staff \relative g' { + \cadenzaOn + \override Stem.hollow-duration-min = #3 + \override NoteHead.hollow-duration-min = #3 + g1_"hollow-duration-min=3" g2 g4 g8 g16 \bar "|" g4[ g4] g8[ g8] g16[ g16] + } + \new Staff \relative g' { + \cadenzaOn + \override Stem.hollow-duration-min = #4 + \override NoteHead.hollow-duration-min = #4 + g1_"hollow-duration-min=4" g2 g4 g8 g16 \bar "|" g4[ g4] g8[ g8] g16[ g16] + } + >> +} + diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index 4e4f991..fdfe984 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -288,7 +288,12 @@ Beam_engraver::acknowledge_stem (Grob_info info) Duration *stem_duration = Duration::unsmob (ev->get_property ("duration")); int durlog = stem_duration->duration_log (); //int durlog = Duration::unsmob (ev->get_property ("duration"))->duration_log (); - if (durlog <= 2) + + // addition to support flagged/hollow crotchets in mensural notation + int max_hollow = robust_scm2int (info.grob()->get_property ("hollow-duration-min"), 1); + int max_beamed = (max_hollow == 1) ? 3 : 2; + + if (durlog < max_beamed) { ev->origin ()->warning (_ ("stem does not fit in beam")); prev_start_ev_->origin ()->warning (_ ("beam was started here")); @@ -304,8 +309,10 @@ Beam_engraver::acknowledge_stem (Grob_info info) stem->set_property ("duration-log", scm_from_int (durlog)); Moment stem_location = now - beam_start_mom_ + beam_start_location_; + int beam_count = max (0, ((durlog <= max_hollow) ? (durlog - 1) : (durlog - 2))); + beam_info_->add_stem (stem_location, - max (durlog - 2, 0), + beam_count, Stem::is_invisible (stem), stem_duration->factor (), (stem->get_property ("tuplet-start") == SCM_BOOL_T)); diff --git a/lily/flag.cc b/lily/flag.cc index 7ce1fc1..8544bf2 100644 --- a/lily/flag.cc +++ b/lily/flag.cc @@ -72,6 +72,13 @@ Flag::glyph_name (SCM smob) Direction d = get_grob_direction (stem); int log = Stem::duration_log (stem); + + // addition to support flagged/hollow crotchets in mensural notation + int max_hollow = robust_scm2int (stem->get_property ("hollow-duration-min"), 1); + + if ((max_hollow < 1) || ((max_hollow > 1) && (log <= max_hollow))) + log = log + 1; + string flag_style; SCM flag_style_scm = me->get_property ("style"); diff --git a/lily/note-head.cc b/lily/note-head.cc index 89c0047..3b1cfdb 100644 --- a/lily/note-head.cc +++ b/lily/note-head.cc @@ -210,5 +210,6 @@ ADD_INTERFACE (Note_head, "glyph-name " "stem-attachment " "style " + "hollow-duration-min " ); diff --git a/lily/stem-engraver.cc b/lily/stem-engraver.cc index 45c777f..df586d2 100644 --- a/lily/stem-engraver.cc +++ b/lily/stem-engraver.cc @@ -157,8 +157,13 @@ Stem_engraver::acknowledge_rhythmic_head (Grob_info gi) Stem::add_head (stem_, gi.grob ()); + // addition to support flagged/hollow crotchets in mensural notation + int min_flagged = + (robust_scm2int (gi.grob()->get_property ("hollow-duration-min"), 1) == 1) ? + 3 : 2; + if (Stem::is_normal_stem (stem_) - && Stem::duration_log (stem_) > 2) + && Stem::duration_log (stem_) >= min_flagged) { Item *flag = make_item ("Flag", stem_->self_scm ()); flag->set_parent (stem_, X_AXIS); diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index d075350..e0ba77e 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -510,6 +510,7 @@ units.") slur, the closer it is to this height.") (hide-tied-accidental-after-break ,boolean? "If set, an accidental that appears on a tied note after a line break will not be displayed.") + (hollow-duration-min ,integer? "Duration log up to which notes are hollow rather than black, in mensural notation.") (horizon-padding ,number? "The amount to pad the axis along which a @code{Skyline} is built for the @code{side-position-interface}.") diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 252733d..757bca4 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1634,6 +1634,7 @@ (extra-spacing-height . ,ly:note-head::include-ledger-line-height) (glyph-name . ,note-head::calc-glyph-name) (ligature-flexa . #f) + (hollow-duration-min . 1) (stem-attachment . ,ly:note-head::calc-stem-attachment) (stencil . ,ly:note-head::print) (X-offset . ,ly:note-head::stem-x-shift) diff --git a/scm/output-lib.scm b/scm/output-lib.scm index 96456b1..eba340a 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -330,9 +330,18 @@ (ly:event-property (event-cause grob) 'duration)))) (define-public (note-head::calc-duration-log grob) - (min 2 - (ly:duration-log - (ly:event-property (event-cause grob) 'duration)))) + (let ( + (hollow (ly:grob-property grob 'hollow-duration-min 1)) + (durlog (ly:duration-log + (ly:event-property (event-cause grob) 'duration)))) + (cond + ;; default case, modern notation + ((= hollow 1) (min durlog 2)) + ;; black mensural notation: smallest notehead type is minim + ((< hollow 1) (min durlog 1)) + ;; white mensural notation with flagged crotchets: + ((<= durlog hollow) (min durlog 1)) + (else 2)))) (define-public (dots::calc-dot-count grob) (ly:duration-dot-count @@ -1469,3 +1478,4 @@ with the subordinate symbols being interfaces." `(cons ',(car form) ,(loop (cdr form))))) forms)) forms))) + -- 1.9.1