]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/axis-group-interface.cc
Run grand-replace (issue 3765)
[lilypond.git] / lily / axis-group-interface.cc
index 707e045c9b1a13b3127997d8c1ec05fed81467b7..af3ddcb8a310b181e910845d7349e0610bf69f8d 100644 (file)
@@ -1,7 +1,7 @@
 /*
   This file is part of LilyPond, the GNU music typesetter.
 
-  Copyright (C) 2000--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  Copyright (C) 2000--2014 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
@@ -243,6 +243,9 @@ Axis_group_interface::adjacent_pure_heights (SCM smob)
       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"));
       Real padding = robust_scm2double (g->get_property ("outside-staff-padding"), get_default_outside_staff_padding ());
 
@@ -392,9 +395,7 @@ SCM
 Axis_group_interface::calc_skylines (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
-  extract_grob_set (me, Grob_array::unsmob (me->get_object ("vertical-skyline-elements")) ? "vertical-skyline-elements" : "elements", elts);
-  Skyline_pair skylines = skyline_spacing (me, elts);
-
+  Skyline_pair skylines = skyline_spacing (me);
   return skylines.smobbed_copy ();
 }
 
@@ -435,11 +436,15 @@ Axis_group_interface::combine_skylines (SCM smob)
 SCM
 Axis_group_interface::generic_group_extent (Grob *me, Axis a)
 {
+  extract_grob_set (me, "elements", elts);
+
   /* trigger the callback to do skyline-spacing on the children */
   if (a == Y_AXIS)
-    (void) me->get_property ("vertical-skylines");
+    for (vsize i = 0; i < elts.size (); i++)
+      if (!(Stem::has_interface (elts[i])
+            && to_boolean (elts[i]->get_property ("cross-staff"))))
+        (void) elts[i]->get_property ("vertical-skylines");
 
-  extract_grob_set (me, "elements", elts);
   Grob *common = common_refpoint_of_array (elts, me, a);
 
   Real my_coord = me->relative_coordinate (common, a);
@@ -469,28 +474,45 @@ SCM
 Axis_group_interface::calc_pure_relevant_grobs (SCM 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);
             }
         }
@@ -511,6 +533,12 @@ Axis_group_interface::calc_pure_y_common (SCM smob)
 
   extract_grob_set (me, "pure-relevant-grobs", elts);
   Grob *common = common_refpoint_of_array (elts, me, Y_AXIS);
+  if (common != me && Align_interface::has_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.");
@@ -558,7 +586,7 @@ Axis_group_interface::pure_group_height (Grob *me, int start, int end)
       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;
@@ -654,8 +682,8 @@ avoid_outside_staff_collisions (Grob *elt,
   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;
@@ -744,7 +772,9 @@ add_grobs_of_one_priority (Grob *me,
         {
           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);
@@ -834,8 +864,10 @@ Axis_group_interface::outside_staff_ancestor (Grob *me)
 // that there is no room for the cross-staff grob. It also means, of course, that
 // we don't get the benefits of skyline placement for cross-staff grobs.
 Skyline_pair
-Axis_group_interface::skyline_spacing (Grob *me, vector<Grob *> elements)
+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);
+  vector<Grob *> elements (fakeelements);
   for (vsize i = 0; i < elements.size (); i++)
     /*
       As a sanity check, we make sure that no grob with an outside staff priority
@@ -862,7 +894,12 @@ Axis_group_interface::skyline_spacing (Grob *me, vector<Grob *> elements)
   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.
@@ -870,6 +907,7 @@ Axis_group_interface::skyline_spacing (Grob *me, vector<Grob *> elements)
 
   vsize i = 0;
   vector<Skyline_pair> inside_staff_skylines;
+
   for (i = 0; i < elements.size ()
        && !scm_is_number (elements[i]->get_property ("outside-staff-priority")); i++)
     {
@@ -1008,7 +1046,6 @@ ADD_INTERFACE (Axis_group_interface,
                "nonstaff-nonstaff-spacing "
                "nonstaff-relatedstaff-spacing "
                "nonstaff-unrelatedstaff-spacing "
-               "outside-staff-placement-directive "
                "pure-relevant-grobs "
                "pure-relevant-items "
                "pure-relevant-spanners "
@@ -1017,7 +1054,6 @@ ADD_INTERFACE (Axis_group_interface,
                "staff-grouper "
                "staff-staff-spacing "
                "system-Y-offset "
-               "vertical-skyline-elements "
                "X-common "
                "Y-common "
               );