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"
27 Paper_column::clone (int count) const
29 return new Paper_column (*this, count);
33 Paper_column::do_break_processing ()
35 Item::do_break_processing ();
39 Paper_column::get_rank (Grob const *me)
41 return dynamic_cast<Paper_column const *> (me)->rank_;
45 Paper_column::get_system () const
51 Paper_column::set_system (System *s)
57 Paper_column::get_column () const
59 return (Paper_column *) (this);
62 Paper_column::Paper_column (SCM l, Object_key const *key)
63 : Item (l, key) // guh.?
69 Paper_column::Paper_column (Paper_column const &src, int count)
77 Paper_column::compare (Grob * const &a,
80 return sign (dynamic_cast<Paper_column*> (a)->rank_
81 - dynamic_cast<Paper_column*> (b)->rank_);
85 Paper_column::less_than (Grob *const &a,
88 Paper_column *pa = dynamic_cast<Paper_column*> (a);
89 Paper_column *pb = dynamic_cast<Paper_column*> (b);
91 return pa->rank_ < pb->rank_;
95 Paper_column::when_mom (Grob *me)
97 SCM m = me->get_property ("when");
98 if (Moment *when = unsmob_moment (m))
104 Paper_column::is_musical (Grob *me)
106 SCM m = me->get_property ("shortest-starter-duration");
108 if (unsmob_moment (m))
109 s = *unsmob_moment (m);
110 return s != Moment (0);
114 Paper_column::is_used (Grob *me)
116 extract_grob_set (me, "elements", elts);
120 extract_grob_set (me, "bounded-by-me", bbm);
124 if (Paper_column::is_breakable (me))
127 if (to_boolean (me->get_property ("used")))
133 Paper_column::is_breakable (Grob *me)
135 return scm_is_symbol (me->get_property ("line-break-permission"));
139 Print a vertical line and the rank number, to aid debugging.
141 MAKE_SCHEME_CALLBACK (Paper_column, print, 1);
143 Paper_column::print (SCM p)
145 Paper_column *me = dynamic_cast<Paper_column*> (unsmob_grob (p));
147 string r = to_string (Paper_column::get_rank (me));
149 Moment *mom = unsmob_moment (me->get_property ("when"));
150 string when = mom ? mom->to_string () : "?/?";
152 Font_metric *musfont = Font_interface::get_default_font (me);
153 SCM properties = Font_interface::text_font_alist_chain (me);
155 SCM scm_mol = Text_interface::interpret_markup (me->layout ()->self_scm (),
158 SCM when_mol = Text_interface::interpret_markup (me->layout ()->self_scm (),
160 ly_string2scm (when));
161 Stencil t = *unsmob_stencil (scm_mol);
162 t.add_at_edge (Y_AXIS, DOWN, *unsmob_stencil (when_mol), 0.1, 0.1);
163 t.align_to (X_AXIS, CENTER);
164 t.align_to (Y_AXIS, DOWN);
166 Stencil l = Lookup::filled_box (Box (Interval (-0.01, 0.01),
171 System * my_system = me->get_system ();
174 - my_system->get_bound (LEFT)->get_column ()->get_rank ();
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));
181 Real y = -j * 0.1 -3;
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 id_stencil.add_stencil (head);
192 id_stencil = id_stencil.in_color (0,0,1);
193 l.add_stencil (id_stencil) ;
197 for (SCM s = me->get_object ("minimum-distances");
198 scm_is_pair (s); s = scm_cdr (s))
200 Grob *other = unsmob_grob (scm_caar (s));
201 Real dist = scm_to_double (scm_cdar (s));
203 Real y = -j * 0.1 -3.5;
205 pts.push_back (Offset (0, y));
210 Stencil id_stencil = Lookup::points_to_line_stencil (0.1, pts);
211 Stencil head (musfont->find_by_name ("arrowheads.open.0M1"));
212 head.translate_axis (y, Y_AXIS);
213 id_stencil.add_stencil (head);
215 id_stencil = id_stencil.in_color (1,0,0);
216 l.add_stencil (id_stencil);
219 return t.smobbed_copy ();
223 This is all too hairy. We use bounded-by-me to make sure that some
224 columns are kept "alive". Unfortunately, when spanners are suicided,
225 this falls apart again, because suicided spanners are still in
228 THIS IS BROKEN KLUDGE. WE SHOULD INVENT SOMETHING BETTER.
230 MAKE_SCHEME_CALLBACK (Paper_column, before_line_breaking, 1);
232 Paper_column::before_line_breaking (SCM grob)
234 Grob *me = unsmob_grob (grob);
236 SCM bbm = me->get_object ("bounded-by-me");
237 Grob_array *ga = unsmob_grob_array (bbm);
239 return SCM_UNSPECIFIED;
241 vector<Grob*> &array (ga->array_reference ());
243 for (vsize i = array.size (); i--;)
247 if (!g || !g->is_live ())
248 /* UGH . potentially quadratic. */
249 array.erase (array.begin () + i);
252 return SCM_UNSPECIFIED;
256 ADD_INTERFACE (Paper_column,
257 "@code{Paper_column} objects form the top-most X-parents for items."
258 " The are two types of columns: musical columns, where are attached to, and "
259 " non-musical columns, where bar-lines, clefs etc. are attached to. "
260 " The spacing engine determines the X-positions of these objects."
264 " numbered, the first (leftmost) is column 0. Numbering happens before\n"
265 " line-breaking, and columns are not renumbered after line breaking.\n"
266 " Since many columns go unused, you should only use the rank field to\n"
267 " get ordering information. Two adjacent columns may have\n"
268 " non-adjacent numbers.\n",
275 "line-break-system-details "
276 "line-break-penalty "
277 "line-break-permission "
278 "page-break-penalty "
279 "page-break-permission "
281 "page-turn-permission "
283 "shortest-playing-duration "
284 "shortest-starter-duration "