2 paper-column.cc -- implement Paper_column
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2006 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 (int count) const
30 return new Paper_column (*this, count);
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, Object_key const *key)
64 : Item (l, key) // guh.?
70 Paper_column::Paper_column (Paper_column const &src, int count)
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, 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 System * my_system = me->get_system ();
171 SCM small_letters = scm_cons (scm_acons (ly_symbol2scm ("font-size"),
172 scm_from_int (-6), SCM_EOL),
176 for (SCM s = me->get_object ("ideal-distances");
177 scm_is_pair (s); s = scm_cdr (s))
179 Spring_smob *sp = unsmob_spring (scm_car (s));
183 pts.push_back (Offset (0, y));
185 Offset p2 (sp->distance_, y);
188 Stencil id_stencil = Lookup::points_to_line_stencil (0.1, pts);
189 Stencil head (musfont->find_by_name ("arrowheads.open.01"));
191 SCM distance_stc = Text_interface::interpret_markup (me->layout ()->self_scm (),
193 ly_string2scm (String_convert::form_string ("%5.2lf", sp->distance_)));
195 id_stencil.add_stencil (unsmob_stencil (distance_stc)->translated (Offset (sp->distance_/3, y+1)));
196 id_stencil.add_stencil (head.translated (p2));
197 id_stencil = id_stencil.in_color (0,0,1);
198 l.add_stencil (id_stencil);
201 for (SCM s = me->get_object ("minimum-distances");
202 scm_is_pair (s); s = scm_cdr (s))
204 Real dist = scm_to_double (scm_cdar (s));
206 Real y = -j * 0.1 -3.5;
208 pts.push_back (Offset (0, y));
213 Stencil id_stencil = Lookup::points_to_line_stencil (0.1, pts);
214 Stencil head (musfont->find_by_name ("arrowheads.open.0M1"));
215 head.translate_axis (y, Y_AXIS);
216 id_stencil.add_stencil (head);
218 SCM distance_stc = Text_interface::interpret_markup (me->layout ()->self_scm (),
220 ly_string2scm (String_convert::form_string ("%5.2lf",
223 id_stencil.add_stencil (unsmob_stencil (distance_stc)->translated (Offset (dist/3, y-1)));
226 id_stencil = id_stencil.in_color (1,0,0);
227 l.add_stencil (id_stencil);
230 return t.smobbed_copy ();
234 This is all too hairy. We use bounded-by-me to make sure that some
235 columns are kept "alive". Unfortunately, when spanners are suicided,
236 this falls apart again, because suicided spanners are still in
239 THIS IS BROKEN KLUDGE. WE SHOULD INVENT SOMETHING BETTER.
241 MAKE_SCHEME_CALLBACK (Paper_column, before_line_breaking, 1);
243 Paper_column::before_line_breaking (SCM grob)
245 Grob *me = unsmob_grob (grob);
247 SCM bbm = me->get_object ("bounded-by-me");
248 Grob_array *ga = unsmob_grob_array (bbm);
250 return SCM_UNSPECIFIED;
252 vector<Grob*> &array (ga->array_reference ());
254 for (vsize i = array.size (); i--;)
258 if (!g || !g->is_live ())
259 /* UGH . potentially quadratic. */
260 array.erase (array.begin () + i);
263 return SCM_UNSPECIFIED;
267 ADD_INTERFACE (Paper_column,
268 "@code{Paper_column} objects form the top-most X-parents for items."
269 " The are two types of columns: musical columns, where are attached to, and "
270 " non-musical columns, where bar-lines, clefs etc. are attached to. "
271 " The spacing engine determines the X-positions of these objects."
275 " numbered, the first (leftmost) is column 0. Numbering happens before\n"
276 " line-breaking, and columns are not renumbered after line breaking.\n"
277 " Since many columns go unused, you should only use the rank field to\n"
278 " get ordering information. Two adjacent columns may have\n"
279 " non-adjacent numbers.\n",
286 "line-break-system-details "
287 "line-break-penalty "
288 "line-break-permission "
289 "page-break-penalty "
290 "page-break-permission "
292 "page-turn-permission "
294 "shortest-playing-duration "
295 "shortest-starter-duration "