]> git.donarmstrong.com Git - lilypond.git/blob - lily/note-spacing.cc
release: 1.5.27
[lilypond.git] / lily / note-spacing.cc
1 /*   
2   note-spacing.cc -- implement Note_spacing
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9
10 #include "paper-column.hh"
11 #include "item.hh"
12 #include "moment.hh"
13 #include "note-spacing.hh"
14 #include "grob.hh"
15 #include "note-column.hh"
16 #include "warn.hh"
17
18 bool
19 Note_spacing::has_interface (Grob* g)
20 {
21   return g && g->has_interface (ly_symbol2scm ("note-spacing-interface"));
22 }
23
24
25
26 Real
27 Note_spacing::get_spacing (Grob *me)
28 {
29   Drul_array<SCM> props(me->get_grob_property ("left-items"),
30                         me->get_grob_property ("right-items"));
31   Direction d = LEFT;
32   Drul_array<Interval> extents;
33   do
34     {
35       for (SCM  s = props[d]; gh_pair_p (s); s = gh_cdr (s))
36         {
37           Item * it= dynamic_cast<Item*> (unsmob_grob (gh_car(s)));
38           extents[d].unite (it->extent (it->column_l (), X_AXIS));
39
40           if (d == RIGHT)
41             {
42               Grob * accs = Note_column::accidentals (it);
43               if (accs)
44                 extents[d].unite (accs->extent (it->column_l (), X_AXIS));
45             }
46         }
47
48       if (extents[d].empty_b ())
49         extents[d] = Interval (0,0);
50     }
51   while (flip (&d) != LEFT);
52
53   /*
54     
55     What's sticking out at the left of the right side has less
56     influence.
57
58   */
59   Real dx= extents[LEFT][RIGHT] - 0.5 * extents[RIGHT][LEFT];
60   return dx;
61 }
62
63
64 MAKE_SCHEME_CALLBACK(Note_spacing, before_line_breaking, 1)
65 SCM
66 Note_spacing::before_line_breaking (SCM g)
67 {
68   Grob * me = unsmob_grob (g);
69   SCM right = me->get_grob_property ("right-items");
70
71   if (gh_pair_p (right))
72     right = gh_car (right);
73   
74   Grob *right_grob = unsmob_grob (right);
75
76   Item * ri = dynamic_cast<Item*> (right_grob);
77   if (!ri)
78     {
79       int r = Paper_column::rank_i (dynamic_cast<Item*>(me)->column_l ());
80       programming_error (_f("Spacing wish column %d has no right item.", r));
81     }
82   else
83     {
84       me->set_grob_property ("right-column", ri->column_l ()->self_scm());
85     }
86   
87   return SCM_UNSPECIFIED;
88 }