From 78c9194fe61a9cbe372b12ec5125779acf706a77 Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Sun, 28 Sep 2014 10:58:43 +0200 Subject: [PATCH] Issue 4138: Make \time work with \tweak and \footnote The way this is done is to let a TimeSignatureMusic expression expand to produce a TimeSignatureEvent that can be listened to. The Time_signature_engraver _does_ listen to this event and uses it to set the origin for TimeSignature grobs created in the same time step. Another effect is that any warnings associated with a TimeSignature grob will be able to point to a source location in case that the respective change of timing parameters can be traced to TimeSignatureMusic in a context below the context of the Time_signature_engraver creating the TimeSignature. Since events that can be listened to create a Bottom context implicitly, this causes a difference for cases like \score { { \time 3/4 \skip 2. r2. } } Previously, Staff (and Voice) contexts were only created _after_ the \skip completed (the timing parameters are set in the Timing context, equal to Score by default), making the time signature appear only in measure 2. Now the implicit creation of a Staff (and thus a Time_signature_engraver) in the course of creating a Bottom context (in this case a Voice) makes the time signature appear right away. If one uses a separate non-printing context for containing timing info, one has to make sure that any implicitly created Bottom context is non-printing as well. --- lily/time-signature-engraver.cc | 20 ++++++++++++++++---- scm/define-event-classes.scm | 1 + scm/define-music-callbacks.scm | 3 ++- scm/define-music-types.scm | 5 +++++ 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lily/time-signature-engraver.cc b/lily/time-signature-engraver.cc index 8461a01058..8c444e5747 100644 --- a/lily/time-signature-engraver.cc +++ b/lily/time-signature-engraver.cc @@ -22,9 +22,12 @@ #include "item.hh" #include "international.hh" #include "misc.hh" +#include "stream-event.hh" #include "time-signature.hh" #include "warn.hh" +#include "translator.icc" + /** generate time_signatures. */ @@ -32,6 +35,7 @@ class Time_signature_engraver : public Engraver { Item *time_signature_; SCM last_time_fraction_; + SCM time_cause_; protected: virtual void derived_mark () const; @@ -39,26 +43,33 @@ protected: void process_music (); public: TRANSLATOR_DECLARATIONS (Time_signature_engraver); + DECLARE_TRANSLATOR_LISTENER (time_signature); }; void Time_signature_engraver::derived_mark () const { scm_gc_mark (last_time_fraction_); + scm_gc_mark (time_cause_); } Time_signature_engraver::Time_signature_engraver () { time_signature_ = 0; + time_cause_ = SCM_EOL; last_time_fraction_ = SCM_BOOL_F; } +IMPLEMENT_TRANSLATOR_LISTENER (Time_signature_engraver, time_signature); +void +Time_signature_engraver::listen_time_signature (Stream_event *ev) +{ + time_cause_ = ev->self_scm (); +} + void Time_signature_engraver::process_music () { - /* - not rigorously safe, since the value might get GC'd and - reallocated in the same spot */ SCM fr = get_property ("timeSignatureFraction"); if (!time_signature_ && last_time_fraction_ != fr @@ -77,7 +88,7 @@ Time_signature_engraver::process_music () den)); } - time_signature_ = make_item ("TimeSignature", SCM_EOL); + time_signature_ = make_item ("TimeSignature", time_cause_); time_signature_->set_property ("fraction", fr); if (last_time_fraction_ == SCM_BOOL_F) @@ -92,6 +103,7 @@ void Time_signature_engraver::stop_translation_timestep () { time_signature_ = 0; + time_cause_ = SCM_EOL; } #include "translator.icc" diff --git a/scm/define-event-classes.scm b/scm/define-event-classes.scm index ac6f215ae2..b568945081 100644 --- a/scm/define-event-classes.scm +++ b/scm/define-event-classes.scm @@ -38,6 +38,7 @@ laissez-vibrer-event mark-event multi-measure-text-event note-grouping-event pes-or-flexa-event repeat-tie-event spacing-section-event layout-instruction-event + time-signature-event completize-extender-event break-span-event alternative-event)) (layout-instruction-event . (apply-output-event)) diff --git a/scm/define-music-callbacks.scm b/scm/define-music-callbacks.scm index e9fe53eb1b..a6441d1e21 100644 --- a/scm/define-music-callbacks.scm +++ b/scm/define-music-callbacks.scm @@ -126,4 +126,5 @@ to be used by the sequential-iterator" (ly:context-set-property! context 'measureLength new-measure-length)))) 'Timing) - 'Score)))) + 'Score) + (make-music 'TimeSignatureEvent music)))) diff --git a/scm/define-music-types.scm b/scm/define-music-types.scm index 8d0464bf4c..359e10eac1 100644 --- a/scm/define-music-types.scm +++ b/scm/define-music-types.scm @@ -666,6 +666,11 @@ Syntax: @code{\\times @var{fraction} @var{music}}, e.g., (types . (general-music time-signature-music)) )) + (TimeSignatureEvent + . ((description . "An event created when setting a new time signature") + (types . (general-music event time-signature-event)) + )) + (TransposedMusic . ((description . "Music that has been transposed.") (iterator-ctor . ,ly:music-wrapper-iterator::constructor) -- 2.47.3