From 2915bb71a554e85088df4c99b648130c3f736be7 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 7 Mar 2005 19:19:22 +0000 Subject: [PATCH] *** empty log message *** --- ChangeLog | 38 ++++++- Documentation/user/notation.itely | 20 +++- VERSION | 2 +- configure.in | 2 +- input/regression/tie-arpeggio.ly | 2 +- lily/include/tie-column.hh | 2 +- lily/include/tie.hh | 3 +- lily/score-engraver.cc | 8 +- lily/tie-column.cc | 153 +++++++++++--------------- lily/tie-engraver.cc | 77 ++++++++----- lily/tie.cc | 12 ++ mf/GNUmakefile | 2 +- scm/define-context-properties.scm | 2 + scm/define-grobs.scm | 1 + stepmake/stepmake/metafont-rules.make | 4 +- 15 files changed, 200 insertions(+), 128 deletions(-) diff --git a/ChangeLog b/ChangeLog index e2b30a7384..4fe7a2ddd1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,8 +5,33 @@ 2005-03-02 Jan Nieuwenhuizen - * configure.in (MAKEINFO): Require 4.7 (Zbyněk Burget). + * configure.in (MAKEINFO): Require 4.7 (Zbyněk Burget). +2005-03-04 Han-Wen Nienhuys + + * VERSION: release 2.4.5 + + * input/regression/tie-arpeggio.ly: new file. Backport. + +2005-02-20 Han-Wen Nienhuys + + * scm/define-context-properties.scm + (all-user-translation-properties): add tieWaitForNote + + * scm/define-grobs.scm (all-grob-descriptions): add + Tie_column::before_line_breaking + + * lily/tie.cc (get_column_rank): new function + + * lily/tie-column.cc (before_line_breaking): new function. + (werner_directions): take into account ties that start on + different columns. + + * lily/score-engraver.cc (set_columns): move add_column() so we + have column rank available. + + * lily/tie.cc (get_column_rank): new function. + 2005-02-28 Jan Nieuwenhuizen * scm/define-grob-properties.scm (all-user-grob-properties): @@ -70,6 +95,15 @@ (The Lyrics context): Corrected link to the SATB example. +2004-12-24 Han-Wen Nienhuys + + * VERSION (PACKAGE_NAME): release 2.4.4 + +2004-12-24 Han-Wen Nienhuys + + * stepmake/stepmake/metafont-rules.make ($(outdir)/%.pfb): update + to mftrace 1.1 + 2004-12-26 Jan Nieuwenhuizen * Documentation/user/changing-defaults.itely: Fix internalsrefs @@ -654,7 +688,7 @@ * tex/lily-pdf-defs.tex, tex/lily-ps-defs.tex (\lilypondexperimentalfeatures): Removed. -2004-10-20 Jürgen Reuter +2004-10-20 Jürgen Reuter * Documentation/user/notation.itely: fixed 2 typos diff --git a/Documentation/user/notation.itely b/Documentation/user/notation.itely index 527264b1c1..b1065c4b52 100644 --- a/Documentation/user/notation.itely +++ b/Documentation/user/notation.itely @@ -463,6 +463,16 @@ automatic note splitting (see @ref{Automatic note splitting}). This mechanism automatically splits long notes, and ties them across bar lines. +Ties are sometimes used to write out arpeggios. In this case, two tied +notes need not be consecutive. This can be achieved by setting the +@code{tieWaitForNote} property to true. For example, + +@lilypond[fragment,verbatim,relative=1,raggedright] +\set tieWaitForNote = ##t +\grace { c16[~ e~ g]~ } 4 +@end lilypond + + @refcommands @@ -3528,11 +3538,11 @@ c\sostenutoDown d e c, f g a\sostenutoUp @subsection Arpeggio @cindex Arpeggio -@cindex broken arpeggio +@cindex broken chord @cindex @code{\arpeggio} -You can specify an arpeggio sign on a chord by attaching an -@code{\arpeggio} to a chord +You can specify an arpeggio sign (also known as broken chord) on a +chord by attaching an @code{\arpeggio} to a chord @lilypond[quote,raggedright,fragment,relative=1,verbatim] @@ -3588,9 +3598,13 @@ arpeggiate the chord @seealso +Notation manual: @ref{Ties}, for writing out arpeggios. + Program reference: @internalsref{ArpeggioEvent}, @internalsref{Arpeggio}. + + @refbugs It is not possible to mix connected arpeggios and unconnected diff --git a/VERSION b/VERSION index ca938d8869..3342533325 100644 --- a/VERSION +++ b/VERSION @@ -1,6 +1,6 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=2 MINOR_VERSION=4 -PATCH_LEVEL=3 +PATCH_LEVEL=5 MY_PATCH_LEVEL= diff --git a/configure.in b/configure.in index 913e8dea48..1aade60597 100644 --- a/configure.in +++ b/configure.in @@ -93,7 +93,7 @@ STEPMAKE_GUILE(OPTIONAL) # perl for help2man. STEPMAKE_PERL(OPTIONAL) # mftrace for generating pfa's, pfb's -STEPMAKE_PROGS(MFTRACE, mftrace, OPTIONAL, 1.0.27) +STEPMAKE_PROGS(MFTRACE, mftrace, OPTIONAL, 1.1.1) # new makeinfo for multi-page website docs STEPMAKE_PROGS(MAKEINFO, makeinfo, REQUIRED, 4.7) diff --git a/input/regression/tie-arpeggio.ly b/input/regression/tie-arpeggio.ly index 0f05b53585..762c6e2e62 100644 --- a/input/regression/tie-arpeggio.ly +++ b/input/regression/tie-arpeggio.ly @@ -8,7 +8,7 @@ } -\version "2.5.12" +\version "2.4.5" \paper { raggedright = ##t } \relative { diff --git a/lily/include/tie-column.hh b/lily/include/tie-column.hh index f1277e8c13..881b456bbf 100644 --- a/lily/include/tie-column.hh +++ b/lily/include/tie-column.hh @@ -20,8 +20,8 @@ public: static bool has_interface (Grob*); static void add_tie (Grob*me,Grob*); DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM)); + DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM)); static void set_directions (Grob*me); - static void old_directions (Grob*me); static void werner_directions (Grob*me); }; diff --git a/lily/include/tie.hh b/lily/include/tie.hh index 1f00f89efa..d1fb2cdb8a 100644 --- a/lily/include/tie.hh +++ b/lily/include/tie.hh @@ -23,10 +23,11 @@ public: static void set_direction (Grob*); static Grob * head (Grob*,Direction) ; static Real get_position (Grob*) ; - DECLARE_SCHEME_CALLBACK (print, (SCM )); + static int get_column_rank (Grob*, Direction); static Direction get_default_dir (Grob*) ; static SCM get_control_points (SCM); DECLARE_SCHEME_CALLBACK (set_spacing_rods, (SCM )); + DECLARE_SCHEME_CALLBACK (print, (SCM )); }; #endif // TIE_HH diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc index 432d18b720..b3158950cf 100644 --- a/lily/score-engraver.cc +++ b/lily/score-engraver.cc @@ -117,8 +117,8 @@ Score_engraver::initialize () pscore_->typeset_line (new System (props)); - make_columns (); system_ = pscore_->system_; + make_columns (); system_->set_bound (LEFT, command_column_); command_column_->set_property ("breakable", SCM_BOOL_T); @@ -201,9 +201,6 @@ Score_engraver::stop_translation_timestep () progress_indication ("[" + to_string (breaks_) + "]"); } - - system_->add_column (command_column_); - system_->add_column (musical_column_); command_column_ = 0; musical_column_ = 0; @@ -226,6 +223,9 @@ Score_engraver::set_columns (Paper_column *new_command, { context ()->set_property ("currentMusicalColumn", new_musical->self_scm ()); } + + system_->add_column (command_column_); + system_->add_column (musical_column_); } Music_output* diff --git a/lily/tie-column.cc b/lily/tie-column.cc index c3ff0c50e6..4c6703e540 100644 --- a/lily/tie-column.cc +++ b/lily/tie-column.cc @@ -7,6 +7,7 @@ */ +#include "paper-column.hh" #include "spanner.hh" #include "tie-column.hh" #include "group-interface.hh" @@ -15,34 +16,33 @@ #include "rhythmic-head.hh" - - - - /* tie dir depends on what Tie_column does. */ -/* - TODO: this doesn't follow standard pattern. Regularize. - */ + + void -Tie_column::add_tie (Grob*me,Grob *s) +Tie_column::add_tie (Grob*me, Grob *tie) { - if (s->get_parent (Y_AXIS) - && Tie_column::has_interface (s->get_parent (Y_AXIS))) + if (tie->get_parent (Y_AXIS) + && Tie_column::has_interface (tie->get_parent (Y_AXIS))) return ; - - if (! Pointer_group_interface::count (me, "ties")) + + + if (!Pointer_group_interface::count (me, "ties")) { - dynamic_cast (me)->set_bound (LEFT, Tie::head (s,LEFT)); - dynamic_cast (me)->set_bound (RIGHT, Tie::head (s,RIGHT)); + dynamic_cast (me)->set_bound (LEFT, Tie::head (tie, LEFT)); + dynamic_cast (me)->set_bound (RIGHT, Tie::head (tie, RIGHT)); } - s->set_parent (me, Y_AXIS); - Pointer_group_interface::add_grob (me, ly_symbol2scm ("ties"), s); - s->add_dependency (me); + + + tie->set_parent (me, Y_AXIS); + Pointer_group_interface::add_grob (me, ly_symbol2scm ("ties"), tie); + tie->add_dependency (me); } + void Tie_column::set_directions (Grob*me) { @@ -56,78 +56,24 @@ tie_compare (Grob* const & s1, return sign (Tie::get_position (s1) - Tie::get_position (s2)); } -/* - See [Ross p. 138]. - - - In normal chord cases, the outer ties point outwards, and the - direction of the rest is determined by their staff position. - - Ross forgets about the tie that is *on* the middle staff line. We - assume it goes UP. (TODO: make me settable) */ -void -Tie_column::old_directions (Grob*me) -{ - Link_array ties = - Pointer_group_interface__extract_grobs (me, (Grob*)0, "ties"); - - for (int i = ties.size (); i--;) - if (get_grob_direction (ties[i])) - ties.del (i); - if (!ties.size ()) - return ; - - Direction d = get_grob_direction (me); - if (d) - { - for (int i = ties.size (); i--;) - { - Grob * t = ties[i]; - set_grob_direction (t, d); - } - return; - } - if (ties.size () == 1) - { - Grob * t = ties[0]; - set_grob_direction (t,Tie::get_default_dir (t)); - return; - } +/* + Werner: - ties.sort (tie_compare); - set_grob_direction (ties[0], DOWN); - ties.del (0); + . The algorithm to choose the direction of the ties doesn't work + properly. I suggest the following for applying ties sequentially + from top to bottom: - set_grob_direction (ties.pop (), UP); - for (int i=ties.size (); i--;) - { - Grob * t = ties[i]; - Real p = Tie::get_position (t); - Direction d = (Direction) sign (p); - if (!d) - d = UP; - set_grob_direction (t, d); - } + + The topmost tie is always `up'. -} - -/* + + If there is a vertical gap to the last note above larger than + or equal to a fifth (or sixth?), the tie is `up', otherwise it + is `down'. -% . The algorithm to choose the direction of the ties doesn't work -% properly. I suggest the following for applying ties sequentially -% from top to bottom: -% -% + The topmost tie is always `up'. -% -% + If there is a vertical gap to the last note above larger than -% or equal to a fifth (or sixth?), the tie is `up', otherwise it -% is `down'. -% -% + The bottommost tie is always `down'. - - */ + + The bottommost tie is always `down'. + +*/ void Tie_column::werner_directions (Grob *me) { @@ -163,7 +109,11 @@ Tie_column::werner_directions (Grob *me) Real last_down_pos = 10000; if (!get_grob_direction (ties[0])) set_grob_direction (ties[0], DOWN); - + + /* + Go downward. + */ + Grob *last_tie = 0; for (int i = ties.size (); i--;) { Grob *t = ties[i]; @@ -172,7 +122,13 @@ Tie_column::werner_directions (Grob *me) Real p = Tie::get_position (t); if (!d) { - if (last_down_pos - p > 5) + if (last_tie + && Tie::get_column_rank (t, LEFT) + < Tie::get_column_rank (last_tie, LEFT)) + { + d = DOWN; + } + else if (last_down_pos - p > 5) { d = UP; } @@ -186,6 +142,8 @@ Tie_column::werner_directions (Grob *me) if (d == DOWN) last_down_pos = p; + + last_tie = t; } return ; @@ -200,7 +158,30 @@ Tie_column::after_line_breaking (SCM smob) return SCM_UNSPECIFIED; } - +/* + Extend the spanner over its Tie constituents. + */ +MAKE_SCHEME_CALLBACK (Tie_column, before_line_breaking, 1); +SCM +Tie_column::before_line_breaking (SCM smob) +{ + Spanner *me = dynamic_cast (unsmob_grob (smob)); + for (SCM s = me->get_property ("ties"); scm_is_pair (s); s = scm_cdr (s)) + { + Spanner *tie = dynamic_cast (unsmob_grob (scm_car (s))); + Direction dir = LEFT; + do + { + if (dir * Paper_column::get_rank (tie->get_bound (dir)->get_column ()) + > dir * Paper_column::get_rank (me->get_bound (dir)->get_column ())) + { + me->set_bound (dir, Tie::head (tie, dir)); + } + } + while (flip (&dir) != LEFT); + } + return SCM_UNSPECIFIED; +} ADD_INTERFACE (Tie_column,"tie-column-interface", "Object that sets directions of multiple ties in a tied chord", diff --git a/lily/tie-engraver.cc b/lily/tie-engraver.cc index 1aecbe526c..8d012afa9a 100644 --- a/lily/tie-engraver.cc +++ b/lily/tie-engraver.cc @@ -29,14 +29,29 @@ TODO: Remove the dependency on musical info. We should tie on the basis of position and duration-log of the heads (not of the events). */ + +struct Head_event_tuple +{ + Grob *head_; + SCM tie_definition_; + Music *event_; + Head_event_tuple() + { + } + Head_event_tuple(Grob *h, Music *m, SCM def) + { + head_ = h; + event_ = m; + tie_definition_ = def; + } +}; + class Tie_engraver : public Engraver { Music *event_; - Music *last_event_; Link_array now_heads_; - Link_array heads_to_tie_; + Array heads_to_tie_; Link_array ties_; - SCM tie_start_definition_; Spanner * tie_column_; @@ -53,19 +68,18 @@ public: }; +void +Tie_engraver::derived_mark () const +{ + Engraver::derived_mark (); + for (int i = 0; i < heads_to_tie_.size(); i++) + scm_gc_mark (heads_to_tie_[i].tie_definition_); +} Tie_engraver::Tie_engraver () { event_ = 0; - last_event_ = 0; tie_column_ = 0; - tie_start_definition_ = SCM_EOL; -} - -void -Tie_engraver::derived_mark () const -{ - scm_gc_mark (tie_start_definition_); } @@ -98,33 +112,34 @@ Tie_engraver::acknowledge_grob (Grob_info i) now_heads_.push (h); for (int i = heads_to_tie_.size (); i--;) { - Grob *th = heads_to_tie_[i]; + Grob *th = heads_to_tie_[i].head_; Music * right_mus = unsmob_music (h->get_property ("cause")); Music * left_mus = unsmob_music (th->get_property ("cause")); /* maybe should check positions too. - */ + */ if (right_mus && left_mus && ly_c_equal_p (right_mus->get_property ("pitch"), - left_mus->get_property ("pitch"))) + left_mus->get_property ("pitch"))) { - Grob * p = new Spanner (tie_start_definition_); - announce_grob (p, last_event_->self_scm ()); + Grob * p = new Spanner (heads_to_tie_[i].tie_definition_); + announce_grob (p, heads_to_tie_[i].event_->self_scm ()); + Tie::set_interface (p); // cannot remove yet! Tie::set_head (p, LEFT, th); Tie::set_head (p, RIGHT, h); ties_.push (p); + heads_to_tie_.del (i); } } if (ties_.size () && ! tie_column_) { - tie_column_ = make_spanner ("TieColumn", SCM_EOL); - - } + tie_column_ = make_spanner ("TieColumn", ties_[0]->self_scm ()); + } if (tie_column_) for (int i = ties_.size (); i--;) @@ -136,7 +151,7 @@ void Tie_engraver::start_translation_timestep () { context ()->set_property ("tieMelismaBusy", - ly_bool2scm (heads_to_tie_.size ())); + ly_bool2scm (heads_to_tie_.size ())); } @@ -145,22 +160,34 @@ Tie_engraver::stop_translation_timestep () { if (ties_.size ()) { - heads_to_tie_.clear (); + if (!to_boolean (get_property ("tieWaitForNote"))) + { + heads_to_tie_.clear (); + } for (int i=0; i< ties_.size (); i++) { typeset_tie (ties_[i]); } ties_.clear (); - last_event_ = 0; tie_column_ =0; } if (event_) { - tie_start_definition_ = updated_grob_properties (context (), ly_symbol2scm ("Tie")); - heads_to_tie_ = now_heads_; - last_event_ = event_; + SCM start_definition + = updated_grob_properties (context (), ly_symbol2scm ("Tie")); + + if (!to_boolean (get_property ("tieWaitForNote"))) + heads_to_tie_.clear(); + + for (int i = 0; i < now_heads_.size(); i++) + { + heads_to_tie_.push (Head_event_tuple (now_heads_[i], event_, + start_definition + )); + } + } event_ = 0; now_heads_.clear (); diff --git a/lily/tie.cc b/lily/tie.cc index 855891f07d..ad07c3168a 100644 --- a/lily/tie.cc +++ b/lily/tie.cc @@ -65,6 +65,18 @@ Tie::head (Grob*me, Direction d) return 0; } +int +Tie::get_column_rank (Grob *me, Direction d) +{ + Spanner *span = dynamic_cast (me); + Grob * h = head (me, d); + if (!h) + h = span->get_bound (d); + + Grob *col = dynamic_cast (h)->get_column (); + return Paper_column::get_rank (col); +} + Real Tie::get_position (Grob*me) { diff --git a/mf/GNUmakefile b/mf/GNUmakefile index 4a6cfa86c9..98e1f404c1 100644 --- a/mf/GNUmakefile +++ b/mf/GNUmakefile @@ -208,7 +208,7 @@ $(SAUTER_FONTS:%=$(outdir)/%.bla): $(foreach i, $@, touch $i && ) true $(outdir)/%.pfa: $(outdir)/%.bla - $(MFTRACE) -I $(outdir)/ --pfa --simplify --keep-trying $(notdir $(basename $@)) && mv $(notdir $@) $(outdir)/ + $(MFTRACE) -I $(outdir)/ --formats=pfa --simplify --keep-trying $(notdir $(basename $@)) && mv $(notdir $@) $(outdir)/ $(outdir)/%.enc.in: %.enc cp $< $@ diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index 8aedad8d88..a4ae0a8a81 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -352,6 +352,8 @@ the system/staff? Set to @code{SystemStartBrace}, takes a string number, a list of string tunings and Pitch object. It returns the text as a string.") + (tieWaitForNote ,boolean? "If true, tied notes do not have to follow each other directly. +This can be used for writing out arpeggios") (timeSignatureFraction ,number-pair? "pair of numbers, signifying the time signature. For example @code{#'(4 . 4)} is a 4/4 time signature.") diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index 05cc4b28f5..b379c5e0a6 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1244,6 +1244,7 @@ (TieColumn . ( (after-line-breaking-callback . ,Tie_column::after_line_breaking) + (before-line-breaking-callback . ,Tie_column::before_line_breaking) (X-extent-callback . #f) (Y-extent-callback . #f) (meta . ((interfaces . (tie-column-interface spanner-interface)))) diff --git a/stepmake/stepmake/metafont-rules.make b/stepmake/stepmake/metafont-rules.make index fb2e6d4428..323c5303ef 100644 --- a/stepmake/stepmake/metafont-rules.make +++ b/stepmake/stepmake/metafont-rules.make @@ -30,11 +30,11 @@ $(outdir)/%.$(XPM_RESOLUTION)pk: $(outdir)/%.$(XPM_RESOLUTION)gf $(outdir)/%.pfa: %.mf - $(MFTRACE) $(MFTRACE_FLAGS) -I $(outdir)/ --pfa --simplify $(basename $(@F)) + $(MFTRACE) $(MFTRACE_FLAGS) -I $(outdir)/ --formats=pfa --simplify $(basename $(@F)) mv $(basename $(@F)).pfa $(outdir) $(outdir)/%.pfb: %.mf - $(MFTRACE) $(MFTRACE_FLAGS) -I $(outdir)/ --pfa --pfb --simplify $(basename $(@F)) + $(MFTRACE) $(MFTRACE_FLAGS) -I $(outdir)/ --formats=pfa,pfb --simplify $(basename $(@F)) -mv $(basename $(@F)).pfa $(outdir) mv $(basename $(@F)).pfb $(outdir) -- 2.39.5