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 */
#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 */
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))
{
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
#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"
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;
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))
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;
--- /dev/null
+/*
+ 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 "
+ );
{
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;
/* properties */
"stem-spacing-correction "
- "left-items "
- "right-items "
);
#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"
(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