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