]> git.donarmstrong.com Git - lilypond.git/blob - lily/separation-item.cc
* scm/music-functions.scm (has-request-chord): don't use
[lilypond.git] / lily / separation-item.cc
1 /*   
2      separation-item.cc --  implement Separation_item
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 "separation-item.hh"
11
12 #include "paper-column.hh"
13 #include "warn.hh"
14 #include "group-interface.hh"
15 #include "accidental-placement.hh"
16
17 void
18 Separation_item::add_item (Grob*s, Item* i)
19 {
20   assert (i);
21   Pointer_group_interface::add_grob (s, ly_symbol2scm ("elements"), i);
22   s->add_dependency (i);
23 }
24
25 void
26 Separation_item::add_conditional_item (Grob* me , Grob *e)
27 {
28   Pointer_group_interface::add_grob (me, ly_symbol2scm ("conditional-elements"), e);
29 }
30
31 /*
32   Return the width of ME given that we are considering the object on
33   the LEFT.
34  */
35 Interval
36 Separation_item::conditional_width (Grob * me, Grob * left)
37 {
38   Interval w = width (me);
39   
40   Item *item = dynamic_cast<Item*> (me);
41   Paper_column * pc = item->get_column ();
42   
43   
44   for (SCM s =  me->get_property ("conditional-elements"); scm_is_pair (s); s = scm_cdr (s))
45     {
46       SCM elt = scm_car (s);
47       if (!unsmob_grob (elt))
48         continue;
49       
50       Item *il = unsmob_item (elt);
51       if (pc != il->get_column ())
52         {
53           /* this shouldn't happen, but let's continue anyway. */
54           programming_error (_ ("Separation_item:  I've been drinking too much"));
55           continue;             /*UGH UGH*/ 
56         }
57
58       if (to_boolean (il->get_property ("no-spacing-rods")))
59         {
60           continue;
61         }
62
63       if (Accidental_placement::has_interface (il))
64         {
65           w.unite (Accidental_placement::get_relevant_accidental_extent (il, pc, left));
66         }
67     }
68
69   SCM pad = me->get_property ("padding");
70
71   w.widen (robust_scm2double (pad, 0.0));
72   return w;
73 }
74
75 Interval
76 Separation_item::width (Grob *me)
77 {
78   SCM sw = me->get_property ("X-extent");
79   if (is_number_pair (sw))
80     {
81       return ly_scm2interval (sw);
82     }
83
84   Item *item = dynamic_cast<Item*> (me);
85   Paper_column * pc = item->get_column ();
86   Interval w;
87   
88   for (SCM s =  me->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s))
89     {
90       SCM elt = scm_car (s);
91       if (!unsmob_grob (elt))
92         continue;
93
94       Item *il = unsmob_item (elt);
95       if (pc != il->get_column ())
96         {
97           /* this shouldn't happen, but let's continue anyway. */
98           programming_error (_ ("Separation_item:  I've been drinking too much"));
99           continue;             /*UGH UGH*/ 
100         }
101
102       if (to_boolean (il->get_property ("no-spacing-rods")))
103         {
104           continue;
105         }
106
107       Interval iv (il->extent (pc, X_AXIS));
108       if (!iv.is_empty ())
109         {
110           w.unite (iv);
111         }
112     }
113
114   SCM pad = me->get_property ("padding");
115
116   w.widen (robust_scm2double (pad, 0.0));
117
118   me->set_property ("X-extent", ly_interval2scm (w));
119   
120   return w;
121 }
122
123 Interval
124 Separation_item::relative_width (Grob * me, Grob * common)
125 {
126   Interval iv = width (me);
127
128   return dynamic_cast<Item*>(me)->get_column ()->relative_coordinate (common, X_AXIS) + iv ;
129 }
130
131
132 /*
133   Try to find the break-aligned symbol in SEPARATION_ITEM that is
134   sticking out at direction D. The x size is put in LAST_EXT
135 */
136 Grob*
137 Separation_item::extremal_break_aligned_grob (Grob *separation_item, Direction d,
138                                             Interval * last_ext)
139 {
140   Grob *col = dynamic_cast<Item*> (separation_item)->get_column ();
141   last_ext->set_empty ();
142   Grob *last_grob = 0;
143   for (SCM s = separation_item->get_property ("elements");
144        scm_is_pair (s); s = scm_cdr (s))
145     {
146       Grob * break_item = unsmob_grob (scm_car (s));
147       
148       if (!scm_is_symbol (break_item->get_property ("break-align-symbol")))
149         continue;
150
151       Interval ext = break_item->extent (col, X_AXIS);
152
153       if (ext.is_empty ())
154         continue;
155       if (!last_grob
156           || (last_grob && d * (ext[d]- (*last_ext)[d]) > 0) )
157         {
158           *last_ext = ext;
159           last_grob = break_item; 
160         }
161     }
162
163   return last_grob;  
164 }
165
166
167
168
169
170 ADD_INTERFACE (Separation_item, "separation-item-interface",
171                "Item that computes widths to generate spacing rods. "
172                "This is done in concert with @ref{separation-spanner-interface}."
173                
174                ,
175
176                "padding X-extent conditional-elements elements");