* Bjoern Jacke <bjoern.jacke@gmx.de> German glossary stuff.
- * Chris Jackson <chris@fluffhouse.org.uk>, Emacs mode
- indentation, directed arpeggios.
+ * Chris Jackson <chris@fluffhouse.org.uk>, Piano pedals, Emacs
+ mode indentation, directed arpeggios.
* Neil Jerram <nj104@cus.cam.ac.uk>. parts of
Documentation/Vocab*
+2002-03-15 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ * VERSION: 1.5.41 released
+
+ * mf/feta-schrift.mf: make Tr. smaller, smoother and closer. Use
+ optima serifs on top of t, bottom of r.
+
+ * mf/feta-bolletjes.mf: make ledger line rounder.
+
+ * mf/feta-toevallig.mf: some smallish fixes for flat sign.
+
+ * mf/feta-eindelijk.mf: make 8th rest a little darker, some more
+ parametrization.
+
+2002-03-15 Chris Jackson <chris@fluffhouse.org.uk>
+
+ * lily/piano-pedal-engraver.cc: Rewritten to support bracketed as
+ well as text pedal indications and a combination of both. All
+ pedal indications are horizontally aligned on a line spanner.
+
+ * lily/text-spanner.cc: Edge-width property added to use in
+ bracketed piano pedals. Function setup_sustain_pedal added to set
+ the dimensions of the brackets.
+
+ * scm/grob-description.scm: New *PedalLineSpanner grobs added, and
+ some of the *Pedal properties tweaked.
+
+ * scm/grob-property-description.scm: New pedal-type (*Pedal) and
+ edge-width (TextSpanner) properties.
+
+ * ly/engraver-init.ly: Default strings added for SostenutoPedal.
+
+ * lilypond-font-lock.el: sostenuto, unaCorda and treCorde added to
+ fontified identifiers list.
+
+ * input/test/pedal.ly: New pedal features added.
+
+ * Documentation/user/refman.itely: New pedal features documented.
+
+
2002-03-15 Jan Nieuwenhuizen <janneke@gnu.org>
* lily/include/new-beam.hh: Previously new-beam.hh
2002-03-14 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ * VERSION: 1.5.40
+
* mf/feta-eindelijk.mf: new 8th rest.
* mf/feta-toevallig.mf: small fixes for the sharp symbol. Don't
@lilypondfile[printfilename]{dynamics-unbound-hairpin.ly}
+@lilypondfile[printfilename]{pedal.ly}
+
@section Chord names
@lilypondfile[printfilename]{chord-names.ly}
@item @email{bjoern.jacke@@gmx.de, Bjoern Jacke}
German glossary stuff.
@item @email{chris@@fluffhouse.org.uk, Chris Jackson},
- Emacs mode indentation, directed arpeggios.
+ Piano pedals, Emacs mode indentation, directed arpeggios.
@item @email{nj104@@cus.cam.ac.uk, Neil Jerram}.
parts of Documentation/Vocab*
@item @email{heikki.junes@@hut.fi, Heikki Junes}.
@end lilypond
The symbols that are printed can be modified by setting
-@code{pedal@var{X}Strings}, where @var{X} is one of the pedal
-types. Refer to the generated documentation of @rgrob{PianoPedal} for
-more information.
+@code{pedal@var{X}Strings}, where @var{X} is one of the pedal types:
+Sustain, Sostenuto or UnaCorda. Refer to the generated documentation of
+@rgrob{PianoPedal} for more information.
-@refbugs
+Pedals can also be indicated by a sequence of brackets, by setting the
+@code{pedal-type} property of SustainPedal grobs:
+
+@lilypond[fragment,verbatim]
+\property Staff.SustainPedal \override #'pedal-type = #'bracket
+c''4 \sustainDown d''4 e''4 a'4 \sustainUp \sustainDown f'4 g'4 a'4 \sustainUp
+@end lilypond
+
+A third style of pedal notation is a mixture of text and brackets,
+obtained by setting @code{pedal-type} to @code{mixed}:
+@lilypond[fragment,verbatim]
+\property Staff.SustainPedal \override #'pedal-type = #'mixed
+c''4 \sustainDown d''4 e''4 c'4 \sustainUp \sustainDown f'4 g'4 a'4 \sustainUp
+@end lilypond
+
+The default '*Ped' style for sustain and damper pedals corresponds to
+@code{\pedal-type = #'text}. However @code{mixed} is the default style
+for a sostenuto pedal:
-Currently, brackets are not supported, only text markings (i.e. `*Ped'
-style).
+@lilypond[fragment,verbatim]
+c''4 \sostenutoDown d''4 e''4 c'4 f'4 g'4 a'4 \sostenutoUp
+@end lilypond
@c . {Arpeggio}
PACKAGE_NAME=LilyPond
MAJOR_VERSION=1
MINOR_VERSION=5
-PATCH_LEVEL=40
-MY_PATCH_LEVEL=jcn1
+PATCH_LEVEL=41
+MY_PATCH_LEVEL=
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
--- /dev/null
+\version "1.5.38"
+\header{
+texidoc = "Piano pedal symbols merge stop and start. The strings are configurable.
+Text style, bracket style, and a mixture of both are supported. "
+}
+
+
+
+
+\score{
+\context Staff \notes\relative c'{
+
+c4 d e f g
+\sustainDown b c
+c, [d16 c c c] [e e \sustainUp \sustainDown e e ] f4 \sustainUp
+g\sustainDown b \sustainUp c
+\property Staff.pedalSustainStrings = #'("-" "-P" "P")
+\property Staff.SustainPedal \override #'padding = #-2
+c, \sustainDown d e \sustainUp \sustainDown f
+ \sustainUp g b c
+
+\property Staff.SustainPedal \override #'pedal-type = #'bracket
+
+c4 d e \sustainDown b c c, \sustainUp \sustainDown [d8 c] [e8 e \sustainUp \sustainDown] f4 d
+\sustainUp g \sustainDown b b, \sustainUp c'
+
+\property Staff.UnaCordaPedal \override #'pedal-type = #'mixed
+
+c4 d \unaCorda e f g
+ b \treCorde c
+
+
+}
+\paper{
+}
+\midi{
+\tempo 4 = 60
+}
+}
+++ /dev/null
-\version "1.3.146"
-\header{
-texidoc = "Piano pedal symbols merge stop and start. The strings are configurable. "
-}
-
-
-
-
-\score{
-\context Staff \notes\relative c'{
-c4\sustainDown d e f\sustainUp g\sustainDown b c
-c, [d16 \sustainUp \sustainDown c c c] [e e \sustainUp \sustainDown e e ] f4 \sustainUp g\sustainDown b c
-\property Staff.pedalSustainStrings = #'("-" "-P" "P")
-\property Staff.SustainPedal \override #'padding = #2
-c, \sustainUp\sustainDown d e f
- \sustainUp g\sustainDown b c
-}
-\paper{
-}
-\midi{
-\tempo 4 = 60
-}
-}
public:
DECLARE_SCHEME_CALLBACK (brew_molecule, (SCM));
static bool has_interface (Grob*);
+private:
+ static void setup_pedal_bracket(Spanner *s);
};
#endif /* TEXT_SPANNER_HH */
source file of the GNU LilyPond music typesetter
(c) 2000--2002 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ Chris Jackson <chris@fluffhouse.org.uk> - extended to support
+ bracketed pedals.
+ TODO: support for __| |__ or __| Ped instead of ___/\__ for pedal up-down
*/
#include "engraver.hh"
#include "grob.hh"
#include "item.hh"
#include "lily-guile.hh"
-#include "rhythmic-head.hh"
-#include "stem.hh"
#include "side-position-interface.hh"
#include "staff-symbol-referencer.hh"
#include "item.hh"
+#include "axis-group-interface.hh"
+#include "translator-group.hh"
+#include "directional-element-interface.hh"
+#include "note-column.hh"
class Piano_pedal_engraver : public Engraver
{
~Piano_pedal_engraver ();
protected:
virtual void initialize ();
+ virtual void finalize ();
virtual bool try_music (Music*);
virtual void stop_translation_timestep ();
virtual void start_translation_timestep ();
Span_req* start_req_l_;
Drul_array<Span_req*> req_l_drul_;
Item* item_p_;
+ Spanner* bracket_p_; // A single portion of a pedal bracket
+ Spanner* finished_bracket_p_;
+ Spanner* line_spanner_; // This grob contains all the pedals of the same type on the same staff
+ Spanner* finished_line_spanner_;
+ Span_req* current_bracket_req_;
};
Pedal_info *info_list_;
+
+ Spanner *previous_p_ [4]; // Record a stack of the current pedal spanners, so if more than one pedal
+ int nspanners_i; // occurs simultaneously then extra space can be added between them.
+ void create_text_grobs (Pedal_info *p, SCM pedaltype);
+ void create_bracket_grobs (Pedal_info *p, SCM pedaltype);
+ void typeset_all();
};
info_list_ = new Pedal_info[4];
Pedal_info *p = info_list_;
+ nspanners_i = 0;
+ for (int i = 0; i < 3; ++i)
+ previous_p_[i] = 0;
+
char * names [] = { "Sostenuto", "Sustain", "UnaCorda", 0 };
char **np = names ;
{
p->name_ = *np;
p->item_p_ = 0;
+ p->bracket_p_ = 0;
+ p->finished_bracket_p_ = 0;
+ p->line_spanner_ = 0;
+ p->finished_line_spanner_ = 0;
+ p->current_bracket_req_ = 0;
p->req_l_drul_[START] = 0;
p->req_l_drul_[STOP] = 0;
p->start_req_l_ = 0;
{
for (Pedal_info*p = info_list_; p && p->name_; p ++)
{
- if (p->item_p_)
+ Grob *g = (Grob *) p->item_p_;
+ int i = 0;
+ while ( i < 2 )
{
- if (Rhythmic_head::has_interface (info.grob_l_))
- {
- Side_position_interface::add_support (p->item_p_, info.grob_l_);
-
- if (Side_position_interface::get_axis (p->item_p_) == X_AXIS
- && !p->item_p_->get_parent (Y_AXIS))
- p->item_p_->set_parent (info.grob_l_, Y_AXIS);
- }
- if (Stem::has_interface (info.grob_l_))
+ if (g && p->line_spanner_)
{
- Side_position_interface::add_support (p->item_p_,info.grob_l_);
+ if (Note_column::has_interface (info.grob_l_))
+ {
+ Side_position_interface::add_support (p->line_spanner_, info.grob_l_);
+ add_bound_item (p->line_spanner_,dynamic_cast<Item*> (info.grob_l_));
+
+ if (Side_position_interface::get_axis (g) == X_AXIS
+ && !g->get_parent (Y_AXIS))
+ g->set_parent (info.grob_l_, Y_AXIS);
+ }
}
+ g = (Grob *) p->bracket_p_;
+ ++i;
}
}
}
{
for (Pedal_info*p = info_list_; p->name_; p ++)
{
+ if (ly_scm2string (s->get_mus_property ("span-type")) == "abort")
+ {
+ p->req_l_drul_[START] = 0;
+ p->req_l_drul_[STOP] = 0;
+
+ if (p->bracket_p_)
+ p->bracket_p_->suicide (); /* as in dynamic-engraver.cc */
+ p->bracket_p_ = 0;
+ }
if (scm_equal_p (s->get_mus_property ("span-type"),
ly_str02scm (p->name_))==SCM_BOOL_T)
{
{
for (Pedal_info*p = info_list_; p && p->name_; p ++)
{
- if (p->item_p_ || ! (p->req_l_drul_[STOP] || p->req_l_drul_[START]))
- continue;
-
- SCM s = SCM_EOL;
- SCM strings = get_property (("pedal" + String (p->name_) + "Strings").ch_C ());
- if (scm_ilength (strings) < 3)
- continue;
-
- if (p->req_l_drul_[STOP] && p->req_l_drul_[START])
+ if (p->req_l_drul_[STOP] || p->req_l_drul_[START])
{
- if (!p->start_req_l_)
- {
- p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->name_));
- }
- else
+ if (!p->line_spanner_)
{
- s = ly_cadr (strings);
+ p->line_spanner_ = new Spanner (get_property ( ( String (p->name_) + "PedalLineSpanner").ch_C() ));
+ Side_position_interface::set_axis (p->line_spanner_, Y_AXIS);
+ Axis_group_interface::set_interface (p->line_spanner_);
+ Axis_group_interface::set_axes (p->line_spanner_, Y_AXIS, Y_AXIS);
+ Music * rq = (p->req_l_drul_[START] ? p->req_l_drul_[START] : p->req_l_drul_[STOP]);
+ announce_grob (p->line_spanner_, rq->self_scm ());
}
- p->start_req_l_ = p->req_l_drul_[START];
+
+ // Choose the appropriate grobs to add to the line spanner
+ // These can be text items or text-spanners
+
+ SCM type = ly_cdr (scm_assoc (ly_symbol2scm("pedal-type"),
+ get_property( ( String (p->name_) + "Pedal").ch_C () )));
+ if (type == ly_symbol2scm("text") || // Ped. *Ped. *
+ type == ly_symbol2scm("mixed") ) // Ped. _____/\____|
+ if (! p->item_p_)
+ create_text_grobs(p, type);
+
+ if (type == ly_symbol2scm("bracket") || // |_________/\____|
+ type == ly_symbol2scm("mixed") )
+ create_bracket_grobs(p, type);
}
- else if (p->req_l_drul_[STOP])
+
+ }
+}
+
+
+void
+Piano_pedal_engraver::create_text_grobs (Pedal_info *p, SCM pedaltype)
+{
+ SCM b;
+ SCM s = SCM_EOL;
+ SCM strings = get_property (("pedal" + String (p->name_) + "Strings").ch_C ());
+
+ if (! (scm_ilength (strings) < 3))
+ {
+ if (p->req_l_drul_[STOP] && p->req_l_drul_[START])
{
- if (!p->start_req_l_)
+ if (pedaltype == ly_symbol2scm("text"))
{
- p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->name_));
+ if (!p->start_req_l_)
+ {
+ p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->name_));
+ }
+ else
+ {
+ s = ly_cadr (strings);
+ }
+ p->start_req_l_ = p->req_l_drul_[START];
}
- else
+ }
+
+ else if (p->req_l_drul_[STOP])
+ {
+ if (pedaltype == ly_symbol2scm("text"))
{
- s = ly_caddr (strings);
+ if (!p->start_req_l_)
+ {
+ p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->name_));
+ }
+ else
+ {
+ s = ly_caddr (strings);
+ nspanners_i --;
+ }
+ p->start_req_l_ = 0;
}
- p->start_req_l_ = 0;
}
- else if (p->req_l_drul_[START])
+
+ else if ( p->req_l_drul_[START] )
{
p->start_req_l_ = p->req_l_drul_[START];
s = ly_car (strings);
+ if (pedaltype == ly_symbol2scm("text")) {
+ nspanners_i ++;
+ previous_p_[nspanners_i] = p->line_spanner_;
+ if (nspanners_i > 1)
+ // add extra space below the previous already-occuring pedal
+ Side_position_interface::add_support(p->line_spanner_, previous_p_[nspanners_i - 1]);
+ }
}
-
+
if (gh_string_p (s))
{
String propname = String (p->name_) + "Pedal";
- p->item_p_ = new Item (get_property (propname.ch_C ()));
+ b = get_property (propname.ch_C ());
+ p->item_p_ = new Item (b);
p->item_p_->set_grob_property ("text", s);
+ Axis_group_interface::add_element (p->line_spanner_, p->item_p_);
+
+ announce_grob (p->item_p_,
+ (p->req_l_drul_[START]
+ ? p->req_l_drul_[START]
+ : p->req_l_drul_[STOP])->self_scm() );
+
+ }
+ if (pedaltype == ly_symbol2scm("text"))
+ {
+ p->req_l_drul_[START] = 0;
+ p->req_l_drul_[STOP] = 0;
+ }
+ }
+}
+void
+Piano_pedal_engraver::create_bracket_grobs (Pedal_info *p, SCM pedaltype)
+{
- Music * c = p->req_l_drul_[START]
- ? p->req_l_drul_[START]
- : p->req_l_drul_[STOP];
- announce_grob (p->item_p_, c ? c->self_scm() : SCM_EOL);
-
+ if (p->req_l_drul_[STOP])
+ {
+ if (!p->start_req_l_)
+ {
+ p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->name_));
+ }
+ else if (!p->req_l_drul_[START])
+ nspanners_i -- ;
+
+ assert (!p->finished_bracket_p_ && p->bracket_p_);
+
+ p->bracket_p_->set_bound (RIGHT, unsmob_grob(get_property ("currentMusicalColumn")));
+
+ // Set a property so that the molecule-creating function will know whether the right edge should be angled ___/
+ p->bracket_p_->set_grob_property("angle-right", gh_bool2scm((bool) p->req_l_drul_[START]) );
+ add_bound_item (p->line_spanner_, p->bracket_p_->get_bound (RIGHT));
+
+ p->finished_bracket_p_ = p->bracket_p_;
+ p->bracket_p_ = 0;
+ p->current_bracket_req_ = 0;
+ p->start_req_l_ = p->req_l_drul_[START];
+ }
+
+ if (p->req_l_drul_[START])
+ {
+ p->start_req_l_ = p->req_l_drul_[START];
+ p->current_bracket_req_ = p->req_l_drul_[START];
+
+ p->bracket_p_ = new Spanner (get_property ("PianoPedalBracket"));
+ p->bracket_p_->set_interface (ly_symbol2scm ("piano-pedal-interface"));
+
+ // Set a property so that the molecule-creating function will know whether the left edge should be angled \___
+ p->bracket_p_->set_grob_property("angle-left", gh_bool2scm((bool) p->req_l_drul_[STOP]) );
+
+ // Set this property for 'mixed style' pedals, Ped._______/\ ,
+ // so the molecule function will shorten the ____ line by the length of the Ped. text.
+ p->bracket_p_->set_grob_property("text-start",
+ pedaltype == ly_symbol2scm("mixed") ?
+ gh_bool2scm((bool) ! p->req_l_drul_[STOP]) :
+ gh_bool2scm(false));
+ if (p->item_p_)
+ p->bracket_p_->set_parent (p->item_p_, Y_AXIS);
+
+ Side_position_interface::set_axis (p->bracket_p_, Y_AXIS);
+ Side_position_interface::set_direction (p->bracket_p_, UP);
+ p->bracket_p_->set_bound (LEFT, unsmob_grob (get_property ("currentMusicalColumn")));
+ Axis_group_interface::add_element (p->line_spanner_, p->bracket_p_);
+
+ add_bound_item (p->line_spanner_, p->bracket_p_->get_bound (LEFT));
+ announce_grob (p->bracket_p_, p->req_l_drul_[START]->self_scm());
+
+ if (!p->req_l_drul_[STOP]) {
+
+ nspanners_i ++;
+ previous_p_[nspanners_i] = p->line_spanner_;
+
+ if (nspanners_i > 1)
+ // position new pedal spanner below the current one
+ Side_position_interface::add_support(p->line_spanner_, previous_p_[nspanners_i - 1]);
+
+ }
+ }
+
+ p->req_l_drul_[START] = 0;
+ p->req_l_drul_[STOP] = 0;
+}
+
+void
+Piano_pedal_engraver::finalize ()
+{
+ for (Pedal_info*p = info_list_; p && p->name_; p ++)
+ {
+ if (p->line_spanner_
+ && p->line_spanner_->immutable_property_alist_ == SCM_EOL)
+ p->line_spanner_ = 0;
+ if (p->line_spanner_)
+ {
+ p->finished_line_spanner_ = p->line_spanner_;
+ typeset_all ();
+ }
+ if (p->bracket_p_
+ && p->bracket_p_->immutable_property_alist_ == SCM_EOL)
+ p->bracket_p_ = 0;
+ if (p->bracket_p_)
+ {
+ p->current_bracket_req_->origin ()->warning (_ ("unterminated pedal bracket"));
+ p->bracket_p_->suicide ();
+ p->bracket_p_ = 0;
}
- p->req_l_drul_[START] = 0;
- p->req_l_drul_[STOP] = 0;
}
}
+
void
Piano_pedal_engraver::stop_translation_timestep ()
{
+ for (Pedal_info*p = info_list_; p && p->name_; p ++)
+ {
+ p->finished_line_spanner_ = p->line_spanner_;
+ }
+ typeset_all ();
+}
+
+
+void
+Piano_pedal_engraver::typeset_all ()
+{
+
+
Item * sustain = 0;
for (Pedal_info*p = info_list_; p->name_; p ++)
{
+ if (p->finished_line_spanner_
+ && p->finished_line_spanner_->immutable_property_alist_ == SCM_EOL)
+ p->finished_line_spanner_ = 0;
+ if (p->finished_bracket_p_
+ && p->finished_bracket_p_->immutable_property_alist_ == SCM_EOL)
+ p->finished_bracket_p_ = 0;
if (p->name_ == String ("Sustain"))
sustain = p->item_p_;
- }
- for (Pedal_info*p = info_list_; p->name_; p ++)
- {
if (p->item_p_)
{
- Side_position_interface::add_staff_support (p->item_p_);
-
/*
Hmm.
*/
}
}
typeset_grob (p->item_p_);
+ p->item_p_ = 0;
+ }
+
+ if (p->finished_bracket_p_)
+ {
+ if (!p->finished_bracket_p_->get_bound (RIGHT))
+ {
+ p->finished_bracket_p_->set_bound (RIGHT, unsmob_grob (get_property ("currentMusicalColumn")));
+
+ if (p->finished_line_spanner_)
+ add_bound_item (p->finished_line_spanner_,
+ p->finished_bracket_p_->get_bound (RIGHT));
+ }
+ typeset_grob (p->finished_bracket_p_);
+ p->finished_bracket_p_ =0;
+ }
+
+ if (p->finished_line_spanner_)
+ {
+ Side_position_interface::add_staff_support (p->finished_line_spanner_);
+ Grob * l = p->finished_line_spanner_->get_bound (LEFT );
+ Grob * r = p->finished_line_spanner_->get_bound (RIGHT);
+ if (!r && l)
+ p->finished_line_spanner_->set_bound (RIGHT, l);
+ else if (!l && r)
+ p->finished_line_spanner_->set_bound (LEFT, r);
+ else if (!r && !l)
+ {
+ Grob * cc = unsmob_grob (get_property ("currentMusicalColumn"));
+ Item * ci = dynamic_cast<Item*>(cc);
+ p->finished_line_spanner_->set_bound (RIGHT, ci);
+ p->finished_line_spanner_->set_bound (LEFT, ci);
+ }
+ typeset_grob (p->finished_line_spanner_);
+ p->finished_line_spanner_ = 0;
}
- p->item_p_ = 0;
}
}
}
}
ENTER_DESCRIPTION(Piano_pedal_engraver,
-/* descr */ "Engrave piano pedal symbols.",
-/* creats*/ "SostenutoPedal SustainPedal UnaCordaPedal",
-/* acks */ "rhythmic-head-interface stem-interface",
+/* descr */ "Engrave piano pedal symbols and brackets.",
+/* creats*/ "SostenutoPedal SustainPedal UnaCordaPedal SostenutoPedalLineSpanner SustainPedalLineSpanner UnaCordaPedalLineSpanner",
+/* acks */ "note-column-interface",
/* reads */ "pedalSostenutoStrings pedalSustainStrings pedalUnaCordaStrings",
/* write */ "");
Grob *me= unsmob_grob (smob);
Spanner *spanner = dynamic_cast<Spanner*> (me);
+ if (spanner->has_interface (ly_symbol2scm ("piano-pedal-interface")) )
+ {
+ setup_pedal_bracket(spanner);
+ }
/* Ugh, must be same as Hairpin::brew_molecule. */
Drul_array<Molecule> edge_line;
s = me->get_grob_property ("edge-height");
+ SCM ew = me->get_grob_property ("edge-width");
if (gh_pair_p (s))
{
Direction d = LEFT;
int dir = to_dir (me->get_grob_property ("direction"));
do
{
+ Real dx = ( gh_pair_p (ew) ?
+ gh_scm2double (index_cell (ew, d)) * - dir :
+ 0 );
Real dy = gh_scm2double (index_cell (s, d)) * - dir;
if (dy)
{
- SCM list = Line_spanner::line_atom (me, 0, dy);
- Box b (Interval (0, thick),
+ SCM list = Line_spanner::line_atom (me, dx, dy);
+ Box b (Interval (-thick, 0),
dy > 0
? Interval (0, dy)
: Interval (dy, 0));
m.add_at_edge (X_AXIS, RIGHT, edge_line[RIGHT], 0);
if (!edge[RIGHT].empty_b ())
m.add_at_edge (X_AXIS, RIGHT, edge[RIGHT], 0);
- m.translate_axis (broken_left + extra_off[LEFT], X_AXIS);
+ m.translate_axis (broken_left + extra_off[LEFT] + shorten[LEFT], X_AXIS);
return m.smobbed_copy ();
}
+
+/*
+ Piano pedal brackets are a special case of a text spanner.
+ Pedal up-down (restart) indicated by the angled right and left edges
+ of consecutive pedals touching exactly to form an __/\__
+ Chris Jackson <chris@fluffhouse.org.uk>
+
+ TODO: Pedal line extending to the end of the note
+*/
+
+void
+Text_spanner::setup_pedal_bracket(Spanner *s)
+{
+
+ Real thick = s->paper_l ()->get_var ("stafflinethickness");
+ Real ss = Staff_symbol_referencer::staff_space (s);
+
+ Drul_array<bool> a, broken;
+ Drul_array<Real> height, width, shorten, r;
+
+ // Pedal has an angled left edge \__ or an angled right edge __/
+ a[LEFT] = a[RIGHT] = false;
+ SCM al = s->get_grob_property ("angle-left");
+ SCM ar = s->get_grob_property ("angle-right");
+ if (gh_boolean_p (al) )
+ a[LEFT] = to_boolean (al);
+ if (gh_boolean_p (ar) )
+ a[RIGHT] = to_boolean (ar);
+
+ height[LEFT] = ( to_boolean (s->get_grob_property ("text-start")) ?
+ 0 :
+ ss );
+ height[RIGHT] = ss;
+
+ Direction d = LEFT;
+ Interval e;
+ Real padding = 0;
+ SCM pa = (s->get_grob_property ("if-text-padding"));
+ if (gh_number_p (pa) )
+ padding = gh_scm2double (pa);
+ do {
+ Item *b = s->get_bound (d);
+
+ e = b->extent (b, X_AXIS);
+ if (!e.empty_b ())
+ r[d] = d * (e[-d] + padding);
+
+ broken[d] = b->break_status_dir () != CENTER;
+ width[d] = (a[d] ? ss*d/2 : 0);
+ if (broken[d])
+ height[d] = 0;
+ }
+ while (flip (&d) != LEFT);
+
+ shorten[RIGHT] = shorten[LEFT] = 0;
+ Real extra_short = 0;
+ // For 'Mixed' style pedals, i.e. a bracket preceded by text: Ped._____|
+ // need to shorten by the extent of the text grob
+ if ( to_boolean (s->get_grob_property ("text-start")) )
+ {
+ Grob * textbit = s->get_parent(Y_AXIS);
+ extra_short = padding;
+ if (textbit->has_interface(ly_symbol2scm("piano-pedal-interface")))
+ // for pretty Ped. scripts.
+ {
+ e = textbit->extent(textbit, Y_AXIS);
+ extra_short += e.length();
+ }
+ if (textbit->has_interface(ly_symbol2scm("text-interface")))
+ // for plain text, e.g., Sost. Ped.
+ {
+ SCM text = textbit->get_grob_property("text");
+ if (gh_string_p (text)) {
+ SCM properties = Font_interface::font_alist_chain (s);
+ Molecule mol = Text_item::text2molecule (s, text, properties);
+ extra_short += mol.extent(X_AXIS).length() / 2;
+ }
+ }
+ shorten[RIGHT] -= thick;
+ }
+
+ // Shorten a \____ on the left so that it will touch an adjoining ___/
+ shorten[LEFT] += abs(width[LEFT]) * 2 + extra_short ;
+
+ if (broken[LEFT]) {
+ shorten[LEFT] -= s->get_broken_left_end_align () ;
+ shorten[RIGHT] -= r[RIGHT];
+ }
+ else
+ // Shorten bracket on the right so it ends just before the spanned note.
+ shorten[RIGHT] += thick - (r[LEFT] + r[RIGHT]);
+
+ // Hmm. TODO: This should be set in grob-description.scm, but side-positioning
+ // of consecutive brackets only seems to work if direction is +1 within the engraver.
+ s->set_grob_property ("direction", gh_int2scm(-1));
+
+ s->set_grob_property ("edge-height", gh_cons ( gh_double2scm ( height[LEFT] ) ,
+ gh_double2scm ( height[RIGHT]) ) );
+ s->set_grob_property ("edge-width", gh_cons ( gh_double2scm ( width[LEFT] ),
+ gh_double2scm ( width[RIGHT] ) ));
+ s->set_grob_property ("shorten", gh_cons ( gh_double2scm ( shorten[LEFT] ),
+ gh_double2scm ( shorten[RIGHT] ) ));
+}
;; in principle, have one or more uppercase letters
"\\(\\(BarNumbering\\|Choir\\|Grand\\|HaraKiri\\|OrchestralPart\\|Piano\\|Rhythmic\\)Staff\\|\\(Cue\\|Lyrics\\)?Voice\\|\\(Orchestral\\)?Score\\|ChordNames\\|Grace\\|Lyrics\\|StaffGroup\\|Thread\\)Context" ; *Context
-"\\(script\\|dots\\|dynamic\\|slur\\|stem\\|sustain\\|tie\\|tuplet\\)\\(Both\\|Down\\|Up\\)" ; *(Both/Down/Up)
+"\\(script\\|dots\\|dynamic\\|slur\\|stem\\|sustain\\|sostenuto\\|unaCorda\\|treCorde\\|tie\\|tuplet\\)\\(Both\\|Down\\|Up\\)" ; *(Both/Down/Up)
"\\(slur\\|tie\\)\\(Dotted\\|Solid\\)" ; *(Dotted/Solid)
"\\(autoBeam\\|cadenza\\|impro\\|turn\\)\\(Off\\|On\\)" ; *(On/Off)
"\\(empty\\|fat\\)Text" ; *Text
pedalSustainStrings = #'("Ped." "*Ped." "*")
pedalUnaCordaStrings = #'("una corda" "" "tre corde")
- pedalSostenutoStrings = #'() % FIXME
+
+ %% these are in ordinary italic font, including the *, but they are unlikely to be used,
+ %% as the default pedal-style for SostenutoPedal is 'mixed': i.e. Sost. Ped_____________________
+ pedalSostenutoStrings = #'("Sost. Ped." "*Sost. Ped." "*")
tupletNumberFormatFunction = #denominator-tuplet-formatter
Begin3
Title: LilyPond
-Version: 1.5.40
+Version: 1.5.41
Entered-date: 15MRT02
Description: @BLURB@
Keywords: music notation typesetting midi fonts engraving
janneke@gnu.org (Jan Nieuwenhuizen)
Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys)
Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert
- 1000k lilypond-1.5.40.tar.gz
+ 1000k lilypond-1.5.41.tar.gz
Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
- 1000k lilypond-1.5.40.tar.gz
+ 1000k lilypond-1.5.41.tar.gz
Copying-policy: GPL
End
%define name lilypond
-%define version 1.5.40
+%define version 1.5.41
%define release 1mdk
Name: %{name}
%define info yes
Name: lilypond
-Version: 1.5.40
+Version: 1.5.41
Release: 1
License: GPL
Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.40.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.41.tar.gz
Summary: Create and print music notation
URL: http://www.lilypond.org/
BuildRoot: /tmp/lilypond-install
Distribution: SuSE Linux 7.0 (i386)
Name: lilypond
-Version: 1.5.40
+Version: 1.5.41
Release: 2
Copyright: GPL
Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.40.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.5.41.tar.gz
# music notation software for.. ?
Summary: A program for printing sheet music.
URL: http://www.lilypond.org/
fet_beginchar("Ledger ending", "ledgerending", "ledgerending")
set_char_box (5/2 ledgerlinethickness#, 5/2 ledgerlinethickness#,
ledgerlinethickness#/2,ledgerlinethickness#/2);
- draw_rounded_block((-b,-d),(w,h),1.3 blot_diameter);
+
+
+ draw_rounded_block((-b,-d),(w,h), 0.8 ledgerlinethickness);
fet_endchar;
% todo: document rest.
%
+def normalize (expr p) =
+ (p / length (p))
+enddef ;
def draw_eighth_rest =
save width, bulb_diam, thin, thick;
- save ycenter, crook_thick;
- save crook_dir;
+ save ycenter, crook_thick, crook_thin;
+ save crook_dir, lower_brush;
pair crook_dir;
width# := 1.0 staff_space#;
bulb_diam# := 0.6 staff_space#;
- thin# := 1.0 stafflinethickness#;
- thick# := 2.0 stafflinethickness#;
- crook_thick# := 1.6 stafflinethickness#;
+ thin# := 1.1 stafflinethickness#;
+ thick# := 2.2 stafflinethickness#;
+ crook_thick# := 1.8 stafflinethickness#;
+ crook_thin := 1.3 stafflinethickness;
+ lower_brush = 1.0 stafflinethickness;
ycenter := 0.5 staff_space;
define_pixels (width, bulb_diam, thin, thick, crook_thick);
penpos2 (thin, 0);
y1 = ycenter + - 1.5 staff_space ;
- y2 = y5 - 2.0 stafflinethickness;
+% y9 = y5 - lower_brush;
+ y2 = y5 - 0.7 stafflinethickness;
+
x2r = width;
y3 - y2l = 0.25 staff_space;
x2r - x1 = 0.5 staff_space;
x3 = x1l ;
- y3 := ycenter +floor (- bulb_diam/2);
+
x4 = 1.02 bulb_diam ;
- y4 = ycenter - stafflinethickness;
+ y4 = ycenter - 2 stafflinethickness + crook_thin;
x5 = 0.5 bulb_diam;
y5 = ycenter +bulb_diam/2;
- crook_dir = (z2l - z4) / length(z2l - z4);
+ z9 = z2 + 0.46 stafflinethickness * dir (angle(z2 - z1)- 10);
+
+ z7 = (bulb_diam/2,ycenter) + 0.26 staff_space * dir ( 35);
+ z8 = (0, ycenter);
z6 = whatever [z1l, z2l];
z6 = whatever [z2l, z4] + crook_thick * (crook_dir rotated -90);
+ crook_dir = normalize(z2l - z4);
- z7 = (bulb_diam/2,ycenter) + 0.26 staff_space * dir ( 35);
- z8 = (0, ycenter);
+ y3 := ycenter +floor (- bulb_diam/2);
- z9 = z2 + 0.46 stafflinethickness * dir (angle(z2 - z1)- 10);
penlabels (1, 2);
labels(3, 4, 5, 6, 7, 8, 9);
input feta-banier;
input feta-eindelijk;
% input feta-klef;
- input feta-toevallig;
+% input feta-toevallig;
% input feta-schrift;
% input feta-haak;
% input feta-timesig;
ascender_extra# = 1/2 ex#;
ascender# = ascender_extra# + ex#;
- ex# = 1.5 staff_space#;
- kerning# = .75 ex#;
+ ex# = 1.4 staff_space#;
+ kerning# = .60 ex#;
start_nib_angle = 20;
bulb_size = 0.47;
define_pixels(ex, ascender_extra, ascender, kerning);
path t_p, krul_p, r_p;
- t_p := z1l -- z2l{down} .. tension (1 + .5 slant)
+ t_p := simple_serif (z1r, z1l, -30) -- z2l {down} .. tension (1 + .5 slant)
.. z3l{right}
.. z4l{up} -- z4r{down}
z5 = (t_fatness/2, 2/3 ex);
lft x6 = - uitschieter;
- y6 = y5 - 1/20 ex;
+ y6 = y5 ; % - 1/20 ex;
z7 = z5 + whatever*dir krul_ang;
up_angle = krul_ang;
penpos9(r_fatness, 0);
x10 = x9;
- y10 = 0;
+ y10 = -0.3 stafflinethickness;
penpos10(r_fatness, 0);
krul_p := z4{up} .. tension 1.1 .. z5
- .. tension 1 and .75 .. {down}z6
+ .. tension 1 and .75 .. z6
.. tension .85 and 1.1 .. z5 --- z7;
draw krul_p;
- r_p := z7l{z7-z5} .. z8l{right} .. z9l{down} --- z10l -- z10r
+ r_p := z7l{z7-z5} .. z9l{down} --- simple_serif (z10l, z10r, -30)
--- z9r{up}
.. z8r{left} .. z7r{z5-z7} -- cycle;
fill r_p;
%
% TODO: remove crook_fatness
+% TODO: document, simplify!
+%
def draw_meta_flat(expr xcenter, w, crook_fatness) =
clearxy;
save crook_thinness;
- save top_stem_thick, bottom_stem_thick, hair;
+ save top_stem_thick, bottom_stem_thick, hair, smaller_hole;
save center;
pair center;
center = (xcenter, 0);
- crook_thinness = 1.25 stafflinethickness;
+%
+% TODO: parameterize this
+%
+ if w >= 0.75 staff_space:
+ smaller_hole = 0.2 stafflinethickness;
+ else:
+ smaller_hole = 0.0 stafflinethickness;
+ fi
+ crook_thinness = 1.1 stafflinethickness;
top_stem_thick = 2 stafflinethickness;
bottom_stem_thick = 1.2 stafflinethickness;
y3l = (staff_space - stafflinethickness)/2 + ypart center;
z3l = whatever [z2r,z1r];
- z3r = .26 [z2r, z1r];
+ z3r = .26 [z2r, z1r] + (smaller_hole, 0);
+ z10 = whatever [z2r, z1r] + (smaller_hole , 0);
+
z4 = (3/8 staff_space, staff_space/2) + center;
penpos4(whatever, 53);
save ne_angle;
ne_angle = angle(z9 - z8);
- z7 = 8/33 [z8,z9];
+ z7 = 8/33 [z8,z9] + (1.0 smaller_hole, 0);
z6l = 18/33 [z8,z9] + .5 crook_thinness *dir(ne_angle -90);
penpos7(crook_thinness, ne_angle + 90);
z6r = .3 (z9-z8) + z7r;
-% penpos7(crook_thinness, angle(dir(z8-center) -180);
-
penpos8(whatever, ne_angle + 90);
x8r = xpart center - bottom_stem_thick/2;
penlabels(range 0 thru 10);
y10 = -1/5 staff_space;
- z10 = whatever [z2r, z1r];
unfill z3r .. z4r{right} .. tension .9
.. z6r ---
- z7r{left}
- .. z10 -- cycle;
+ z7r{left}
+ .. z10{z3r-z10} -- cycle;
fill z8r{down}
.. tension 0.8 ..z8l{(z9-z8)}
.. z7l
(meta . ,(grob-description multi-measure-rest-interface font-interface percent-repeat-interface))
))
+ (PianoPedalBracket ;; an example of a text spanner
+ . (
+ (molecule-callback . ,Text_spanner::brew_molecule)
+ (font-family . roman)
+ (type . line)
+ (if-text-padding . 1.0)
+ (width-correct . 0)
+ (outer . #t)
+ (angle-left . #f)
+ (angle-right . #f)
+ (text-start . #f)
+ (meta . ,(grob-description text-spanner-interface piano-pedal-interface font-interface))
+ ))
+
(RepeatSlash
. (
(molecule-callback . , Percent_repeat_item_interface::beat_slash)
(SostenutoPedal
. (
(molecule-callback . ,Text_item::brew_molecule)
- (direction . -1)
+ (direction . 1)
(X-offset-callbacks . (,Side_position_interface::aligned_on_self))
- (Y-offset-callbacks .
- (,Side_position_interface::aligned_side
- ,Side_position_interface::centered_on_parent))
+ (Y-offset-callbacks . (,Side_position_interface::aligned_side))
(no-spacing-rods . #t)
+ (padding . 0.0) ;; padding relative to SostenutoPedalLineSpanner
+ (pedal-type . mixed)
+ (font-family . roman)
(font-shape . italic)
(self-alignment-X . 0)
(meta . ,(grob-description text-interface font-interface))
))
+ (SostenutoPedalLineSpanner
+ . (
+ (axes . ( 1))
+ (padding . 1.2)
+ (minimum-space . 1.0)
+ (direction . -1)
+ (meta . ,(grob-description piano-pedal-interface axis-group-interface side-position-interface))
+ ))
+
(Stem
. (
(before-line-breaking-callback . ,Stem::before_line_breaking)
(no-spacing-rods . #t)
(molecule-callback . ,Sustain_pedal::brew_molecule)
(self-alignment-X . 0)
- (direction . -1)
+ (direction . 1)
+ (padding . 0.0) ;; padding relative to SustainPedalLineSpanner
+ (pedal-type . text)
(X-offset-callbacks . (,Side_position_interface::aligned_on_self))
- (Y-offset-callbacks .
- (,Side_position_interface::aligned_side
- ,Side_position_interface::centered_on_parent))
+ (Y-offset-callbacks . (,Side_position_interface::aligned_side ))
+ (meta . ,(grob-description piano-pedal-interface side-position-interface font-interface))
+ ))
- (meta . ,(grob-description sustain-pedal-interface side-position-interface font-interface))
+ (SustainPedalLineSpanner
+ . (
+ (axes . ( 1))
+ (padding . 1.2)
+ (minimum-space . 1.0)
+ (direction . -1)
+ (meta . ,(grob-description piano-pedal-interface axis-group-interface side-position-interface))
))
(SystemStartBrace
. (
(molecule-callback . ,Text_spanner::brew_molecule)
(font-family . roman)
- (type . "line")
+ (type . line)
;; urg, only for (de)cresc. text spanners
(if-text-padding . 1.0)
(font-shape . italic)
(no-spacing-rods . #t)
(self-alignment-X . 0)
- (direction . -1)
+ (direction . 1)
+ (pedal-type . text)
+ (padding . 0.0) ;; padding relative to UnaCordaPedalLineSpanner
(X-offset-callbacks . (,Side_position_interface::aligned_on_self))
- (Y-offset-callbacks .
- (,Side_position_interface::aligned_side
- ,Side_position_interface::centered_on_parent))
+ (Y-offset-callbacks . (,Side_position_interface::aligned_side ))
(meta . ,(grob-description text-interface font-interface))
))
+ (UnaCordaPedalLineSpanner
+ . (
+ (axes . ( 1))
+ (padding . 1.2)
+ (minimum-space . 1.0)
+ (direction . -1)
+ (meta . ,(grob-description piano-pedal-interface axis-group-interface side-position-interface))
+ ))
+
(VoltaBracket
. (
(molecule-callback . ,Volta_spanner::brew_molecule)
(grob-property-description 'duration-log integer? "2-log of the notehead duration, i.e. 0=whole note, 1 = half note, etc.")
(grob-property-description 'dy number? "set by beam: vertical travel height")
(grob-property-description 'edge-height pair? "a cons that specifies the heights of the vertical egdes '(LEFT-height . RIGHT-height).")
+(grob-property-description 'edge-width pair? "a cons that specifies the widths of the slanted edges '(LEFT-width . RIGHT-width).")
(grob-property-description 'edge-text pair? "a cons that specifies the texts to be set at the edges '(LEFT-text . RIGHT-text).")
(grob-property-description 'elements list? "list of grobs, type depending on the Grob where this is set in.")
(grob-property-description 'expand-limit integer? "maximum number of measures expanded in church rests.")
(grob-property-description 'padding number? "add this much extra space between objects that are next to each other.")
(grob-property-description 'parallel-beam boolean? "internal: true if there is a beam just as wide as the bracket .")
(grob-property-description 'paren-cautionaries boolean? "Whether to add parenthesis around cautionary accidentals.")
+(grob-property-description 'pedal-type symbol? "Style of piano pedal: text, bracket or mixed")
(grob-property-description 'penalty number? "Penalty for breaking at
this column. 10000 or more means forbid linebreak, -10000 or less
means force linebreak. Other values influence linebreaking decisions
TODO: revise typing.")
(grob-property-description 'self-alignment-Y number? "like self-alignment-X but for Y axis.")
+(grob-property-description 'shorten number? "the amount of space that a stem should be shortened (DOCME!)")
+
(grob-property-description 'shortest-playing-duration moment? "duration of the shortest playing in that column.")
(grob-property-description 'shortest-starter-duration moment? "duration of the shortest notes that starts exactly in this column.")
(grob-property-description 'side-relative-direction dir? "if set: get the direction from a different object, and multiply by this.")
contains-grace extra-space stretch-distance ))
+ (lily-interface
+ 'piano-pedal-interface
+ ""
+ '(pedal-type
+ ))
+
(lily-interface
'porrectus-interface
))
- (lily-interface
- 'sustain-pedal-interface
- ""
- '(
- ))
-
(lily-interface
'system-start-delimiter-interface
"#'style can be bar-line, bracket or brace"
dash-length
line-thickness
edge-height
+ edge-width
edge-text
type
))
(define (dashed-line thick on off dx dy)
(string-append
- (ly-number->string dx)
+ (ly-number->string (* dx (/ 72 72.27)))
" "
(ly-number->string dy)
" "
- (ly-number->string thick)
+ (ly-number->string (* thick (/ 72 72.27)))
" [ "
(ly-number->string on)
" "