]> git.donarmstrong.com Git - lilypond.git/blob - lily/staff-spacing.cc
release: 1.5.37
[lilypond.git] / lily / staff-spacing.cc
1 /*   
2 staff-spacing.cc --  implement Staff_spacing
3
4 source file of the GNU LilyPond music typesetter
5
6 (c) 2001--2002  Han-Wen Nienhuys <hanwen@cs.uu.nl>
7
8  */
9 #include "paper-column.hh" 
10 #include "separation-item.hh"
11 #include "item.hh"
12 #include "staff-spacing.hh"
13 #include "grob.hh"
14 #include "warn.hh"
15
16 bool
17 Staff_spacing::has_interface (Grob* g)
18 {
19   return g && g->has_interface (ly_symbol2scm ("staff-spacing-interface"));
20 }
21
22
23 /*
24 */
25 void
26 Staff_spacing::get_spacing_params (Grob *me, Real * space, Real * fixed)
27 {
28   *space = 1.0;
29   *fixed = 1.0;
30
31   
32
33   Grob * separation_item=0;
34   
35   for (SCM s = me->get_grob_property ("left-items");
36        gh_pair_p (s); s = gh_cdr(s))
37     {
38       Grob * cand = unsmob_grob(gh_car (s));
39       if (cand && Separation_item::has_interface (cand))
40         separation_item = cand ;
41     }
42
43   Grob *left_col = dynamic_cast<Item*> (me)->column_l ();
44
45   Grob *last_grob = 0;
46   Interval last_ext ;
47
48   if (!separation_item)
49     {
50       programming_error ("no sep item");
51       return;
52     }
53   
54   for (SCM s = separation_item->get_grob_property ("elements");
55        gh_pair_p (s); s = gh_cdr (s))
56     {
57       Grob * break_item = unsmob_grob (gh_car (s));
58
59       
60       if (!gh_symbol_p (break_item->get_grob_property ("break-align-symbol")))
61         continue;
62
63       Interval ext = break_item->extent (left_col, X_AXIS);
64
65       if (ext.empty_b ())
66         continue;
67       if (!last_grob
68           || (last_grob && ext[RIGHT] > last_ext[RIGHT]))
69         {
70           last_ext = ext;
71           last_grob = break_item; 
72         }
73     }
74
75   if (!last_grob)
76     {
77       programming_error ("empty break column? --fixme");
78       return ;
79     }
80
81   *fixed = last_ext[RIGHT];
82   *space = *fixed + 1.0;
83   
84   SCM alist = last_grob->get_grob_property ("space-alist");
85   if (!scm_list_p (alist))
86     return ;
87
88   SCM space_def = scm_sloppy_assq (ly_symbol2scm ("begin-of-note"), alist);
89   if (!gh_pair_p (space_def))
90     {
91       programming_error ("Unknown prefatory spacing. "); 
92       return; 
93     }
94
95   space_def = gh_cdr (space_def);
96   Real distance = gh_scm2double (gh_cdr (space_def));
97   SCM type = gh_car (space_def) ;
98
99   *fixed = last_ext[RIGHT];
100   if (type == ly_symbol2scm ("extra-space"))
101     *space = *fixed + distance;
102   else if (type == ly_symbol2scm("minimum-space"))
103     *space = last_ext[LEFT] + (last_ext.length () >? distance);
104   
105 }