+2004-08-22 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ * lily/horizontal-bracket.cc (print): use
+ Tuplet_bracket::make_bracket, so it supports bracket-flare,
+ edge-eight and shorten-pair.
+
2004-08-22 Pedro Kroger <kroeger@pedrokroeger.net>
* scm/framework-ps.scm (output-framework): set the first
2004-08-22 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ * lily/slur-engraver.cc (class Slur_engraver): simplify: remove
+ nested slurs.
+
* scripts/convert-ly.py (lilypond_version_re_str): handle
\version "bar" % "foo"
is erased
@lilypond[quote,fragment,relative=1,verbatim]
-\context Staff {
+{
f8[ r16 f g a]
f8[ r16 \set stemLeftBeamCount = #1 f g a]
}
@end lilypond
@cindex @code{subdivideBeams}
-Kneed beams are inserted automatically, when a large gap is detected
-between the note heads. This behavior can be tuned through the object
-property @code{auto-knee-gap}.
-
Normally, line breaks are forbidden when beams cross bar lines. This
behavior can be changed by setting @code{allowBeamBreak}.
@refbugs
@cindex Frenched staves
+Kneed beams are inserted automatically, when a large gap is detected
+between the note heads. This behavior can be tuned through the object
+
Automatically kneed cross-staff beams cannot be used together with
-hidden staves.
+hidden staves. See @ref{Hiding staves}.
Beams do not avoid collisions with symbols around the notes, such as
texts and accidentals.
+@c FIXME.
@node Setting automatic beam behavior, Beam formatting, Manual beams, Beaming
beams and sixteenth beams, a beam that contains both eight and
sixteenth notes will use the rules for the sixteenth beam.
-In the example below, the autobeamer makes eight beams and sixteenth
-end at 3 eights; the third beam can only be corrected by specifying
-manual beaming.
+In the example below, the autobeamer makes eighth beams and sixteenth
+end at three eighths. The third beam can only be corrected by
+specifying manual beaming.
@lilypond[quote,raggedright,fragment,relative=1]
#(override-auto-beam-setting '(end * * * *) 3 8)
individually for each voice. Apart from that, the rule is similar to
@code{code}.
- This leads to some weird and often unwanted results
- because accidentals from one voice do not get canceled in other
- voices
+ As a result,
+ accidentals from one voice do not get canceled in other
+ voices, which is often unwanted result
+ @c
@lilypond[quote,raggedright,relative=1,fragment,verbatim]
\context Staff <<
#(set-accidental-style 'voice)
{ c, e }
>> >>
@end lilypond
- Hence you should only use @code{voice} if the voices
+@c
+ The @code{voice} option should be used if the voices
are to be read solely by individual musicians. If the staff is to be
-used by one musician (e.g. a conductor) then you use
+used by one musician (e.g. a conductor) then
@code{modern} or @code{modern-cautionary}
-instead.
+should be used instead.
@item modern
@cindex @code{modern} style accidentals
@item piano-cautionary
@cindex @code{#(set-accidental-style 'piano-cautionary)}
- As @code{#(set-accidental-style 'piano)' , str)} but with the extra accidentals
+ As @code{#(set-accidental-style 'piano)} but with the extra accidentals
typeset as cautionaries.
@item no-reset
notes in the chord happened once at a time - in the order in which
they appear in the input file.
-This is only a problem when accidentals in a chord depend on each
-other. This problem can be solved by manually inserting @code{!} and
-@code{?} for the problematic notes.
+This is a problem when accidentals in a chord depend on each other,
+which does not happen for the default accidental style. The problem
+can be solved by manually inserting @code{!} and @code{?} for the
+problematic notes.
-In the default scheme, accidentals only depend on other
-accidentals with the same pitch on the same staff, so no conflicts are
-possible.
@node Expressive marks, Repeats, Accidentals, Notation manual
@section Expressive marks
A slur indicates that notes are to be played bound or @emph{legato}.
-
They are entered using parentheses
@lilypond[quote,relative=2,fragment,verbatim]
-f( g)( a) a8 b( a4 g2 f4)
+f( g a) a8 b( a4 g2 f4)
<c e>2( <b d>2)
@end lilypond
directions. By adding @code{_} or @code{^} before the opening
parentheses, the direction is also set. For example,
-@lilypond[relative=2,fragment]
+@lilypond[relative=2,verbatim,fragment]
c4_( c) c^( c)
@end lilypond
Typographically, the phrasing slur behaves almost exactly like a
normal slur. However, they are treated as different objects. A
-@code{\slurUp} will have no effect on a phrasing slur; instead, you
-should use @code{\phrasingSlurUp}, @code{\phrasingSlurDown}, and
+@code{\slurUp} will have no effect on a phrasing slur; instead, use
+@code{\phrasingSlurUp}, @code{\phrasingSlurDown}, and
@code{\phrasingSlurBoth}.
The commands @code{\slurUp}, @code{\slurDown}, and @code{\slurBoth}
Some performance indications, e.g. @i{rallentando} or @i{accelerando},
are written as texts, and extended over many measures with dotted
-lines. You can create such texts using text spanners: attach
-@code{\startTextSpan} and @code{\stopTextSpan} to the
-start and ending note of the spanner.
+lines. Such texts are created using text spanners: attach
+@code{\startTextSpan} and @code{\stopTextSpan} to the start and ending
+note of the spanner.
The string to be printed, as well as the style, is set through object
properties
@file{ly/script-init.ly} for examples.
-The script is automatically placed, but if you need to force
-directions, you can use @code{_} to force them down, or @code{^} to
-put them up
+The script is automatically placed, but the direction can be forced as
+well. @code{_} will put them down, and @code{^} will put them up,
+
+
@lilypond[quote,fragment,verbatim]
c''4^^ c''4_^
@end lilypond
#include "directional-element-interface.hh"
#include "output-def.hh"
#include "staff-symbol-referencer.hh"
+#include "tuplet-bracket.hh" // ugh.
struct Horizontal_bracket
{
Interval ext = gs.top ()->extent (cx, X_AXIS);
ext.unite (gs[0]->extent (cx, X_AXIS));
- Direction d = get_grob_direction (me);
+ Drul_array<Real> edge_height = robust_scm2interval (me->get_property ("edge-height"),
+ Interval (1.0, 1.0));
- Real thickness = Staff_symbol_referencer::line_thickness (me);
- thickness *= robust_scm2double (me->get_property ("thickness"), 1.0);
- Stencil b = Lookup::bracket (X_AXIS, ext, thickness, - d* 1.0, thickness/2);
-
- b.translate_axis ( - sp->get_bound (LEFT)->relative_coordinate (cx, X_AXIS), X_AXIS);
+ Drul_array<Real> flare = robust_scm2interval (me->get_property ("bracket-flare"),
+ Interval (0,0));
+
+ Drul_array<Real> shorten = robust_scm2interval (me->get_property ("shorten-pair"),
+ Interval (0,0));
+
+ Interval empty;
+ Stencil b
+ = Tuplet_bracket::make_bracket (me, Y_AXIS, Offset (ext.length (), 0),
+ edge_height, empty, flare, shorten);
+
+ b.translate_axis (ext[LEFT] - sp->get_bound (LEFT)->relative_coordinate (cx, X_AXIS), X_AXIS);
return b.smobbed_copy ();
}
ADD_INTERFACE (Horizontal_bracket,"horizontal-bracket-interface",
"A horizontal bracket encompassing notes.",
- "thickness columns direction");
+ "columns");
/*
TODO:
-
- ALGRGRRGRG
- Derive this from Slur_engraver. This code is completely duplicate.
+ copy from new slur engraver. This code handles nesting (which
+ doesn't exist for slurs)
+
*/
class Phrasing_slur_engraver : public Engraver
{
#include "engraver.hh"
#include "spanner.hh"
-/*
- TODO: junk nested slur functionality.
- */
class Slur_engraver : public Engraver
{
- Link_array<Music> events_;
- Link_array<Music> new_slur_evs_;
- Link_array<Grob> slur_stack_;
- Link_array<Grob> end_slurs_;
+ Drul_array<Music *> events_;
+ Music * running_slur_start_;
+ Grob * slur_;
+
Moment last_start_;
void set_melisma (bool);
Slur_engraver::Slur_engraver ()
{
+ events_[START] =events_[STOP] = 0;
+ slur_ = 0;
last_start_ = Moment (-1);
}
Direction d = to_dir (m->get_property ("span-direction"));
if (d == START)
{
- if (now_mom () > last_start_)
- {
- new_slur_evs_.push (m);
- last_start_ = now_mom ();
- }
-
- /*
- But we swallow other slur events.
- */
-
+ if (slur_)
+ return false;
+
+ events_[START] = m;
return true;
}
else if (d == STOP)
{
- /*
- Swallow other events.
- */
- for (int j = new_slur_evs_.size (); j--;)
- {
- Direction nd = to_dir (new_slur_evs_[j]->get_property ("span-direction"));
-
- if (nd == STOP)
- return true;
- }
-
- new_slur_evs_.push (m);
+ if (!slur_)
+ return false;
+
+ events_[STOP] = m;
return true;
}
}
Grob *e =info.grob_;
if (Note_column::has_interface (info.grob_))
{
- for (int i = 0; i < slur_stack_.size (); i++)
- New_slur::add_column (slur_stack_[i], e);
- for (int i = 0; i < end_slurs_.size (); i++)
- New_slur::add_column (end_slurs_[i], e);
+ if (slur_)
+ New_slur::add_column (slur_, e);
}
else
{
- for (int i = 0; i < slur_stack_.size (); i++)
- New_slur::add_extra_encompass (slur_stack_[i], e);
- for (int i = 0; i < end_slurs_.size (); i++)
- New_slur::add_extra_encompass (end_slurs_[i], e);
+ if (slur_)
+ New_slur::add_extra_encompass (slur_, e);
}
}
void
Slur_engraver::finalize ()
{
- for (int i = 0; i < slur_stack_.size (); i++)
- {
- /*
- Let's not typeset unterminated stuff
- */
- slur_stack_[i]->suicide ();
- }
- slur_stack_.clear ();
-
- for (int i=0; i < events_.size (); i++)
- {
- events_[i]->origin ()->warning (_ ("unterminated slur"));
- }
+ if (slur_)
+ slur_->warning (_("unterminated slur"));
}
void
Slur_engraver::process_music ()
{
- Link_array<Grob> start_slurs;
- for (int i=0; i< new_slur_evs_.size (); i++)
+ if (events_[STOP] && events_[START])
{
- Music* slur_ev = new_slur_evs_[i];
- // end slur: move the slur to other array
- Direction d = to_dir (slur_ev->get_property ("span-direction"));
- if (d== STOP)
- {
- if (slur_stack_.is_empty ())
- /* How to shut up this warning, when Voice_devnull_engraver has
- eaten start event? */
- slur_ev->origin ()->warning (_f ("can't find start of slur"));
- else
- {
- Grob* slur = slur_stack_.pop ();
-
- end_slurs_.push (slur);
- events_.pop ();
- }
- }
- else if (d == START)
- {
- /* push a new slur onto stack.
- (use temp. array to wait for all slur STOPs) */
- Grob *slur = make_spanner ("Slur", slur_ev->self_scm ());
-
- if (Direction updown = to_dir (slur_ev->get_property ("direction")))
- slur->set_property ("direction", scm_int2num (updown));
-
- start_slurs.push (slur);
- events_.push (slur_ev);
- }
+ events_[START]->origin()->warning (_ ("Cannot start and end slur on same note"));
+ }
+
+ if (events_[START] && !slur_)
+ {
+ Music *ev = events_[START];
+ slur_ = make_spanner ("Slur", events_[START]->self_scm ());
+ if (Direction updown = to_dir (ev->get_property ("direction")))
+ slur_->set_property ("direction", scm_int2num (updown));
}
- slur_stack_.concat (start_slurs);
-
- set_melisma (slur_stack_.size ());
-
- new_slur_evs_.clear ();
+ set_melisma (slur_ && !events_[STOP]);
}
void
Slur_engraver::stop_translation_timestep ()
{
- end_slurs_.clear ();
- new_slur_evs_.clear ();
+ if (events_[STOP])
+ {
+ slur_ = 0;
+ }
+
+ events_[START] = events_[STOP] = 0;
}
(Y-offset-callbacks . (,Side_position_interface::aligned_side))
(padding . 0.2)
(direction . -1)
- (meta . ((interfaces . (horizontal-bracket-interface side-position-interface spanner-interface))))
+ (bracket-flare . (0.5 . 0.5))
+ (meta . ((interfaces . (horizontal-bracket-interface
+ side-position-interface
+ bracket-interface line-interface
+ spanner-interface))))
))
(InstrumentName
. (