source file of the GNU LilyPond music typesetter
- (c) 2000--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ (c) 2000--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
#include "align-interface.hh"
-#include "spanner.hh"
-#include "item.hh"
#include "axis-group-interface.hh"
-#include "pointer-group-interface.hh"
-#include "hara-kiri-group-spanner.hh"
#include "grob-array.hh"
+#include "hara-kiri-group-spanner.hh"
#include "international.hh"
+#include "item.hh"
+#include "paper-column.hh"
+#include "pointer-group-interface.hh"
+#include "spanner.hh"
+#include "skyline-pair.hh"
#include "system.hh"
#include "warn.hh"
-#include "paper-column.hh"
/*
TODO: for vertical spacing, should also include a rod & spring
bool pure, int start, int end,
vector<Skyline_pair> *const ret)
{
- /* each child's skyline was calculated according to the common refpoint of its
- elements. Here we need all the skylines to be positioned with respect to
- a single refpoint, so we need the common refpoint of the common refpoints
- of the elements of the children */
- vector<Grob*> child_refpoints;
- for (vsize i = 0; i < elements->size (); i++)
- {
- Grob *elt = (*elements)[i];
- Grob *child_common = unsmob_grob ((a == Y_AXIS)
- ? elt->get_object ("X-common")
- : elt->get_object ("Y-common"));
-
- if (!child_common)
- {
- extract_grob_set (elt, "elements", child_elts);
- child_common = common_refpoint_of_array (child_elts, elt, other_axis (a));
- }
-
- child_refpoints.push_back (child_common);
- }
- Grob *common_refpoint = common_refpoint_of_array (child_refpoints, me, other_axis (a));
+ Grob *other_common = common_refpoint_of_array (*elements, me, other_axis (a));
for (vsize i = elements->size (); i--;)
{
Grob *g = (*elements)[i];
Skyline_pair skylines;
- /* each skyline is calculated relative to (potentially) a different other_axis
- coordinate. In order to compare the skylines effectively, we need to shift them
- to some absolute reference point */
if (!pure)
{
- Skyline_pair *skys = Skyline_pair::unsmob (g->get_property ("skylines"));
+ Skyline_pair *skys = Skyline_pair::unsmob (g->get_property (a == Y_AXIS
+ ? "vertical-skylines"
+ : "horizontal-skylines"));
if (skys)
skylines = *skys;
if (is_number_pair (min_extent))
{
Box b;
- Interval other_extent = g->extent (common_refpoint, other_axis (a));
+ Interval other_extent = g->extent (other_common, other_axis (a));
b[a] = ly_scm2interval (min_extent);
b[other_axis (a)] = other_extent;
if (!other_extent.is_empty ())
skylines.insert (b, 0, other_axis (a));
}
- Real offset = child_refpoints[i]->relative_coordinate (common_refpoint, other_axis (a));
+ /* This skyline was calculated relative to the grob g. In order to compare it to
+ skylines belonging to other grobs, we need to shift it so that it is relative
+ to the common reference. */
+ Real offset = g->relative_coordinate (other_common, other_axis (a));
skylines.shift (offset);
}
else
line_break_details = me_spanner->get_bound (LEFT)->get_property ("line-break-system-details");
if (!me->get_system () && !pure)
- me->warning (_ ("vertical alignment called before line-breaking.\n"
- "Only do cross-staff spanners with PianoStaff."));
-
+ me->programming_error ("vertical alignment called before line-breaking");
}
Direction stacking_dir = robust_scm2dir (me->get_property ("stacking-dir"),
dy = down_skyline.distance (skylines[j][-stacking_dir]);
}
+ if (isinf (dy)) /* if the skyline is empty, maybe max_height is infinity_f */
+ dy = 0.0;
+
dy = max (0.0, dy + padding + extra_space / elems.size ());
down_skyline.raise (-stacking_dir * dy);
where += stacking_dir * dy;
Real non_empty_elts = stretchable_children_count (me);
Real offset = 0.0;
Direction dir = robust_scm2dir (me->get_property ("stacking-dir"), DOWN);
- for (vsize i = 0; i < elts.size (); i++)
+ for (vsize i = 1; i < elts.size (); i++)
{
- elts[i]->translate_axis (dir * offset, a);
if (!elts[i]->extent (me, a).is_empty ()
&& !to_boolean (elts[i]->get_property ("keep-fixed-while-stretching")))
offset += amount / non_empty_elts;
+ elts[i]->translate_axis (dir * offset, a);
}
me->flush_extent_cache (Y_AXIS);
}
}
ADD_INTERFACE (Align_interface,
+ "Order grobs from top to bottom, left to right, right to left"
+ " or bottom to top. For vertical alignments of staves, the"
+ " @code{break-system-details} of the left"
+ " @rinternals{NonMusicalPaperColumn} may be set to tune"
+ " vertical spacing. Set @code{alignment-extra-space} to add"
+ " extra space for staves. Set"
+ " @code{fixed-alignment-extra-space} to force staves in"
+ " @code{PianoStaff}s further apart.",
- "Order grobs from top to bottom, left to right, right to left or bottom "
- "to top. "
- "For vertical alignments of staves, the @code{break-system-details} of "
- "the left @internalsref{NonMusicalPaperColumn} may be set to tune vertical spacing "
- "Set @code{alignment-extra-space} to add extra space for staves. Set "
- "@code{fixed-alignment-extra-space} to force staves in PianoStaves further apart."
- ,
-
- /*
- properties
- */
+ /* properties */
"align-dir "
"axes "
"elements "