#include "string-convert.hh"
#include "system.hh"
#include "warn.hh"
+#include "unpure-pure-container.hh"
void
Side_position_interface::add_support (Grob *me, Grob *e)
{
Grob *me = unsmob_grob (smob);
extract_grob_set (me, "side-support-elements", elts);
-// Commented out because of cross staff issues
-// Direction for cross staff stems depends on the spacing of staves,
-// which depends on the inclusion of cross-staff side position grobs,
-// which need the direction for positioning. So the get_grob_direction call
-// may lead to circular dependencies.
-// #if 0
+
Direction my_dir = get_grob_direction (me) ;
- // if a cross-staff grob is pointing in a different direction than
- // that of an aligning element, we assume that the alignment
- // of said element will not be influenced the cross-staffitude
- // of the grob and thus we do not mark the aligning element
- // as cross-staff
- for (vsize i = 0; i < elts.size (); i++)
- if (to_boolean (elts[i]->get_property ("cross-staff"))
- && my_dir == get_grob_direction (elts[i]))
- return SCM_BOOL_T;
-//#endif
-#if 0
for (vsize i = 0; i < elts.size (); i++)
- if (to_boolean (elts[i]->get_property ("cross-staff")))
- return SCM_BOOL_T;
-#endif
+ {
+ /*
+ If 'me' is placed relative to any cross-staff element with a
+ 'direction callback defined, the placement of 'me' is likely
+ to depend on staff-spacing, thus 'me' should be considered
+ cross-staff.
+ */
+ if (to_boolean (elts[i]->get_property ("cross-staff"))
+ && !is_direction (elts[i]->get_property_data ("direction")))
+ return SCM_BOOL_T;
+
+ /*
+ If elts[i] is cross-staff and is pointing in the same
+ direction as 'me', we assume that the alignment
+ of 'me' is influenced the cross-staffitude of elts[i]
+ and thus we mark 'me' as cross-staff.
+ */
+ if (to_boolean (elts[i]->get_property ("cross-staff"))
+ && my_dir == get_grob_direction (elts[i]))
+ return SCM_BOOL_T;
+ }
+
Grob *myvag = Grob::get_vertical_axis_group (me);
for (vsize i = 0; i < elts.size (); i++)
if (myvag != Grob::get_vertical_axis_group (elts[i]))
SCM
Side_position_interface::aligned_side (Grob *me, Axis a, bool pure, int start, int end,
Real *current_off)
-{//printf (" %s\n", me->name ().c_str ());
+{
Direction dir = get_grob_direction (me);
set<Grob *> support = get_support_set (me);
ax);
Grob *staff_symbol = Staff_symbol_referencer::get_staff_symbol (me);
+ bool quantize_position = to_boolean (me->get_maybe_pure_property ("quantize-position", pure, start, end));
bool include_staff
= staff_symbol
&& a == Y_AXIS
- && scm_is_number (me->get_property ("staff-padding"))
- && !to_boolean (me->get_property ("quantize-position"));
+ && scm_is_number (me->get_maybe_pure_property ("staff-padding", pure, start, end))
+ && !quantize_position;
if (include_staff)
common[Y_AXIS] = staff_symbol->common_refpoint (common[Y_AXIS], Y_AXIS);
for (it = support.begin (); it != support.end (); it++)
{
Grob *e = *it;
-//printf (" %s\n", e->name ().c_str ());
+
// In the case of a stem, we will find a note head as well
// ignoring the stem solves cyclic dependencies if the stem is
// attached to a cross-staff beam.
+ bool cross_staff = to_boolean (e->get_property ("cross-staff"));
+
+ // avoid cyclic dependency for direction
+ if (a == Y_AXIS
+ && pure
+ && Stem::has_interface (e)
+ && cross_staff
+ && !is_direction (e->get_property_data ("direction")))
+ continue;
+
+ // avoid unnecessary stem look up (if pointing away, it is not
+ // supporting anything)
if (a == Y_AXIS
&& Stem::has_interface (e)
&& dir == - get_grob_direction (e))
if (e)
{
- bool cross_staff = to_boolean (e->get_property ("cross-staff"));
Skyline_pair *sp = Skyline_pair::unsmob
(e->get_maybe_pure_property (a == X_AXIS
Skyline_pair copy = Skyline_pair (*sp);
if (a == Y_AXIS
&& Stem::has_interface (e)
- && to_boolean (me->get_property ("add-stem-support")))
+ && to_boolean (me->get_maybe_pure_property ("add-stem-support", pure, start, end)))
copy[dir].set_minimum_height (copy[dir].max_height ());
copy.shift (a == X_AXIS ? yc : xc);
copy.raise (a == X_AXIS ? xc : yc);
dim.set_minimum_height (staff_extents[dir]);
}
- // this seems kinda kludgy, as there is no apparent logic to it
- // however, it is a holdover from the previous code and
- // necessary for the InstrumentName grob
- // TODO: find a better way to deal with this...
+ // Sometimes, we want to side position for grobs but they
+ // don't position against anything. Some cases where this is true:
+ // - StanzaNumber if the supporting lyrics are hara-kiri'd
+ // SystemStartBracket
+ // InstrumentName
+ // In all these cases, we set the height of the support to 0.
+ // This becomes then like the self-alignment-interface with the
+ // caveat that there is padding added.
+ // TODO: if there is a grob that never has side-support-elements
+ // (like InstrumentName), why are we using this function? Isn't it
+ // overkill? A function like self-alignment-interface with padding
+ // works just fine.
+ // One could even imagine the two interfaces merged, as the only
+ // difference is that in self-alignment-interface we align on the parent
+ // where as here we align on a group of grobs.
if (dim.is_empty ())
{
dim = Skyline (dim.direction ());
dim.set_minimum_height (0.0);
}
- // Ditto - seems kludgy, but this time logic of SystemStartBrackets
- if (my_dim.is_empty ())
- {
- my_dim = Skyline (my_dim.direction ());
- my_dim.set_minimum_height (isinf (max_raise) ? 0.0 : max_raise);
- }
-
// Many cross-staff grobs do not have good height estimations.
// We give the grob the best chance of not colliding by shifting
// it to the maximum height in the case of cross-staff alignment.
dim.set_minimum_height (dim.max_height ());
Real ss = Staff_symbol_referencer::staff_space (me);
- Real dist = dim.distance (my_dim, robust_scm2double (me->get_property ("horizon-padding"), 0.0));
+ Real dist = dim.distance (my_dim, robust_scm2double (me->get_maybe_pure_property ("horizon-padding", pure, start, end), 0.0));
Real total_off = !isinf (dist) ? dir * dist : 0.0;
- total_off += dir * ss * robust_scm2double (me->get_property ("padding"), 0.0);
+ total_off += dir * ss * robust_scm2double (me->get_maybe_pure_property ("padding", pure, start, end), 0.0);
- Real minimum_space = ss * robust_scm2double (me->get_property ("minimum-space"), -1);
+ Real minimum_space = ss * robust_scm2double (me->get_maybe_pure_property ("minimum-space", pure, start, end), -1);
if (minimum_space >= 0
&& dir
Grob *staff = Staff_symbol_referencer::get_staff_symbol (me);
if (staff && a == Y_AXIS)
{
- if (to_boolean (me->get_property ("quantize-position")))
+ if (quantize_position)
{
Grob *common = me->common_refpoint (staff, Y_AXIS);
Real my_off = me->get_parent (Y_AXIS)->maybe_pure_coordinate (common, Y_AXIS, pure, start, end);
total_off += dir * 0.5 * ss;
}
}
- else if (scm_is_number (me->get_property ("staff-padding")) && dir)
+ else if (scm_is_number (me->get_maybe_pure_property ("staff-padding", pure, start, end)) && dir)
{
Interval iv = me->maybe_pure_extent (me, a, pure, start, end);
Real staff_padding
= Staff_symbol_referencer::staff_space (me)
- * scm_to_double (me->get_property ("staff-padding"));
+ * scm_to_double (me->get_maybe_pure_property ("staff-padding", pure, start, end));
Grob *parent = me->get_parent (Y_AXIS);
Grob *common = me->common_refpoint (staff, Y_AXIS);
chain_offset_callback (me,
(a == X_AXIS)
? x_aligned_side_proc
- : y_aligned_side_proc,
+ : ly_make_unpure_pure_container (y_aligned_side_proc, pure_y_aligned_side_proc),
a);
}
}