From 253d39e7113c4b93736e2e80cd4dea44514d6247 Mon Sep 17 00:00:00 2001 From: Joe Neeman Date: Sun, 17 Jun 2007 19:22:21 +1000 Subject: [PATCH] introduce Spacing_interface for code sharing between Note_spacing and Staff_spacing --- lily/include/note-spacing.hh | 2 - lily/include/spacing-interface.hh | 9 ++ lily/note-spacing.cc | 61 ----------- lily/spacing-determine-loose-columns.cc | 9 +- lily/spacing-interface.cc | 128 ++++++++++++++++++++++++ lily/spacing-spanner.cc | 4 +- lily/staff-spacing.cc | 2 - lily/system.cc | 1 - scm/define-grobs.scm | 6 +- 9 files changed, 148 insertions(+), 74 deletions(-) create mode 100644 lily/spacing-interface.cc diff --git a/lily/include/note-spacing.hh b/lily/include/note-spacing.hh index af04260cea..dcc9b2fe5a 100644 --- a/lily/include/note-spacing.hh +++ b/lily/include/note-spacing.hh @@ -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 */ diff --git a/lily/include/spacing-interface.hh b/lily/include/spacing-interface.hh index b558ede709..08e404e4e7 100644 --- a/lily/include/spacing-interface.hh +++ b/lily/include/spacing-interface.hh @@ -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 note_columns (Grob *me); + static Item* right_column (Grob *me); + static Item* left_column (Grob *me); + DECLARE_GROB_INTERFACE(); }; +#endif /* SPACING_INTERFACE_HH */ diff --git a/lily/note-spacing.cc b/lily/note-spacing.cc index ed18b91913..345b9209e7 100644 --- a/lily/note-spacing.cc +++ b/lily/note-spacing.cc @@ -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 (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 &right = a->array_reference (); - for (vsize i = right.size (); i--;) - { - if (dynamic_cast (right[i])->get_column () != mincol) - right.erase (right.begin () + i); - } - } - - return mincol; -} /** Correct for optical illusions. See [Wanske] p. 138. The combination diff --git a/lily/spacing-determine-loose-columns.cc b/lily/spacing-determine-loose-columns.cc index 45f2f0ae7c..7274ef1363 100644 --- a/lily/spacing-determine-loose-columns.cc +++ b/lily/spacing-determine-loose-columns.cc @@ -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 (Note_spacing::right_column (r_neighbor)); + r_neighbor = dynamic_cast (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 const &cols) Item *wish = dynamic_cast (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 index 0000000000..8a0c353c4b --- /dev/null +++ b/lily/spacing-interface.cc @@ -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 +*/ + +#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 skylines = Drul_array (Skyline (RIGHT), Skyline (LEFT)); + Drul_array > 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 &right = a->array_reference (); + for (vsize i = right.size (); i--;) + { + if (dynamic_cast (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 (me)->get_column (); +} + +Drul_array +Spacing_interface::note_columns (Grob *me) +{ + Drul_array ret (0, 0); + Drul_array > 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 (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 " + ); diff --git a/lily/spacing-spanner.cc b/lily/spacing-spanner.cc index 568283846d..721fcd30a4 100644 --- a/lily/spacing-spanner.cc +++ b/lily/spacing-spanner.cc @@ -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; diff --git a/lily/staff-spacing.cc b/lily/staff-spacing.cc index b93a4ee6b0..2919602843 100644 --- a/lily/staff-spacing.cc +++ b/lily/staff-spacing.cc @@ -269,6 +269,4 @@ ADD_INTERFACE (Staff_spacing, /* properties */ "stem-spacing-correction " - "left-items " - "right-items " ); diff --git a/lily/system.cc b/lily/system.cc index eb6d05a881..e8af537be1 100644 --- a/lily/system.cc +++ b/lily/system.cc @@ -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" diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index c3315a3b42..9c8e83d311 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1145,6 +1145,7 @@ (Y-extent . ,ly:axis-group-interface::height) (meta . ((class . Item) (interfaces . (axis-group-interface + separation-item-iterface note-column-interface)))))) (NoteHead @@ -1171,7 +1172,7 @@ ;; 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 @@ -1560,7 +1561,8 @@ (non-musical . #t) (stem-spacing-correction . 0.4) (meta . ((class . Item) - (interfaces . (staff-spacing-interface)))))) + (interfaces . (spacing-interface + staff-spacing-interface)))))) (StaffSymbol -- 2.39.2