/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 2000--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ Copyright (C) 2000--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
LilyPond is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "separation-item.hh"
#include "skyline-pair.hh"
#include "staff-grouper-interface.hh"
+#include "stem.hh"
#include "stencil.hh"
#include "system.hh"
#include "warn.hh"
+#include "unpure-pure-container.hh"
static bool
pure_staff_priority_less (Grob *const &g1, Grob *const &g2);
Interval
Axis_group_interface::relative_group_extent (vector<Grob *> const &elts,
Grob *common, Axis a)
+{
+ return relative_maybe_bound_group_extent (elts, common, a, false);
+}
+
+Interval
+Axis_group_interface::relative_maybe_bound_group_extent (vector<Grob *> const &elts,
+ Grob *common, Axis a, bool bound)
{
Interval r;
for (vsize i = 0; i < elts.size (); i++)
Grob *se = elts[i];
if (!to_boolean (se->get_property ("cross-staff")))
{
- Interval dims = se->extent (common, a);
+ Interval dims = (bound && has_interface (se)
+ ? generic_bound_extent (se, common, a)
+ : se->extent (common, a));
if (!dims.is_empty ())
r.unite (dims);
}
return r;
}
+Interval
+Axis_group_interface::generic_bound_extent (Grob *me, Grob *common, Axis a)
+{
+ /* trigger the callback to do skyline-spacing on the children */
+ if (a == Y_AXIS)
+ (void) me->get_property ("vertical-skylines");
+
+ extract_grob_set (me, "elements", elts);
+ vector<Grob *> new_elts;
+
+ SCM interfaces = me->get_property ("bound-alignment-interfaces");
+
+ for (vsize i = 0; i < elts.size (); i++)
+ for (SCM l = interfaces; scm_is_pair (l); l = scm_cdr (l))
+ if (elts[i]->internal_has_interface (scm_car (l)))
+ new_elts.push_back (elts[i]);
+
+ if (!new_elts.size ())
+ return robust_relative_extent (me, common, a);
+
+ if (!common)
+ common = common_refpoint_of_array (new_elts, me, a);
+
+ return relative_maybe_bound_group_extent (new_elts, common, a, true);
+}
+
Interval
Axis_group_interface::sum_partial_pure_heights (Grob *me, int start, int end)
{
Interval_t<int> rank_span = g->spanned_rank_interval ();
if (rank_span[LEFT] <= end && rank_span[RIGHT] >= start
&& g->pure_is_visible (start, end)
- && !to_boolean (g->get_property ("cross-staff")))
+ && !(to_boolean (g->get_property ("cross-staff"))
+ && Stem::has_interface (g)))
{
Interval dims = g->pure_height (common, start, end);
if (!dims.is_empty ())
Axis_group_interface::calc_pure_relevant_grobs (SCM smob)
{
Grob *me = unsmob_grob (smob);
+ return internal_calc_pure_relevant_grobs (me, "elements");
+}
- extract_grob_set (me, "elements", elts);
+SCM
+Axis_group_interface::internal_calc_pure_relevant_grobs (Grob *me, string grob_set_name)
+{
+ extract_grob_set (me, grob_set_name.c_str (), elts);
vector<Grob *> relevant_grobs;
SCM pure_relevant_p = ly_lily_module_constant ("pure-relevant?");
if (Item *it = dynamic_cast<Item *> (elts[i]))
{
- Direction d = LEFT;
- do
+ for (LEFT_and_RIGHT (d))
{
Item *piece = it->find_prebroken_piece (d);
if (piece && to_boolean (scm_apply_1 (pure_relevant_p, piece->self_scm (), SCM_EOL)))
relevant_grobs.push_back (piece);
}
- while (flip (&d) != LEFT);
}
}
vector<Grob *> current_elts;
current_elts.push_back (elements[i]);
while (i + 1 < elements.size ()
- && scm_eq_p (elements[i + 1]->get_property ("outside-staff-priority"), priority))
+ && scm_is_eq (elements[i + 1]->get_property ("outside-staff-priority"), priority))
{
if (!to_boolean (elements[i + 1]->get_property ("cross-staff")))
current_elts.push_back (elements[i + 1]);
/* properties */
"adjacent-pure-heights "
"axes "
+ "bound-alignment-interfaces "
"default-staff-staff-spacing "
"elements "
"max-stretch "