2 separation-item.cc -- implement Separation_item
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
9 #include "separation-item.hh"
11 #include "accidental-placement.hh"
12 #include "axis-group-interface.hh"
14 #include "note-column.hh"
15 #include "note-head.hh"
16 #include "paper-column.hh"
17 #include "pointer-group-interface.hh"
18 #include "skyline-pair.hh"
23 Separation_item::add_item (Grob
*s
, Item
*i
)
26 Pointer_group_interface::add_grob (s
, ly_symbol2scm ("elements"), i
);
30 Separation_item::add_conditional_item (Grob
*me
, Grob
*e
)
32 Pointer_group_interface::add_grob (me
, ly_symbol2scm ("conditional-elements"), e
);
36 Separation_item::set_distance (Item
*l
, Item
*r
, Real padding
)
38 Drul_array
<Skyline_pair
*> lines (Skyline_pair::unsmob (l
->get_property ("horizontal-skylines")),
39 Skyline_pair::unsmob (r
->get_property ("horizontal-skylines")));
40 Skyline right
= conditional_skyline (r
, l
);
41 right
.merge ((*lines
[RIGHT
])[LEFT
]);
43 Real dist
= padding
+ (*lines
[LEFT
])[RIGHT
].distance (right
);
48 rod
.item_drul_
= Drul_array
<Item
*> (l
, r
);
54 return max (dist
, 0.0);
58 Separation_item::is_empty (Grob
*me
)
60 Skyline_pair
*sky
= Skyline_pair::unsmob (me
->get_property ("horizontal-skylines"));
61 return (!sky
|| sky
->is_empty ());
65 Return the width of ME given that we are considering the object on
69 Separation_item::conditional_skyline (Grob
*me
, Grob
*left
)
71 vector
<Box
> bs
= boxes (me
, left
);
72 return Skyline (bs
, 0.1, Y_AXIS
, LEFT
);
76 MAKE_SCHEME_CALLBACK (Separation_item
, calc_skylines
,1);
78 Separation_item::calc_skylines (SCM smob
)
80 Item
*me
= unsmob_item (smob
);
81 vector
<Box
> bs
= boxes (me
, 0);
82 /* todo: the horizon_padding is somewhat arbitrary */
83 return Skyline_pair (bs
, 0.1, Y_AXIS
).smobbed_copy ();
86 /* if left is non-NULL, get the boxes corresponding to the
87 conditional-elements (conditioned on the grob LEFT). This
88 sounds more general than it is: conditional-elements are
89 always accidentals attached to a tied note.
92 Separation_item::boxes (Grob
*me
, Grob
*left
)
94 Item
*item
= dynamic_cast<Item
*> (me
);
96 int very_large
= INT_MAX
;
97 Paper_column
*pc
= item
->get_column ();
99 extract_grob_set (me
, left
? "conditional-elements" : "elements", read_only_elts
);
103 elts
= Accidental_placement::get_relevant_accidentals (read_only_elts
, left
);
106 elts
= read_only_elts
;
108 /* This is a special-case for NoteColumn: we want to include arpeggio in its
109 skyline (so spacing takes it into account) but we don't want to include it
110 in the NoteColumn's extent because some spanners (eg. Hairpin) bound themselves
111 on the NoteColumn and we don't want them to include arpeggios in their bounds.
113 if (Grob
*a
= Note_column::arpeggio (me
)) {
118 Grob
*ycommon
= common_refpoint_of_array (elts
, me
, Y_AXIS
);
120 for (vsize i
= 0; i
< elts
.size (); i
++)
122 Item
*il
= dynamic_cast<Item
*> (elts
[i
]);
123 if (pc
!= il
->get_column ())
126 /* ugh. We want to exclude groups of grobs (so that we insert each grob
127 individually into the skyline instead of adding a single box that
128 bounds all of them). However, we can't exclude an axis-group that
129 adds to its childrens' stencil. Currently, this is just TrillPitchGroup;
130 hence the check for note-head-interface. */
131 if (Axis_group_interface::has_interface (il
)
132 && !Note_head::has_interface (il
))
135 Interval
y (il
->pure_height (ycommon
, 0, very_large
));
136 Interval
x (il
->extent (pc
, X_AXIS
));
138 Interval extra
= robust_scm2interval (elts
[i
]->get_property ("extra-spacing-width"),
139 Interval (-0.1, 0.1));
140 x
[LEFT
] += extra
[LEFT
];
141 x
[RIGHT
] += extra
[RIGHT
];
142 if (to_boolean (elts
[i
]->get_property ("infinite-spacing-height")))
143 y
= Interval (-infinity_f
, infinity_f
);
145 if (!x
.is_empty () && !y
.is_empty ())
146 out
.push_back (Box (x
, y
));
152 MAKE_SCHEME_CALLBACK (Separation_item
, print
, 1)
154 Separation_item::print (SCM smob
)
159 Grob
*me
= unsmob_grob (smob
);
161 if (Skyline_pair
*s
= Skyline_pair::unsmob (me
->get_property ("horizontal-skylines")))
163 ret
.add_stencil (Lookup::points_to_line_stencil (0.1, (*s
)[LEFT
].to_points (Y_AXIS
)).in_color (255, 255, 0));
164 ret
.add_stencil (Lookup::points_to_line_stencil (0.1, (*s
)[RIGHT
].to_points (Y_AXIS
)).in_color (0, 255, 255));
166 return ret
.smobbed_copy ();
169 ADD_INTERFACE (Separation_item
,
170 "Item that computes widths to generate spacing rods.",
174 "conditional-elements "
177 "horizontal-skylines "