2004-01-06 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ * lily/separating-line-group-engraver.cc (acknowledge_grob):
+ set/unset breakableSeparationItem
+
+ * lily/separation-item.cc (relative_width): add function.
+
+ * scm/define-grob-interfaces.scm (only-prebreak-interface): add
+ only-prebreak-interface
+
+ * lily/system.cc (output_lines): only junk only-prebreak-interface grobs.
+
+ * lily/multi-measure-rest-engraver.cc (stop_translation_timestep):
+ read breakableSeparationItem
+
+ * input/regression/multi-measure-rest-multi-staff-center.ly: new file.
+
+ * lily/system.cc (output_lines): don't suicide Spacing_items.
+
* lily/dot-column.cc (dot_config_badness): new function:
select the best scoring dot configuration: dots should go close to
the note heads, but be shifted up or down according to conventions.
@chapter New features in 2.1 since 2.0
@itemize
+@item Multi measure rests are now truly centered between the
+clefs/barlines of the staff, independent of symbols on the other staffs.
+
@item Collision resolution for dots in chords has been improved greatly.
@item
Spacing following barlines was improved for widely stretched lines.
@item
-Lyric hyphens now conform to standard typesetting practice.
+Lyric hyphens and extenders now conform to standard typesetting
+practice.
@item
Lyrics are now aligned under note heads conforming to engraving
--- /dev/null
+\header { texidoc = "The centering of multi-measure rests is
+independent on prefatory matter in other staves."
+
+ }
+\version "2.1.6"
+
+\score {
+\notes << \new Staff { R1 }
+ \new Staff { r1 \clef bass }
+
+ >>
+
+\paper { raggedright = ##t }
+}
static bool has_interface (Grob*);
static Interval conditional_width (Grob*,Grob*) ;
static Interval width (Grob*) ;
+ static Interval relative_width (Grob*, Grob*) ;
static Grob*extremal_break_aligned_grob (Grob*,Direction, Interval*);
static void add_item (Grob*,Item*);
static void add_conditional_item (Grob*,Grob*);
Moment start_moment_;
Rational last_main_moment_;
+ bool bar_seen_;
+
Spanner *mmrest_;
Link_array<Spanner> numbers_;
Multi_measure_rest_engraver::Multi_measure_rest_engraver ()
{
+ bar_seen_ = false;
start_measure_ = 0;
mmrest_ = 0;
last_rest_ =0;
void
Multi_measure_rest_engraver::process_music ()
{
+
if (new_req_ && stop_req_)
stop_req_ = 0;
= gh_scm2int (get_property ("currentBarNumber"));
}
- if (gh_string_p (get_property ("whichBar")))
+ bar_seen_ = gh_string_p (get_property ("whichBar"));
+}
+
+void
+Multi_measure_rest_engraver::stop_translation_timestep ()
+{
+ /*
+ We can not do this earlier, as breakableSeparationItem is not yet there.
+ */
+
+ if (bar_seen_)
{
- Grob *cmc = unsmob_grob (get_property( "currentCommandColumn"));
+ Grob *cmc = unsmob_grob (get_property("breakableSeparationItem"));
+ if (!cmc)
+ cmc = unsmob_grob (get_property ("currentCommandColumn"));
+
Item *it = dynamic_cast<Item*> (cmc);
+
if (mmrest_)
{
add_bound_item (mmrest_, it);
add_bound_item (last_numbers_[i], it);
}
}
-}
-
-void
-Multi_measure_rest_engraver::stop_translation_timestep ()
-{
+
+
SCM smp = get_property ("measurePosition");
Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
void
Multi_measure_rest_engraver::start_translation_timestep ()
{
+ bar_seen_ = false;
+
SCM smp = get_property ("measurePosition");
Moment mp = (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
/* creats*/ "MultiMeasureRest MultiMeasureRestNumber MultiMeasureRestText",
/* accepts */ "multi-measure-rest-event multi-measure-text-event",
/* acks */ "",
-/* reads */ "currentBarNumber restNumberThreshold currentCommandColumn measurePosition measureLength",
+/* reads */ "currentBarNumber restNumberThreshold breakableSeparationItem currentCommandColumn measurePosition measureLength",
/* write */ "");
#include "text-item.hh"
#include "percent-repeat-item.hh"
#include "lookup.hh"
+#include "separation-item.hh"
MAKE_SCHEME_CALLBACK (Multi_measure_rest,percent,1);
SCM
Grob *common = sp->get_bound (LEFT)->common_refpoint (sp->get_bound (RIGHT), X_AXIS);
do
{
- Item * col = sp->get_bound (d)->get_column ();
+ Item * b = sp->get_bound (d);
- Interval coldim = col->extent (common, X_AXIS);
+ Interval coldim = (Separation_item::has_interface (b))
+ ? Separation_item::relative_width (b, common)
+ : b->extent (common, X_AXIS);
- sp_iv[d] = coldim[-d] ;
+ sp_iv[d] = coldim.is_empty () ? b->relative_coordinate (common, X_AXIS) : coldim[-d];
}
while ((flip (&d)) != LEFT);
#include "note-spacing.hh"
#include "group-interface.hh"
#include "accidental-placement.hh"
+#include "translator-group.hh"
+
struct Spacings
{
}
};
+
class Separating_line_group_engraver : public Engraver
{
protected:
- Item * break_malt_;
- Item * musical_malt_;
- Item * last_musical_malt_;
+ Item * break_item_;
+ Item * musical_item_;
+ Item * last_musical_item_;
Spacings current_spacings_;
Spacings last_spacings_;
Separating_line_group_engraver::Separating_line_group_engraver ()
{
sep_span_ = 0;
- break_malt_ = 0;
- musical_malt_ =0;
+ break_item_ = 0;
+ musical_item_ =0;
}
void
}
bool ib =Item::breakable_b (it);
- Item *&p_ref_ (ib ? break_malt_
- : musical_malt_);
+ Item *&p_ref_ (ib ? break_item_
+ : musical_item_);
if (!p_ref_)
{
p_ref_ = new Item (get_property ("SeparationItem"));
if (ib)
- p_ref_->set_grob_property ("breakable", SCM_BOOL_T);
+ {
+ p_ref_->set_grob_property ("breakable", SCM_BOOL_T);
+ daddy_trans_->set_property ("breakableSeparationItem", p_ref_->self_scm ());
+ }
announce_grob(p_ref_, SCM_EOL);
- if (p_ref_ == break_malt_)
+ if (p_ref_ == break_item_)
{
Item *it = new Item (get_property ("StaffSpacing"));
current_spacings_.staff_spacing_ = it;
- it->set_grob_property ("left-items", gh_cons (break_malt_->self_scm (), SCM_EOL));
+ it->set_grob_property ("left-items", gh_cons (break_item_->self_scm (), SCM_EOL));
announce_grob(it, SCM_EOL);
for (; i--;)
Pointer_group_interface::add_grob (last_spacings_.note_spacings_[i],
ly_symbol2scm ("right-items"),
- break_malt_);
+ break_item_);
}
else if (last_spacings_.staff_spacing_)
{
last_spacings_.staff_spacing_->set_grob_property ("right-items",
- gh_cons (break_malt_->self_scm(), SCM_EOL));
+ gh_cons (break_item_->self_scm(), SCM_EOL));
}
}
}
void
Separating_line_group_engraver::start_translation_timestep ()
{
-
+ if (break_item_)
+ daddy_trans_->unset_property (ly_symbol2scm ("breakableSeparationItem"));
+ break_item_ =0;
}
void
Separating_line_group_engraver::stop_translation_timestep ()
{
- if (break_malt_)
+ if (break_item_)
{
- Separating_group_spanner::add_spacing_unit (sep_span_, break_malt_);
- typeset_grob (break_malt_);
-
- break_malt_ =0;
+ Separating_group_spanner::add_spacing_unit (sep_span_, break_item_);
+ typeset_grob (break_item_);
}
if (Item * sp = current_spacings_.staff_spacing_)
TODO: should really look at the left-items of following
note-spacing grobs.
*/
- if (musical_malt_)
+ if (musical_item_)
Pointer_group_interface::add_grob (sp, ly_symbol2scm ("right-items"),
- musical_malt_);
+ musical_item_);
typeset_grob (sp);
}
current_spacings_.clear ();
- if (musical_malt_)
+ if (musical_item_)
{
- Separating_group_spanner::add_spacing_unit (sep_span_, musical_malt_);
- typeset_grob (musical_malt_);
+ Separating_group_spanner::add_spacing_unit (sep_span_, musical_item_);
+ typeset_grob (musical_item_);
}
- musical_malt_ =0;
+ musical_item_ =0;
}
/* accepts */ "",
/* acks */ "item-interface",
/* reads */ "",
-/* write */ "");
+/* write */ "breakableSeparationItem");
return w;
}
+Interval
+Separation_item::relative_width (Grob * me, Grob * common)
+{
+ Interval iv = width (me);
+
+ return dynamic_cast<Item*>(me)->get_column ()->relative_coordinate (common, X_AXIS) + iv ;
+}
+
/*
Try to find the break-aligned symbol in SEPARATION_ITEM that is
/* creats*/ "RepeatSlash",
/* accepts */ "repeated-music",
/* acks */ "",
-/* reads */ "measureLength currentCommandColumn",
+/* reads */ "measureLength",
/* write */ "");
gh_pair_p (s); s = ly_cdr (s))
{
Grob * g = unsmob_grob (ly_car (s));
- if (Spacing_interface::has_interface (g))
+ if (g->internal_has_interface ("only-prebreak-interface"))
{
/*
Kill no longer needed grobs.
Timing_translator::stop_translation_timestep ();
daddy_trans_->set_property ("whichBar", SCM_EOL);
last_moment_ = now_mom ();
-
}
"Note name"
'(style))
+(ly:add-interface
+ 'only-prebreak-interface
+ "Kill this grob after the line breaking process."
+ '() )
+
+(ly:add-interface
+ 'piano-pedal-interface
+ "A piano pedal sign"
+ '())
+
+
(ly:add-interface
'rhythmic-grob-interface
"Any object with a rhythmic basis. Used to determine which grobs
"tablature notes"
'())
-(ly:add-interface
- 'piano-pedal-interface
- "A piano pedal sign"
- '())
-
;; todo: figure out where to put this doco:
(SeparationItem
. (
+ (X-extent-callback . #f)
+ (Y-extent-callback . #f)
(meta . ((interfaces . (spacing-interface separation-item-interface item-interface ))))
))
(SeparatingGroupSpanner
. (
(spacing-procedure . ,Separating_group_spanner::set_spacing_rods)
- (meta . ((interfaces . (spacing-interface separation-spanner-interface spanner-interface))))
+ (meta . ((interfaces . (only-prebreak-interface spacing-interface separation-spanner-interface spanner-interface))))
))
(SustainPedal
(translator-property-description 'beatGrouping list?
"List of beatgroups. Eg. in 5/8 time #(list 2 3).")
+
+(translator-property-description 'breakableSeparationItem ly:grob?
+"The breakable items in this time step, for this staff.")
+
(translator-property-description 'breakAlignOrder list? "Defines the order in which
prefatory matter (clefs, key signatures) appears, eg. this puts the
key signatures after the bar lines: