]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/self-alignment-interface.cc
parser.yy: introduce make_music_from_simple function
[lilypond.git] / lily / self-alignment-interface.cc
index a6fde153e043e826b4865c467c3267d6bdeb1685..ff2b5bfd59ed3bea08a0d77335111f4427091d3f 100644 (file)
@@ -1,7 +1,7 @@
 /*
   This file is part of LilyPond, the GNU music typesetter.
 
-  Copyright (C) 2004--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  Copyright (C) 2004--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
@@ -23,6 +23,7 @@
 #include "grob.hh"
 #include "grob-array.hh"
 #include "interval-minefield.hh"
+#include "note-column.hh"
 #include "paper-column.hh"
 #include "pointer-group-interface.hh"
 #include "warn.hh"
@@ -58,9 +59,7 @@ Self_alignment_interface::aligned_on_self (Grob *me, Axis a, bool pure, int star
   if (scm_is_number (align))
     {
       Interval ext (me->maybe_pure_extent (me, a, pure, start, end));
-      if (ext.is_empty ())
-        programming_error ("cannot align on self: empty element");
-      else
+      if (!ext.is_empty ())
         return scm_from_double (- ext.linear_combination (scm_to_double (align)));
     }
   return scm_from_double (0.0);
@@ -79,6 +78,27 @@ Self_alignment_interface::centered_on_x_parent (SCM smob)
   return centered_on_object (unsmob_grob (smob)->get_parent (X_AXIS), X_AXIS);
 }
 
+MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_note_columns, 1);
+SCM
+Self_alignment_interface::centered_on_note_columns (SCM smob)
+{
+  Item *it = unsmob_item (smob)->get_column ();
+  if (!it)
+    return scm_from_double (0.0);
+
+  extract_grob_set (it, "elements", elts);
+  vector<Grob *> ncs;
+  Interval centers;
+  for (vsize i = 0; i < elts.size (); i++)
+    if (Note_column::has_interface (elts[i]))
+      centers.add_point (scm_to_double (centered_on_object (elts[i], X_AXIS)));
+
+  if (centers.is_empty ())
+    return scm_from_double (0.0);
+
+  return scm_from_double (centers.center ());
+}
+
 MAKE_SCHEME_CALLBACK (Self_alignment_interface, centered_on_y_parent, 1);
 SCM
 Self_alignment_interface::centered_on_y_parent (SCM smob)
@@ -179,7 +199,24 @@ Self_alignment_interface::avoid_colliding_grobs (Grob *me, Axis a, Real offset)
 
   Interval iv = me->extent (me, a) + offset;
   for (vsize i = 0; i < colls.size (); i++)
-    ivs.push_back (colls[i]->extent (refp, a));
+    {
+      int my_vai = Grob::get_vertical_axis_group_index (colls[i]);
+      Direction dir = get_grob_direction (colls[i]);
+      // if coll is cross staff but extremal and pointing in the
+      // direction of the extrema, we don't take it into consideration
+      if (Grob *beam = unsmob_grob (colls[i]->get_object ("beam")))
+        {
+          Interval_t<int> vais;
+          extract_grob_set (beam, "normal-stems", stems);
+          for (vsize j = 0; j < stems.size (); j++)
+            vais.add_point (Grob::get_vertical_axis_group_index (stems[j]));
+          // ugh...up and down are different for VerticalAxisGroup order...
+          if ((my_vai == vais[DOWN] && dir == UP)
+              || (my_vai == vais[UP] && dir == DOWN))
+            continue;
+        }
+      ivs.push_back (colls[i]->extent (refp, a));
+    }
 
   Interval_minefield minefield (Interval (iv.center (), iv.center ()), iv.length ());
   for (vsize i = 0; i < ivs.size (); i++)
@@ -197,8 +234,8 @@ Self_alignment_interface::avoid_colliding_grobs (Grob *me, Axis a, Real offset)
                       : LEFT;
 
   return scm_from_double ((pos[col_dir] - (iv.length () / 2)
-                          + col_dir
-                          * robust_scm2double (me->get_property ("collision-padding"), 0.0)));
+                           + col_dir
+                           * robust_scm2double (me->get_property ("collision-padding"), 0.0)));
 }
 
 void