positions, one for above the staff, one for below).
In each pass, we loop through the unplaced grobs from left to right.
- If the grob overlaps the right-most affected position, we place it
+ If the grob doesn't overlap the right-most affected position, we place it
(and then update the right-most affected position to point to the right
edge of the just-placed grob). Otherwise, we skip it until the next pass.
*/
+++ /dev/null
-/*
- separating-group-spanner.hh -- declare Separating_group_spanner
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1998--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
-*/
-
-#ifndef SEPARATING_GROUP_SPANNER_HH
-#define SEPARATING_GROUP_SPANNER_HH
-
-#include "grob-interface.hh"
-#include "lily-proto.hh"
-
-class Separating_group_spanner
-{
- static void find_rods (Item *,
- vector<Grob*> const &separators,
- vsize idx,
- Real);
-public:
- static void add_spacing_unit (Grob *me, Item *);
-
- DECLARE_GROB_INTERFACE();
- DECLARE_SCHEME_CALLBACK (set_spacing_rods, (SCM));
-};
-
-#endif /* SEPARATING_GROUP_SPANNER_HH */
-
static vector<Box> boxes (Grob *me, Grob *left);
static Skyline conditional_skyline (Grob *, Grob *);
- static Interval width (Grob *);
- static Interval relative_width (Grob *, Grob *);
static Grob *extremal_break_aligned_grob (Grob *, Direction, Interval *);
- static bool set_distance (Drul_array<Item *>, Real);
- static void set_skyline_distance (Drul_array<Item*>, Real);
+ static void set_distance (Drul_array<Item *>, Real);
+ static bool is_empty (Grob *me);
static void add_item (Grob *, Item *);
static void add_conditional_item (Grob *, Grob *);
};
{
Item *b = sp->get_bound (d);
- Interval coldim = (Separation_item::has_interface (b))
- ? Separation_item::relative_width (b, common)
- : b->extent (common, X_AXIS);
+ Interval coldim = b->extent (common, X_AXIS);
sp_iv[d] = coldim.is_empty () ? b->relative_coordinate (common, X_AXIS) : coldim[-d];
}
#include "paper-column-engraver.hh"
#include "system.hh"
#include "international.hh"
+#include "accidental-placement.hh"
#include "axis-group-interface.hh"
#include "context.hh"
#include "note-spacing.hh"
#include "paper-column.hh"
#include "pointer-group-interface.hh"
+#include "separation-item.hh"
#include "staff-spacing.hh"
#include "system.hh"
#include "warn.hh"
for (vsize i = 0; i < items_.size (); i++)
{
Item *elem = items_[i];
+ Grob *col = Item::is_non_musical (elem) ? command_column_ : musical_column_;
+
if (!elem->get_parent (X_AXIS)
|| !unsmob_grob (elem->get_object ("axis-group-parent-X")))
{
- bool br = Item::is_non_musical (elem);
- Axis_group_interface::add_element (br ? command_column_ : musical_column_, elem);
+ Axis_group_interface::add_element (col, elem);
}
+ else if (Accidental_placement::has_interface (elem))
+ Separation_item::add_conditional_item (col, elem);
+ else
+ Separation_item::add_item (col, elem);
}
items_.clear ();
Direction d = LEFT;
do
{
- skys[d].set_minimum_height (0.0);
- extract_grob_set (cols[d], "elements", elts);
-
- for (vsize i = 0; i < elts.size (); i++)
- if (Separation_item::has_interface (elts[i]))
- {
- Skyline_pair *sp = Skyline_pair::unsmob (elts[i]->get_property ("horizontal-skylines"));
- if (sp)
- skys[d].merge ((*sp)[-d]);
- }
+ Skyline_pair *sp = Skyline_pair::unsmob (cols[d]->get_property ("horizontal-skylines"));
+ if (sp)
+ skys[d] = (*sp)[-d];
}
while (flip (&d) != LEFT);
+++ /dev/null
-/*
- separating-group-spanner.cc -- implement Separating_group_spanner
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1998--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
-*/
-
-#include "separating-group-spanner.hh"
-
-#include "separation-item.hh"
-#include "paper-column.hh"
-#include "output-def.hh"
-#include "dimensions.hh"
-#include "pointer-group-interface.hh"
-#include "moment.hh"
-
-void
-Separating_group_spanner::find_rods (Item *r,
- vector<Grob*> const &separators,
- vsize idx,
- Real padding)
-{
-
- /*
- This is an inner loop: look for the first normal (unbroken) Left
- grob. This looks like an inner loop (ie. quadratic total), but in
- most cases, the interesting L will just be the first entry of
- NEXT, making it linear in most of the cases.
- */
- for (; idx != VPOS; idx--)
- {
- Item *l = dynamic_cast<Item *> (separators[idx]);
- Item *lb = l->find_prebroken_piece (RIGHT);
-
- if (lb)
- {
- Separation_item::set_distance (Drul_array<Item*> (lb, r), padding);
- }
-
- if (Separation_item::set_distance (Drul_array<Item *> (l, r), padding)
- /*
- This check is because grace notes are set very tight, and
- the accidentals of main note may stick out so far to cover
- a barline preceding the grace note.
- */
- && spanned_time_interval (l, r).length ().main_part_ > Rational (0))
- break;
-
- /*
- this grob doesn't cause a constraint. We look further until we
- find one that does.
- */
- }
-}
-
-MAKE_SCHEME_CALLBACK (Separating_group_spanner, set_spacing_rods, 1);
-SCM
-Separating_group_spanner::set_spacing_rods (SCM smob)
-{
- Grob *me = unsmob_grob (smob);
-
- /*
- Ugh: padding is added doubly, also for SeparationItem
- */
- Real padding = robust_scm2double (me->get_property ("padding"), 0.1);
-
- extract_grob_set (me, "elements", elts);
- for (vsize i = elts.size (); i-- > 1;)
- {
- Item *r = dynamic_cast<Item *> (elts[i]);
- if (!r)
- continue;
-
- if (Separation_item::width (r).is_empty ())
- continue;
-
- Item *rb
- = dynamic_cast<Item *> (r->find_prebroken_piece (LEFT));
-
- find_rods (r, elts, i - 1, padding);
- if (rb)
- find_rods (rb, elts, i - 1, padding);
- }
-
- return SCM_UNSPECIFIED;
-}
-
-void
-Separating_group_spanner::add_spacing_unit (Grob *me, Item *i)
-{
- Pointer_group_interface::add_unordered_grob (me, ly_symbol2scm ("elements"), i);
-}
-
-ADD_INTERFACE (Separating_group_spanner,
- "A spanner that calculates spacing constraints (\"rods\") "
- "using the @code{separation-item-interface} grobs in @code{elements}.",
-
- /* properties */
- "elements "
- "padding ");
#include "engraver.hh"
-#include "separating-group-spanner.hh"
#include "separation-item.hh"
#include "paper-column.hh"
#include "output-def.hh"
Spacings current_spacings_;
Spacings last_spacings_;
- Spanner *sep_span_;
-
DECLARE_ACKNOWLEDGER (item);
- void process_music ();
- virtual void finalize ();
void stop_translation_timestep ();
void start_translation_timestep ();
public:
Separating_line_group_engraver::Separating_line_group_engraver ()
{
- sep_span_ = 0;
break_item_ = 0;
musical_item_ = 0;
}
-void
-Separating_line_group_engraver::process_music ()
-{
- if (!sep_span_)
- {
- sep_span_ = make_spanner ("SeparatingGroupSpanner", SCM_EOL);
-
- sep_span_->set_bound (LEFT, unsmob_grob (get_property ("currentCommandColumn")));
- }
-}
-void
-Separating_line_group_engraver::finalize ()
-{
- if (!sep_span_)
- return;
-
- SCM ccol = get_property ("currentCommandColumn");
- Grob *column = unsmob_grob (ccol);
-
- sep_span_->set_bound (RIGHT, unsmob_grob (ccol));
- sep_span_ = 0;
-
- if (last_spacings_.staff_spacing_
- && last_spacings_.staff_spacing_->get_column () == column)
- last_spacings_.staff_spacing_->suicide ();
-}
-
void
Separating_line_group_engraver::acknowledge_item (Grob_info i)
{
void
Separating_line_group_engraver::stop_translation_timestep ()
{
- if (break_item_)
- Separating_group_spanner::add_spacing_unit (sep_span_, break_item_);
-
if (Item *sp = current_spacings_.staff_spacing_)
{
/*
current_spacings_.clear ();
- if (musical_item_)
- Separating_group_spanner::add_spacing_unit (sep_span_, musical_item_);
-
musical_item_ = 0;
}
}
void
-Separation_item::set_skyline_distance (Drul_array<Item *> items,
+Separation_item::set_distance (Drul_array<Item *> items,
Real padding)
{
Drul_array<Skyline_pair*> lines (Skyline_pair::unsmob (items[LEFT]->get_property ("horizontal-skylines")),
}
bool
-Separation_item::set_distance (Drul_array<Item *> items,
- Real padding)
+Separation_item::is_empty (Grob *me)
{
- set_skyline_distance (items, padding);
- return true;
+ Skyline_pair *sky = Skyline_pair::unsmob (me->get_property ("horizontal-skylines"));
+ return (!sky || sky->is_empty ());
}
/*
return out;
}
-Interval
-Separation_item::width (Grob *me)
-{
- SCM sw = me->get_property ("X-extent");
- return ly_scm2interval (sw);
-}
-
-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
sticking out at direction D. The x size is put in LAST_EXT
bool
Skyline::is_empty () const
{
- return buildings_.empty ();
+ Building b = buildings_.front ();
+ return b.end_ == infinity_f && b.y_intercept_ == -infinity_f;
}
Skyline_pair::Skyline_pair ()
#include "paper-column.hh"
#include "paper-score.hh"
#include "pointer-group-interface.hh"
+#include "separation-item.hh"
#include "spaceable-grob.hh"
#include "spacing-interface.hh"
#include "staff-spacing.hh"
}
}
+static void
+set_column_rods (vector<Grob*> const &cols, vsize idx, Real padding)
+{
+
+ /*
+ This is an inner loop: look for the first normal (unbroken) Left
+ grob. This looks like an inner loop (ie. quadratic total), but in
+ most cases, the interesting L will just be the first entry of
+ NEXT, making it linear in most of the cases.
+ */
+ Item *r = dynamic_cast<Item*> (cols[idx]);
+
+ if (Separation_item::is_empty (r))
+ return;
+
+ for (; idx != VPOS; idx--)
+ {
+ Item *l = dynamic_cast<Item*> (cols[idx]);
+ Item *lb = l->find_prebroken_piece (RIGHT);
+
+ if (Separation_item::is_empty (l) && (!lb || Separation_item::is_empty (lb)))
+ continue;
+
+ Separation_item::set_distance (Drul_array<Item *> (l, r), padding);
+ if (lb)
+ Separation_item::set_distance (Drul_array<Item*> (lb, r), padding);
+
+
+ /*
+ This check is because grace notes are set very tight, and
+ the accidentals of main note may stick out so far to cover
+ a barline preceding the grace note.
+ */
+ if (spanned_time_interval (l, r).length ().main_part_ > Rational (0))
+ break;
+
+ /*
+ this grob doesn't cause a constraint. We look further until we
+ find one that does.
+ */
+ }
+}
+
void
Spacing_spanner::generate_springs (Grob *me,
vector<Grob*> const &cols,
Paper_column *next = (i + 1 < cols.size ()) ? dynamic_cast<Paper_column *> (cols[i+1]) : 0;
if (i > 0)
- generate_pair_spacing (me, prev, col, next, options);
+ {
+ generate_pair_spacing (me, prev, col, next, options);
+ set_column_rods (cols, i, 0.1); // FIXME
+ }
prev = col;
}
ideal = fixed;
}
+ Grob *left_col = dynamic_cast<Item*> (me)->get_column ();
Real optical_correction = next_notes_correction (me, last_grob);
- Real min_dist = Spacing_interface::minimum_distance (me, right_col);
+ Real min_dist = Paper_column::minimum_distance (left_col, right_col);
/* ensure that the "fixed" distance will leave a gap of at least 0.3 ss. */
Real min_dist_correction = max (0.0, 0.3 + min_dist - fixed);
(axes . (0))
(before-line-breaking . ,ly:paper-column::before-line-breaking)
(X-extent . ,ly:axis-group-interface::width)
+ (horizontal-skylines . ,ly:separation-item::calc-skylines)
;; (stencil . ,ly:paper-column::print)
(non-musical . #t)
(axes . (0))
(allow-loose-spacing . #t)
(before-line-breaking . ,ly:paper-column::before-line-breaking)
+ (horizontal-skylines . ,ly:separation-item::calc-skylines)
;; (stencil . ,ly:paper-column::print)
(X-extent . ,ly:axis-group-interface::width)
(interfaces . (
separation-item-interface))))))
- (SeparatingGroupSpanner
- . (
- (springs-and-rods . ,ly:separating-group-spanner::set-spacing-rods)
- (meta . ((class . Spanner)
- (interfaces . (only-prebreak-interface
-
- separating-group-spanner-interface))))))
-
(Slur
. ((details . ,default-slur-details)
(control-points . ,ly:slur::calc-control-points)
ly:piano-pedal-bracket::print
ly:rest::print
ly:script-interface::print
- ly:separating-group-spanner::set-spacing-rods
ly:slur::height
ly:slur::print
ly:spacing-spanner::set-springs