X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fvolta-engraver.cc;h=bd198cbb67faad5c395bd1567133d6413019c938;hb=579cc91ea384517d2c6b85e224074ffdfaa1f5ba;hp=1227a9315bc25bbdbd0880f7b7e05dd59d891306;hpb=f25fce62a31762d6621272fa7b703cf38d481b3a;p=lilypond.git diff --git a/lily/volta-engraver.cc b/lily/volta-engraver.cc index 1227a9315b..bd198cbb67 100644 --- a/lily/volta-engraver.cc +++ b/lily/volta-engraver.cc @@ -1,186 +1,208 @@ -/* - volta-engraver.cc -- implement Volta_engraver - - source file of the GNU LilyPond music typesetter - - (c) 2000--2001 Han-Wen Nienhuys - - */ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 2000--2015 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 "translator-group.hh" -#include "volta-spanner.hh" -#include "item.hh" + +#include "axis-group-interface.hh" +#include "context.hh" +#include "grob-array.hh" +#include "international.hh" #include "note-column.hh" -#include "bar.hh" +#include "item.hh" #include "side-position-interface.hh" +#include "staff-symbol.hh" +#include "text-interface.hh" +#include "volta-bracket.hh" +#include "warn.hh" + +#include "translator.icc" /* Create Volta spanners, by reading repeatCommands property, usually - set by Unfolded_repeat_iterator. - */ + set by Volta_repeat_iterator. +*/ class Volta_engraver : public Engraver { public: - Volta_engraver (); - VIRTUAL_COPY_CONS (Translator); + TRANSLATOR_DECLARATIONS (Volta_engraver); protected: - virtual void acknowledge_grob (Grob_info); - virtual void finalize (); - virtual void stop_translation_timestep (); - virtual void process_music (); - virtual void create_grobs (); - - Moment started_mom_; - Spanner *volta_span_p_; - Spanner *end_volta_span_p_; + DECLARE_ACKNOWLEDGER (bar_line); + + virtual void derived_mark () const; + void stop_translation_timestep (); + void process_music (); - SCM start_str_; + Moment started_mom_; + Spanner *volta_bracket_; + Spanner *end_volta_bracket_; + Spanner *volta_spanner_; + SCM start_string_; }; -ADD_THIS_TRANSLATOR (Volta_engraver); +void +Volta_engraver::derived_mark () const +{ + scm_gc_mark (start_string_); +} Volta_engraver::Volta_engraver () { - volta_span_p_ = 0; - end_volta_span_p_ = 0; + start_string_ = SCM_EOL; + volta_bracket_ = 0; + end_volta_bracket_ = 0; + volta_spanner_ = 0; } - void Volta_engraver::process_music () { SCM cs = get_property ("repeatCommands"); - bool end = false; - start_str_ = SCM_EOL; - while (gh_pair_p (cs)) + bool end = false; + start_string_ = SCM_EOL; + while (scm_is_pair (cs)) { - SCM c = gh_car (cs); - - if (gh_pair_p (c) && gh_car (c) == ly_symbol2scm ("volta") - && gh_pair_p (gh_cdr (c))) - { - if (gh_cadr (c) == SCM_BOOL_F) - end = true; - else - start_str_ = gh_cadr (c); - } - - cs = gh_cdr (cs); + SCM c = scm_car (cs); + + if (scm_is_pair (c) + && scm_is_eq (scm_car (c), ly_symbol2scm ("volta")) + && scm_is_pair (scm_cdr (c))) + { + if (scm_is_false (scm_cadr (c))) + end = true; + else + start_string_ = scm_cadr (c); + } + + cs = scm_cdr (cs); } - if (volta_span_p_) + if (volta_bracket_) { SCM l (get_property ("voltaSpannerDuration")); Moment now = now_mom (); - - bool early_stop = unsmob_moment (l) - && *unsmob_moment (l) <= now - started_mom_; - + + bool early_stop = unsmob (l) + && *unsmob (l) <= now - started_mom_; + end = end || early_stop; } - - if (end && !volta_span_p_) + if (end && !volta_bracket_) + /* fixme: be more verbose. */ + warning (_ ("cannot end volta spanner")); + else if (end) { - warning (_ ("No volta spanner to end")); // fixme: be more verbose. + end_volta_bracket_ = volta_bracket_; + volta_bracket_ = 0; } - else if (end) + + if (volta_bracket_ + && (scm_is_string (start_string_) || scm_is_pair (start_string_))) { - end_volta_span_p_ = volta_span_p_; - volta_span_p_ =0; + warning (_ ("already have a volta spanner, ending that one prematurely")); - /* - maybe do typeset_grob () directly? - */ + if (end_volta_bracket_) + { + warning (_ ("also already have an ended spanner")); + warning (_ ("giving up")); + return; + } - if (!gh_string_p (start_str_)) - end_volta_span_p_->set_grob_property ("last-volta", SCM_BOOL_T); + end_volta_bracket_ = volta_bracket_; + volta_bracket_ = 0; } - if (gh_string_p (start_str_) && volta_span_p_) + if (!volta_bracket_ + && Text_interface::is_markup (start_string_)) { - warning (_ ("Already have a volta spanner. Stopping that one prematurely.")); - - if (end_volta_span_p_) - { - warning (_ ("Also have a stopped spanner. Giving up.")); - return ; - } - - end_volta_span_p_ = volta_span_p_; - volta_span_p_ = 0; - } -} + started_mom_ = now_mom (); -/* - this could just as well be done in process_music (), but what the hack. - */ -void -Volta_engraver::create_grobs () -{ - if (!volta_span_p_ && gh_string_p (start_str_)) - { - started_mom_ = now_mom () ; + volta_bracket_ = make_spanner ("VoltaBracket", SCM_EOL); + + volta_bracket_->set_property ("text", start_string_); - volta_span_p_ = new Spanner (get_property ("VoltaBracket")); - Volta_spanner::set_interface (volta_span_p_); - announce_grob (volta_span_p_,0); - volta_span_p_->set_grob_property ("text", start_str_); + if (!volta_spanner_) + volta_spanner_ = make_spanner ("VoltaBracketSpanner", SCM_EOL); + + Axis_group_interface::add_element (volta_spanner_, volta_bracket_); } } void -Volta_engraver::acknowledge_grob (Grob_info i) +Volta_engraver::acknowledge_bar_line (Grob_info i) { - if (Item* item = dynamic_cast (i.elem_l_)) - { - if (Note_column::has_interface (item)) - { - if (volta_span_p_) - Volta_spanner::add_column (volta_span_p_,item); - if (end_volta_span_p_) - Volta_spanner::add_column (end_volta_span_p_,item); - } - if (Bar::has_interface (item)) - { - if (volta_span_p_) - Volta_spanner::add_bar (volta_span_p_, item); - if (end_volta_span_p_) - Volta_spanner::add_bar (end_volta_span_p_ , item); - } - } + if (volta_bracket_) + Volta_bracket_interface::add_bar (volta_bracket_, i.item ()); + if (end_volta_bracket_) + Volta_bracket_interface::add_bar (end_volta_bracket_, i.item ()); + + if (volta_spanner_) + Side_position_interface::add_support (volta_spanner_, i.grob ()); } void -Volta_engraver::finalize () +Volta_engraver::stop_translation_timestep () { - if (volta_span_p_) - { - typeset_grob (volta_span_p_); - } - if (end_volta_span_p_) - { - typeset_grob (end_volta_span_p_); - } -} + Grob *cc = unsmob (get_property ("currentCommandColumn")); + Item *ci = dynamic_cast (cc); + if (end_volta_bracket_ && !end_volta_bracket_->get_bound (RIGHT)) + end_volta_bracket_->set_bound (RIGHT, ci); + if (volta_spanner_ && end_volta_bracket_) + volta_spanner_->set_bound (RIGHT, end_volta_bracket_->get_bound (RIGHT)); -void -Volta_engraver::stop_translation_timestep () -{ - if (end_volta_span_p_) + if (end_volta_bracket_ && !volta_bracket_) { - Side_position_interface::add_staff_support (end_volta_span_p_); - - typeset_grob (end_volta_span_p_); - end_volta_span_p_ =0; + for (SCM s = get_property ("stavesFound"); scm_is_pair (s); s = scm_cdr (s)) + Side_position_interface::add_support (volta_spanner_, unsmob (scm_car (s))); + volta_spanner_ = 0; } + + end_volta_bracket_ = 0; + + if (volta_bracket_ && !volta_bracket_->get_bound (LEFT)) + volta_bracket_->set_bound (LEFT, ci); + + if (volta_spanner_ && volta_bracket_ && !volta_spanner_->get_bound (LEFT)) + volta_spanner_->set_bound (LEFT, volta_bracket_->get_bound (LEFT)); } /* TODO: should attach volta to paper-column if no bar is found. - */ +*/ +ADD_ACKNOWLEDGER (Volta_engraver, bar_line); +ADD_TRANSLATOR (Volta_engraver, + /* doc */ + "Make volta brackets.", + + /* create */ + "VoltaBracket " + "VoltaBracketSpanner ", + + /* read */ + "repeatCommands " + "voltaSpannerDuration " + "stavesFound ", + + /* write */ + "" + );