From: fred Date: Tue, 26 Mar 2002 23:56:27 +0000 (+0000) Subject: lilypond-1.3.92 X-Git-Tag: release/1.5.59~1282 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=2cfe887679ff462572ec6b10fe985eb41366e731;p=lilypond.git lilypond-1.3.92 --- diff --git a/CHANGES b/CHANGES index 79bdc9e7cd..5282a4ded3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,39 @@ -1.3.90.jcn1 +1.3.91.uu1 +========== + +* RPM .spec fixes. + +* italiano.ly + +* mudela-book updates by Tom Cato Amundsen. + +* Allow lyric hara kiri as well. + +* Bugfix: left/right mixup in Side_position_interface::aligned_on_self () + +* rest collision of differing rests. + +* Cleanup of Sequential_music_iterator, Simple_music_iterator. + +* Unfolded_repeat_iterator now signals repeats using \property + repeatCommands. You could override this, eg. + + \property Score.repeatCommands = #'((volta "X") start-repeat) + + will print a |: and a volta bracket saying X. See also + input/test/manual-volta.ly + +* Volta_engraver, Repeat_acknowledge_engraver: new engravers that are +controlled by repeatCommands; much cleaner than the Repeat_engraver. + +* Junked Repeat_engraver. + +1.3.91.jcn1 =========== +* Abort all running spanners when part-combiner combines voices. + +1.3.91 +====== * Use S_ISDIR () and check for stat.h. diff --git a/Documentation/header.html.in b/Documentation/header.html.in index 9ec9553da7..3454056125 100644 --- a/Documentation/header.html.in +++ b/Documentation/header.html.in @@ -50,7 +50,7 @@ which substitutes some @AT_VARIABLES@ as well. NEWS
Change Log
- FAQ
+ FAQ
User manual
Features
Todo
diff --git a/Documentation/regression-test.tely b/Documentation/regression-test.tely index 127f991038..5d9ca9f197 100644 --- a/Documentation/regression-test.tely +++ b/Documentation/regression-test.tely @@ -8,7 +8,7 @@ @title LilyPond Regression test @end ignore -@node Top, , , +@node Top, , , (dir) @section Introduction @@ -17,6 +17,12 @@ the text correspond with the shown notation, we consider LilyPond Officially BugFree (tm). This document is intended for finding bugs, and documenting bugfixes. +[TODO: revise and completize this. ] + +[TODO: should generate out of header fields using ly2dvi?] + + + @section Notes and rests Rests. Note that the dot of 8th, 16th and 32nd rests rest should be @@ -246,7 +252,10 @@ bracket should be equal @mudelafile{repeat-line-break.ly} +Auto change piano staff switches voices between up and down staffs +automatically; rests are switched along with the coming note. +@mudelafile{auto-change.ly} @section Lyrics @@ -327,6 +336,13 @@ textNonEmpty is used to respect the horizontal size of text. @mudelafile{non-empty-text.ly} + + + +@section PianoStaff + + + @section Global stuff Breaks can be encouraged and discouraged using @code{\break} and @@ -334,7 +350,6 @@ Breaks can be encouraged and discouraged using @code{\break} and @mudelafile{break.ly} - Markings that are attached to (invisible) barlines are delicate: the are attached to the rest of the score without the score knowing it. Consequently, they fall over often. diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index 725091c139..3cbf3e94eb 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -724,11 +724,16 @@ appearance of note heads or rests. Rests are entered like notes, with note name `@code{r}@indexcode{r}', -or `@code{R}@indexcode{R}'. There is also a note name `@code{s}@indexcode{s}', -which produces a space of the specified duration. -`@code{R}' is specifically meant for entering parts: the @code{R} rest -can expand to fill a score with rests, or it can be printed as a -single multimeasure rest. +or `@code{R}@indexcode{R}'. There is also a note name +`@code{s}@indexcode{s}', which produces a space of the specified +duration. `@code{R}' is specifically meant for entering parts: the +@code{R} rest can expand to fill a score with rests, or it can be +printed as a single multimeasure rest. + +You can control the expansion by setting the property +@code{Score.skipBars}. If this is set to true, Lily will not expand +empty measures, and the multimeasure rests automatically adds the +appropriate number. @cindex lyrics expressions diff --git a/input/test/manual-volta.ly b/input/test/manual-volta.ly new file mode 100644 index 0000000000..e458b78781 --- /dev/null +++ b/input/test/manual-volta.ly @@ -0,0 +1,9 @@ + +\score { \notes { + c4 + \property Score.repeatCommands = #'((volta "93") end-repeat) + c4 c4 + \property Score.repeatCommands = #'((volta #f)) + c4 c4 +} +} diff --git a/lily/align-interface.cc b/lily/align-interface.cc index 621c691203..8e07f9870e 100644 --- a/lily/align-interface.cc +++ b/lily/align-interface.cc @@ -30,19 +30,6 @@ Align_interface::alignment_callback (Score_element *sc, Axis ax) } -Real -Align_interface::center_on_element (Score_element *me, Axis a) -{ - Score_element *cent = unsmob_element (me->get_elt_property ("group-center-element")); - - if (cent) - { - Real r = cent->relative_coordinate (me, a); - return -r; - } - return 0; -} - /* Hairy function to put elements where they should be. Can be tweaked from the outside by setting minimum-space and extra-space in its diff --git a/lily/bar-engraver.cc b/lily/bar-engraver.cc index c9d1466f6f..5a45005be8 100644 --- a/lily/bar-engraver.cc +++ b/lily/bar-engraver.cc @@ -9,7 +9,6 @@ #include "bar.hh" #include "score-engraver.hh" -#include "bar-engraver.hh" #include "musical-request.hh" #include "multi-measure-rest.hh" #include "command-request.hh" @@ -17,6 +16,30 @@ #include "engraver-group-engraver.hh" #include "warn.hh" #include "item.hh" +#include "engraver.hh" + +/** + generate bars. Either user ("|:"), or default (new measure) + */ +class Bar_engraver : public Engraver +{ +public: + Bar_engraver(); + VIRTUAL_COPY_CONS(Translator); + void request_bar (String type_str); + +protected: + virtual void do_creation_processing (); + virtual void do_removal_processing (); + virtual void do_process_music(); + virtual void do_pre_move_processing(); + +private: + void typeset_bar (); + void create_bar (); + + Item * bar_p_; +}; Bar_engraver::Bar_engraver() { @@ -30,6 +53,11 @@ Bar_engraver::create_bar () if (!bar_p_) { bar_p_ = new Item (get_property ("basicBarProperties")); + + SCM gl = get_property ("whichBar"); + if (scm_equal_p (gl, bar_p_->get_elt_property ("glyph")) != SCM_BOOL_T) + bar_p_->set_elt_property ("glyph", gl); + announce_element (bar_p_, 0); } } @@ -64,9 +92,6 @@ Bar_engraver::typeset_bar () { if (bar_p_) { - SCM gl = get_property ("whichBar"); - if (scm_equal_p (gl, bar_p_->get_elt_property ("glyph")) != SCM_BOOL_T) - bar_p_->set_elt_property ("glyph", gl); typeset_element (bar_p_); bar_p_ =0; } @@ -97,6 +122,3 @@ Bar_engraver::do_pre_move_processing() } ADD_THIS_TRANSLATOR(Bar_engraver); - - - diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index a4ffe9a519..25ab6a735e 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -66,29 +66,38 @@ Beam_engraver::do_try_music (Music *m) { if (Span_req * c = dynamic_cast(m)) { - if (c->span_type_str_ != "beam") - return false; - - Direction d =c->span_dir_; - - if (d == STOP && !beam_p_) + if (c->span_type_str_ == "abort") { - m->origin ()->warning (_ ("can't find start of beam")); - return false; + reqs_drul_[START] = 0; + reqs_drul_[STOP] = 0; + if (beam_p_) + beam_p_->suicide (); + beam_p_ = 0; } - - if(d == STOP) + else if (c->span_type_str_ == "beam") { - SCM m = get_property ("automaticMelismata"); - SCM b = get_property("noAutoBeaming"); - if (to_boolean (m) && to_boolean(b)) + + Direction d =c->span_dir_; + + if (d == STOP && !beam_p_) { - set_melisma (false); + m->origin ()->warning (_ ("can't find start of beam")); + return false; } - } - reqs_drul_[d ] = c; - return true; + if(d == STOP) + { + SCM m = get_property ("automaticMelismata"); + SCM b = get_property("noAutoBeaming"); + if (to_boolean (m) && to_boolean(b)) + { + set_melisma (false); + } + } + + reqs_drul_[d ] = c; + return true; + } } return false; } diff --git a/lily/break-align-engraver.cc b/lily/break-align-engraver.cc index aa3bc9760c..df01cfb4d0 100644 --- a/lily/break-align-engraver.cc +++ b/lily/break-align-engraver.cc @@ -37,7 +37,7 @@ void Break_align_engraver::add_column (SCM smob) { Score_element * e = unsmob_element (smob); - Break_align_item::add_element (align_l_,e); + Break_align_interface::add_element (align_l_,e); typeset_element (e); } @@ -104,12 +104,19 @@ Break_align_engraver::acknowledge_element (Score_element_info inf) if (!align_l_) { align_l_ = new Item (get_property ("basicBreakAlignProperties")); - Break_align_item::set_interface (align_l_); + Break_align_interface::set_interface (align_l_); announce_element (align_l_,0); SCM edge_sym = ly_symbol2scm ("Left_edge_item"); Item * edge = new Item (get_property ("leftEdgeBasicProperties")); + /* + We must have left-edge in the middle. Instrument-names + are left to left-edge, so they don't enter the staff. + */ + align_l_->set_elt_property ("self-alignment-X", edge->self_scm ()); + + /* If the element is empty, it will be ignored in the break alignment stuff. @@ -144,6 +151,7 @@ Break_align_engraver::acknowledge_element (Score_element_info inf) group->set_parent (align_l_, Y_AXIS); announce_element (group, 0); column_alist_ = scm_assoc_set_x (column_alist_, align_name, group->self_scm ()); + } Axis_group_interface::add_element (group, item_l); } diff --git a/lily/break-align-item.cc b/lily/break-align-item.cc index 91ea3fea3e..d8c5f6d2b2 100644 --- a/lily/break-align-item.cc +++ b/lily/break-align-item.cc @@ -1,5 +1,5 @@ /* - break-align-item.cc -- implement Break_align_item + break-align-item.cc -- implement Break_align_interface source file of the GNU LilyPond music typesetter @@ -21,10 +21,10 @@ #include "group-interface.hh" #include "align-interface.hh" -MAKE_SCHEME_CALLBACK(Break_align_item,before_line_breaking); +MAKE_SCHEME_CALLBACK(Break_align_interface,before_line_breaking); SCM -Break_align_item::before_line_breaking (SCM smob) +Break_align_interface::before_line_breaking (SCM smob) { Score_element* me = unsmob_element (smob); do_alignment (me); @@ -32,39 +32,46 @@ Break_align_item::before_line_breaking (SCM smob) } Real -Break_align_item::alignment_callback (Score_element*c, Axis a) +Break_align_interface::alignment_callback (Score_element*c, Axis a) { assert (a == X_AXIS); Score_element *par = c->parent_l (a); if (par && !to_boolean (par->get_elt_property ("break-alignment-done")))\ { par->set_elt_property ("break-alignment-done", SCM_BOOL_T); - Break_align_item::do_alignment (par); + Break_align_interface::do_alignment (par); } return 0.0; } +Real +Break_align_interface::self_align_callback (Score_element *me, Axis a) +{ + assert (a == X_AXIS); + + Item* item = dynamic_cast (me); + Direction bsd = item->break_status_dir(); + if (bsd == LEFT) + { + me->set_elt_property ("self-alignment-X", gh_int2scm (RIGHT)); + } + + return Side_position::aligned_on_self (me, a); +} + void -Break_align_item::add_element (Score_element*me, Score_element *toadd) +Break_align_interface::add_element (Score_element*me, Score_element *toadd) { toadd->add_offset_callback (alignment_callback, X_AXIS); Axis_group_interface::add_element (me, toadd); } void -Break_align_item::do_alignment (Score_element *me) +Break_align_interface::do_alignment (Score_element *me) { Item * item = dynamic_cast (me); Item *column = item->column_l (); - if (item->break_status_dir() == LEFT) - { - me->set_elt_property ("self-alignment-X", gh_int2scm (RIGHT)); - } - else - { - me->add_offset_callback (Align_interface::center_on_element, X_AXIS); - } Real interline= me->paper_l ()->get_var ("staffspace"); Link_array elems; @@ -206,10 +213,10 @@ Break_align_item::do_alignment (Score_element *me) void -Break_align_item::set_interface (Score_element*me) +Break_align_interface::set_interface (Score_element*me) { Align_interface::set_interface (me); Align_interface::set_axis (me,X_AXIS); - me->add_offset_callback (Side_position::aligned_on_self, X_AXIS); + me->add_offset_callback (Break_align_interface::self_align_callback, X_AXIS); } diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc index bdd8f8e656..e0788f08e5 100644 --- a/lily/dynamic-engraver.cc +++ b/lily/dynamic-engraver.cc @@ -100,7 +100,15 @@ Dynamic_engraver::do_try_music (Music * m) } else if (Span_req* s = dynamic_cast (m)) { - if ((s->span_type_str_ == "crescendo" + if (s->span_type_str_ == "abort") + { + accepted_spanreqs_drul_[LEFT] = 0; + accepted_spanreqs_drul_[RIGHT] = 0; + if (line_spanner_) + line_spanner_->suicide (); + line_spanner_ = 0; + } + else if ((s->span_type_str_ == "crescendo" || s->span_type_str_ == "decrescendo")) { accepted_spanreqs_drul_[s->span_dir_] = s; diff --git a/lily/folded-repeat-iterator.cc b/lily/folded-repeat-iterator.cc index b8b4e16033..ddc6e68839 100644 --- a/lily/folded-repeat-iterator.cc +++ b/lily/folded-repeat-iterator.cc @@ -7,6 +7,12 @@ */ + +/* + Folded repeats are a stupid idea at this point, so we refrain from + implementing get_music () and skip (). +*/ + #include "folded-repeat-iterator.hh" #include "repeated-music.hh" #include "music-list.hh" diff --git a/lily/include/align-interface.hh b/lily/include/align-interface.hh index f570a60509..3eb8b9e972 100644 --- a/lily/include/align-interface.hh +++ b/lily/include/align-interface.hh @@ -31,8 +31,10 @@ alignment-done -- boolean to administrate whether we've done the alignment already (to ensure that the process is done only once) - group-center-element -- element which will be at the center of the group - after aligning (when using Align_interface::center_on_element) + center-element -- element which will be at the center of the group + after aligning (when using + Align_interface::center_on_element). The center element should + have this object as a reference point. elements -- to be aligned elements diff --git a/lily/include/break-align-item.hh b/lily/include/break-align-item.hh index 028b4f282e..8449f07498 100644 --- a/lily/include/break-align-item.hh +++ b/lily/include/break-align-item.hh @@ -20,11 +20,8 @@ break-align-symbol -- the index in the spacing table (symbol) of the to be aligned item. - - TODO: remove this as a class, and make interface. - */ - -class Break_align_item +*/ +class Break_align_interface { public: static SCM before_line_breaking (SCM); @@ -33,5 +30,6 @@ public: static bool has_interface (Score_element*); static void add_element (Score_element*me, Score_element*add); static Real alignment_callback (Score_element*, Axis); + static Real self_align_callback (Score_element*, Axis); }; #endif // BREAK_ALIGN_ITEM_HH diff --git a/lily/include/rest-collision.hh b/lily/include/rest-collision.hh index f7a547a94b..c2ae9cd1fd 100644 --- a/lily/include/rest-collision.hh +++ b/lily/include/rest-collision.hh @@ -12,12 +12,34 @@ #include "lily-proto.hh" #include "lily-guile.hh" + + + /* + Move rests in note-columns so that they do not collide. + properties: + read-only + + maximum-rest-count -- kill off rests so we don't more than this + number left. + + minimum-distance -- minimum distance between notes and rests. + + read/write + elements -- list of elts (both rests and notes) participating in the collision. + + sets in elements: + + rest-collision -- pointer to self. + + + + */ class Rest_collision // interface diff --git a/lily/include/sequential-music-iterator.hh b/lily/include/sequential-music-iterator.hh index d4f83c4585..a2dee9359d 100644 --- a/lily/include/sequential-music-iterator.hh +++ b/lily/include/sequential-music-iterator.hh @@ -35,10 +35,10 @@ protected: private: Moment here_mom_; - SCM cursor_; Music_iterator * iter_p_; + void next_element (); void descend_to_child (); }; diff --git a/lily/include/side-position-interface.hh b/lily/include/side-position-interface.hh index 6d8563d434..a4f8e90356 100644 --- a/lily/include/side-position-interface.hh +++ b/lily/include/side-position-interface.hh @@ -33,6 +33,8 @@ self-alignment-X -- real number: -1 = left aligned, 0 = center, 1 right-aligned in X direction. + + Set to an element pointer, if you want that element to be the center. self-alignment-Y -- like self-alignment-X but for Y axis diff --git a/lily/include/unfolded-repeat-iterator.hh b/lily/include/unfolded-repeat-iterator.hh index 6ffdbb62aa..3aa3ceae32 100644 --- a/lily/include/unfolded-repeat-iterator.hh +++ b/lily/include/unfolded-repeat-iterator.hh @@ -18,6 +18,8 @@ */ class Unfolded_repeat_iterator : public Music_iterator { + void add_repeat_command (SCM); + public: VIRTUAL_COPY_CONS (Music_iterator); /** @@ -25,17 +27,16 @@ public: */ int done_count_; + /* + are we now busy doing the body? - /// unfold everything, or do volta? - bool full_unfold_b_; - - /// are we busy doing the body? + */ bool do_main_b_; /** How far have we progressed into the repeat. This excludes the elt currently being iterated. */ - Moment done_mom_; + Moment here_mom_; int alternative_count_i_; Music_iterator * current_iter_p_; @@ -44,15 +45,16 @@ public: ~Unfolded_repeat_iterator(); Unfolded_repeat_iterator (); - protected: virtual void construct_children (); virtual Moment pending_moment () const; virtual void process (Moment); virtual Music_iterator *try_music_in_children (Music *) const; - + virtual void skip (Moment); + virtual SCM get_music (Moment) const; + virtual bool ok () const; - virtual void next_element (); + virtual void next_element (bool side_effect); }; #endif /* UNFOLDED_REPEAT_ITERATOR_HH */ diff --git a/lily/lexer.ll b/lily/lexer.ll index 87fbcacb82..208e703420 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -480,7 +480,7 @@ My_lily_lexer::scan_escaped_word (String str) } else if (gh_number_p (sid)) { yylval.scm = sid; return NUMBER_IDENTIFIER; - } else if (Translator_def* tr = unsmob_translator_def (sid)) { + } else if (unsmob_translator_def (sid)) { yylval.scm = sid; return TRANSLATOR_IDENTIFIER; } else if (Music * mus =unsmob_music (sid)) { diff --git a/lily/multi-measure-rest-engraver.cc b/lily/multi-measure-rest-engraver.cc index 3729344c06..552865111b 100644 --- a/lily/multi-measure-rest-engraver.cc +++ b/lily/multi-measure-rest-engraver.cc @@ -17,7 +17,11 @@ /** The name says it all: make multi measure rests - */ + +FIXME? The MM rest engraver must be able to see bar lines, so it won't +work at Voice level. Not a problem in practice, but aesthetically pleasing? + +*/ class Multi_measure_rest_engraver : public Engraver { public: diff --git a/lily/part-combine-music-iterator.cc b/lily/part-combine-music-iterator.cc index 754b1023bb..498f0fc831 100644 --- a/lily/part-combine-music-iterator.cc +++ b/lily/part-combine-music-iterator.cc @@ -325,6 +325,26 @@ Part_combine_music_iterator::process (Moment m) else if (state & (UNIRHYTHM | UNISILENCE)) combine_b = true; + /* + When combining, abort all running spanners + */ + if (combine_b && combine_b != previously_combined_b) + { +#if 0 + // Urg: Error in unknown function during GC: rogue pointer in heap + // Who deletes this 'pointer'? + Span_req abort; + abort.span_type_str_ = "abort"; + if (second_iter_p_ && second_iter_p_->ok ()) + second_translator->try_music (&abort); +#else + Span_req* abort = new Span_req; + abort->span_type_str_ = "abort"; + if (second_iter_p_ && second_iter_p_->ok ()) + second_iter_p_->try_music (abort); +#endif + } + if (combine_b != previously_combined_b) change_to (second_iter_p_, p->what_str_, (combine_b ? "one" : "two") + suffix_); diff --git a/lily/repeat-acknowledge-engraver.cc b/lily/repeat-acknowledge-engraver.cc new file mode 100644 index 0000000000..477e295fb1 --- /dev/null +++ b/lily/repeat-acknowledge-engraver.cc @@ -0,0 +1,89 @@ +/* + repeat-acknowledge-engraver.cc -- implement Repeat_acknowledge_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2000 Han-Wen Nienhuys + + */ +#include "engraver.hh" +#include "translator-group.hh" +#include "repeated-music.hh" + + +/* + Objective: + + -- set and reset repeatCommands, so Unfolded_repeat_iterator knows + where to set variables. + + -- collect information passed by Unfolded_repeat_iterator for + Bar_engraver: writes whichBar property. (TODO: check for + interactions with timing engraver.) + + */ +class Repeat_acknowledge_engraver : public Engraver +{ +public: + VIRTUAL_COPY_CONS (Translator); + Repeat_acknowledge_engraver(); + + virtual void do_post_move_processing (); + virtual void do_process_music (); + virtual void do_creation_processing (); +}; + +void +Repeat_acknowledge_engraver::do_creation_processing () +{ + daddy_trans_l_->set_property ("repeatCommands", SCM_EOL); +} + + +Repeat_acknowledge_engraver::Repeat_acknowledge_engraver() +{ +} + +void +Repeat_acknowledge_engraver::do_post_move_processing () +{ + Translator_group * tr = daddy_trans_l_->where_defined (ly_symbol2scm ("repeatCommands")); + if (!tr) + tr = daddy_trans_l_; + + tr->set_property ("repeatCommands", SCM_EOL); +} + +void +Repeat_acknowledge_engraver::do_process_music () +{ + SCM cs = get_property ("repeatCommands"); + + String s = ""; + bool start = false; + bool end = false; + while (gh_pair_p (cs)) + { + SCM command = gh_car (cs); + if (command == ly_symbol2scm ("start-repeat")) + start = true; + else if (command == ly_symbol2scm ("end-repeat")) + end = true; + cs = gh_cdr (cs); + } + + if ( start && end ) + s = ":|:"; + else if (start) + s = "|:"; + else if (end) + s = ":|"; + + if (s != "") + { + daddy_trans_l_->set_property ("whichBar", ly_str02scm(s.ch_C())); + } +} + + +ADD_THIS_TRANSLATOR(Repeat_acknowledge_engraver); diff --git a/lily/request-chord-iterator.cc b/lily/request-chord-iterator.cc index 080240a8b5..aaeeeecac7 100644 --- a/lily/request-chord-iterator.cc +++ b/lily/request-chord-iterator.cc @@ -49,7 +49,7 @@ SCM Request_chord_iterator::get_music (Moment) const { SCM s = SCM_EOL; - if (music_l_) + if (last_processed_mom_ < Moment (0)) { Music_sequence * ms = dynamic_cast (music_l_); @@ -64,7 +64,7 @@ Request_chord_iterator::get_music (Moment) const void Request_chord_iterator::process (Moment m) { - if (music_l_) + if (last_processed_mom_ < Moment (0)) { for (SCM s = dynamic_cast (music_l_)->music_list (); gh_pair_p (s); s = gh_cdr (s)) diff --git a/lily/sequential-music-iterator.cc b/lily/sequential-music-iterator.cc index de480844e5..7260e3eb83 100644 --- a/lily/sequential-music-iterator.cc +++ b/lily/sequential-music-iterator.cc @@ -12,10 +12,28 @@ #include "music-list.hh" #include "request-chord-iterator.hh" +/* + Invariant for the data structure. + + + if (gh_pair_p (cursor_)) + iter_p_->music_l_ == unsmob_music (gh_car (cursor_)) + else + iter_p_ == 0; + + The length of musiclist from start to up to cursor_ (cursor_ not + including), is summed + + here_mom_ = sum (length (musiclist [start ... cursor> )) %) + + */ + + Sequential_music_iterator::Sequential_music_iterator () { - cursor_ = 0; - here_mom_ = 0; + cursor_ = SCM_EOL; + here_mom_ = Moment (0); + iter_p_ =0; } @@ -39,23 +57,40 @@ void Sequential_music_iterator::construct_children() { cursor_ = dynamic_cast (music_l_)->music_list (); - - while (gh_pair_p (cursor_ )) + + iter_p_ = gh_pair_p (cursor_) ? get_iterator_p (unsmob_music (gh_car (cursor_))) : 0; + while (iter_p_ && !iter_p_->ok ()) { - iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_))); - - if (iter_p_->ok()) - { - descend_to_child (); - return; - } - - delete iter_p_ ; - iter_p_ =0; - cursor_ = gh_cdr (cursor_); + next_element (); } + + /* + iter_p_->ok () is tautology, but what the heck. + */ + if (iter_p_ && iter_p_->ok()) + descend_to_child (); + +} + + +/* + maintain invariants: change cursor, iter and here_mom_ in one fell + swoop. +*/ +void +Sequential_music_iterator::next_element () +{ + here_mom_ += iter_p_->music_length_mom (); + delete iter_p_; + cursor_ = gh_cdr (cursor_); + + if (gh_pair_p (cursor_)) + iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_))); + else + iter_p_ = 0; } - /* + +/* move to context of child iterator if it is deeper down in the hierarchy. */ @@ -63,7 +98,6 @@ Sequential_music_iterator::construct_children() void Sequential_music_iterator::descend_to_child () { - Translator_group * child_report = child_report = iter_p_->report_to_l (); if (dynamic_cast (iter_p_)) child_report = child_report->daddy_trans_l_; @@ -96,28 +130,24 @@ Sequential_music_iterator::get_music (Moment until)const if (until < pending_moment ()) return s; - SCM curs = cursor_; - Music_iterator * iter = iter_p_->clone (); - while (1) + Sequential_music_iterator * me = + dynamic_cast (clone ()); + while (me->ok ()) { - SCM nm = iter->get_music (until - here_mom_); + SCM nm = me->iter_p_->get_music (until - me->here_mom_); s = gh_append2 (nm, s); Moment m = 0; for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i)) m = m >? unsmob_music (gh_car (i))->length_mom (); - delete iter; - - curs = gh_cdr (curs); - - if (!gh_pair_p (curs) || m > Moment (0)) - return s; + if (m > Moment (0)) + break ; else - { - iter = get_iterator_p (unsmob_music (gh_car (curs))); - } + me->next_element (); } + delete me; + return s; } /* @@ -129,7 +159,7 @@ Sequential_music_iterator::get_music (Moment until)const void Sequential_music_iterator::skip (Moment until) { - while (1) + while (ok ()) { Moment l =iter_p_->music_length_mom (); if (l >= until - here_mom_) @@ -137,24 +167,15 @@ Sequential_music_iterator::skip (Moment until) if (iter_p_->ok ()) return ; - - here_mom_ = here_mom_ + l; - delete iter_p_; - iter_p_ =0; - - cursor_ = gh_cdr (cursor_); - if (!gh_pair_p (cursor_)) - return ; - else - iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_))); + next_element (); } } void Sequential_music_iterator::process (Moment until) { - while (1) + while (iter_p_) { iter_p_->process (until - here_mom_); @@ -167,23 +188,9 @@ Sequential_music_iterator::process (Moment until) if (iter_p_->ok ()) return ; - here_mom_ += iter_p_->music_length_mom (); - descend_to_child (); - delete iter_p_; - iter_p_ =0; - - cursor_ = gh_cdr (cursor_); - - if (!gh_pair_p (cursor_)) - return ; - else - { - delete iter_p_; - iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_))); - } + next_element (); } - } Moment diff --git a/lily/side-position-interface.cc b/lily/side-position-interface.cc index e3ea3d6501..7c2c974c7e 100644 --- a/lily/side-position-interface.cc +++ b/lily/side-position-interface.cc @@ -108,16 +108,16 @@ Side_position::side_position (Score_element *cme, Axis axis) callback that centers the element on itself */ Real -Side_position::aligned_on_self (Score_element *elm, Axis ax) +Side_position::aligned_on_self (Score_element *me, Axis ax) { String s ("self-alignment-"); s += (ax == X_AXIS) ? "X" : "Y"; - SCM align (elm->get_elt_property (s.ch_C())); + SCM align (me->get_elt_property (s.ch_C())); if (gh_number_p (align)) { - Interval ext(elm->extent (ax)); + Interval ext(me->extent (ax)); if (ext.empty_b ()) { @@ -126,11 +126,14 @@ Side_position::aligned_on_self (Score_element *elm, Axis ax) } else { - Real lambda = (0.5 + gh_scm2double (align) / 2.0); + Real lambda = (0.5 - gh_scm2double (align) / 2.0); return - (lambda * ext[LEFT] + (1 - lambda) * ext[RIGHT]); } } - else + else if (unsmob_element (align)) + { + return - unsmob_element (align)->relative_coordinate (me, ax); + } return 0.0; } diff --git a/lily/simple-music-iterator.cc b/lily/simple-music-iterator.cc index c4a78e9583..855ff70780 100644 --- a/lily/simple-music-iterator.cc +++ b/lily/simple-music-iterator.cc @@ -32,7 +32,7 @@ Simple_music_iterator::ok ()const Moment Simple_music_iterator::pending_moment ()const { - if (music_l_) + if (last_processed_mom_ < Moment (0)) return Moment (0); else return music_length_mom (); @@ -48,17 +48,9 @@ Simple_music_iterator::skip (Moment m) void Simple_music_iterator::process (Moment m) { -#if 0 /* - try_music () causes trouble for base classes - */ - if (music_l_) - { - bool b = try_music (music_l_); - if (!b) - music_l_->origin ()->warning (_f ("Junking music: `%s'", - classname (music_l_))); - } -#endif + don't do try_music (), since it would make the function useless for + base classes */ + skip (m); } diff --git a/lily/slur-engraver.cc b/lily/slur-engraver.cc index 763d77a3e5..8fe4f5de85 100644 --- a/lily/slur-engraver.cc +++ b/lily/slur-engraver.cc @@ -13,13 +13,15 @@ #include "engraver.hh" #include "spanner.hh" -class Slur_engraver :public Engraver { +class Slur_engraver : public Engraver +{ Link_array requests_arr_; Link_array new_slur_req_l_arr_; Link_array slur_l_stack_; Link_array end_slur_l_arr_; void set_melisma (bool); + protected: virtual bool do_try_music (Music*); virtual void do_process_music (); @@ -30,7 +32,6 @@ protected: public: VIRTUAL_COPY_CONS (Translator); - }; bool @@ -38,11 +39,26 @@ Slur_engraver::do_try_music (Music *req_l) { if (Span_req *sl = dynamic_cast (req_l)) { - if (sl->span_type_str_ != "slur") - return false; - new_slur_req_l_arr_.push (sl); - - return true; + if (sl->span_type_str_ == "abort") + { + for (int i = 0; i < slur_l_stack_.size (); i++) + { + slur_l_stack_[i]->suicide (); + } + slur_l_stack_.clear (); + for (int i = 0; i < end_slur_l_arr_.size (); i++) + { + end_slur_l_arr_[i]->suicide (); + } + end_slur_l_arr_.clear (); + requests_arr_.clear (); + new_slur_req_l_arr_.clear (); + } + else if (sl->span_type_str_ == "slur") + { + new_slur_req_l_arr_.push (sl); + return true; + } } return false; } @@ -93,7 +109,7 @@ Slur_engraver::do_removal_processing () void Slur_engraver::do_process_music () { - Link_array start_slur_l_arr_; + Link_array start_slur_l_arr; for (int i=0; i< new_slur_req_l_arr_.size (); i++) { Span_req* slur_req_l = new_slur_req_l_arr_[i]; @@ -125,13 +141,13 @@ Slur_engraver::do_process_music () { index_set_cell (slur->get_elt_property ("attachment"), START, s); } - start_slur_l_arr_.push (slur); + start_slur_l_arr.push (slur); requests_arr_.push (slur_req_l); announce_element (slur, slur_req_l); } } - for (int i=0; i < start_slur_l_arr_.size (); i++) - slur_l_stack_.push (start_slur_l_arr_[i]); + for (int i=0; i < start_slur_l_arr.size (); i++) + slur_l_stack_.push (start_slur_l_arr[i]); } void diff --git a/lily/stem-tremolo.cc b/lily/stem-tremolo.cc index 2bfd4dfcbe..11e2441645 100644 --- a/lily/stem-tremolo.cc +++ b/lily/stem-tremolo.cc @@ -25,6 +25,13 @@ void Stem_tremolo::set_interface (Score_element *me) { + me->set_interface (ly_symbol2scm ("stem-tremolo")); +} + +bool +Stem_tremolo::has_interface (Score_element *me) +{ + return me->has_interface (ly_symbol2scm ("stem-tremolo")); } diff --git a/lily/timing-engraver.cc b/lily/timing-engraver.cc index 95b68d0369..c727c58896 100644 --- a/lily/timing-engraver.cc +++ b/lily/timing-engraver.cc @@ -5,6 +5,7 @@ (c) 1997--2000 Han-Wen Nienhuys */ +#include #include "translator-group.hh" #include "command-request.hh" @@ -23,8 +24,8 @@ protected: virtual bool do_try_music (Music * ); virtual void do_post_move_processing (); virtual void do_process_music (); + virtual void do_pre_move_processing (); public: - String which_bar (); VIRTUAL_COPY_CONS(Translator); }; @@ -37,9 +38,12 @@ Timing_engraver::do_post_move_processing( ) Timing_translator::do_post_move_processing (); SCM nonauto = get_property ("barNonAuto"); - SCM which = now_mom () ? SCM_UNDEFINED : ly_str02scm ("|"); + + SCM which = get_property ("whichBar"); + if (!gh_string_p (which)) + which = now_mom () ? SCM_EOL : ly_str02scm ("|"); - if (which == SCM_UNDEFINED && !to_boolean (nonauto)) + if (!gh_string_p (which) && !to_boolean (nonauto)) { SCM always = get_property ("barAlways"); if (!measure_position () @@ -52,6 +56,13 @@ Timing_engraver::do_post_move_processing( ) daddy_trans_l_->set_property ("whichBar", which); } +void +Timing_engraver::do_pre_move_processing () +{ + Timing_translator::do_pre_move_processing (); + daddy_trans_l_->set_property ("whichBar", SCM_EOL); +} + bool Timing_engraver::do_try_music (Music*m) { diff --git a/lily/unfolded-repeat-iterator.cc b/lily/unfolded-repeat-iterator.cc index 9a4155f54d..6e6b665f01 100644 --- a/lily/unfolded-repeat-iterator.cc +++ b/lily/unfolded-repeat-iterator.cc @@ -38,28 +38,45 @@ the alternative just set. */ void -Unfolded_repeat_iterator::next_element () +Unfolded_repeat_iterator::next_element (bool side_effect) { - Repeated_music * mus =dynamic_cast (music_l_); + Repeated_music * repmus =dynamic_cast (music_l_); delete current_iter_p_; current_iter_p_ =0; - + bool do_repcommands = side_effect && repmus->volta_fold_b_; + if (do_main_b_) { - done_mom_ += mus->body ()->length_mom (); + /* + we were busy doing the main body, so + + - go to alternative if we're a volta + + - do something intelligent when we're fully unfolding (fixcomment) + */ + + here_mom_ += repmus->body ()->length_mom (); - if (!mus->volta_fold_b_) + if (!repmus->volta_fold_b_) done_count_ ++; if (gh_pair_p (alternative_cons_)) { current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_))); do_main_b_ = false; + + if (repmus->volta_fold_b_) + { + String repstr = to_str (done_count_ + 1); + if (do_repcommands) + add_repeat_command (gh_list (ly_symbol2scm ("volta"), + gh_str02scm (repstr.ch_C()), SCM_UNDEFINED)); + } } - else if (done_count_ < mus->repeats_i_ && !mus->volta_fold_b_) + else if (done_count_ < repmus->repeats_i_ && !repmus->volta_fold_b_) { - current_iter_p_ = get_iterator_p (mus->body ()); + current_iter_p_ = get_iterator_p (repmus->body ()); do_main_b_ = true; } } @@ -69,28 +86,55 @@ Unfolded_repeat_iterator::next_element () we're not in the main part. So we're either in an alternative, or we just finished. */ + + /* + we're in the alternatives. We move the pointer to the + next alternative. + */ if (alternative_cons_) { - done_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom (); + here_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom (); - if (mus->volta_fold_b_ || - mus->repeats_i_ - done_count_ < alternative_count_i_) + if (repmus->volta_fold_b_ || + repmus->repeats_i_ - done_count_ < alternative_count_i_) alternative_cons_ = gh_cdr (alternative_cons_); + if (do_repcommands) + add_repeat_command (gh_list (ly_symbol2scm ("volta"), SCM_BOOL_F, SCM_UNDEFINED)); + + + /* we've done the main body as well, but didn't go over the other increment. */ - if (mus->volta_fold_b_) + if (repmus->volta_fold_b_) done_count_ ++; } + + /* + We still have alternatives left, so + + if we're volta: traverse them + + if we're full unfold: go back to main body. + */ - if (done_count_ < mus->repeats_i_ && gh_pair_p (alternative_cons_)) + if (done_count_ < repmus->repeats_i_ && gh_pair_p (alternative_cons_)) { - if (mus->volta_fold_b_) + if (do_repcommands) + { + String repstr = to_str (done_count_ + 1); + add_repeat_command (gh_list (ly_symbol2scm ("volta"), + gh_str02scm (repstr.ch_C()), SCM_UNDEFINED)); + add_repeat_command (ly_symbol2scm ("end-repeat")); + } + + + if (repmus->volta_fold_b_) current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_))); else { - current_iter_p_ = get_iterator_p (mus->body ()); + current_iter_p_ = get_iterator_p (repmus->body ()); do_main_b_ = true; } } @@ -107,7 +151,7 @@ Unfolded_repeat_iterator::ok () const Moment Unfolded_repeat_iterator::pending_moment () const { - return done_mom_ + current_iter_p_->pending_moment (); + return here_mom_ + current_iter_p_->pending_moment (); } void @@ -134,34 +178,95 @@ Unfolded_repeat_iterator::construct_children () } } +void +Unfolded_repeat_iterator::add_repeat_command (SCM what) +{ + SCM reps = ly_symbol2scm ("repeatCommands"); + SCM current_reps = report_to_l ()->get_property(reps); + + Translator_group * where = report_to_l ()->where_defined (reps); + if (where + && current_reps == SCM_EOL || gh_pair_p (current_reps)) + { + current_reps = gh_cons (what, current_reps); + where->set_property (reps, current_reps); + } +} + void Unfolded_repeat_iterator::process (Moment m) { if (!m) { - Music_iterator *yeah = try_music (music_l_); - if (yeah) - set_translator (yeah->report_to_l ()); - else - music_l_->origin ()->warning ( _("no one to print a volta bracket")); + if (dynamic_cast (music_l_)->volta_fold_b_) + add_repeat_command (ly_symbol2scm ("start-repeat")); } while (1) { while (!current_iter_p_->ok ()) { - next_element(); + next_element(true); if (!current_iter_p_) return; } - if (m - done_mom_ >= current_iter_p_->pending_moment ()) - current_iter_p_->process (m - done_mom_); + if (m - here_mom_ >= current_iter_p_->pending_moment ()) + current_iter_p_->process (m - here_mom_); else return; } } +void +Unfolded_repeat_iterator::skip (Moment until) +{ + while (current_iter_p_) + { + Moment l =current_iter_p_->music_length_mom (); + if (l >= until - here_mom_) + current_iter_p_->skip (until - here_mom_); + + if (current_iter_p_->ok ()) + return ; + + next_element (false); + } +} + +SCM +Unfolded_repeat_iterator::get_music (Moment until)const +{ + SCM s = SCM_EOL; + if (until < pending_moment ()) + return s; + + + Unfolded_repeat_iterator * me + = dynamic_cast (this->clone ()); + + while (me->ok ()) + { + SCM nm = me->current_iter_p_->get_music (until - + me->here_mom_); + + s = gh_append2 (nm, s); + + Moment m = 0; + for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i)) + m = m >? unsmob_music (gh_car (i))->length_mom (); + + if (m > Moment (0)) + break ; + else + me->next_element (false); + } + + delete me; + + return s; +} + Music_iterator* Unfolded_repeat_iterator::try_music_in_children (Music * m) const diff --git a/lily/volta-engraver.cc b/lily/volta-engraver.cc new file mode 100644 index 0000000000..4f5baf6b24 --- /dev/null +++ b/lily/volta-engraver.cc @@ -0,0 +1,160 @@ +/* + volta-engraver.cc -- implement Volta_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2000 Han-Wen Nienhuys + + */ + +#include "engraver.hh" +#include "translator-group.hh" +#include "volta-spanner.hh" +#include "item.hh" +#include "note-column.hh" +#include "bar.hh" +#include "side-position-interface.hh" + +/* + Create Volta spanners, by reading repeatCommands property, usually + set by Unfolded_repeat_iterator. + */ +class Volta_engraver : public Engraver +{ +public: + Volta_engraver(); + VIRTUAL_COPY_CONS(Translator); +protected: + + virtual void acknowledge_element (Score_element_info); + virtual void do_removal_processing (); + virtual void do_pre_move_processing (); + virtual void do_process_music (); + + Moment started_mom_; + Spanner * volta_span_p_; + Spanner* end_volta_span_p_; +}; + +ADD_THIS_TRANSLATOR(Volta_engraver); + +Volta_engraver::Volta_engraver () +{ + volta_span_p_ = 0; + end_volta_span_p_ = 0; +} + +void +Volta_engraver::do_process_music () +{ + SCM cs = get_property ("repeatCommands"); + + SCM str = SCM_EOL; + bool end = false; + while (gh_pair_p (cs)) + { + SCM c = gh_car (cs); + + if (gh_pair_p (c) && gh_car (c) == ly_symbol2scm ("volta")) + { + if (gh_cadr (c) == SCM_BOOL_F) + end = true; + else + str = gh_cadr (c); + } + + cs = gh_cdr (cs); + } + + SCM l (get_property ("voltaSpannerDuration")); + Moment now = now_mom (); + + bool early_stop = volta_span_p_ && unsmob_moment (l) + &&*unsmob_moment (l) <= now - started_mom_; + + if (end || early_stop) + { + end_volta_span_p_ = volta_span_p_; + volta_span_p_ =0; + + /* + maybe do typeset_element () directly? + */ + + if (!gh_string_p (str)) + end_volta_span_p_->set_elt_property ("last-volta", SCM_BOOL_T); + } + + if (gh_string_p (str)) + { + started_mom_ = now; + if (volta_span_p_) + { + 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; + } + + volta_span_p_ = new Spanner (get_property ("basicVoltaSpannerProperties")); + Volta_spanner::set_interface (volta_span_p_); + announce_element (volta_span_p_,0); + volta_span_p_->set_elt_property ("text", str); + } +} + +void +Volta_engraver::acknowledge_element (Score_element_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); + } + } +} + +void +Volta_engraver::do_removal_processing () +{ + if (volta_span_p_) + { + typeset_element(volta_span_p_); + } + if (end_volta_span_p_) + { + typeset_element (end_volta_span_p_); + } +} + +void +Volta_engraver::do_pre_move_processing () +{ + if (end_volta_span_p_) + { + Side_position::add_staff_support (end_volta_span_p_); + + typeset_element (end_volta_span_p_ ); + end_volta_span_p_ =0; + } +} diff --git a/ly/engraver.ly b/ly/engraver.ly index 00a0a29caf..b3fa68374f 100644 --- a/ly/engraver.ly +++ b/ly/engraver.ly @@ -16,7 +16,8 @@ StaffContext=\translator { % with empty ones. - \consists "Repeat_engraver"; +% \consists "Repeat_engraver"; + \consists "Volta_engraver"; \consists "Separating_line_group_engraver"; @@ -78,7 +79,8 @@ RhythmicStaffContext=\translator{ basicVoltaSpannerProperties \push #'padding = #5 % urg, in \pt basicStaffSymbolProperties \push #'line-count = #1 - \consists "Repeat_engraver"; +% \consists "Repeat_engraver"; + \consists "Volta_engraver"; \consists "Bar_engraver"; \consists "Time_signature_engraver"; \consists "Staff_symbol_engraver"; @@ -331,13 +333,13 @@ ScoreContext = \translator { \name Score; + \consists "Repeat_acknowledge_engraver"; \consists "Timing_engraver"; \consists "Output_property_engraver"; \consists "System_start_delimiter_engraver"; \consists "Mark_engraver"; \consists "Break_align_engraver"; \consists "Spacing_engraver"; - \consists "Vertical_align_engraver"; \consists "Lyric_phrasing_engraver"; diff --git a/ly/params.ly b/ly/params.ly index 640a603464..5e89fd3f35 100644 --- a/ly/params.ly +++ b/ly/params.ly @@ -10,6 +10,9 @@ TODO: %} + +papersizename = \papersize ; + paperfile = \papersize + ".ly"; % paperfile = "a4.ly"; \include \paperfile; diff --git a/make/toplevel.make.in b/make/toplevel.make.in index 389a87c28f..59d033d477 100644 --- a/make/toplevel.make.in +++ b/make/toplevel.make.in @@ -14,7 +14,7 @@ SUBDIRS = scripts buildscripts flower lily mf midi2ly po debian \ # SCRIPTS = configure aclocal.m4 -README_FILES = DEDICATION COPYING NEWS TODO CHANGES ROADMAP +README_FILES = DEDICATION COPYING NEWS CHANGES ROADMAP README_TXT_FILES = AUTHORS.txt README.txt INSTALL.txt IN_FILES := $(wildcard *.in) EXTRA_DIST_FILES = dstreamrc lilypond-mode.el vimrc VERSION $(README_FILES) $(SCRIPTS) $(IN_FILES) diff --git a/midi2ly/GNUmakefile b/midi2ly/GNUmakefile index 5a6f293e33..d585c5c702 100644 --- a/midi2ly/GNUmakefile +++ b/midi2ly/GNUmakefile @@ -7,7 +7,6 @@ NAME = midi2ly MODULE_NAME = midi2ly SUBDIRS = include -EXTRA_DIST_FILES += TODO MODULE_LIBS=$(depth)/flower HELP2MAN_EXECS = midi2ly STEPMAKE_TEMPLATES=c++ executable po help2man