From 71056f5964c862b038992b54edb49de5a1d1ffa6 Mon Sep 17 00:00:00 2001 From: Glen Prideaux Date: Sat, 22 Jul 2000 17:49:13 +0200 Subject: [PATCH] patch::: 1.3.74.gp1 * Improved default handling of Lyric_phrasing_engraver and made it on by default. * Beginnings of a stanza number engraver (\property LyricVoice.stanza = #"1:" etc.) * fixed bug in script.cc so fermata (and other scripts) get flipped correctly when they are above the staff. 1.3.74 ====== --- CHANGES | 13 ++++ VERSION | 2 +- lily/include/lyric-phrasing-engraver.hh | 7 +- lily/lyric-phrasing-engraver.cc | 99 +++++++++++-------------- lily/scm-hash.cc | 2 +- lily/script.cc | 10 +-- lily/stanza-number-engraver.cc | 88 ++++++++++++++++++++++ ly/engraver.ly | 14 +++- 8 files changed, 165 insertions(+), 70 deletions(-) create mode 100644 lily/stanza-number-engraver.cc diff --git a/CHANGES b/CHANGES index 0e730c4cdf..597aa4bbfa 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,16 @@ +* Improved default handling of Lyric_phrasing_engraver and made it on by +default. + +* Beginnings of a stanza number engraver (\property LyricVoice.stanza = +#"1:" etc.) + +* fixed bug in script.cc so fermata (and other scripts) get flipped +correctly when they are above the staff. + + + +1.3.74 +====== * Small bugfix: also do a deep copy on submusices * Fixed: \autochange doesn't crash anymore. diff --git a/VERSION b/VERSION index 26c0f60758..968d29242b 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 PATCH_LEVEL=74 -MY_PATCH_LEVEL= +MY_PATCH_LEVEL=gp1 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/lily/include/lyric-phrasing-engraver.hh b/lily/include/lyric-phrasing-engraver.hh index 45b0769de2..f5a410308c 100644 --- a/lily/include/lyric-phrasing-engraver.hh +++ b/lily/include/lyric-phrasing-engraver.hh @@ -81,6 +81,7 @@ private: /** association list of Voice_alist_entry smobs */ Protected_scm voice_alist_; + Score_element * any_notehead_l_; }; @@ -89,8 +90,8 @@ class Voice_alist_entry bool first_in_phrase_b_; Score_element * notehead_l_; Link_array lyric_list_; - int longest_lyric_; - int shortest_lyric_; + Score_element * longest_lyric_l_; + Score_element * shortest_lyric_l_; int alignment_i_; public: @@ -100,7 +101,7 @@ public: void add_lyric(Score_element * lyric); void clear(); bool is_empty(); - bool set_lyric_align(const char *punc); + bool set_lyric_align(const char *punc, Score_element *default_notehead_l); int appropriate_alignment(const char *punc); void next_lyric(); private: diff --git a/lily/lyric-phrasing-engraver.cc b/lily/lyric-phrasing-engraver.cc index c17755f745..2b507ea027 100644 --- a/lily/lyric-phrasing-engraver.cc +++ b/lily/lyric-phrasing-engraver.cc @@ -21,6 +21,7 @@ ADD_THIS_TRANSLATOR (Lyric_phrasing_engraver); Lyric_phrasing_engraver::Lyric_phrasing_engraver() { voice_alist_ = SCM_EOL; + any_notehead_l_ = 0; } Lyric_phrasing_engraver::~Lyric_phrasing_engraver() @@ -52,8 +53,8 @@ Lyric_phrasing_engraver::record_notehead(const String &context_id, Score_element { Voice_alist_entry * v = lookup_context_id(context_id); v->set_notehead(notehead); - // voice_alist_ = - // scm_assoc_set_x(voice_alist_, ly_str02scm(context_id.ch_C()), smobify(v)); + if(!any_notehead_l_) + any_notehead_l_ = notehead; } void @@ -61,8 +62,6 @@ Lyric_phrasing_engraver::record_lyric(const String &context_id, Score_element * { Voice_alist_entry * v = lookup_context_id(context_id); v->add_lyric(lyric); - // voice_alist_ = - // scm_assoc_set_x(voice_alist_, ly_str02scm(context_id.ch_C()), smobify(v)); } @@ -136,15 +135,13 @@ void Lyric_phrasing_engraver::process_acknowledged () */ Voice_alist_entry *entry; String punc; - if (punc.empty_b()) { - SCM sp = get_property("phrasingPunctuation"); - punc = gh_string_p(sp) ? ly_scm2string(sp) : ".,;?!"; - } - + SCM sp = get_property("phrasingPunctuation"); + punc = gh_string_p(sp) ? ly_scm2string(sp) : ".,;:?!\""; + for(unsigned v=0; v < gh_length(voice_alist_); v++) { entry = unsmob_voice_entry(gh_cdr(gh_list_ref(voice_alist_, gh_int2scm(v)))); - if(! entry->set_lyric_align(punc.ch_C())) - warning (_ ("lyrics found without matching notehead ... aligning on self")); + if(! entry->set_lyric_align(punc.ch_C(), any_notehead_l_)) + warning (_ ("lyrics found without any matching notehead")); } } @@ -157,6 +154,7 @@ Lyric_phrasing_engraver::do_pre_move_processing () entry = unsmob_voice_entry(gh_cdr(gh_list_ref(voice_alist_, gh_int2scm(v)))); entry->next_lyric(); } + any_notehead_l_ = 0; } @@ -181,8 +179,8 @@ Voice_alist_entry::clear() { notehead_l_=0; lyric_list_.clear(); - longest_lyric_=-1; - shortest_lyric_=-1; + longest_lyric_l_=0; + shortest_lyric_l_=0; } void @@ -202,22 +200,20 @@ Voice_alist_entry::set_notehead(Score_element * notehead) void Voice_alist_entry::add_lyric(Score_element * lyric) { - int this_lyric = lyric_list_.size(); lyric_list_.push(lyric); /* record longest and shortest lyrics */ - if(longest_lyric_>-1) { - Real this_length = (lyric->extent(X_AXIS)).length(); - if(this_length > (lyric_list_[longest_lyric_]->extent(X_AXIS)).length()) - longest_lyric_ = this_lyric; - if(this_length < (lyric_list_[shortest_lyric_]->extent(X_AXIS)).length()) - shortest_lyric_ = this_lyric; + if( longest_lyric_l_ ) { + if(lyric->extent(X_AXIS).length() > (longest_lyric_l_->extent(X_AXIS)).length()) + longest_lyric_l_ = lyric; + if(lyric->extent(X_AXIS).length() < (shortest_lyric_l_->extent(X_AXIS)).length()) + shortest_lyric_l_ = lyric; } else - longest_lyric_ = shortest_lyric_ = this_lyric; + longest_lyric_l_ = shortest_lyric_l_ = lyric; } bool -Voice_alist_entry::set_lyric_align(const char *punc) +Voice_alist_entry::set_lyric_align(const char *punc, Score_element *default_notehead_l) { if(lyric_list_.size()<2) { /* Only for multi-stanza songs ... if we've only a single lyric (or none at all) we @@ -236,48 +232,37 @@ Voice_alist_entry::set_lyric_align(const char *punc) lyric = lyric_list_[l]; lyric->set_elt_property("self-alignment-X", gh_int2scm(alignment_i_)); - // centre on notehead - - if(notehead_l_) { + // centre on notehead ... if we have one. If there was no notehead in the matching + // voice context, use the first notehead caught from any voice context (any port in a storm). + if(notehead_l_ || default_notehead_l) { /* set the parent of each lyric to the notehead, set the offset callback of each lyric to centered_on_parent, */ - lyric->set_parent(notehead_l_, X_AXIS); + Score_element * parent_nh = notehead_l_ ? notehead_l_ : default_notehead_l; + lyric->set_parent(parent_nh, X_AXIS); lyric->add_offset_callback (Side_position::centered_on_parent, X_AXIS); /* reference is on the right of the notehead; move it left half way */ - lyric->translate_axis (-(notehead_l_->extent(X_AXIS)).center(), X_AXIS); - } - else { - /* No matching notehead: just align to the first lyric, and - issue a warning about lyric without matching notehead - */ - if(l) { - lyric->set_parent(lyric_list_[0], X_AXIS); - lyric->add_offset_callback (Side_position::centered_on_parent, X_AXIS); - } - else - lyric->add_offset_callback (Side_position::aligned_on_self, X_AXIS); - } - - if(alignment_i_ != CENTER) { - // right or left align ... - /* If length of longest lyric < 2 * length of shortest lyric, - - centre longest lyric on notehead - Otherwise - - move so shortest lyric just reaches notehead centre - */ - // FIXME: do we really know the lyric extent here? Some font sizing comes later? - Real translate; - if((lyric_list_[longest_lyric_]->extent(X_AXIS)).length() < - (lyric_list_[shortest_lyric_]->extent(X_AXIS)).length() * 2 ) - translate = alignment_i_*(lyric_list_[longest_lyric_]->extent(X_AXIS)).length()/2; - else - translate = alignment_i_*(lyric_list_[shortest_lyric_]->extent(X_AXIS)).length(); - lyric->translate_axis (translate, X_AXIS); + lyric->translate_axis (-(parent_nh->extent(X_AXIS)).center(), X_AXIS); + + if(alignment_i_ != CENTER) { + // right or left align ... + /* If length of longest lyric < 2 * length of shortest lyric, + - centre longest lyric on notehead + Otherwise + - move so shortest lyric just reaches notehead centre + */ + // FIXME: do we really know the lyric extent here? Some font sizing comes later? + Real translate; + if((longest_lyric_l_->extent(X_AXIS)).length() < + (shortest_lyric_l_->extent(X_AXIS)).length() * 2 ) + translate = alignment_i_*(longest_lyric_l_->extent(X_AXIS)).length()/2; + else + translate = alignment_i_*(shortest_lyric_l_->extent(X_AXIS)).length(); + lyric->translate_axis (translate, X_AXIS); } } - - return (notehead_l_ != 0); + } + return (notehead_l_ || default_notehead_l); } /** determine what alignment we want. diff --git a/lily/scm-hash.cc b/lily/scm-hash.cc index 16c5974737..23f587f6c7 100644 --- a/lily/scm-hash.cc +++ b/lily/scm-hash.cc @@ -9,6 +9,7 @@ #include #include "scm-hash.hh" +#include "ly-smobs.icc" @@ -116,7 +117,6 @@ Scheme_hash_table::to_alist () const } -#include "ly-smobs.icc" IMPLEMENT_UNSMOB(Scheme_hash_table,scheme_hash); IMPLEMENT_SMOBS(Scheme_hash_table); IMPLEMENT_DEFAULT_EQUAL_P(Scheme_hash_table); diff --git a/lily/script.cc b/lily/script.cc index 677dbd22d7..c4c875f563 100644 --- a/lily/script.cc +++ b/lily/script.cc @@ -54,11 +54,11 @@ SCM Script::brew_molecule (SCM smob) { Score_element *me= unsmob_element (smob); - Direction dir = DOWN; - SCM d = me->get_elt_property ("direction"); - if (isdir_b (d)) - dir = to_dir (d); - +// Direction dir = DOWN; +// SCM d = me->get_elt_property ("direction"); +// if (isdir_b (d)) +// dir = to_dir (d); + Direction dir = Side_position::get_direction(me); return get_molecule (me, dir).create_scheme(); } diff --git a/lily/stanza-number-engraver.cc b/lily/stanza-number-engraver.cc new file mode 100644 index 0000000000..86d62e4fbd --- /dev/null +++ b/lily/stanza-number-engraver.cc @@ -0,0 +1,88 @@ + +/* + lyric-number-engraver.cc -- implement Stanza_number_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2000 Han-Wen Nienhuys , Glen Prideaux + + Similar to (and derived from) Instrument_name_engraver. + */ + +#include "engraver.hh" +#include "item.hh" +//#include "system-start-delimiter.hh" +//#include "side-position-interface.hh" +//#include "staff-symbol-referencer.hh" +#include "bar.hh" + +class Stanza_number_engraver : public Engraver +{ + Item *text_; + bool bar_b_;; + + void create_text (SCM s); +public: + VIRTUAL_COPY_CONS(Translator); + Stanza_number_engraver (); + + virtual void acknowledge_element (Score_element_info); + virtual void do_pre_move_processing (); +}; + +ADD_THIS_TRANSLATOR(Stanza_number_engraver); + +Stanza_number_engraver::Stanza_number_engraver () +{ + text_ = 0; + bar_b_ = false; +} + +void +Stanza_number_engraver::acknowledge_element(Score_element_info i) +{ + SCM s = get_property ("stanza"); + + if (now_mom () > Moment (0)) + s = get_property ("stz"); + + if (gh_string_p (s)) + { +// if (i.elem_l_->has_interface (ly_symbol2scm ("lyric-syllable-interface"))) + // Tried catching lyric items to generate stanza numbers, but it spoils lyric spacing. + if (Bar::has_interface (i.elem_l_) || now_mom() == Moment(0)) + // Works, but requires bar_engraver in LyricVoice context apart from at beginning. + // Is there any score element we can catch that will do the trick? +// if (! i.elem_l_->has_interface (ly_symbol2scm ("lyric-syllable-interface")) || +// now_mom() == Moment(0)) + // What happens if we try anything at all EXCEPT a lyric? Is there anything else? + // Not sure what it's catching, but it still mucks up lyrics. + create_text (s); + } +} + + +void +Stanza_number_engraver::do_pre_move_processing () +{ + if (text_) + { + typeset_element (text_); + text_ = 0; + } +} + +void +Stanza_number_engraver::create_text (SCM txt) +{ + if(!text_) + { + text_ = new Item (get_property ("basicStanzaNumberProperties")); + text_->set_elt_property ("text", txt); + announce_element (text_,0); + } +} + + + + diff --git a/ly/engraver.ly b/ly/engraver.ly index d189cae32a..5553f0a1b9 100644 --- a/ly/engraver.ly +++ b/ly/engraver.ly @@ -271,8 +271,9 @@ LyricsVoiceContext= \translator{ \consists "Lyric_engraver"; \consists "Extender_engraver"; \consists "Hyphen_engraver"; - - phrasingPunctuation = #".,;:!?" + \consists "Stanza_number_engraver"; + phrasingPunctuation = #".,;:!?\"" + }; \translator{ \LyricsVoiceContext } @@ -374,13 +375,14 @@ ScoreContext = \translator { Key_item Staff_bar Time_signature + Stanza_number ) \consists "Spacing_engraver"; \consists "Vertical_align_engraver"; \consists "Lyric_phrasing_engraver"; - automaticPhrasing = ##f; + automaticPhrasing = ##t; \consists "Bar_number_engraver"; alignmentReference = \down; @@ -725,6 +727,12 @@ ScoreContext = \translator { (molecule-callback . ,Volta_spanner::brew_molecule) (interfaces . (volta-spanner-interface)) ) + basicStanzaNumberProperties = #`( + (breakable . #t) + (molecule-callback . ,Text_item::brew_molecule) + (break-align-symbol . Clef_item) + (visibility-lambda . ,begin-of-line-visible) + ) \accepts "Staff"; \accepts "StaffGroup"; -- 2.39.5