/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 2000--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ Copyright (C) 2000--2015 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
return default_outside_staff_padding_;
}
-MAKE_SCHEME_CALLBACK (Axis_group_interface, cross_staff, 1);
-SCM
-Axis_group_interface::cross_staff (SCM smob)
-{
- Grob *me = unsmob_grob (smob);
- extract_grob_set (me, "elements", elts);
- for (vsize i = 0; i < elts.size (); i++)
- if (to_boolean (elts[i]->get_property ("cross-staff")))
- return SCM_BOOL_T;
-
- return SCM_BOOL_F;
-}
-
void
Axis_group_interface::add_element (Grob *me, Grob *e)
{
{
SCM axes = me->get_property ("axes");
- return (SCM_BOOL_F != scm_memq (scm_from_int (a), axes));
+ return scm_is_true (scm_memq (scm_from_int (a), axes));
}
Interval
for (vsize i = 0; i < elts.size (); i++)
{
Grob *se = elts[i];
- if (has_interface (se)
- || !to_boolean (se->get_property ("cross-staff")))
+ if (!to_boolean (se->get_property ("cross-staff")))
{
- Interval dims = (bound && has_interface (se)
+ Interval dims = (bound && has_interface<Axis_group_interface> (se)
? generic_bound_extent (se, common, a)
: se->extent (common, a));
if (!dims.is_empty ())
Axis_group_interface::part_of_line_pure_height (Grob *me, bool begin, int start, int end)
{
Spanner *sp = dynamic_cast<Spanner *> (me);
+ if (!sp)
+ return Interval (0, 0);
SCM cache_symbol = begin
? ly_symbol2scm ("begin-of-line-pure-height")
: ly_symbol2scm ("rest-of-line-pure-height");
SCM
Axis_group_interface::adjacent_pure_heights (SCM smob)
{
- Grob *me = unsmob_grob (smob);
+ Grob *me = unsmob<Grob> (smob);
- Grob *common = unsmob_grob (me->get_object ("pure-Y-common"));
+ Grob *common = unsmob<Grob> (me->get_object ("pure-Y-common"));
extract_grob_set (me, "pure-relevant-grobs", elts);
Paper_score *ps = get_root_system (me)->paper_score ();
{
Grob *g = elts[i];
- if (to_boolean (g->get_property ("cross-staff"))
- && !has_interface (g))
+ if (to_boolean (g->get_property ("cross-staff")))
+ continue;
+
+ if (!g->is_live ())
continue;
bool outside_staff = scm_is_number (g->get_property ("outside-staff-priority"));
if (g->pure_is_visible (start, visibility_end))
{
- Interval dims = g->pure_height (common, start, end);
+ Interval dims = g->pure_y_extent (common, start, end);
if (!dims.is_empty ())
{
if (rank_span[LEFT] <= start)
reasonably safe to assume that if our parent is a VerticalAlignment,
we can assume additivity and cache things nicely. */
Grob *p = me->get_parent (Y_AXIS);
- if (p && Align_interface::has_interface (p))
+ if (has_interface<Align_interface> (p))
return Axis_group_interface::sum_partial_pure_heights (me, start, end);
- Grob *common = unsmob_grob (me->get_object ("pure-Y-common"));
+ Grob *common = unsmob<Grob> (me->get_object ("pure-Y-common"));
extract_grob_set (me, "pure-relevant-grobs", elts);
Interval r;
if (rank_span[LEFT] <= end && rank_span[RIGHT] >= start
&& g->pure_is_visible (start, end)
&& !(to_boolean (g->get_property ("cross-staff"))
- && Stem::has_interface (g)))
+ && has_interface<Stem> (g)))
{
- Interval dims = g->pure_height (common, start, end);
+ Interval dims = g->pure_y_extent (common, start, end);
if (!dims.is_empty ())
r.unite (dims);
}
SCM
Axis_group_interface::width (SCM smob)
{
- Grob *me = unsmob_grob (smob);
+ Grob *me = unsmob<Grob> (smob);
return generic_group_extent (me, X_AXIS);
}
SCM
Axis_group_interface::height (SCM smob)
{
- Grob *me = unsmob_grob (smob);
+ Grob *me = unsmob<Grob> (smob);
return generic_group_extent (me, Y_AXIS);
}
{
int start = robust_scm2int (start_scm, 0);
int end = robust_scm2int (end_scm, INT_MAX);
- Grob *me = unsmob_grob (smob);
+ Grob *me = unsmob<Grob> (smob);
/* Maybe we are in the second pass of a two-pass spacing run. In that
case, the Y-extent of a system is already given to us */
SCM
Axis_group_interface::calc_skylines (SCM smob)
{
- Grob *me = unsmob_grob (smob);
+ Grob *me = unsmob<Grob> (smob);
Skyline_pair skylines = skyline_spacing (me);
return skylines.smobbed_copy ();
}
SCM
Axis_group_interface::combine_skylines (SCM smob)
{
- Grob *me = unsmob_grob (smob);
+ Grob *me = unsmob<Grob> (smob);
extract_grob_set (me, "elements", elements);
Grob *y_common = common_refpoint_of_array (elements, me, Y_AXIS);
Grob *x_common = common_refpoint_of_array (elements, me, X_AXIS);
for (vsize i = 0; i < elements.size (); i++)
{
SCM skyline_scm = elements[i]->get_property ("vertical-skylines");
- if (Skyline_pair::unsmob (skyline_scm))
+ if (unsmob<Skyline_pair> (skyline_scm))
{
Real offset = elements[i]->relative_coordinate (y_common, Y_AXIS);
- Skyline_pair other = *Skyline_pair::unsmob (skyline_scm);
+ Skyline_pair other = *unsmob<Skyline_pair> (skyline_scm);
other.raise (offset);
other.shift (elements[i]->relative_coordinate (x_common, X_AXIS));
ret.merge (other);
/* trigger the callback to do skyline-spacing on the children */
if (a == Y_AXIS)
for (vsize i = 0; i < elts.size (); i++)
- (void) elts[i]->get_property ("vertical-skylines");
+ if (!(has_interface<Stem> (elts[i])
+ && to_boolean (elts[i]->get_property ("cross-staff"))))
+ (void) elts[i]->get_property ("vertical-skylines");
Grob *common = common_refpoint_of_array (elts, me, a);
SCM
Axis_group_interface::calc_pure_relevant_grobs (SCM smob)
{
- Grob *me = unsmob_grob (smob);
+ Grob *me = unsmob<Grob> (smob);
+ /* TODO: Filter out elements that belong to a different Axis_group,
+ such as the tie in
+ << \new Staff=A { c'1~ \change Staff=B c'}
+ \new Staff=B { \clef bass R1 R } >>
+ because thier location relative to this Axis_group is not known before
+ page layout. For now, we need to trap this case in calc_pure_y_common.
+ */
return internal_calc_pure_relevant_grobs (me, "elements");
}
SCM
-Axis_group_interface::internal_calc_pure_relevant_grobs (Grob *me, string grob_set_name)
+Axis_group_interface::internal_calc_pure_relevant_grobs (Grob *me, const 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?");
for (vsize i = 0; i < elts.size (); i++)
{
- if (to_boolean (scm_apply_1 (pure_relevant_p, elts[i]->self_scm (), SCM_EOL)))
+ if (elts[i] && elts[i]->is_live ())
relevant_grobs.push_back (elts[i]);
-
+ /*
+ TODO (mikesol): it is probably bad that we're reading prebroken
+ pieces from potentially suicided elements. This behavior
+ has been in current master since at least 2.16.
+
+ We need to fully suicide all Items, meaning that their
+ prebroken pieces should not be accessible, which means that
+ Item::handle_prebroken_dependencies should only be called
+ AFTER this list is composed. The list composition function
+ should probably not check for suicided items or NULL pointers
+ but leave that to the various methods that use it.
+ */
if (Item *it = dynamic_cast<Item *> (elts[i]))
{
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)))
+ if (piece && piece->is_live ())
relevant_grobs.push_back (piece);
}
}
vector_sort (relevant_grobs, pure_staff_priority_less);
SCM grobs_scm = Grob_array::make_array ();
- unsmob_grob_array (grobs_scm)->set_array (relevant_grobs);
+ unsmob<Grob_array> (grobs_scm)->set_array (relevant_grobs);
return grobs_scm;
}
SCM
Axis_group_interface::calc_pure_y_common (SCM smob)
{
- Grob *me = unsmob_grob (smob);
+ Grob *me = unsmob<Grob> (smob);
extract_grob_set (me, "pure-relevant-grobs", elts);
Grob *common = common_refpoint_of_array (elts, me, Y_AXIS);
+ if (common != me && has_interface<Align_interface> (common))
+ {
+ me->programming_error("My pure_y_common is a VerticalAlignment,"
+ " which might contain several staves.");
+ common = me;
+ }
if (!common)
{
me->programming_error ("No common parent found in calc_pure_y_common.");
SCM
Axis_group_interface::calc_x_common (SCM grob)
{
- return calc_common (unsmob_grob (grob), X_AXIS);
+ return calc_common (unsmob<Grob> (grob), X_AXIS);
}
MAKE_SCHEME_CALLBACK (Axis_group_interface, calc_y_common, 1);
SCM
Axis_group_interface::calc_y_common (SCM grob)
{
- return calc_common (unsmob_grob (grob), Y_AXIS);
+ return calc_common (unsmob<Grob> (grob), Y_AXIS);
}
Interval
Axis_group_interface::pure_group_height (Grob *me, int start, int end)
{
- Grob *common = unsmob_grob (me->get_object ("pure-Y-common"));
+ Grob *common = unsmob<Grob> (me->get_object ("pure-Y-common"));
if (!common)
{
programming_error ("no pure Y common refpoint");
return Interval ();
}
- Real my_coord = me->relative_coordinate (common, Y_AXIS);
+ Real my_coord = me->pure_relative_y_coordinate (common, start, end);
Interval r (relative_pure_height (me, start, end));
return r - my_coord;
{
found->push_back (me);
- if (!has_interface (me))
+ if (!has_interface<Axis_group_interface> (me))
return;
extract_grob_set (me, "elements", elements);
static void
add_interior_skylines (Grob *me, Grob *x_common, Grob *y_common, vector<Skyline_pair> *skylines)
{
- if (Grob_array *elements = unsmob_grob_array (me->get_object ("elements")))
+ if (Grob_array *elements = unsmob<Grob_array> (me->get_object ("elements")))
{
for (vsize i = 0; i < elements->size (); i++)
add_interior_skylines (elements->grob (i), x_common, y_common, skylines);
else if (!scm_is_number (me->get_property ("outside-staff-priority"))
&& !to_boolean (me->get_property ("cross-staff")))
{
- Skyline_pair *maybe_pair = Skyline_pair::unsmob (me->get_property ("vertical-skylines"));
+ Skyline_pair *maybe_pair = unsmob<Skyline_pair> (me->get_property ("vertical-skylines"));
if (!maybe_pair)
return;
if (maybe_pair->is_empty ())
for (vsize j = 0; j < other_v_skylines.size (); j++)
{
Skyline_pair const &v_other = other_v_skylines[j];
- Real pad = (padding + other_padding[j]);
- Real horizon_pad = (horizon_padding + other_horizon_padding[j]);
+ Real pad = max (padding, other_padding[j]);
+ Real horizon_pad = max (horizon_padding, other_horizon_padding[j]);
// We need to push elt up by at least this much to be above v_other.
Real up = (*v_skyline)[DOWN].distance (v_other[UP], horizon_pad) + pad;
{
SCM directive = me->get_property ("outside-staff-placement-directive");
- if ((directive == ly_symbol2scm ("left-to-right-greedy"))
- || (directive == ly_symbol2scm ("left-to-right-polite"))
- || (directive == ly_symbol2scm ("right-to-left-greedy"))
- || (directive == ly_symbol2scm ("right-to-left-polite")))
+ if (scm_is_eq (directive, ly_symbol2scm ("left-to-right-greedy"))
+ || scm_is_eq (directive, ly_symbol2scm ("left-to-right-polite"))
+ || scm_is_eq (directive, ly_symbol2scm ("right-to-left-greedy"))
+ || scm_is_eq (directive, ly_symbol2scm ("right-to-left-polite")))
return directive;
me->warning (_f ("\"%s\" is not a valid outside-staff-placement-directive",
SCM directive
= valid_outside_staff_placement_directive (me);
- bool l2r = ((directive == ly_symbol2scm ("left-to-right-greedy"))
- || (directive == ly_symbol2scm ("left-to-right-polite")));
+ bool l2r = (scm_is_eq (directive, ly_symbol2scm ("left-to-right-greedy"))
+ || scm_is_eq (directive, ly_symbol2scm ("left-to-right-polite")));
- bool polite = ((directive == ly_symbol2scm ("left-to-right-polite"))
- || (directive == ly_symbol2scm ("right-to-left-polite")));
+ bool polite = (scm_is_eq (directive, ly_symbol2scm ("left-to-right-polite"))
+ || scm_is_eq (directive, ly_symbol2scm ("right-to-left-polite")));
vector<Box> boxes;
vector<Skyline_pair> skylines_to_merge;
{
Grob *elt = elements[i];
Real padding
- = robust_scm2double (elt->get_property ("outside-staff-padding"), 0.25);
+ = robust_scm2double (elt->get_property ("outside-staff-padding"),
+ Axis_group_interface
+ ::get_default_outside_staff_padding ());
Real horizon_padding
= robust_scm2double (elt->get_property ("outside-staff-horizontal-padding"), 0.0);
Interval x_extent = elt->extent (x_common, X_AXIS);
}
last_end[dir] = x_extent[RIGHT];
- Skyline_pair *v_orig = Skyline_pair::unsmob (elt->get_property ("vertical-skylines"));
- if (v_orig->is_empty ())
+ Skyline_pair *v_orig = unsmob<Skyline_pair> (elt->get_property ("vertical-skylines"));
+ if (!v_orig || v_orig->is_empty ())
continue;
// Find the riders associated with this grob, and merge their
for (GrobMapIterator j = range.first; j != range.second; j++)
{
Grob *rider = j->second;
- Skyline_pair *v_rider = Skyline_pair::unsmob (rider->get_property ("vertical-skylines"));
+ Skyline_pair *v_rider = unsmob<Skyline_pair> (rider->get_property ("vertical-skylines"));
if (v_rider)
{
Skyline_pair copy (*v_rider);
Skyline_pair
Axis_group_interface::skyline_spacing (Grob *me)
{
- extract_grob_set (me, Grob_array::unsmob (me->get_object ("vertical-skyline-elements")) ? "vertical-skyline-elements" : "elements", fakeelements);
+ extract_grob_set (me, unsmob<Grob_array> (me->get_object ("vertical-skyline-elements")) ? "vertical-skyline-elements" : "elements", fakeelements);
vector<Grob *> elements (fakeelements);
for (vsize i = 0; i < elements.size (); i++)
/*
Grob *x_common = common_refpoint_of_array (elements, me, X_AXIS);
Grob *y_common = common_refpoint_of_array (elements, me, Y_AXIS);
- assert (y_common == me);
+ if (y_common != me)
+ {
+ me->programming_error("Some of my vertical-skyline-elements"
+ " are outside my VerticalAxisGroup.");
+ y_common = me;
+ }
// A rider is a grob that is not outside-staff, but has an outside-staff
// ancestor. In that case, the rider gets moved along with its ancestor.
{
Grob *elt = elements[i];
Grob *ancestor = outside_staff_ancestor (elt);
- if (!ancestor)
+ if (!(to_boolean (elt->get_property ("cross-staff")) || ancestor))
add_interior_skylines (elt, x_common, y_common, &inside_staff_skylines);
if (ancestor)
riders.insert (pair<Grob *, Grob *> (ancestor, elt));
vector<Grob *> current_elts;
current_elts.push_back (elements[i]);
while (i + 1 < elements.size ()
- && scm_is_eq (elements[i + 1]->get_property ("outside-staff-priority"), priority))
+ && ly_is_equal (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]);
if (!debug_skylines)
return SCM_BOOL_F;
- Grob *me = unsmob_grob (smob);
+ Grob *me = unsmob<Grob> (smob);
Stencil ret;
- if (Skyline_pair *s = Skyline_pair::unsmob (me->get_property ("vertical-skylines")))
+ if (Skyline_pair *s = unsmob<Skyline_pair> (me->get_property ("vertical-skylines")))
{
ret.add_stencil (Lookup::points_to_line_stencil (0.1, (*s)[UP].to_points (X_AXIS))
.in_color (255, 0, 255));
SCM
Axis_group_interface::calc_pure_staff_staff_spacing (SCM smob, SCM start, SCM end)
{
- return calc_maybe_pure_staff_staff_spacing (unsmob_grob (smob),
+ return calc_maybe_pure_staff_staff_spacing (unsmob<Grob> (smob),
true,
scm_to_int (start),
scm_to_int (end));
SCM
Axis_group_interface::calc_staff_staff_spacing (SCM smob)
{
- return calc_maybe_pure_staff_staff_spacing (unsmob_grob (smob),
+ return calc_maybe_pure_staff_staff_spacing (unsmob<Grob> (smob),
false,
0,
INT_MAX);
SCM
Axis_group_interface::calc_maybe_pure_staff_staff_spacing (Grob *me, bool pure, int start, int end)
{
- Grob *grouper = unsmob_grob (me->get_object ("staff-grouper"));
+ Grob *grouper = unsmob<Grob> (me->get_object ("staff-grouper"));
if (grouper)
{
"bound-alignment-interfaces "
"default-staff-staff-spacing "
"elements "
- "max-stretch "
"no-alignment "
"nonstaff-nonstaff-spacing "
"nonstaff-relatedstaff-spacing "
"nonstaff-unrelatedstaff-spacing "
- "outside-staff-placement-directive "
"pure-relevant-grobs "
"pure-relevant-items "
"pure-relevant-spanners "
"staff-grouper "
"staff-staff-spacing "
"system-Y-offset "
- "vertical-skyline-elements "
"X-common "
"Y-common "
);