]> git.donarmstrong.com Git - lilypond.git/commitdiff
introduce Spacing_interface for code sharing between Note_spacing and Staff_spacing
authorJoe Neeman <joeneeman@gmail.com>
Sun, 17 Jun 2007 09:22:21 +0000 (19:22 +1000)
committerJoe Neeman <joeneeman@gmail.com>
Sun, 17 Jun 2007 09:22:21 +0000 (19:22 +1000)
lily/include/note-spacing.hh
lily/include/spacing-interface.hh
lily/note-spacing.cc
lily/spacing-determine-loose-columns.cc
lily/spacing-interface.cc [new file with mode: 0644]
lily/spacing-spanner.cc
lily/staff-spacing.cc
lily/system.cc
scm/define-grobs.scm

index af04260ceab39f07243c754a843efe938a7a3639..dcc9b2fe5a4ba68866ccf77af8482533c35d10f9 100644 (file)
@@ -20,8 +20,6 @@ public:
   static void get_spacing (Grob *me, Item *, Real, Real, Real *, Real *);
   static void stem_dir_correction (Grob *me, Item *next_col, Real incr,
                                   Real *, Real *);
-  static Item *right_column (Grob *);
-  static Item *left_column (Grob *);
 };
 
 #endif /* NOTE_SPACING_HH */
index b558ede709aa46f9a69ad54f9fc910c564c79938..08e404e4e742ad9500fef7d1f8e6ca9c1d0ce250 100644 (file)
@@ -8,8 +8,17 @@
 #include "grob-interface.hh"
 #include "lily-proto.hh"
 
+#ifndef SPACING_INTERFACE_HH
+#define SPACING_INTERFACE_HH
+
 struct Spacing_interface
 {
+  static Real minimum_distance (Grob *me);
+  static Drul_array<Item*> note_columns (Grob *me);
+  static Item* right_column (Grob *me);
+  static Item* left_column (Grob *me);
+
   DECLARE_GROB_INTERFACE();
 };
 
+#endif /* SPACING_INTERFACE_HH */
index ed18b919138782d6fea80806fcb6c5f8ed7547b2..345b9209e787107668cc6be0a9fe0285460fb4a9 100644 (file)
@@ -58,12 +58,6 @@ Note_spacing::get_spacing (Grob *me, Item *right_col,
          if (d == RIGHT && right_col != it_col)
            continue;
 
-         if (Separation_item::has_interface (it))
-           {
-             extents[d].unite (Separation_item::width (it));
-             continue;
-           }
-
          if (d == LEFT
              && Note_column::has_interface (it))
            {
@@ -155,61 +149,6 @@ Note_spacing::get_spacing (Grob *me, Item *right_col,
   stem_dir_correction (me, right_col, increment, space, fixed);
 }
 
-Item *
-Note_spacing::left_column (Grob *me)
-{
-  if (!me->is_live ())
-    return 0;
-
-  return dynamic_cast<Item *> (me)->get_column ();
-}
-
-/*
-  Compute the column of the right-items.  This is a big function,
-  since RIGHT-ITEMS may span more columns (eg. if a clef is inserted,
-  this will add a new column to RIGHT-ITEMS. Here we look at the
-  columns, and return the left-most. If there are multiple columns, we
-  prune RIGHT-ITEMS.
-*/
-Item *
-Note_spacing::right_column (Grob *me)
-{
-  if (!me->is_live ())
-    return 0;
-
-  Grob_array *a = unsmob_grob_array (me->get_object ("right-items"));
-  Item *mincol = 0;
-  int min_rank = INT_MAX;
-  bool prune = false;
-  for (vsize i = 0; a && i < a->size (); i++)
-    {
-      Item *ri = a->item (i);
-      Item *col = ri->get_column ();
-
-      int rank = Paper_column::get_rank (col);
-
-      if (rank < min_rank)
-       {
-         min_rank = rank;
-         if (mincol)
-           prune = true;
-
-         mincol = col;
-       }
-    }
-
-  if (prune && a)
-    {
-      vector<Grob*> &right = a->array_reference ();
-      for (vsize i = right.size (); i--;)
-       {
-         if (dynamic_cast<Item *> (right[i])->get_column () != mincol)
-           right.erase (right.begin () + i);
-       }
-    }
-
-  return mincol;
-}
 
 /**
    Correct for optical illusions. See [Wanske] p. 138. The combination
index 45f2f0ae7ce56f2dace4a5112810c584baec426a..7274ef1363b4fdeaf504aec7157dea257be97cf8 100644 (file)
@@ -14,6 +14,7 @@
 #include "paper-column.hh"
 #include "column-x-positions.hh"
 #include "pointer-group-interface.hh"
+#include "spacing-interface.hh"
 #include "spacing-spanner.hh"
 #include "note-spacing.hh"
 #include "moment.hh"
@@ -86,7 +87,7 @@ is_loose_column (Grob *l, Grob *col, Grob *r, Spacing_options const *options)
     return false;
 
   l_neighbor = l_neighbor->get_column ();
-  r_neighbor = dynamic_cast<Item *> (Note_spacing::right_column (r_neighbor));
+  r_neighbor = dynamic_cast<Item *> (Spacing_interface::right_column (r_neighbor));
 
   if (l == l_neighbor && r == r_neighbor)
     return false;
@@ -143,8 +144,8 @@ Spacing_spanner::set_distances_for_loose_col (Grob *me, Grob *c,
       for (vsize k = wishes.size (); k--;)
        {
          Grob *sp = wishes[k];
-         if (Note_spacing::left_column (sp) != lc
-             || Note_spacing::right_column (sp) != rc)
+         if (Spacing_interface::left_column (sp) != lc
+             || Spacing_interface::right_column (sp) != rc)
            continue;
 
          if (Note_spacing::has_interface (sp))
@@ -276,7 +277,7 @@ Spacing_spanner::set_explicit_neighbor_columns (vector<Grob*> const &cols)
          Item *wish = dynamic_cast<Item *> (wishes[k]);
 
          Item *lc = wish->get_column ();
-         Grob *right = Note_spacing::right_column (wish);
+         Grob *right = Spacing_interface::right_column (wish);
 
          if (!right)
            continue;
diff --git a/lily/spacing-interface.cc b/lily/spacing-interface.cc
new file mode 100644 (file)
index 0000000..8a0c353
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+  spacing-interface.cc -- functionality that is shared between Note_spacing
+  and Staff_spacing
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2007 Joe Neeman <joeneeman@gmail.com>
+*/
+
+#include "spacing-interface.hh"
+
+#include "grob.hh"
+#include "grob-array.hh"
+#include "item.hh"
+#include "note-column.hh"
+#include "paper-column.hh"
+#include "separation-item.hh"
+#include "skyline.hh"
+
+/* return the minimum distance between the left-items and the right-items of
+   this spacing object */
+Real
+Spacing_interface::minimum_distance (Grob *me)
+{
+  Drul_array<Skyline> skylines = Drul_array<Skyline> (Skyline (RIGHT), Skyline (LEFT));
+  Drul_array<vector<Grob*> > items (ly_scm2link_array (me->get_object ("left-items")),
+                                   ly_scm2link_array (me->get_object ("right-items")));
+
+  Direction d = LEFT;
+  do
+    {
+      for (vsize i = 0; i < items[d].size (); i++)
+       if (Separation_item::has_interface (items[d][i]))
+         {
+           SCM sky_scm = items[d][i]->get_property ("horizontal-skylines");
+           Skyline_pair *sky = Skyline_pair::unsmob (sky_scm);
+           skylines[d].merge ((*sky)[-d]);
+           
+           if (d == RIGHT && items[LEFT].size ())
+             skylines[d].merge (Separation_item::conditional_skyline (items[d][i], items[LEFT][0]));
+         }
+    }
+  while (flip (&d) != LEFT);
+
+  return skylines[LEFT].distance (skylines[RIGHT]);
+}
+
+/*
+  Compute the column of the right-items.  This is a big function,
+  since RIGHT-ITEMS may span more columns (eg. if a clef is inserted,
+  this will add a new column to RIGHT-ITEMS. Here we look at the
+  columns, and return the left-most. If there are multiple columns, we
+  prune RIGHT-ITEMS.
+*/
+Item *
+Spacing_interface::right_column (Grob *me)
+{
+  if (!me->is_live ())
+    return 0;
+
+  Grob_array *a = unsmob_grob_array (me->get_object ("right-items"));
+  Item *mincol = 0;
+  int min_rank = INT_MAX;
+  bool prune = false;
+  for (vsize i = 0; a && i < a->size (); i++)
+    {
+      Item *ri = a->item (i);
+      Item *col = ri->get_column ();
+
+      int rank = Paper_column::get_rank (col);
+
+      if (rank < min_rank)
+       {
+         min_rank = rank;
+         if (mincol)
+           prune = true;
+
+         mincol = col;
+       }
+    }
+
+  if (prune && a)
+    {
+      vector<Grob*> &right = a->array_reference ();
+      for (vsize i = right.size (); i--;)
+       {
+         if (dynamic_cast<Item *> (right[i])->get_column () != mincol)
+           right.erase (right.begin () + i);
+       }
+    }
+
+  return mincol;
+}
+
+Item *
+Spacing_interface::left_column (Grob *me)
+{
+  if (!me->is_live ())
+    return 0;
+
+  return dynamic_cast<Item *> (me)->get_column ();
+}
+
+Drul_array<Item*>
+Spacing_interface::note_columns (Grob *me)
+{
+  Drul_array<Item*> ret (0, 0);
+  Drul_array<vector<Grob*> > items (ly_scm2link_array (me->get_object ("left-items")),
+                                   ly_scm2link_array (me->get_object ("right-items")));
+
+  Direction d = LEFT;
+  do
+    {
+      for (vsize i = 0; i < items[d].size (); i++)
+       if (Note_column::has_interface (items[d][i]))
+         ret[d] = dynamic_cast<Item*> (items[d][i]);
+    }
+  while (flip (&d) != LEFT);
+
+  return ret;
+}
+
+ADD_INTERFACE (Spacing_interface,
+              "This object calculates the desired and minimum distances between two columns.",
+
+              "left-items "
+              "right-items "
+              );
index 568283846d345b99065c56f3c0d922e0922f9804..721fcd30a497538fa85513329b78caf2ca07ec45 100644 (file)
@@ -272,8 +272,8 @@ Spacing_spanner::musical_column_spacing (Grob *me,
        {
          Grob *wish = neighbors[i];
 
-         Item *wish_rcol = Note_spacing::right_column (wish);
-         if (Note_spacing::left_column (wish) != left_col
+         Item *wish_rcol = Spacing_interface::right_column (wish);
+         if (Spacing_interface::left_column (wish) != left_col
              || (wish_rcol != right_col && wish_rcol != right_col->original ()))
            continue;
 
index b93a4ee6b00bdd514c203ef7536ffc00730b395f..2919602843f32ccdc15bff7de1ea719211d93da3 100644 (file)
@@ -269,6 +269,4 @@ ADD_INTERFACE (Staff_spacing,
 
               /* properties */
               "stem-spacing-correction "
-              "left-items "
-              "right-items "
               );
index eb6d05a8810f1b8662a8739615aac685a23e62d5..e8af537be179b4c3c607de37972aaa004800344c 100644 (file)
@@ -19,7 +19,6 @@
 #include "paper-score.hh"
 #include "paper-system.hh"
 #include "pointer-group-interface.hh"
-#include "spacing-interface.hh"
 #include "staff-symbol-referencer.hh"
 #include "warn.hh"
 #include "lookup.hh"
index c3315a3b42c77d830d9b858ca5a1d0f21f35688f..9c8e83d3110f0b025c8b38569123bf6c213e2ca1 100644 (file)
        (Y-extent . ,ly:axis-group-interface::height)
        (meta . ((class . Item)
                 (interfaces . (axis-group-interface
+                               separation-item-iterface
                                note-column-interface))))))
 
     (NoteHead
        ;; If you ever change this back, please document! --hwn
        (knee-spacing-correction . 1.0)
        (meta . ((class . Item)
-                (interfaces . (
+                (interfaces . (spacing-interface
                                note-spacing-interface))))))
 
     (NoteName
        (non-musical . #t)
        (stem-spacing-correction . 0.4)
        (meta . ((class . Item)
-                (interfaces . (staff-spacing-interface))))))
+                (interfaces . (spacing-interface
+                               staff-spacing-interface))))))
 
    
     (StaffSymbol