]> git.donarmstrong.com Git - lilypond.git/blob - lily/separating-group-spanner.cc
* scm/music-functions.scm (has-request-chord): don't use
[lilypond.git] / lily / separating-group-spanner.cc
1 /*   
2   separating-group-spanner.cc --  implement Separating_group_spanner
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1998--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "separating-group-spanner.hh"
11
12 #include "separation-item.hh"
13 #include "paper-column.hh"
14 #include "output-def.hh"
15 #include "dimensions.hh"
16 #include "group-interface.hh"
17
18 void
19 Separating_group_spanner::find_rods (Item * r, SCM next, Real padding)
20 {
21
22   /*
23     This is an inner loop: look for the first normal (unbroken) Left
24     grob.  This looks like an inner loop (ie. quadratic total), but in
25     most cases, the interesting L will just be the first entry of
26     NEXT, making it linear in most of the cases.
27   */
28   if (Separation_item::width (r).is_empty ())
29     return; 
30
31
32   for (; scm_is_pair (next); next = scm_cdr (next))
33     {
34       Item *l = dynamic_cast<Item*> (unsmob_grob (scm_car ( next)));
35       Item *lb = l->find_prebroken_piece (RIGHT);
36
37       if (lb)
38         {
39           Interval li (Separation_item::width (lb));
40           Interval ri (Separation_item::conditional_width (r, lb));
41           if (!li.is_empty () && !ri.is_empty ())
42             {
43               Rod rod;
44
45               rod.item_l_drul_[LEFT] = lb;
46               rod.item_l_drul_[RIGHT] = r;
47
48               rod.distance_ = li[RIGHT] - ri[LEFT] + padding;
49               rod.add_to_cols ();
50             }
51         }
52
53       Interval li (Separation_item::width (l));
54       Interval ri (Separation_item::conditional_width (r, l));
55       if (!li.is_empty () && !ri.is_empty ())
56         {
57           Rod rod;
58
59           rod.item_l_drul_[LEFT] = l;
60           rod.item_l_drul_[RIGHT]= r;
61
62           rod.distance_ = li[RIGHT] - ri[LEFT] + padding;
63         
64           rod.add_to_cols ();
65           break;
66         }
67
68       /*
69         this grob doesn't cause a constraint. We look further until we
70         find one that does.
71       */
72
73     }
74 }
75
76 MAKE_SCHEME_CALLBACK (Separating_group_spanner, set_spacing_rods, 1);
77 SCM
78 Separating_group_spanner::set_spacing_rods (SCM smob)
79 {
80   Grob*me = unsmob_grob (smob);
81
82   /*
83     Ugh: padding is added doubly, also for SeparationItem
84    */
85   Real padding = robust_scm2double (me->get_property ("padding"), 0.1);
86   
87   for (SCM s = me->get_property ("elements"); scm_is_pair (s) && scm_is_pair (scm_cdr (s)); s = scm_cdr (s))
88     {
89       /*
90         Order of elements is reversed!
91        */
92       SCM elt = scm_car (s);
93       Item *r = unsmob_item (elt);
94
95       if (!r)
96         continue;
97
98       Item *rb
99         = dynamic_cast<Item*> (r->find_prebroken_piece (LEFT));
100       
101       find_rods (r, scm_cdr (s), padding);
102       if (rb)
103         find_rods (rb, scm_cdr (s), padding);
104     }
105
106   return SCM_UNSPECIFIED ;
107 }
108
109 void
110 Separating_group_spanner::add_spacing_unit (Grob* me , Item*i)
111 {
112   Pointer_group_interface::add_grob (me, ly_symbol2scm ("elements"), i);
113   me->add_dependency (i);
114 }
115
116
117
118
119
120 ADD_INTERFACE (Separating_group_spanner, "separation-spanner-interface",
121                "A spanner that calculates spacing constraints (\"rods\") "
122                "using the @code{separation-item-interface} grobs in @code{elements}.",
123                "elements padding");