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_width
= robust_scm2interval (elts
[i
]->get_property ("extra-spacing-width"),
139 Interval (-0.1, 0.1));
140 Interval extra_height
= robust_scm2interval (elts
[i
]->get_property ("extra-spacing-height"),
141 Interval (-0.1, 0.1));
143 x
[LEFT
] += extra_width
[LEFT
];
144 x
[RIGHT
] += extra_width
[RIGHT
];
145 y
[DOWN
] += extra_height
[DOWN
];
146 y
[UP
] += extra_height
[UP
];
148 if (!x
.is_empty () && !y
.is_empty ())
149 out
.push_back (Box (x
, y
));
155 MAKE_SCHEME_CALLBACK (Separation_item
, print
, 1)
157 Separation_item::print (SCM smob
)
162 Grob
*me
= unsmob_grob (smob
);
164 if (Skyline_pair
*s
= Skyline_pair::unsmob (me
->get_property ("horizontal-skylines")))
166 ret
.add_stencil (Lookup::points_to_line_stencil (0.1, (*s
)[LEFT
].to_points (Y_AXIS
)).in_color (255, 255, 0));
167 ret
.add_stencil (Lookup::points_to_line_stencil (0.1, (*s
)[RIGHT
].to_points (Y_AXIS
)).in_color (0, 255, 255));
169 return ret
.smobbed_copy ();
172 ADD_INTERFACE (Separation_item
,
173 "Item that computes widths to generate spacing rods.",
177 "conditional-elements "
180 "horizontal-skylines "