<a href="http://appel.lilypond.org/wiki?LilyPondFaqs">Full FAQ</a><br>
<a href="@TOP@Documentation/user/out-www/lilypond/lilypond.html">User manual</a><br>
<a href="@TOP@Documentation/out-www/regression-test.html">Regression Test</a><br>
- <a href="http://appel.lilypond.org/wiki?LilyPondToDo">To do</a><br>
+ <a href="@TOP@Documentation/user/out-www/lilypond-internals/lilypond-internals.html">Documentation of internals</a><br>
<br>
</td></tr>
<tr><td bgcolor="#e8e8ff">
\score{
\context Staff <
- \context Voice=one\skip 1;
- \context Voice=two\skip 1;
+ \context Voice=one \skip 1;
+ \context Voice=two \skip 1;
\context Voice=one \partcombine Voice
\context Thread=one \notes\relative c'' {
c2 \clef bass; c2
--- /dev/null
+\header{
+texidoc=" Dynamics appear below or above the staff. If multiple
+dynamics are linked with (de)crescendi, they should be on the same
+line. Isolated dynamics may be forced up or down. ";
+}
+
+\version "1.3.122";
+
+\score{
+\notes\relative c''{
+a1^\sfz
+a1-\fff\> \!c,,-\pp a'' a-\p
+
+% We need this to test if we get two Dynamic line spanners
+a
+
+% because do_removal_processing ()
+% doesn't seem to post_process elements
+d\f
+
+a
+
+}
+\paper{
+}
+\midi{
+\tempo 1 = 60;
+}
+}
--- /dev/null
+\header{
+texidoc="
+Adding a @code{Bar_engraver} to the LyricsVoice context makes sure that
+lyrics don't collide with barlines.
+";
+}
+
+\score {
+ \context StaffGroup <
+ \notes \context Staff {
+ b1 b1 \bar "|.";
+ }
+ \lyrics\context Lyrics <
+ \context LyricsVoiceWithBars {
+% thisContextHasSpanBarEngraver1 added
+ ThisContextCertainlyHasSpanBarEngraverAddedButTheresSomethingFunny1. Here.
+ }
+ \context LyricsVoice {
+ this4 one has no SpanBarEngraverAddedToContext1
+ }
+ >
+ \notes \context Staff = SB { b1 b1 }
+ >
+ \paper {
+ linewidth = -1.0\cm;
+ \translator {
+ \LyricsContext
+ \accepts "LyricsVoiceWithBars";
+ }
+ \translator {
+ \LyricsVoiceContext
+ \consists "Bar_engraver";
+ \name "LyricsVoiceWithBars";
+ }
+
+ }
+}
global = \notes {
s1 | \mark "A";
s1 | \mark ;
+ s1 | \mark ;
s1 | \mark "12";
s1 | \mark ;
s1 | \mark "A2";
--- /dev/null
+
+\header {
+
+ texidoc = "By splitting the grouping (Axis_group_engraver) and
+creation functionality into separate contexts, you can override
+interesting things. You can also drop the \consistsend feature.";
+
+}
+
+
+\score {
+ \notes <
+ \context StaffContainer = SA { \property StaffContainer.StaffSymbol \set
+ #'staff-space = #0.8
+ \context Staff { c4 c4 } }
+ \context StaffContainer =SB { \context Staff { d f } }
+ >
+
+\paper {
+ \translator {
+ \ScoreContext
+ \accepts StaffContainer;
+ \denies Staff;
+ }
+ \translator {
+ \type Engraver_group_engraver;
+ \consists "Axis_group_engraver";
+ \accepts "Staff";
+ \name StaffContainer;
+
+ }
+ \translator {
+ \StaffContext
+ \remove Axis_group_engraver;
+ }
+}
Link_array<Grob> elems;
Link_array<Grob> all_grobs
- = Pointer_group_interface__extract_elements ( me, (Grob*) 0, "elements");
+ = Pointer_group_interface__extract_elements (me, (Grob*) 0, "elements");
for (int i=0; i < all_grobs.size(); i++)
{
Interval y = all_grobs[i]->extent(me, a);
&& gh_number_p (gh_cdr (min_dims)))
{
y.unite (ly_scm2interval (min_dims));
-
}
SCM extra_dims = e->remove_grob_property ("extra-space");
SCM size = me->get_grob_property ("bar-size");
if (gh_number_p (size))
return gh_double2scm (gh_scm2double(size)*ss);
- else
+ else if (Staff_symbol_referencer::staff_symbol_l (me))
{
+ /*
+ If there is no staff-symbol, we get -1 from the next
+ calculation. That's a nonsense value, which would collapse the
+ barline so we return 0.0 in the next alternative.
+ */
return gh_double2scm ((Staff_symbol_referencer::line_count (me) -1) * ss);
}
+ else
+ return gh_int2scm (0);
}
virtual void acknowledge_grob (Grob_info);
virtual bool try_music (Music *req_l);
virtual void stop_translation_timestep ();
-
- virtual void create_grobs ();
+ virtual void process_music ();
virtual void start_translation_timestep ();
};
}
void
-Dynamic_engraver::create_grobs ()
+Dynamic_engraver::process_music ()
{
if (accepted_spanreqs_drul_[START] || accepted_spanreqs_drul_[STOP] || script_req_l_)
{
/*
finish side position alignment if the (de)cresc ends here, and
there are no new dynamics.
-
- */
+ */
if ( !cresc_p_)
{
cresc_p_->set_bound (RIGHT, script_p_
? script_p_
: unsmob_grob (get_property ("currentMusicalColumn")));
+ add_bound_item (line_spanner_, cresc_p_->get_bound (RIGHT));
+
finished_cresc_p_ = cresc_p_;
cresc_p_ = 0;
current_cresc_req_ = 0;
}
}
+
if (accepted_spanreqs_drul_[START])
{
if (current_cresc_req_)
/*
TODO: Use symbols.
- */
+ */
String start_type = ly_scm2string (accepted_spanreqs_drul_[START]->get_mus_property ("span-type"));
/*
ugh. Use push/pop?
- */
+ */
SCM s = get_property ((start_type + "Spanner").ch_C());
if (!gh_symbol_p (s) || s == ly_symbol2scm ("hairpin"))
{
cresc_p_ = new Spanner (get_property ("Hairpin"));
cresc_p_->set_grob_property ("grow-direction",
- gh_int2scm ((start_type == "crescendo")
- ? BIGGER : SMALLER));
+ gh_int2scm ((start_type == "crescendo")
+ ? BIGGER : SMALLER));
}
/*
This is a convenient (and legacy) interface to TextSpanners
for use in (de)crescendi.
Hmm.
- */
+ */
else
{
cresc_p_ = new Spanner (get_property ("TextSpanner"));
if (gh_string_p (s))
{
cresc_p_->set_grob_property ("edge-text",
- gh_cons (s, ly_str02scm ("")));
+ gh_cons (s, ly_str02scm ("")));
daddy_trans_l_->set_property (start_type + "Text",
SCM_UNDEFINED);
}
: unsmob_grob (get_property ("currentMusicalColumn")));
Axis_group_interface::add_element (line_spanner_, cresc_p_);
+
+ add_bound_item (line_spanner_, cresc_p_->get_bound (LEFT));
+
announce_grob (cresc_p_, accepted_spanreqs_drul_[START]);
}
}
- script_req_l_ = 0;
- accepted_spanreqs_drul_[START] = 0;
- accepted_spanreqs_drul_[STOP] = 0;
}
void
Dynamic_engraver::stop_translation_timestep ()
{
typeset_all ();
+ if (script_req_l_ && !current_cresc_req_)
+ {
+ finished_line_spanner_ = line_spanner_;
+ line_spanner_ =0;
+ typeset_all ();
+ }
}
void
{
if (finished_cresc_p_)
{
-#if 1
- finished_cresc_p_->set_bound (RIGHT, script_p_
- ? script_p_
- : unsmob_grob (get_property ("currentMusicalColumn")));
-#endif
+ if (!finished_cresc_p_->get_bound (RIGHT))
+ {
+ finished_cresc_p_->set_bound (RIGHT, script_p_
+ ? script_p_
+ : unsmob_grob (get_property ("currentMusicalColumn")));
+
+ if (finished_line_spanner_)
+ add_bound_item (finished_line_spanner_,
+ finished_cresc_p_->get_bound (RIGHT));
+ }
typeset_grob (finished_cresc_p_);
finished_cresc_p_ =0;
}
}
if (finished_line_spanner_)
{
+ /*
+ To make sure that this works
+ */
Side_position::add_staff_support (finished_line_spanner_);
- extend_spanner_over_elements (finished_line_spanner_);
+ /*
+ We used to have
+
+ extend_spanner_over_elements (finished_line_spanner_);
+
+ but this is rather kludgy, since finished_line_spanner_
+ typically has a staff-symbol field set , extending it over the
+ entire staff.
+
+ */
+
+ if (!finished_line_spanner_->get_bound (RIGHT))
+ finished_line_spanner_->set_bound (RIGHT, finished_line_spanner_->get_bound (LEFT));
+
typeset_grob (finished_line_spanner_);
finished_line_spanner_ = 0;
}
Paper_column *
Item::column_l () const
{
- return dynamic_cast<Item*> (parent_l (X_AXIS))->column_l ();
+ Item *parent = dynamic_cast<Item*> (parent_l (X_AXIS));
+ return parent ? parent->column_l () : 0;
}
Line_of_score *
virtual bool try_music (Music *req_l);
virtual void start_translation_timestep ();
virtual void initialize ();
- virtual void create_grobs ();
+ virtual void process_music ();
private:
Mark_req * mark_req_l_;
return false;
}
+
+/*
+
+ TODO: make the increment function in Scheme.
+
+*/
void
-Mark_engraver::create_grobs ()
+Mark_engraver::process_music ()
{
if (mark_req_l_)
{
sp->set_bound (RIGHT, it);
}
+/*
+ Extends EXTREMAL_PAIR to include IT
+ */
static void
extend_spanner_over_item (Item *it, SCM extremal_pair)
{
}
}
+/*
+ Extends EXTREMAL_PAIR to include every grob in VALUE
+ */
static void
extend_spanner_over_elements (SCM value, SCM extremal_pair)
{
\translator { \ThreadContext}
\translator { \PianoStaffContext}
\translator { \LyricsVoiceContext }
-
+\translator { \StaffContainerContext }