2 paper-column.cc -- implement Paper_column
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
9 #include "paper-column.hh"
12 #include "paper-score.hh"
14 #include "axis-group-interface.hh"
15 #include "spaceable-grob.hh"
16 #include "text-interface.hh"
18 #include "font-interface.hh"
19 #include "output-def.hh"
20 #include "pointer-group-interface.hh"
21 #include "grob-array.hh"
25 #include "string-convert.hh"
28 Paper_column::clone () const
30 return new Paper_column (*this);
34 Paper_column::do_break_processing ()
36 Item::do_break_processing ();
40 Paper_column::get_rank (Grob const *me)
42 return dynamic_cast<Paper_column const *> (me)->rank_;
46 Paper_column::get_system () const
52 Paper_column::set_system (System *s)
58 Paper_column::get_column () const
60 return (Paper_column *) (this);
63 Paper_column::Paper_column (SCM l)
70 Paper_column::Paper_column (Paper_column const &src)
78 Paper_column::compare (Grob * const &a,
81 return sign (dynamic_cast<Paper_column*> (a)->rank_
82 - dynamic_cast<Paper_column*> (b)->rank_);
86 Paper_column::less_than (Grob *const &a,
89 Paper_column *pa = dynamic_cast<Paper_column*> (a);
90 Paper_column *pb = dynamic_cast<Paper_column*> (b);
92 return pa->rank_ < pb->rank_;
96 Paper_column::when_mom (Grob *me)
98 SCM m = me->get_property ("when");
99 if (Moment *when = unsmob_moment (m))
105 Paper_column::is_musical (Grob *me)
107 SCM m = me->get_property ("shortest-starter-duration");
109 if (unsmob_moment (m))
110 s = *unsmob_moment (m);
111 return s != Moment (0);
115 Paper_column::is_used (Grob *me)
117 extract_grob_set (me, "elements", elts);
121 extract_grob_set (me, "bounded-by-me", bbm);
125 if (Paper_column::is_breakable (me))
128 if (to_boolean (me->get_property ("used")))
134 Paper_column::is_breakable (Grob *me)
136 return scm_is_symbol (me->get_property ("line-break-permission"));
140 Print a vertical line and the rank number, to aid debugging.
142 MAKE_SCHEME_CALLBACK (Paper_column, print, 1);
144 Paper_column::print (SCM p)
146 Paper_column *me = dynamic_cast<Paper_column*> (unsmob_grob (p));
148 string r = to_string (Paper_column::get_rank (me));
150 Moment *mom = unsmob_moment (me->get_property ("when"));
151 string when = mom ? mom->to_string () : "?/?";
153 Font_metric *musfont = Font_interface::get_default_font (me);
154 SCM properties = Font_interface::text_font_alist_chain (me);
156 SCM scm_mol = Text_interface::interpret_markup (me->layout ()->self_scm (),
159 SCM when_mol = Text_interface::interpret_markup (me->layout ()->self_scm (),
161 ly_string2scm (when));
162 Stencil t = *unsmob_stencil (scm_mol);
163 t.add_at_edge (Y_AXIS, DOWN, *unsmob_stencil (when_mol), 0.1);
164 t.align_to (X_AXIS, CENTER);
165 t.align_to (Y_AXIS, DOWN);
167 Stencil l = Lookup::filled_box (Box (Interval (-0.01, 0.01),
170 SCM small_letters = scm_cons (scm_acons (ly_symbol2scm ("font-size"),
171 scm_from_int (-6), SCM_EOL),
175 for (SCM s = me->get_object ("ideal-distances");
176 scm_is_pair (s); s = scm_cdr (s))
178 Spring_smob *sp = unsmob_spring (scm_car (s));
179 if (!sp->other_->get_system ())
185 pts.push_back (Offset (0, y));
187 Offset p2 (sp->distance_, y);
190 Stencil id_stencil = Lookup::points_to_line_stencil (0.1, pts);
191 Stencil head (musfont->find_by_name ("arrowheads.open.01"));
193 SCM distance_stc = Text_interface::interpret_markup (me->layout ()->self_scm (),
195 ly_string2scm (String_convert::form_string ("%5.2lf", sp->distance_)));
197 id_stencil.add_stencil (unsmob_stencil (distance_stc)->translated (Offset (sp->distance_/3, y+1)));
198 id_stencil.add_stencil (head.translated (p2));
199 id_stencil = id_stencil.in_color (0,0,1);
200 l.add_stencil (id_stencil);
203 for (SCM s = me->get_object ("minimum-distances");
204 scm_is_pair (s); s = scm_cdr (s))
206 Real dist = scm_to_double (scm_cdar (s));
207 Grob *other = unsmob_grob (scm_caar (s));
208 if (!other || other->get_system () != me->get_system ())
213 Real y = -j * 1.0 -3.5;
215 pts.push_back (Offset (0, y));
220 Stencil id_stencil = Lookup::points_to_line_stencil (0.1, pts);
221 Stencil head (musfont->find_by_name ("arrowheads.open.0M1"));
222 head.translate_axis (y, Y_AXIS);
223 id_stencil.add_stencil (head);
225 SCM distance_stc = Text_interface::interpret_markup (me->layout ()->self_scm (),
227 ly_string2scm (String_convert::form_string ("%5.2lf",
230 id_stencil.add_stencil (unsmob_stencil (distance_stc)->translated (Offset (dist/3, y-1)));
233 id_stencil = id_stencil.in_color (1,0,0);
234 l.add_stencil (id_stencil);
237 return t.smobbed_copy ();
241 This is all too hairy. We use bounded-by-me to make sure that some
242 columns are kept "alive". Unfortunately, when spanners are suicided,
243 this falls apart again, because suicided spanners are still in
246 THIS IS BROKEN KLUDGE. WE SHOULD INVENT SOMETHING BETTER.
248 MAKE_SCHEME_CALLBACK (Paper_column, before_line_breaking, 1);
250 Paper_column::before_line_breaking (SCM grob)
252 Grob *me = unsmob_grob (grob);
254 SCM bbm = me->get_object ("bounded-by-me");
255 Grob_array *ga = unsmob_grob_array (bbm);
257 return SCM_UNSPECIFIED;
259 vector<Grob*> &array (ga->array_reference ());
261 for (vsize i = array.size (); i--;)
265 if (!g || !g->is_live ())
266 /* UGH . potentially quadratic. */
267 array.erase (array.begin () + i);
270 return SCM_UNSPECIFIED;
274 ADD_INTERFACE (Paper_column,
275 "@code{Paper_column} objects form the top-most X-parents for items."
276 " The are two types of columns: musical columns, where are attached to, and "
277 " non-musical columns, where bar-lines, clefs etc. are attached to. "
278 " The spacing engine determines the X-positions of these objects."
282 " numbered, the first (leftmost) is column 0. Numbering happens before\n"
283 " line-breaking, and columns are not renumbered after line breaking.\n"
284 " Since many columns go unused, you should only use the rank field to\n"
285 " get ordering information. Two adjacent columns may have\n"
286 " non-adjacent numbers.\n",
293 "line-break-system-details "
294 "line-break-penalty "
295 "line-break-permission "
296 "page-break-penalty "
297 "page-break-permission "
299 "page-turn-permission "
301 "shortest-playing-duration "
302 "shortest-starter-duration "