From fd33235cac623bef31610d01e8bbb120139334cc Mon Sep 17 00:00:00 2001 From: fred Date: Tue, 26 Mar 2002 23:54:51 +0000 Subject: [PATCH] lilypond-1.3.78 --- input/test/dynamic-dir.ly | 12 + input/test/non-empty-text.ly | 14 +- input/test/part-combine.ly | 22 ++ lily/a2-devnull-engraver.cc | 41 ++++ lily/a2-engraver.cc | 137 +++++++++++ lily/axis-group-engraver.cc | 17 +- lily/axis-group-interface.cc | 17 +- lily/bar.cc | 6 +- lily/hara-kiri-group-spanner.cc | 25 ++ lily/include/hara-kiri-group-spanner.hh | 5 + lily/include/part-combine-music-iterator.hh | 40 ++++ lily/include/part-combine-music.hh | 35 +++ lily/include/score-element.hh | 2 + lily/music-iterator.cc | 4 + lily/my-lily-lexer.cc | 1 + lily/parser.yy | 12 +- lily/part-combine-music-iterator.cc | 249 ++++++++++++++++++++ lily/part-combine-music.cc | 65 +++++ lily/property-engraver.cc | 2 +- lily/score-element.cc | 12 +- lily/span-bar.cc | 15 +- lily/text-engraver.cc | 20 +- ly/engraver.ly | 13 +- 23 files changed, 725 insertions(+), 41 deletions(-) create mode 100644 input/test/dynamic-dir.ly create mode 100644 input/test/part-combine.ly create mode 100644 lily/a2-devnull-engraver.cc create mode 100644 lily/a2-engraver.cc create mode 100644 lily/include/part-combine-music-iterator.hh create mode 100644 lily/include/part-combine-music.hh create mode 100644 lily/part-combine-music-iterator.cc create mode 100644 lily/part-combine-music.cc diff --git a/input/test/dynamic-dir.ly b/input/test/dynamic-dir.ly new file mode 100644 index 0000000000..b7d353b09f --- /dev/null +++ b/input/test/dynamic-dir.ly @@ -0,0 +1,12 @@ +%non of the dynamics properties work anymore + +\score { + \context Voice \notes\relative c { +% \property Voice.verticalDirection = #-1 + + \property Voice.dynamicDirection = #1 + \property Voice.dynamicPadding = #40 + c \p c \< \! c \ff\> c \!c-\p + + } +} diff --git a/input/test/non-empty-text.ly b/input/test/non-empty-text.ly index 6244598991..7054d872f6 100644 --- a/input/test/non-empty-text.ly +++ b/input/test/non-empty-text.ly @@ -4,20 +4,10 @@ % \score{ \notes\relative c''{ - %\property Staff.textEmptyDimension=1 - a-"This text has no" - a - a - a-"width; the default" - \break \property Staff.textNonEmpty=##t - %\property Staff.textEmptyDimension=0 - a-"This text" - a-"is fat: notes are spaced" - a-"far apart and text" - a-"does not collide" + c4_"longlonglonglonglonglong" c4_"text" } \paper{ - linewidth=80.\mm; + linewidth=-80.\mm; } } diff --git a/input/test/part-combine.ly b/input/test/part-combine.ly new file mode 100644 index 0000000000..074498488e --- /dev/null +++ b/input/test/part-combine.ly @@ -0,0 +1,22 @@ +\score{ + \context Staff = first < + \context Voice=first { \skip 1; } + \context Voice=second { \skip 1; } + + \context Voice=first \partcombine Voice + \context Thread=first \notes\relative c'' + { + c4 d e f + b,4 d c d + r2 e4 f + c4 d e f + } + \context Thread=second \notes\relative c'' + { + a b c d + r2 c4 d + a c c d + a4. b8 c4 d + } + > +} diff --git a/lily/a2-devnull-engraver.cc b/lily/a2-devnull-engraver.cc new file mode 100644 index 0000000000..680dedb5a3 --- /dev/null +++ b/lily/a2-devnull-engraver.cc @@ -0,0 +1,41 @@ +/* + a2-devnull-engraver.cc -- implement A2_devnull_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2000 Jan Nieuwenhuizen +*/ + +#include "engraver.hh" +#include "item.hh" +#include "musical-request.hh" +#include "translator-group.hh" + +class A2_devnull_engraver : public Engraver +{ +public: + VIRTUAL_COPY_CONS (Translator); + +protected: + virtual bool do_try_music (Music*); +}; + +ADD_THIS_TRANSLATOR (A2_devnull_engraver); + +bool +A2_devnull_engraver::do_try_music (Music *m) +{ + if (Note_req * n = dynamic_cast (m)) + { + SCM a2 = get_property ("a2"); + // should be able to read id_str_, no? + SCM second = get_property ("second"); + + if (a2 == SCM_BOOL_T && second == SCM_BOOL_T) + { + return true; + } + } + return false; +} + diff --git a/lily/a2-engraver.cc b/lily/a2-engraver.cc new file mode 100644 index 0000000000..65a239e030 --- /dev/null +++ b/lily/a2-engraver.cc @@ -0,0 +1,137 @@ +/* + a2-engraver.cc -- implement A2_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2000 Jan Nieuwenhuizen +*/ + +#include "engraver.hh" +#include "item.hh" +#include "note-head.hh" +#include "stem.hh" +#include "translator-group.hh" +#include "side-position-interface.hh" +#include "directional-element-interface.hh" + +class A2_engraver : public Engraver +{ +public: + A2_engraver (); + VIRTUAL_COPY_CONS (Translator); + +protected: + virtual void do_process_music (); + virtual void acknowledge_element (Score_element_info); + //virtual void process_acknowledged (); + + virtual void do_pre_move_processing (); + +private: + Item* text_p_; +}; + +ADD_THIS_TRANSLATOR (A2_engraver); + +A2_engraver::A2_engraver () +{ + text_p_ = 0; +} + +void +A2_engraver::do_process_music () +{ + if (!text_p_) + { + SCM a2 = get_property ("a2"); + SCM solo = get_property ("solo"); + SCM solo2 = get_property ("solo2"); + + if (solo == SCM_BOOL_T || a2 == SCM_BOOL_T || solo2 == SCM_BOOL_T) + { + text_p_ = new Item (get_property ("basicTextScriptProperties")); + Side_position::set_axis (text_p_, Y_AXIS); + announce_element (text_p_, 0); + + /* + Urg, read prop + */ + SCM text; + Direction dir = UP; + if (solo == SCM_BOOL_T) + { + text = ly_str02scm ("Solo"); + } + else if (solo2 == SCM_BOOL_T) + { + text = ly_str02scm ("Solo II"); + dir = DOWN; + } + else if (a2 == SCM_BOOL_T) + { + text = ly_str02scm ("\\`a 2"); + } + + Side_position::set_direction (text_p_, dir); + text_p_->set_elt_property ("text", text); + + } + } +} + +void +A2_engraver::acknowledge_element (Score_element_info i) +{ + if (text_p_) + { + if (Note_head::has_interface (i.elem_l_)) + { + Score_element*t = text_p_; + Side_position::add_support (t, i.elem_l_); + if (Side_position::get_axis (t) == X_AXIS + && !t->parent_l (Y_AXIS)) + t->set_parent (i.elem_l_, Y_AXIS); + } + if (Stem::has_interface (i.elem_l_)) + { + Side_position::add_support (text_p_, i.elem_l_); + + SCM a2 = get_property ("a2"); + SCM solo = get_property ("solo"); + SCM solo2 = get_property ("solo2"); + + SCM first = get_property ("first"); + SCM second = get_property ("second"); + + if (solo != SCM_BOOL_T + && solo2 != SCM_BOOL_T + && a2 != SCM_BOOL_T) + { + if (first == SCM_BOOL_T) + { + Directional_element_interface (i.elem_l_).set (UP); + } + else if (second == SCM_BOOL_T) + { + Directional_element_interface (i.elem_l_).set (DOWN); + } + } + } + } +} + +void +A2_engraver::do_pre_move_processing () +{ + if (text_p_) + { + Side_position::add_staff_support (text_p_); + typeset_element (text_p_); + text_p_ = 0; + } + // burp: reset properties + daddy_trans_l_->set_property ("a2", SCM_BOOL_F); + daddy_trans_l_->set_property ("solo", SCM_BOOL_F); + daddy_trans_l_->set_property ("solo2", SCM_BOOL_F); +} + diff --git a/lily/axis-group-engraver.cc b/lily/axis-group-engraver.cc index ca6f5fb359..606c93ef8b 100644 --- a/lily/axis-group-engraver.cc +++ b/lily/axis-group-engraver.cc @@ -26,7 +26,9 @@ protected: virtual void acknowledge_element (Score_element_info); virtual void process_acknowledged (); virtual Spanner* get_spanner_p () const; + virtual void add_element (Score_element*) ; public: + VIRTUAL_COPY_CONS(Translator); Axis_group_engraver (); }; @@ -106,11 +108,16 @@ Axis_group_engraver::process_acknowledged () if ((!par || !Axis_group_interface::has_interface (par)) && ! elts_[i]->empty_b (Y_AXIS)) - Axis_group_interface::add_element (staffline_p_, elts_[i]); + add_element (elts_[i]); } elts_.clear (); } +void +Axis_group_engraver::add_element (Score_element*e) +{ + Axis_group_interface::add_element (staffline_p_, e); +} //////////////////////////////////////////////////////// @@ -124,10 +131,18 @@ class Hara_kiri_engraver : public Axis_group_engraver protected: virtual Spanner*get_spanner_p ()const; virtual void acknowledge_element (Score_element_info); + virtual void add_element (Score_element *e); public: VIRTUAL_COPY_CONS(Translator); }; +void +Hara_kiri_engraver::add_element (Score_element*e) +{ + Hara_kiri_group_spanner::add_element (staffline_p_, e); +} + + Spanner* Hara_kiri_engraver::get_spanner_p () const { diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 943c74a7ba..a156379adb 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -6,7 +6,7 @@ (c) 2000 Han-Wen Nienhuys */ - +#include "hara-kiri-group-spanner.hh" #include "axis-group-interface.hh" #include "score-element.hh" @@ -28,7 +28,13 @@ Axis_group_interface::add_element (Score_element*me,Score_element *e) bool Axis_group_interface::axis_b (Score_element*me,Axis a ) { - return me->has_extent_callback_b (group_extent_callback, a); + /* + urg. FIXME, check for Hara_kiri_group_spanner shouldn't be necessary? + + + */ + return me->has_extent_callback_b (group_extent_callback, a) || + (me->has_extent_callback_b (Hara_kiri_group_spanner::y_extent, a)); } Interval @@ -88,8 +94,11 @@ Axis_group_interface::set_axes (Score_element*me,Axis a1, Axis a2) if (a1 != Y_AXIS && a2 != Y_AXIS) me->set_extent_callback (0, Y_AXIS); - me->set_extent_callback (Axis_group_interface::group_extent_callback,a1); - me->set_extent_callback (Axis_group_interface::group_extent_callback,a2); + // if (!me->has_extent_callback_b (a1)) + if (me->has_extent_callback_b (Score_element::molecule_extent, a1)) + me->set_extent_callback (Axis_group_interface::group_extent_callback,a1); + if (me->has_extent_callback_b (Score_element::molecule_extent, a2)) + me->set_extent_callback (Axis_group_interface::group_extent_callback,a2); } Link_array diff --git a/lily/bar.cc b/lily/bar.cc index cb956edf23..7eaa478b7d 100644 --- a/lily/bar.cc +++ b/lily/bar.cc @@ -33,7 +33,11 @@ Bar::brew_molecule (SCM smob) { String str =ly_scm2string (s); SCM siz = gh_call1 (barsiz_proc, me->self_scm ()); - return compound_barline (me, str, gh_scm2double (siz)).create_scheme (); + Real sz = gh_scm2double (siz); + if (sz < 0) + return SCM_EOL; + + return compound_barline (me, str, sz).create_scheme (); } return SCM_EOL; } diff --git a/lily/hara-kiri-group-spanner.cc b/lily/hara-kiri-group-spanner.cc index cd16fab04f..25680db3ef 100644 --- a/lily/hara-kiri-group-spanner.cc +++ b/lily/hara-kiri-group-spanner.cc @@ -19,8 +19,18 @@ Hara_kiri_group_spanner::set_interface (Score_element*me) me->set_elt_property ("items-worth-living", SCM_EOL); me->add_offset_callback (force_hara_kiri_callback, Y_AXIS); me->set_interface (ly_symbol2scm ("hara-kiri-spanner-interface")); + me->set_extent_callback (Hara_kiri_group_spanner::y_extent, Y_AXIS); } +Interval +Hara_kiri_group_spanner::y_extent(Score_element*me, Axis a) +{ + assert (a == Y_AXIS); + consider_suicide (me); + return Axis_group_interface::group_extent_callback (me, a); +} + + bool Hara_kiri_group_spanner::has_interface (Score_element*me) { @@ -66,3 +76,18 @@ Hara_kiri_group_spanner::force_hara_kiri_callback (Score_element *elt, Axis a) return 0.0; } + +Real +Hara_kiri_group_spanner::force_hara_kiri_in_parent_callback (Score_element*daughter, Axis a) +{ + assert (a == Y_AXIS); + force_hara_kiri_callback (daughter->parent_l (a), Y_AXIS); + return 0.0; +} + +void +Hara_kiri_group_spanner::add_element (Score_element * me, Score_element *e) +{ + // e->add_offset_callback (force_hara_kiri_in_parent_callback, Y_AXIS); + Axis_group_interface::add_element (me, e); +} diff --git a/lily/include/hara-kiri-group-spanner.hh b/lily/include/hara-kiri-group-spanner.hh index b2ddc79a08..9f42879107 100644 --- a/lily/include/hara-kiri-group-spanner.hh +++ b/lily/include/hara-kiri-group-spanner.hh @@ -24,11 +24,16 @@ items-worth-living -- list of interesting items. If empty in a particular system, clear this line + + todo: naming */ class Hara_kiri_group_spanner { public: static Real force_hara_kiri_callback (Score_element * , Axis); + static Interval y_extent (Score_element * , Axis); + static Real force_hara_kiri_in_parent_callback (Score_element * , Axis); + static void add_element (Score_element *me, Score_element *e); static void set_interface (Score_element*me); static bool has_interface (Score_element*); static void consider_suicide (Score_element*me); diff --git a/lily/include/part-combine-music-iterator.hh b/lily/include/part-combine-music-iterator.hh new file mode 100644 index 0000000000..60cbebc8fc --- /dev/null +++ b/lily/include/part-combine-music-iterator.hh @@ -0,0 +1,40 @@ +/* + part-combine-music-iterator.hh -- declare Part_combine_music_iterator + + source file of the GNU LilyPond music typesetter + + (c) 2000 Jan Nieuwenhuizen + + */ + +#ifndef PART_COMBINE_MUSIC_ITERATOR_HH +#define PART_COMBINE_MUSIC_ITERATOR_HH + +#include "music-iterator.hh" + +class Part_combine_music_iterator : public Music_iterator +{ +public: + Part_combine_music_iterator (); + +protected: + virtual void construct_children (); + virtual Moment next_moment () const; + virtual void do_process_and_next (Moment); + virtual Music_iterator *try_music_in_children (Music *) const; + + virtual bool ok () const; + virtual void do_print () const; + virtual ~Part_combine_music_iterator (); + +private: + void change_to (Music_iterator*, String, String); + + Music_iterator * first_iter_p_; + Music_iterator * second_iter_p_; + + bool combined_b_; +}; + +#endif /* PART_COMBINE_MUSIC_ITERATOR_HH */ + diff --git a/lily/include/part-combine-music.hh b/lily/include/part-combine-music.hh new file mode 100644 index 0000000000..102de3ad06 --- /dev/null +++ b/lily/include/part-combine-music.hh @@ -0,0 +1,35 @@ +/* + part-combine-music.hh -- declare Part_combine_music + + source file of the GNU LilyPond music typesetter + + (c) 2000 Jan Nieuwenhuizen + + */ + +#ifndef PART_COMBINE_MUSIC_HH +#define PART_COMBINE_MUSIC_HH + +#include "music.hh" + + +class Part_combine_music : public Music +{ +public: + VIRTUAL_COPY_CONS (Music); + Part_combine_music (String, Music*, Music*); + + Music * first_l () const; + Music * second_l () const; + + virtual void transpose (Musical_pitch); + virtual void do_print () const; + virtual Moment length_mom () const; + virtual Musical_pitch to_relative_octave (Musical_pitch); + virtual void compress (Moment); + + String what_str_; +}; + +#endif /* PART_COMBINE_MUSIC_HH */ + diff --git a/lily/include/score-element.hh b/lily/include/score-element.hh index 85ff5e8774..f1a86dee28 100644 --- a/lily/include/score-element.hh +++ b/lily/include/score-element.hh @@ -187,9 +187,11 @@ public: Score_element*common_refpoint (Score_element const* s, Axis a) const; Score_element*common_refpoint (SCM elt_list, Axis a) const; + // duh. slim down interface here. (todo) bool has_offset_callback_b (Offset_callback, Axis)const; void add_offset_callback (Offset_callback, Axis); bool has_extent_callback_b (Extent_callback, Axis)const; + bool has_extent_callback_b (Axis) const; void set_extent_callback (Extent_callback , Axis); /** diff --git a/lily/music-iterator.cc b/lily/music-iterator.cc index d3a92834e7..9e88aeb12b 100644 --- a/lily/music-iterator.cc +++ b/lily/music-iterator.cc @@ -34,6 +34,8 @@ #include "lyric-combine-music-iterator.hh" #include "auto-change-music.hh" #include "auto-change-iterator.hh" +#include "part-combine-music.hh" +#include "part-combine-music-iterator.hh" #include "request.hh" #include "request-iterator.hh" #include "output-property.hh" @@ -146,6 +148,8 @@ Music_iterator::static_get_iterator_p (Music *m) p = new Grace_iterator; else if (dynamic_cast (m)) p = new Auto_change_iterator; + else if (dynamic_cast (m)) + p = new Part_combine_music_iterator; else if (dynamic_cast (m)) p = new Music_wrapper_iterator; else if (Repeated_music * n = dynamic_cast (m)) diff --git a/lily/my-lily-lexer.cc b/lily/my-lily-lexer.cc index 9020ae1659..4bd5a30495 100644 --- a/lily/my-lily-lexer.cc +++ b/lily/my-lily-lexer.cc @@ -66,6 +66,7 @@ static Keyword_ent the_key_tab[]={ {"remove", REMOVE}, {"repeat", REPEAT}, {"addlyrics", ADDLYRICS}, + {"partcombine", PARTCOMBINE}, {"score", SCORE}, {"script", SCRIPT}, {"skip", SKIP}, diff --git a/lily/parser.yy b/lily/parser.yy index 5c4632ac72..215dd69394 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -41,6 +41,7 @@ #include "mudela-version.hh" #include "grace-music.hh" #include "auto-change-music.hh" +#include "part-combine-music.hh" #include "output-property.hh" bool @@ -168,6 +169,7 @@ yylex (YYSTYPE *s, void * v_l) %token REMOVE %token REPEAT %token ADDLYRICS +%token PARTCOMBINE %token SCM_T %token SCORE %token SCRIPT @@ -237,7 +239,7 @@ yylex (YYSTYPE *s, void * v_l) %type embedded_scm scalar %type Music Sequential_music Simultaneous_music Music_sequence -%type relative_music re_rhythmed_music +%type relative_music re_rhythmed_music part_combined_music %type property_def translator_change %type Music_list %type music_output_def_body @@ -757,6 +759,7 @@ Composite_music: } | relative_music { $$ = $1; } | re_rhythmed_music { $$ = $1; } + | part_combined_music { $$ = $1; } ; relative_music: @@ -773,6 +776,13 @@ re_rhythmed_music: } ; +part_combined_music: + PARTCOMBINE STRING Music Music { + Part_combine_music * p = new Part_combine_music (ly_scm2string ($2), $3, $4); + $$ = p; + } + ; + translator_change: TRANSLATOR STRING '=' STRING { Change_translator * t = new Change_translator; diff --git a/lily/part-combine-music-iterator.cc b/lily/part-combine-music-iterator.cc new file mode 100644 index 0000000000..86f035486b --- /dev/null +++ b/lily/part-combine-music-iterator.cc @@ -0,0 +1,249 @@ +/* + part-combine-music-iterator.cc -- implement Part_combine_music_iterator + + source file of the GNU LilyPond music typesetter + + (c) 2000 Jan Nieuwenhuizen + */ + +#include "part-combine-music.hh" +#include "part-combine-music-iterator.hh" +#include "translator-group.hh" +#include "musical-request.hh" +#include "warn.hh" + +Part_combine_music_iterator::Part_combine_music_iterator () +{ + combined_b_ = false; + + first_iter_p_ = 0; + second_iter_p_ = 0; +} + +Part_combine_music_iterator::~Part_combine_music_iterator () +{ + delete second_iter_p_; + delete first_iter_p_; +} + +Moment +Part_combine_music_iterator::next_moment () const +{ + Moment first_next = first_iter_p_->next_moment (); + Moment second_next = second_iter_p_->next_moment (); + return first_next ok (); +} + +void +Part_combine_music_iterator::do_print () const +{ + first_iter_p_->print (); + second_iter_p_->print (); +} + +void +Part_combine_music_iterator::construct_children () +{ + Part_combine_music const * m = dynamic_cast (music_l_); + + first_iter_p_ = get_iterator_p (m->first_l ()); + second_iter_p_ = get_iterator_p (m->second_l ()); +} + +void +Part_combine_music_iterator::change_to (Music_iterator *it, String to_type, + String to_id) +{ + Translator_group * current = it->report_to_l (); + Translator_group * last = 0; + + /* + Cut & Paste from from Auto_change_iterator from Change_iterator (ugh). + + TODO: abstract this function + */ + + /* find the type of translator that we're changing. + + If \translator Staff = bass, then look for Staff = * + */ + while (current && current->type_str_ != to_type) + { + last = current; + current = current->daddy_trans_l_; + } + + if (current && current->id_str_ == to_id) + { + String msg; + msg += _ ("Can't switch translators, I'm there already"); + } + + if (current) + if (last) + { + Translator_group * dest = + it->report_to_l ()->find_create_translator_l (to_type, to_id); + current->remove_translator_p (last); + dest->add_translator (last); + } + else + { + /* + We could change the current translator's id, but that would make + errors hard to catch + + last->translator_id_str_ = change_l ()->change_to_id_str_; + */ + error (_f ("I'm one myself: `%s'", to_type.ch_C ())); + } + else + error (_f ("none of these in my family: `%s'", to_id.ch_C ())); +} + +Pitch_interrogate_req* first_spanish_inquisition; // nobody expects it +Pitch_interrogate_req* second_spanish_inquisition; // won't strike twice + +void +Part_combine_music_iterator::do_process_and_next (Moment m) +{ + Moment first_next = first_iter_p_->next_moment (); + Moment second_next = second_iter_p_->next_moment (); + + bool changed_b = false; + Part_combine_music const * p = dynamic_cast (music_l_); + + String to_id = combined_b_ ? "first" : "second"; + /* + different rhythm for combined voices: separate + same rhythm for separated voices: combine + */ + if ((first_next != second_next && combined_b_) + || (first_next == second_next && !combined_b_)) + { + combined_b_ = !combined_b_; + to_id = combined_b_ ? "first" : "second"; + change_to (second_iter_p_, p->what_str_, to_id); + changed_b = true; + } + + Translator_group * fd = + first_iter_p_->report_to_l ()->find_create_translator_l (p->what_str_, + "first"); + Translator_group * sd = + second_iter_p_->report_to_l ()->find_create_translator_l (p->what_str_, + to_id); + + fd->set_property ("first", SCM_BOOL_T); + sd->set_property ("second", SCM_BOOL_T); + + if (first_next <= m) + first_iter_p_->process_and_next (m); + + if (second_next <= m) + second_iter_p_->process_and_next (m); + + Music_iterator::do_process_and_next (m); + + /* + TODO: + + * "a2" string is fine, but "Soli" strings are one request late, + second a2 requests are junked one requst late... + + The problem seems to be: we need to do_try_music for the + spanish_inquisition to work; but the properties that we set + need to be set *before* we do_try_music? + + * setting of stem directions by a2-engraver don't work + + * move much as possible code (changed?) to engravers: just notify + them of status: unison/solo. Engravers should be able to find + out whether something changed and if so, what to do. + + * who should reset the properties, it's a mess now? + + + Later (because currently,we only handle thread swiching, really): + + Maybe different modes exist? + + * Wind instruments (Flute I/II) + * Hymnals: + + + Rules for Hymnals/SATB (John Henckel ): + + 1. if S and A differ by less than a third, the stems should be up/down. + 2. else if S and A have different values, the stems should be up/down. + 3. else if A sings "la" or higher, both S and A stems should be down. + 4. else both stems should be up + + * This may get really tricky: combining voices/staffs: string instruments + + */ + + if (!first_spanish_inquisition) + first_spanish_inquisition = new Pitch_interrogate_req; + Music_iterator* fit = first_iter_p_->try_music (first_spanish_inquisition); + + if (!second_spanish_inquisition) + second_spanish_inquisition = new Pitch_interrogate_req; + Music_iterator* sit = second_iter_p_->try_music (second_spanish_inquisition); + + + // URG, moveme: just set properties + if (//changed_b + //&& + (first_next == second_next) + && first_spanish_inquisition->pitch_arr_.size () + && (first_spanish_inquisition->pitch_arr_.size () + == second_spanish_inquisition->pitch_arr_.size ()) + && (first_spanish_inquisition->pitch_arr_[0] == + second_spanish_inquisition->pitch_arr_[0])) + { + if (changed_b) + { + fd->set_property ("a2", SCM_BOOL_T); + sd->set_property ("a2", SCM_BOOL_T); + } + second_iter_p_->report_to_l ()->set_property ("a2", SCM_BOOL_T); + } + else + second_iter_p_->report_to_l ()->set_property ("a2", SCM_BOOL_F); + + if (changed_b + && first_spanish_inquisition->pitch_arr_.size () + && !second_spanish_inquisition->pitch_arr_.size ()) + { + fd->set_property ("solo", SCM_BOOL_T); + } + + if (changed_b + && !first_spanish_inquisition->pitch_arr_.size () + && second_spanish_inquisition->pitch_arr_.size ()) + { + sd->set_property ("solo2", SCM_BOOL_T); + } + + first_spanish_inquisition->pitch_arr_.clear (); + second_spanish_inquisition->pitch_arr_.clear (); +} + +Music_iterator* +Part_combine_music_iterator::try_music_in_children (Music *m) const +{ + Music_iterator * i = first_iter_p_->try_music (m); + if (i) + return i; + else + return second_iter_p_->try_music (m); +} + diff --git a/lily/part-combine-music.cc b/lily/part-combine-music.cc new file mode 100644 index 0000000000..41127ac741 --- /dev/null +++ b/lily/part-combine-music.cc @@ -0,0 +1,65 @@ +/* + part-combine-music.cc -- implement Part_combine_music + + source file of the GNU LilyPond music typesetter + + (c) 2000 Jan Nieuwenhuizen + + */ + +#include "part-combine-music.hh" +#include "musical-pitch.hh" + +Part_combine_music::Part_combine_music (String what, Music * f, Music * s) +{ + what_str_ = what; + set_mus_property ("first", f->self_scm ()); + set_mus_property ("second", s->self_scm ()); +} + + +void +Part_combine_music::transpose (Musical_pitch p) +{ + first_l ()->transpose (p); + second_l () ->transpose (p); +} + +void +Part_combine_music::do_print () const +{ + first_l ()->print(); + second_l () ->print (); +} + +Moment +Part_combine_music::length_mom () const +{ + return first_l ()->length_mom (); +} + +Musical_pitch +Part_combine_music::to_relative_octave (Musical_pitch p) +{ + p = first_l ()->to_relative_octave (p); + return second_l ()->to_relative_octave (p); +} + +void +Part_combine_music::compress (Moment m) +{ + first_l ()->compress (m); + second_l ()->compress (m); +} + +Music* +Part_combine_music::first_l () const +{ + return unsmob_music (get_mus_property ("first")); +} + +Music* +Part_combine_music::second_l () const +{ + return unsmob_music (get_mus_property ("second")); +} diff --git a/lily/property-engraver.cc b/lily/property-engraver.cc index c6e5430263..e7baf2ec25 100644 --- a/lily/property-engraver.cc +++ b/lily/property-engraver.cc @@ -85,7 +85,7 @@ Property_engraver::acknowledge_element (Score_element_info i) void Property_engraver::apply_properties (SCM p, Score_element *e) -{ +{ for (; gh_pair_p (p); p = gh_cdr (p)) { /* diff --git a/lily/score-element.cc b/lily/score-element.cc index c39624b53b..6a294a4301 100644 --- a/lily/score-element.cc +++ b/lily/score-element.cc @@ -45,6 +45,9 @@ remove dynamic_cast and put this code into respective Score_element::Score_element(SCM basicprops) { + /* + fixme: default should be no callback. + */ set_extent_callback (molecule_extent, X_AXIS); set_extent_callback (molecule_extent, Y_AXIS); @@ -520,8 +523,8 @@ Score_element::get_offset (Axis a) const Real r = (*c) (me,a ); if (isinf (r) || isnan (r)) { - r = 0.0; programming_error (INFINITY_MSG); + r = 0.0; } me->dim_cache_[a].offset_ +=r; } @@ -641,6 +644,13 @@ Score_element::has_extent_callback_b (Extent_callback cb, Axis a)const return cb == dim_cache_[a].extent_callback_l_; } + +bool +Score_element::has_extent_callback_b (Axis a) const +{ + return dim_cache_[a].extent_callback_l_; +} + bool Score_element::has_offset_callback_b (Offset_callback cb, Axis a)const { diff --git a/lily/span-bar.cc b/lily/span-bar.cc index e4e790da14..722dd45d77 100644 --- a/lily/span-bar.cc +++ b/lily/span-bar.cc @@ -66,7 +66,13 @@ Span_bar::center_on_spanned_callback (Score_element * me, Axis a) void Span_bar::evaluate_empty (Score_element*me) -{ +{ + /* + TODO: filter all hara-kiried out of ELEMENS list, and then + optionally do suicide. Call this cleanage function from + center_on_spanned_callback() as well. + + */ if (!gh_pair_p (me->get_elt_property ("elements"))) { me->suicide (); @@ -113,8 +119,11 @@ Span_bar::get_bar_size (SCM smob) Interval iv (get_spanned_interval (me)); if (iv.empty_b ()) { - programming_error("Huh? My children deflated (FIXME)"); - iv = Interval (0,0); + /* + This happens if the bars are hara-kiried from under us. + */ + me->suicide (); + return gh_double2scm (-1); } return gh_double2scm (iv.length ()); } diff --git a/lily/text-engraver.cc b/lily/text-engraver.cc index 0fa41ca7cd..b634bf70e6 100644 --- a/lily/text-engraver.cc +++ b/lily/text-engraver.cc @@ -98,25 +98,19 @@ Text_engraver::do_process_music () text->set_elt_property ("style", ly_str02scm (r->style_str_.ch_C())); /* - huh?, this said: - - SCM empty = get_property ("textNonEmpty"); - if (to_boolean (empty)) - no-spacing-rods - Text is empty by default, which means that the only condition for not setting 'no-spacing-rods' should be: boolean && true. Anyway, non-empty text has been broken for some time now. */ SCM nonempty = get_property ("textNonEmpty"); - if (to_boolean (nonempty)) - ; - else - { - text->set_elt_property ("no-spacing-rods" , SCM_BOOL_F); - text->set_extent_callback (0, X_AXIS); - } + if (!to_boolean (nonempty)) + /* + empty text: signal that no rods should be applied. + */ + text->set_elt_property ("no-spacing-rods" , SCM_BOOL_T); + + announce_element (text, r); texts_.push (text); } diff --git a/ly/engraver.ly b/ly/engraver.ly index 790704c229..60399daa1b 100644 --- a/ly/engraver.ly +++ b/ly/engraver.ly @@ -145,6 +145,7 @@ VoiceContext = \translator { \consists "Melisma_engraver"; textScriptPadding = #3.0 \consists "Text_engraver"; + \consists "A2_engraver"; startSustain = #"Ped." @@ -204,7 +205,8 @@ GraceContext=\translator { ThreadContext = \translator{ \type Engraver_group_engraver; - \consists "Note_heads_engraver" ; + \consists "A2_devnull_engraver"; + \consists "Note_heads_engraver"; \consists "Output_property_engraver"; Generic_property_list = #generic-thread-properties \consists "Property_engraver"; @@ -472,6 +474,7 @@ ScoreContext = \translator { basicChordNameProperties = #`( (molecule-callback . ,Chord_name::brew_molecule) (interfaces . (chord-name-interface)) + (after-line-breaking-callback . ,Chord_name::after_line_breaking) ) basicCollisionProperties = #`( (axes 0 1) @@ -491,12 +494,12 @@ ScoreContext = \translator { (interfaces . (dot-interface)) ) basicDynamicLineSpannerProperties = #`( - (interfaces (dynamic-interface axis-group-interface)) + (interfaces . (dynamic-interface axis-group-interface)) (axes . ( 1)) ) basicDynamicTextProperties = # `( (style . "dynamic") - (interface (dynamic-interface)) + (interfaces . (dynamic-interface)) (molecule-callback . ,Text_item::brew_molecule) (script-priority . 100) (self-alignment-Y . 0) @@ -683,7 +686,9 @@ ScoreContext = \translator { ) basicTextScriptProperties = #`( (molecule-callback . ,Text_item::brew_molecule) - (no-spacing-rods . #t) + +: -- don't set, because property-engraver will not override it. +; (no-spacing-rods . #t) (interfaces . (text-script-interface text-item-interface)) ) basicTieProperties = #`( -- 2.39.5