source file of the GNU LilyPond music typesetter
- (c) 1999--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 1999--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
-#include "new-spacing-spanner.hh"
+
#include "paper-column.hh"
#include "dimensions.hh"
#include "paper-def.hh"
#include "line-of-score.hh"
#include "misc.hh"
#include "separation-item.hh"
+#include "spanner.hh"
+#include "spring.hh"
+class New_spacing_spanner
+{
+public:
+ static void set_interface (Grob*);
+ static void do_measure (Grob*,Link_array<Grob> *) ;
+ static void stretch_to_regularity (Grob*, Array<Spring> *, Link_array<Grob> const &);
+ static void breakable_column_spacing (Item* l, Item *r);
+ DECLARE_SCHEME_CALLBACK (set_springs, (SCM ));
+ static Real default_bar_spacing (Grob*,Grob*,Grob*,Moment) ;
+ static Real note_spacing (Grob*,Grob*,Grob*,Moment) ;
+ static Real get_duration_space (Grob*,Moment dur, Moment shortest) ;
+ static void prune_loose_colunms (Link_array<Grob>*);
+};
void
New_spacing_spanner::set_interface (Grob*me)
me->set_extent_callback (SCM_EOL, Y_AXIS) ;
}
+/*
+ Remove all columns that are not tightly
+ fitting part of the spacing problem.
+ */
+void
+New_spacing_spanner::prune_loose_colunms (Link_array<Grob> *cols)
+{
+ for (int i = cols->size(); i--;)
+ {
+ SCM between = cols->elem(i)->get_grob_property ("between-cols");
+ if (!gh_pair_p (between))
+ continue;
+
+ Item * l = dynamic_cast<Item*> (unsmob_grob (gh_car (between)));
+ Item * r = dynamic_cast<Item*> (unsmob_grob (gh_cdr (between)));
+ if (l->column_l () != cols->elem (i-1)
+ || r->column_l () != cols->elem (i +1))
+ {
+ cols->del (i);
+ }
+ }
+}
+
/*
The algorithm is partly taken from :
Moment base_shortest_duration = *unsmob_moment (me->get_grob_property ("maximum-duration-for-spacing"));
shortest_in_measure.set_infinite (1);
- for (int i = cols->size(); i--;)
- {
- if (gh_pair_p (cols->elem(i)->get_grob_property ("between-cols")))
- cols->del (i);
- }
-
- int n = 0;
+ prune_loose_colunms (cols);
+
for (int i =0 ; i < cols->size (); i++)
{
if (Paper_column::musical_b (cols->elem (i)))
*/
for (SCM s = seq; gh_pair_p (s); s = ly_cdr (s))
{
- Grob *lm = unsmob_grob (gh_caar (s));
- Grob *rm = unsmob_grob (gh_cdar (s));
+ Grob *lm = unsmob_grob (ly_caar (s));
+ Grob *rm = unsmob_grob (ly_cdar (s));
// TODO; configgable.
hinterfleisch += -headwid + Separation_item::my_width (lm)[RIGHT] -
0.5 * Separation_item::my_width (rm)[LEFT];
-
- hinterfleisch += stem_dir_correction (me, l, r);
}
// ? why.
return dist;
}
-
-/**
- Correct for optical illusions. See [Wanske] p. 138. The combination
- up-stem + down-stem should get extra space, the combination
- down-stem + up-stem less.
-
- This should be more advanced, since relative heights of the note
- heads also influence required correction.
-
- Also might not work correctly in case of multi voices or staff
- changing voices
-
- TODO: lookup correction distances? More advanced correction?
- Possibly turn this off?
-
- TODO: have to check wether the stems are in the same staff.
-
- This routine reads the DIR-LIST property of both its L and R arguments. */
-Real
-New_spacing_spanner::stem_dir_correction (Grob*me, Grob*l, Grob*r)
-{
- SCM dl = l->get_grob_property ("dir-list");
- SCM dr = r->get_grob_property ("dir-list");
-
- if (scm_ilength (dl) != 1 || scm_ilength (dr) != 1)
- return 0.;
-
- dl = ly_car (dl);
- dr = ly_car (dr);
-
- assert (gh_number_p (dl) && gh_number_p (dr));
- int d1 = gh_scm2int (dl);
- int d2 = gh_scm2int (dr);
-
- if (d1 == d2)
- return 0.0;
-
-
- Real correction = 0.0;
- Real ssc = gh_scm2double (me->get_grob_property ("stem-spacing-correction"));
-
- if (d1 && d2 && d1 * d2 == -1)
- {
- correction = d1 * ssc;
- }
- else
- programming_error ("Stem directions not set correctly for optical correction");
- return correction;
-}
MAKE_SCHEME_CALLBACK (New_spacing_spanner, set_springs,1);