From: David Kastrup Date: Sun, 6 Oct 2013 12:21:56 +0000 (+0200) Subject: Issue 3602/2: Rename lily/new-dynamic-engraver.cc to lily/dynamic-engraver.cc X-Git-Tag: release/2.17.29-1~20^2~1 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=c5e974190861845c4ff31e47db3ddecb4eb496d0;p=lilypond.git Issue 3602/2: Rename lily/new-dynamic-engraver.cc to lily/dynamic-engraver.cc --- diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc new file mode 100644 index 0000000000..cd7db644a6 --- /dev/null +++ b/lily/dynamic-engraver.cc @@ -0,0 +1,305 @@ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 2008--2012 Han-Wen Nienhuys + + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . +*/ + +#include "engraver.hh" +#include "hairpin.hh" +#include "international.hh" +#include "item.hh" +#include "note-column.hh" +#include "pointer-group-interface.hh" +#include "self-alignment-interface.hh" +#include "spanner.hh" +#include "stream-event.hh" +#include "text-interface.hh" + +#include "translator.icc" + +class New_dynamic_engraver : public Engraver +{ + TRANSLATOR_DECLARATIONS (New_dynamic_engraver); + DECLARE_ACKNOWLEDGER (note_column); + DECLARE_TRANSLATOR_LISTENER (absolute_dynamic); + DECLARE_TRANSLATOR_LISTENER (span_dynamic); + DECLARE_TRANSLATOR_LISTENER (break_span); + +protected: + virtual void process_music (); + virtual void stop_translation_timestep (); + virtual void finalize (); + +private: + SCM get_property_setting (Stream_event *evt, char const *evprop, + char const *ctxprop); + string get_spanner_type (Stream_event *ev); + + Drul_array accepted_spanevents_drul_; + Spanner *current_spanner_; + Spanner *finished_spanner_; + + Item *script_; + Stream_event *script_event_; + Stream_event *current_span_event_; + bool end_new_spanner_; +}; + +New_dynamic_engraver::New_dynamic_engraver () +{ + script_event_ = 0; + current_span_event_ = 0; + script_ = 0; + finished_spanner_ = 0; + current_spanner_ = 0; + accepted_spanevents_drul_.set (0, 0); + end_new_spanner_ = false; +} + +IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_engraver, absolute_dynamic); +void +New_dynamic_engraver::listen_absolute_dynamic (Stream_event *ev) +{ + ASSIGN_EVENT_ONCE (script_event_, ev); +} + +IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_engraver, span_dynamic); +void +New_dynamic_engraver::listen_span_dynamic (Stream_event *ev) +{ + Direction d = to_dir (ev->get_property ("span-direction")); + + ASSIGN_EVENT_ONCE (accepted_spanevents_drul_[d], ev); +} + +IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_engraver, break_span); +void +New_dynamic_engraver::listen_break_span (Stream_event *event) +{ + if (event->in_event_class ("break-dynamic-span-event")) + { + // Case 1: Already have a start dynamic event -> break applies to new + // spanner (created later) -> set a flag + // Case 2: no new spanner, but spanner already active -> break it now + if (accepted_spanevents_drul_[START]) + end_new_spanner_ = true; + else if (current_spanner_) + current_spanner_->set_property ("spanner-broken", SCM_BOOL_T); + } +} + +SCM +New_dynamic_engraver::get_property_setting (Stream_event *evt, + char const *evprop, + char const *ctxprop) +{ + SCM spanner_type = evt->get_property (evprop); + if (spanner_type == SCM_EOL) + spanner_type = get_property (ctxprop); + return spanner_type; +} + +void +New_dynamic_engraver::process_music () +{ + if (current_spanner_ + && (accepted_spanevents_drul_[STOP] + || script_event_ + || accepted_spanevents_drul_[START])) + { + Stream_event *ender = accepted_spanevents_drul_[STOP]; + if (!ender) + ender = script_event_; + + if (!ender) + ender = accepted_spanevents_drul_[START]; + + finished_spanner_ = current_spanner_; + announce_end_grob (finished_spanner_, ender->self_scm ()); + current_spanner_ = 0; + current_span_event_ = 0; + } + + if (accepted_spanevents_drul_[START]) + { + current_span_event_ = accepted_spanevents_drul_[START]; + + string start_type = get_spanner_type (current_span_event_); + SCM cresc_type = get_property_setting (current_span_event_, "span-type", + (start_type + "Spanner").c_str ()); + + if (cresc_type == ly_symbol2scm ("text")) + { + current_spanner_ + = make_spanner ("DynamicTextSpanner", + accepted_spanevents_drul_[START]->self_scm ()); + + SCM text = get_property_setting (current_span_event_, "span-text", + (start_type + "Text").c_str ()); + if (Text_interface::is_markup (text)) + current_spanner_->set_property ("text", text); + /* + If the line of a text spanner is hidden, end the alignment spanner + early: this allows dynamics to be spaced individually instead of + being linked together. + */ + if (current_spanner_->get_property ("style") == ly_symbol2scm ("none")) + current_spanner_->set_property ("spanner-broken", SCM_BOOL_T); + } + else + { + if (cresc_type != ly_symbol2scm ("hairpin")) + { + string as_string = ly_scm_write_string (cresc_type); + current_span_event_ + ->origin ()->warning (_f ("unknown crescendo style: %s\ndefaulting to hairpin.", as_string.c_str ())); + } + current_spanner_ = make_spanner ("Hairpin", + current_span_event_->self_scm ()); + } + // if we have a break-dynamic-span event right after the start dynamic, break the new spanner immediately + if (end_new_spanner_) + { + current_spanner_->set_property ("spanner-broken", SCM_BOOL_T); + end_new_spanner_ = false; + } + if (finished_spanner_) + { + if (Hairpin::has_interface (finished_spanner_)) + Pointer_group_interface::add_grob (finished_spanner_, + ly_symbol2scm ("adjacent-spanners"), + current_spanner_); + if (Hairpin::has_interface (current_spanner_)) + Pointer_group_interface::add_grob (current_spanner_, + ly_symbol2scm ("adjacent-spanners"), + finished_spanner_); + } + } + + if (script_event_) + { + script_ = make_item ("DynamicText", script_event_->self_scm ()); + script_->set_property ("text", + script_event_->get_property ("text")); + + if (finished_spanner_) + finished_spanner_->set_bound (RIGHT, script_); + if (current_spanner_) + current_spanner_->set_bound (LEFT, script_); + } +} + +void +New_dynamic_engraver::stop_translation_timestep () +{ + if (finished_spanner_ && !finished_spanner_->get_bound (RIGHT)) + finished_spanner_ + ->set_bound (RIGHT, + unsmob_grob (get_property ("currentMusicalColumn"))); + + if (current_spanner_ && !current_spanner_->get_bound (LEFT)) + current_spanner_ + ->set_bound (LEFT, + unsmob_grob (get_property ("currentMusicalColumn"))); + script_ = 0; + script_event_ = 0; + accepted_spanevents_drul_.set (0, 0); + finished_spanner_ = 0; + end_new_spanner_ = false; +} + +void +New_dynamic_engraver::finalize () +{ + if (current_spanner_ + && !current_spanner_->is_live ()) + current_spanner_ = 0; + if (current_spanner_) + { + current_span_event_ + ->origin ()->warning (_f ("unterminated %s", + get_spanner_type (current_span_event_) + .c_str ())); + current_spanner_->suicide (); + current_spanner_ = 0; + } +} + +string +New_dynamic_engraver::get_spanner_type (Stream_event *ev) +{ + string type; + SCM start_sym = scm_car (ev->get_property ("class")); + + if (start_sym == ly_symbol2scm ("decrescendo-event")) + type = "decrescendo"; + else if (start_sym == ly_symbol2scm ("crescendo-event")) + type = "crescendo"; + else + programming_error ("unknown dynamic spanner type"); + + return type; +} + +void +New_dynamic_engraver::acknowledge_note_column (Grob_info info) +{ + if (script_ && !script_->get_parent (X_AXIS)) + { + extract_grob_set (info.grob (), "note-heads", heads); + Grob *stem = unsmob_grob (info.grob ()->get_object ("stem")); + /* + Spacing constraints may require dynamics to be aligned on rests, + so check for a rest if this note column has no note heads. + */ + Grob *x_parent = (heads.size () + ? heads[0] + : unsmob_grob (info.grob ()->get_object ("rest"))); + if (x_parent) + { + script_->set_parent (x_parent, X_AXIS); + Self_alignment_interface::set_center_parent (script_, X_AXIS); + } + if (stem) + Pointer_group_interface::add_grob (script_, ly_symbol2scm ("potential-X-colliding-grobs"), stem); + } + + if (current_spanner_ && !current_spanner_->get_bound (LEFT)) + current_spanner_->set_bound (LEFT, info.grob ()); + if (finished_spanner_ && !finished_spanner_->get_bound (RIGHT)) + finished_spanner_->set_bound (RIGHT, info.grob ()); +} + +ADD_ACKNOWLEDGER (New_dynamic_engraver, note_column); +ADD_TRANSLATOR (New_dynamic_engraver, + /* doc */ + "Create hairpins, dynamic texts and dynamic text spanners.", + + /* create */ + "DynamicTextSpanner " + "DynamicText " + "Hairpin ", + + /* read */ + "crescendoSpanner " + "crescendoText " + "currentMusicalColumn " + "decrescendoSpanner " + "decrescendoText ", + + /* write */ + "" + ); diff --git a/lily/new-dynamic-engraver.cc b/lily/new-dynamic-engraver.cc deleted file mode 100644 index cd7db644a6..0000000000 --- a/lily/new-dynamic-engraver.cc +++ /dev/null @@ -1,305 +0,0 @@ -/* - This file is part of LilyPond, the GNU music typesetter. - - Copyright (C) 2008--2012 Han-Wen Nienhuys - - LilyPond is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - LilyPond is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with LilyPond. If not, see . -*/ - -#include "engraver.hh" -#include "hairpin.hh" -#include "international.hh" -#include "item.hh" -#include "note-column.hh" -#include "pointer-group-interface.hh" -#include "self-alignment-interface.hh" -#include "spanner.hh" -#include "stream-event.hh" -#include "text-interface.hh" - -#include "translator.icc" - -class New_dynamic_engraver : public Engraver -{ - TRANSLATOR_DECLARATIONS (New_dynamic_engraver); - DECLARE_ACKNOWLEDGER (note_column); - DECLARE_TRANSLATOR_LISTENER (absolute_dynamic); - DECLARE_TRANSLATOR_LISTENER (span_dynamic); - DECLARE_TRANSLATOR_LISTENER (break_span); - -protected: - virtual void process_music (); - virtual void stop_translation_timestep (); - virtual void finalize (); - -private: - SCM get_property_setting (Stream_event *evt, char const *evprop, - char const *ctxprop); - string get_spanner_type (Stream_event *ev); - - Drul_array accepted_spanevents_drul_; - Spanner *current_spanner_; - Spanner *finished_spanner_; - - Item *script_; - Stream_event *script_event_; - Stream_event *current_span_event_; - bool end_new_spanner_; -}; - -New_dynamic_engraver::New_dynamic_engraver () -{ - script_event_ = 0; - current_span_event_ = 0; - script_ = 0; - finished_spanner_ = 0; - current_spanner_ = 0; - accepted_spanevents_drul_.set (0, 0); - end_new_spanner_ = false; -} - -IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_engraver, absolute_dynamic); -void -New_dynamic_engraver::listen_absolute_dynamic (Stream_event *ev) -{ - ASSIGN_EVENT_ONCE (script_event_, ev); -} - -IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_engraver, span_dynamic); -void -New_dynamic_engraver::listen_span_dynamic (Stream_event *ev) -{ - Direction d = to_dir (ev->get_property ("span-direction")); - - ASSIGN_EVENT_ONCE (accepted_spanevents_drul_[d], ev); -} - -IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_engraver, break_span); -void -New_dynamic_engraver::listen_break_span (Stream_event *event) -{ - if (event->in_event_class ("break-dynamic-span-event")) - { - // Case 1: Already have a start dynamic event -> break applies to new - // spanner (created later) -> set a flag - // Case 2: no new spanner, but spanner already active -> break it now - if (accepted_spanevents_drul_[START]) - end_new_spanner_ = true; - else if (current_spanner_) - current_spanner_->set_property ("spanner-broken", SCM_BOOL_T); - } -} - -SCM -New_dynamic_engraver::get_property_setting (Stream_event *evt, - char const *evprop, - char const *ctxprop) -{ - SCM spanner_type = evt->get_property (evprop); - if (spanner_type == SCM_EOL) - spanner_type = get_property (ctxprop); - return spanner_type; -} - -void -New_dynamic_engraver::process_music () -{ - if (current_spanner_ - && (accepted_spanevents_drul_[STOP] - || script_event_ - || accepted_spanevents_drul_[START])) - { - Stream_event *ender = accepted_spanevents_drul_[STOP]; - if (!ender) - ender = script_event_; - - if (!ender) - ender = accepted_spanevents_drul_[START]; - - finished_spanner_ = current_spanner_; - announce_end_grob (finished_spanner_, ender->self_scm ()); - current_spanner_ = 0; - current_span_event_ = 0; - } - - if (accepted_spanevents_drul_[START]) - { - current_span_event_ = accepted_spanevents_drul_[START]; - - string start_type = get_spanner_type (current_span_event_); - SCM cresc_type = get_property_setting (current_span_event_, "span-type", - (start_type + "Spanner").c_str ()); - - if (cresc_type == ly_symbol2scm ("text")) - { - current_spanner_ - = make_spanner ("DynamicTextSpanner", - accepted_spanevents_drul_[START]->self_scm ()); - - SCM text = get_property_setting (current_span_event_, "span-text", - (start_type + "Text").c_str ()); - if (Text_interface::is_markup (text)) - current_spanner_->set_property ("text", text); - /* - If the line of a text spanner is hidden, end the alignment spanner - early: this allows dynamics to be spaced individually instead of - being linked together. - */ - if (current_spanner_->get_property ("style") == ly_symbol2scm ("none")) - current_spanner_->set_property ("spanner-broken", SCM_BOOL_T); - } - else - { - if (cresc_type != ly_symbol2scm ("hairpin")) - { - string as_string = ly_scm_write_string (cresc_type); - current_span_event_ - ->origin ()->warning (_f ("unknown crescendo style: %s\ndefaulting to hairpin.", as_string.c_str ())); - } - current_spanner_ = make_spanner ("Hairpin", - current_span_event_->self_scm ()); - } - // if we have a break-dynamic-span event right after the start dynamic, break the new spanner immediately - if (end_new_spanner_) - { - current_spanner_->set_property ("spanner-broken", SCM_BOOL_T); - end_new_spanner_ = false; - } - if (finished_spanner_) - { - if (Hairpin::has_interface (finished_spanner_)) - Pointer_group_interface::add_grob (finished_spanner_, - ly_symbol2scm ("adjacent-spanners"), - current_spanner_); - if (Hairpin::has_interface (current_spanner_)) - Pointer_group_interface::add_grob (current_spanner_, - ly_symbol2scm ("adjacent-spanners"), - finished_spanner_); - } - } - - if (script_event_) - { - script_ = make_item ("DynamicText", script_event_->self_scm ()); - script_->set_property ("text", - script_event_->get_property ("text")); - - if (finished_spanner_) - finished_spanner_->set_bound (RIGHT, script_); - if (current_spanner_) - current_spanner_->set_bound (LEFT, script_); - } -} - -void -New_dynamic_engraver::stop_translation_timestep () -{ - if (finished_spanner_ && !finished_spanner_->get_bound (RIGHT)) - finished_spanner_ - ->set_bound (RIGHT, - unsmob_grob (get_property ("currentMusicalColumn"))); - - if (current_spanner_ && !current_spanner_->get_bound (LEFT)) - current_spanner_ - ->set_bound (LEFT, - unsmob_grob (get_property ("currentMusicalColumn"))); - script_ = 0; - script_event_ = 0; - accepted_spanevents_drul_.set (0, 0); - finished_spanner_ = 0; - end_new_spanner_ = false; -} - -void -New_dynamic_engraver::finalize () -{ - if (current_spanner_ - && !current_spanner_->is_live ()) - current_spanner_ = 0; - if (current_spanner_) - { - current_span_event_ - ->origin ()->warning (_f ("unterminated %s", - get_spanner_type (current_span_event_) - .c_str ())); - current_spanner_->suicide (); - current_spanner_ = 0; - } -} - -string -New_dynamic_engraver::get_spanner_type (Stream_event *ev) -{ - string type; - SCM start_sym = scm_car (ev->get_property ("class")); - - if (start_sym == ly_symbol2scm ("decrescendo-event")) - type = "decrescendo"; - else if (start_sym == ly_symbol2scm ("crescendo-event")) - type = "crescendo"; - else - programming_error ("unknown dynamic spanner type"); - - return type; -} - -void -New_dynamic_engraver::acknowledge_note_column (Grob_info info) -{ - if (script_ && !script_->get_parent (X_AXIS)) - { - extract_grob_set (info.grob (), "note-heads", heads); - Grob *stem = unsmob_grob (info.grob ()->get_object ("stem")); - /* - Spacing constraints may require dynamics to be aligned on rests, - so check for a rest if this note column has no note heads. - */ - Grob *x_parent = (heads.size () - ? heads[0] - : unsmob_grob (info.grob ()->get_object ("rest"))); - if (x_parent) - { - script_->set_parent (x_parent, X_AXIS); - Self_alignment_interface::set_center_parent (script_, X_AXIS); - } - if (stem) - Pointer_group_interface::add_grob (script_, ly_symbol2scm ("potential-X-colliding-grobs"), stem); - } - - if (current_spanner_ && !current_spanner_->get_bound (LEFT)) - current_spanner_->set_bound (LEFT, info.grob ()); - if (finished_spanner_ && !finished_spanner_->get_bound (RIGHT)) - finished_spanner_->set_bound (RIGHT, info.grob ()); -} - -ADD_ACKNOWLEDGER (New_dynamic_engraver, note_column); -ADD_TRANSLATOR (New_dynamic_engraver, - /* doc */ - "Create hairpins, dynamic texts and dynamic text spanners.", - - /* create */ - "DynamicTextSpanner " - "DynamicText " - "Hairpin ", - - /* read */ - "crescendoSpanner " - "crescendoText " - "currentMusicalColumn " - "decrescendoSpanner " - "decrescendoText ", - - /* write */ - "" - );