]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/align-interface.cc (stretch_after_break): new
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 3 Oct 2005 11:15:56 +0000 (11:15 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Mon, 3 Oct 2005 11:15:56 +0000 (11:15 +0000)
function. Read fixed-alignment-extra-space property.
(align_elements_to_extents): read alignment-extra-space property.

* lily/lily-guile.cc (robust_scm2dir): new function.

lily/align-interface.cc
lily/include/align-interface.hh
lily/include/lily-guile.hh
lily/lily-guile.cc

index 1b661e8f9ed8028c1c6a2f2606023ae58c731247..ce3e9b873173915167ee8d85f3c0a4c1ddfae81e 100644 (file)
@@ -39,6 +39,44 @@ Align_interface::fixed_distance_alignment_callback (SCM element_smob, SCM axis)
   return scm_from_double (0.0);
 }
 
+/*
+  merge with align-to-extents?
+*/
+MAKE_SCHEME_CALLBACK(Align_interface, stretch_after_break, 1)
+SCM
+Align_interface::stretch_after_break (SCM grob)
+{
+  Grob *me = unsmob_grob (grob);
+
+  Spanner *me_spanner = dynamic_cast<Spanner *> (me);
+  extract_grob_set (me, "elements", elems);
+  if (me_spanner && elems.size ())
+    {
+      Grob *common = common_refpoint_of_array (elems, me, Y_AXIS);
+
+      /* force position callbacks */
+      for (int i = 0; i < elems.size (); i++)
+       elems[i]->relative_coordinate (common, Y_AXIS);
+
+      SCM details =  me_spanner->get_bound (LEFT)->get_property ("line-break-system-details");
+      SCM extra_space_handle = scm_assoc (ly_symbol2scm ("fixed-alignment-extra-space"), details);
+      
+      Real extra_space = robust_scm2double (scm_is_pair (extra_space_handle)
+                                           ? scm_cdr (extra_space_handle)
+                                           : SCM_EOL,
+                                           0.0);
+
+      Direction stacking_dir = robust_scm2dir (me->get_property ("stacking-dir"),
+                                              DOWN);
+  
+      Real delta  = extra_space / elems.size();
+      for (int i = 0; i < elems.size (); i++)
+       elems[i]->translate_axis (i * delta, Y_AXIS);
+    }
+  
+  return SCM_UNSPECIFIED;
+}
+
 /*
   merge with align-to-extents?
 */
@@ -73,8 +111,6 @@ Align_interface::align_to_fixed_distance (Grob *me, Axis a)
        force_hara_kiri_callback () (extent and offset callback) is
        such that we might get into a loop if we call extent () or
        offset () the elements.
-
-
       */
       if (a == Y_AXIS
          && Hara_kiri_group_spanner::has_interface (elems[j]))
@@ -116,14 +152,26 @@ Align_interface::align_to_fixed_distance (Grob *me, Axis a)
 void
 Align_interface::align_elements_to_extents (Grob *me, Axis a)
 {
+  Real extra_space = 0.0;
   Spanner *me_spanner = dynamic_cast<Spanner *> (me);
   if (a == Y_AXIS
-      && me_spanner
-      && me_spanner->get_bound (LEFT)->break_status_dir () == CENTER)
-    me_spanner->warning (_ ("vertical alignment called before line-breaking. Only do cross-staff spanners with PianoStaff."));
+      && me_spanner)
+    {
+      if (me_spanner->get_bound (LEFT)->break_status_dir () == CENTER)
+       me->warning (_ ("vertical alignment called before line-breaking. "
+                       "Only do cross-staff spanners with PianoStaff."));
 
-  me->set_property ("positioning-done", SCM_BOOL_T);
+      SCM details =  me_spanner->get_bound (LEFT)->get_property ("line-break-system-details");
+      SCM extra_space_handle = scm_assoc (ly_symbol2scm ("alignment-extra-space"), details);
 
+      extra_space = robust_scm2double (scm_is_pair (extra_space_handle)
+                                      ? scm_cdr (extra_space_handle)
+                                      : SCM_EOL,
+                                      extra_space);
+    }
+  
+  me->set_property ("positioning-done", SCM_BOOL_T);
+  
   SCM d = me->get_property ("stacking-dir");
 
   Direction stacking_dir = scm_is_number (d) ? to_dir (d) : CENTER;
@@ -156,19 +204,13 @@ Align_interface::align_elements_to_extents (Grob *me, Axis a)
     prevent ugly cyclic dependencies that arise when you combine
     self-alignment on a child with alignment of children.
   */
-  static SCM prop_syms[2];
-
-  if (!prop_syms[0])
-    {
-      prop_syms[X_AXIS] = ly_symbol2scm ("self-alignment-X");
-      prop_syms[Y_AXIS] = ly_symbol2scm ("self-alignment-Y");
-    }
-
-  SCM align (me->internal_get_property (prop_syms[a]));
+  SCM align ((a == X_AXIS)
+            ? me->get_property ("self-alignment-X")
+            : me->get_property ("self-alignment-Y"));
 
   Array<Real> translates;
   Interval total;
-  Real where_f = 0;
+  Real where = 0;
 
   for (int j = 0; j < elems.size (); j++)
     {
@@ -183,12 +225,13 @@ Align_interface::align_elements_to_extents (Grob *me, Axis a)
       if (j)
        dy = min (max (dy, threshold[SMALLER]), threshold[BIGGER]);
 
-      where_f += stacking_dir * dy;
-      total.unite (dims[j] + where_f);
-      translates.push (where_f);
+      where += stacking_dir * (dy + extra_space / elems.size ());
+      total.unite (dims[j] + where);
+      translates.push (where);
     }
 
   Real center_offset = 0.0;
+  
   /*
     also move the grobs that were empty, to maintain spatial order.
   */
@@ -266,9 +309,17 @@ find_fixed_alignment_parent (Grob *g)
 }
 
 ADD_INTERFACE (Align_interface, "align-interface",
-              "Order grobs from top to bottom, left to right, right to left or bottom"
+              "Order grobs from top to bottom, left to right, right to left or bottom "
               "to top.",
-              "forced-distance stacking-dir align-dir threshold positioning-done "
+              
+              /*
+                properties
+               */
+              "forced-distance "
+              "stacking-dir "
+              "align-dir "
+              "threshold "
+              "positioning-done "
               "elements axes");
 
 struct Foobar
index 8ac3503a4bf04789e1b87a20bb8bcb1f2e65c8f2..ec8099d2524260687b35d70b1a92c898ed8a43eb 100644 (file)
@@ -16,6 +16,7 @@ struct Align_interface
 {
   DECLARE_SCHEME_CALLBACK (alignment_callback, (SCM element, SCM axis));
   DECLARE_SCHEME_CALLBACK (fixed_distance_alignment_callback, (SCM element, SCM axis));
+  DECLARE_SCHEME_CALLBACK (stretch_after_break, (SCM element));
   static void align_to_fixed_distance (Grob *, Axis a);
   static void align_elements_to_extents (Grob *, Axis a);
   static void set_axis (Grob *, Axis);
index 672a0df804fdd7197d8b2a0154e2fa014ba011f9..ad01de36948d566777400d0293501ad10a6d232f 100644 (file)
@@ -51,6 +51,7 @@ char *ly_scm2newstr (SCM str, size_t *lenp);
 
 Real robust_scm2double (SCM, double);
 int robust_scm2int (SCM, int);
+Direction robust_scm2dir (SCM, Direction);
 Drul_array<Real> robust_scm2drul (SCM, Drul_array<Real>);
 Interval robust_scm2interval (SCM, Drul_array<Real>);
 Offset robust_scm2offset (SCM, Offset);
index 17409239b14a6e2956cfebc70cd79ef759629e17..681d1762c02ca4a1d486b7a32d95c7f3265fd5b6 100644 (file)
@@ -613,6 +613,14 @@ robust_scm2double (SCM k, double x)
   return x;
 }
 
+Direction
+robust_scm2dir (SCM d, Direction def)
+{
+  if (is_direction (d))
+    def = to_dir (d);
+  return def;
+}
+
 Interval
 robust_scm2interval (SCM k, Drul_array<Real> v)
 {