LEFT | RIGHT |
1 /* | 1 /* |
2 This file is part of LilyPond, the GNU music typesetter. | 2 This file is part of LilyPond, the GNU music typesetter. |
3 | 3 |
4 Copyright (C) 1996--2011 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 1996--2011 Han-Wen Nienhuys <hanwen@xs4all.nl> |
5 | 5 |
6 LilyPond is free software: you can redistribute it and/or modify | 6 LilyPond is free software: you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
8 the Free Software Foundation, either version 3 of the License, or | 8 the Free Software Foundation, either version 3 of the License, or |
9 (at your option) any later version. | 9 (at your option) any later version. |
10 | 10 |
11 LilyPond is distributed in the hope that it will be useful, | 11 LilyPond is distributed in the hope that it will be useful, |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 GNU General Public License for more details. | 14 GNU General Public License for more details. |
15 | 15 |
16 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>. | 17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>. |
18 */ | 18 */ |
19 | 19 |
20 #include "system.hh" | 20 #include "system.hh" |
21 | 21 |
22 #include "align-interface.hh" | 22 #include "align-interface.hh" |
23 #include "all-font-metrics.hh" | 23 #include "all-font-metrics.hh" |
24 #include "axis-group-interface.hh" | 24 #include "axis-group-interface.hh" |
25 #include "break-align-interface.hh" | 25 #include "break-align-interface.hh" |
| 26 #include "column-description.hh" |
26 #include "grob-array.hh" | 27 #include "grob-array.hh" |
27 #include "hara-kiri-group-spanner.hh" | 28 #include "hara-kiri-group-spanner.hh" |
28 #include "international.hh" | 29 #include "international.hh" |
29 #include "lookup.hh" | 30 #include "lookup.hh" |
30 #include "main.hh" | 31 #include "main.hh" |
31 #include "output-def.hh" | 32 #include "output-def.hh" |
32 #include "page-layout-problem.hh" | 33 #include "page-layout-problem.hh" |
33 #include "paper-column.hh" | 34 #include "paper-column.hh" |
34 #include "paper-score.hh" | 35 #include "paper-score.hh" |
35 #include "paper-system.hh" | 36 #include "paper-system.hh" |
36 #include "pointer-group-interface.hh" | 37 #include "pointer-group-interface.hh" |
37 #include "skyline-pair.hh" | 38 #include "skyline-pair.hh" |
38 #include "staff-symbol-referencer.hh" | 39 #include "staff-symbol-referencer.hh" |
39 #include "text-interface.hh" | 40 #include "text-interface.hh" |
40 #include "warn.hh" | 41 #include "warn.hh" |
| 42 #include "unpure-pure-container.hh" |
41 | 43 |
42 System::System (System const &src) | 44 System::System (System const &src) |
43 : Spanner (src) | 45 : Spanner (src) |
44 { | 46 { |
45 all_elements_ = 0; | 47 all_elements_ = 0; |
46 pscore_ = 0; | 48 pscore_ = 0; |
47 rank_ = 0; | 49 rank_ = 0; |
48 checked_footnotes_ = false; | |
49 init_elements (); | 50 init_elements (); |
50 } | 51 } |
51 | 52 |
52 System::System (SCM s) | 53 System::System (SCM s) |
53 : Spanner (s) | 54 : Spanner (s) |
54 { | 55 { |
55 all_elements_ = 0; | 56 all_elements_ = 0; |
56 rank_ = 0; | 57 rank_ = 0; |
57 checked_footnotes_ = false; | |
58 init_elements (); | 58 init_elements (); |
59 } | 59 } |
60 | 60 |
61 void | 61 void |
62 System::init_elements () | 62 System::init_elements () |
63 { | 63 { |
64 SCM scm_arr = Grob_array::make_array (); | 64 SCM scm_arr = Grob_array::make_array (); |
65 all_elements_ = unsmob_grob_array (scm_arr); | 65 all_elements_ = unsmob_grob_array (scm_arr); |
66 all_elements_->set_ordered (false); | 66 all_elements_->set_ordered (false); |
67 set_object ("all-elements", scm_arr); | 67 set_object ("all-elements", scm_arr); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 | 182 |
183 /* Because the this->get_property (all-elements) contains items in 3 | 183 /* Because the this->get_property (all-elements) contains items in 3 |
184 versions, handle_broken_dependencies () will leave duplicated | 184 versions, handle_broken_dependencies () will leave duplicated |
185 items in all-elements. Strictly speaking this is harmless, but | 185 items in all-elements. Strictly speaking this is harmless, but |
186 it leads to duplicated symbols in the output. uniq makes sure | 186 it leads to duplicated symbols in the output. uniq makes sure |
187 that no duplicates are in the list. */ | 187 that no duplicates are in the list. */ |
188 for (vsize i = 0; i < broken_intos_.size (); i++) | 188 for (vsize i = 0; i < broken_intos_.size (); i++) |
189 { | 189 { |
190 System *child = dynamic_cast<System *> (broken_intos_[i]); | 190 System *child = dynamic_cast<System *> (broken_intos_[i]); |
191 child->all_elements_->remove_duplicates (); | 191 child->all_elements_->remove_duplicates (); |
| 192 |
192 for (vsize j = 0; j < child->all_elements_->size (); j++) | 193 for (vsize j = 0; j < child->all_elements_->size (); j++) |
193 { | 194 { |
194 Grob *g = child->all_elements_->grob (j); | 195 Grob *g = child->all_elements_->grob (j); |
195 | 196 |
196 (void) g->get_property ("after-line-breaking"); | 197 (void) g->get_property ("after-line-breaking"); |
197 } | 198 } |
198 } | 199 } |
199 | 200 |
200 if (be_verbose_global) | 201 debug_output (_f ("Element count %d", count + element_count ()) + "\n"); |
201 message (_f ("Element count %d", count + element_count ()) + "\n"); | |
202 } | 202 } |
203 | 203 |
204 SCM | 204 SCM |
205 System::get_broken_system_grobs () | 205 System::get_broken_system_grobs () |
206 { | 206 { |
207 SCM ret = SCM_EOL; | 207 SCM ret = SCM_EOL; |
208 for (vsize i = 0; i < broken_intos_.size (); i++) | 208 for (vsize i = 0; i < broken_intos_.size (); i++) |
209 ret = scm_cons (broken_intos_[i]->self_scm (), ret); | 209 ret = scm_cons (broken_intos_[i]->self_scm (), ret); |
210 return scm_reverse (ret); | 210 return scm_reverse (ret); |
211 } | 211 } |
212 | 212 |
213 SCM | 213 SCM |
214 System::get_paper_systems () | 214 System::get_paper_systems () |
215 { | 215 { |
216 SCM lines = scm_c_make_vector (broken_intos_.size (), SCM_EOL); | 216 SCM lines = scm_c_make_vector (broken_intos_.size (), SCM_EOL); |
217 for (vsize i = 0; i < broken_intos_.size (); i++) | 217 for (vsize i = 0; i < broken_intos_.size (); i++) |
218 { | 218 { |
219 if (be_verbose_global) | 219 debug_output ("[", false); |
220 progress_indication ("["); | |
221 | 220 |
222 System *system = dynamic_cast<System *> (broken_intos_[i]); | 221 System *system = dynamic_cast<System *> (broken_intos_[i]); |
223 | 222 |
224 scm_vector_set_x (lines, scm_from_int (i), | 223 scm_vector_set_x (lines, scm_from_int (i), |
225 system->get_paper_system ()); | 224 system->get_paper_system ()); |
226 | 225 |
227 if (be_verbose_global) | 226 debug_output (to_string (i) + "]", false); |
228 progress_indication (to_string (i) + "]"); | |
229 } | 227 } |
230 return lines; | 228 return lines; |
231 } | 229 } |
232 | 230 |
233 void | 231 vector<Grob *> |
234 System::populate_footnote_grob_vector () | 232 System::get_footnote_grobs_in_range (vsize start, vsize end) |
235 { | 233 { |
236 extract_grob_set (this, "all-elements", all_elts); | 234 vector<Grob *> out; |
237 for (vsize i = 0; i < all_elts.size (); i++) | 235 extract_grob_set (this, "footnotes-before-line-breaking", footnote_grobs); |
238 if (all_elts[i]->internal_has_interface (ly_symbol2scm ("footnote-interface"
))) | 236 for (vsize i = 0; i < footnote_grobs.size (); i++) |
239 footnote_grobs_.push_back (all_elts[i]); | 237 { |
240 | 238 Grob *at_bat = footnote_grobs[i]; |
241 vector_sort (footnote_grobs_, Grob::less); | 239 int pos = at_bat->spanned_rank_interval ()[LEFT]; |
242 checked_footnotes_ = true; | |
243 } | |
244 | |
245 void | |
246 System::get_footnote_grobs_in_range (vector<Grob *> &out, vsize start, vsize end
) | |
247 { | |
248 if (!checked_footnotes_) | |
249 populate_footnote_grob_vector (); | |
250 | |
251 for (vsize i = 0; i < footnote_grobs_.size (); i++) | |
252 { | |
253 int pos = footnote_grobs_[i]->spanned_rank_interval ()[LEFT]; | |
254 bool end_of_line_visible = true; | 240 bool end_of_line_visible = true; |
255 if (Spanner *s = dynamic_cast<Spanner *>(footnote_grobs_[i])) | 241 if (Spanner *s = dynamic_cast<Spanner *>(at_bat)) |
256 { | 242 { |
257 Direction spanner_placement = robust_scm2dir (s->get_property ("spanne
r-placement"), LEFT); | 243 Direction spanner_placement = robust_scm2dir (s->get_property ("spanne
r-placement"), LEFT); |
258 if (spanner_placement == CENTER) | 244 if (spanner_placement == CENTER) |
259 spanner_placement = LEFT; | 245 spanner_placement = LEFT; |
260 | 246 |
261 pos = s->spanned_rank_interval ()[spanner_placement]; | 247 pos = s->spanned_rank_interval ()[spanner_placement]; |
262 } | 248 if (s->original ()) |
263 | 249 { |
264 if (Item *item = dynamic_cast<Item *>(footnote_grobs_[i])) | 250 Spanner *orig = dynamic_cast<Spanner *>(s->original ()); |
| 251 at_bat = spanner_placement == LEFT ? orig->broken_intos_[0] : orig
->broken_intos_.back (); |
| 252 pos = at_bat->spanned_rank_interval ()[RIGHT]; |
| 253 } |
| 254 } |
| 255 |
| 256 if (Item *item = dynamic_cast<Item *>(at_bat)) |
265 { | 257 { |
266 if (!Item::break_visible (item)) | 258 if (!Item::break_visible (item)) |
267 continue; | 259 continue; |
268 // safeguard to bring down the column rank so that end of line footnot
es show up on the correct line | 260 // safeguard to bring down the column rank so that end of line footnot
es show up on the correct line |
269 end_of_line_visible = (LEFT == item->break_status_dir ()); | 261 if (pos == int (start) && item->break_status_dir () != RIGHT) |
| 262 continue; |
| 263 if (pos == int (end) && item->break_status_dir () != LEFT) |
| 264 continue; |
| 265 if (pos != int (end) && pos != int (start) && item->break_status_dir (
) != CENTER) |
| 266 continue; |
270 } | 267 } |
271 | 268 |
272 if (pos < int (start)) | 269 if (pos < int (start)) |
273 continue; | 270 continue; |
274 if (pos > int (end)) | 271 if (pos > int (end)) |
275 break; | 272 continue; |
276 if (pos == int (start) && end_of_line_visible) | 273 if (pos == int (start) && end_of_line_visible) |
277 continue; | 274 continue; |
278 if (pos == int (end) && !end_of_line_visible) | 275 if (pos == int (end) && !end_of_line_visible) |
279 continue; | 276 continue; |
280 if (!footnote_grobs_[i]->is_live ()) | 277 if (!at_bat->is_live ()) |
281 continue; | 278 continue; |
282 | 279 |
283 out.push_back (footnote_grobs_[i]); | 280 out.push_back (at_bat); |
284 } | 281 } |
285 } | 282 return out; |
286 | 283 } |
287 vector<Stencil *> | 284 |
288 System::get_footnotes_in_range (vsize start, vsize end) | 285 vector<Real> |
289 { | 286 System::get_footnote_heights_in_range (vsize start, vsize end) |
290 vector<Grob *> footnote_grobs; | 287 { |
291 get_footnote_grobs_in_range (footnote_grobs, start, end); | 288 return internal_get_note_heights_in_range (start, end, true); |
292 vector<Stencil *> out; | 289 } |
| 290 |
| 291 vector<Real> |
| 292 System::get_in_note_heights_in_range (vsize start, vsize end) |
| 293 { |
| 294 return internal_get_note_heights_in_range (start, end, false); |
| 295 } |
| 296 |
| 297 vector<Real> |
| 298 System::internal_get_note_heights_in_range (vsize start, vsize end, bool foot) |
| 299 { |
| 300 vector<Grob *> footnote_grobs = get_footnote_grobs_in_range (start, end); |
| 301 vector<Real> out; |
| 302 |
| 303 for (vsize i = footnote_grobs.size (); i--;) |
| 304 if (foot |
| 305 ? !to_boolean (footnote_grobs[i]->get_property ("footnote")) |
| 306 : to_boolean (footnote_grobs[i]->get_property ("footnote"))) |
| 307 footnote_grobs.erase (footnote_grobs.begin () + i); |
293 | 308 |
294 for (vsize i = 0; i < footnote_grobs.size (); i++) | 309 for (vsize i = 0; i < footnote_grobs.size (); i++) |
295 { | 310 { |
296 SCM footnote_markup = footnote_grobs[i]->get_property ("footnote-text"); | 311 SCM footnote_markup = footnote_grobs[i]->get_property ("footnote-text"); |
297 | 312 |
298 if (!Text_interface::is_markup (footnote_markup)) | 313 if (!Text_interface::is_markup (footnote_markup)) |
299 continue; | 314 continue; |
300 | 315 |
301 SCM props = scm_call_1 (ly_lily_module_constant ("layout-extract-page-prop
erties"), | 316 SCM props = scm_call_1 (ly_lily_module_constant ("layout-extract-page-prop
erties"), |
302 pscore_->layout ()->self_scm ()); | 317 pscore_->layout ()->self_scm ()); |
303 | 318 |
304 SCM footnote_stl = Text_interface::interpret_markup (pscore_->layout ()->s
elf_scm (), | 319 SCM footnote_stl = Text_interface::interpret_markup (pscore_->layout ()->s
elf_scm (), |
305 props, footnote_marku
p); | 320 props, footnote_marku
p); |
306 | 321 |
307 Stencil *footnote_stencil = unsmob_stencil (footnote_stl); | 322 Stencil *footnote_stencil = unsmob_stencil (footnote_stl); |
308 out.push_back (footnote_stencil); | 323 out.push_back (footnote_stencil->extent (Y_AXIS).length ()); |
309 } | 324 } |
310 | 325 |
311 return out; | 326 return out; |
312 } | 327 } |
313 | 328 |
314 vsize | 329 vsize |
315 System::num_footnotes () | 330 System::num_footnotes () |
316 { | 331 { |
317 return footnote_grobs_.size (); | 332 extract_grob_set (this, "footnotes-after-line-breaking", footnote_grobs); |
| 333 return footnote_grobs.size (); |
318 } | 334 } |
319 | 335 |
320 bool | 336 bool |
321 grob_2D_less (Grob *g1, Grob *g2) | 337 grob_2D_less (Grob *g1, Grob *g2) |
322 { | 338 { |
323 int sri[] = {0,0}; | 339 int sri[] = {0,0}; |
324 Grob *gs[] = {g1, g2}; | 340 Grob *gs[] = {g1, g2}; |
325 | 341 |
326 for (int i = 0; i < 2; i++) | 342 for (int i = 0; i < 2; i++) |
327 { | 343 { |
328 sri[i] = gs[i]->spanned_rank_interval ()[LEFT]; | 344 sri[i] = gs[i]->spanned_rank_interval ()[LEFT]; |
329 if (Spanner *s = dynamic_cast<Spanner *> (gs[i])) | 345 if (Spanner *s = dynamic_cast<Spanner *> (gs[i])) |
330 { | 346 { |
331 if (s->broken_intos_.size ()) | 347 if (s->broken_intos_.size ()) |
332 s = (scm_to_int (s->broken_intos_[0]->get_property ("spanner-placeme
nt")) == LEFT | 348 s = (scm_to_int (s->broken_intos_[0]->get_property ("spanner-placeme
nt")) == LEFT |
333 ? s->broken_intos_[0] | 349 ? s->broken_intos_[0] |
334 : s->broken_intos_.back ()); | 350 : s->broken_intos_.back ()); |
| 351 gs[i] = s; |
335 if (robust_scm2double (s->get_property ("X-offset"), 0.0) > 0) | 352 if (robust_scm2double (s->get_property ("X-offset"), 0.0) > 0) |
336 sri[i] = s->spanned_rank_interval ()[RIGHT]; | 353 sri[i] = s->spanned_rank_interval ()[RIGHT]; |
337 } | 354 } |
338 } | 355 } |
339 | 356 |
340 | |
341 if (sri[0] == sri[1]) | 357 if (sri[0] == sri[1]) |
342 { | 358 return Grob::vertical_less (gs[0], gs[1]); |
343 Grob *commony = g1->common_refpoint (g2, Y_AXIS); | 359 |
344 if (commony) | |
345 return g1->extent (commony, Y_AXIS)[DOWN] > g2->extent (commony, Y_AXIS)
[DOWN]; | |
346 } | |
347 return sri[0] < sri[1]; | 360 return sri[0] < sri[1]; |
348 } | 361 } |
349 | 362 |
350 vector<Grob *>* | 363 MAKE_SCHEME_CALLBACK (System, footnotes_before_line_breaking, 1); |
351 System::footnote_grobs () | 364 SCM |
352 { | 365 System::footnotes_before_line_breaking (SCM smob) |
353 // Careful - don't call this too soon, as it calls a VerticalAlignment | 366 { |
354 vector_sort (footnote_grobs_, grob_2D_less); | 367 Grob *me = unsmob_grob (smob); |
355 return &footnote_grobs_; | 368 vector<Grob *> footnotes; |
| 369 SCM grobs_scm = Grob_array::make_array (); |
| 370 extract_grob_set (me, "all-elements", elts); |
| 371 for (vsize i = 0; i < elts.size (); i++) |
| 372 if (elts[i]->internal_has_interface (ly_symbol2scm ("footnote-interface"))) |
| 373 footnotes.push_back (elts[i]); |
| 374 ···· |
| 375 unsmob_grob_array (grobs_scm)->set_array (footnotes); |
| 376 return grobs_scm; |
| 377 } |
| 378 |
| 379 MAKE_SCHEME_CALLBACK (System, footnotes_after_line_breaking, 1); |
| 380 SCM |
| 381 System::footnotes_after_line_breaking (SCM smob) |
| 382 { |
| 383 Spanner *sys_span = unsmob_spanner (smob); |
| 384 System *sys = dynamic_cast<System *> (sys_span); |
| 385 Interval_t<int> sri = sys->spanned_rank_interval (); |
| 386 vector<Grob *> footnote_grobs = sys->get_footnote_grobs_in_range (sri[LEFT], s
ri[RIGHT]); |
| 387 vector_sort (footnote_grobs, grob_2D_less); |
| 388 |
| 389 SCM grobs_scm = Grob_array::make_array (); |
| 390 unsmob_grob_array (grobs_scm)->set_array (footnote_grobs); |
| 391 return grobs_scm; |
356 } | 392 } |
357 | 393 |
358 void | 394 void |
359 System::break_into_pieces (vector<Column_x_positions> const &breaking) | 395 System::break_into_pieces (vector<Column_x_positions> const &breaking) |
360 { | 396 { |
361 for (vsize i = 0; i < breaking.size (); i++) | 397 for (vsize i = 0; i < breaking.size (); i++) |
362 { | 398 { |
363 System *system = dynamic_cast<System *> (clone ()); | 399 System *system = dynamic_cast<System *> (clone ()); |
364 system->rank_ = broken_intos_.size (); | 400 system->rank_ = broken_intos_.size (); |
365 | 401 |
366 vector<Grob *> c (breaking[i].cols_); | 402 vector<Grob *> c (breaking[i].cols_); |
367 pscore_->typeset_system (system); | 403 pscore_->typeset_system (system); |
368 | 404 |
369 int st = Paper_column::get_rank (c[0]); | 405 int st = Paper_column::get_rank (c[0]); |
370 int end = Paper_column::get_rank (c.back ()); | 406 int end = Paper_column::get_rank (c.back ()); |
371 Interval iv (pure_height (this, st, end)); | 407 Interval iv (pure_height (this, st, end)); |
372 system->set_property ("pure-Y-extent", ly_interval2scm (iv)); | 408 system->set_property ("pure-Y-extent", ly_interval2scm (iv)); |
373 | |
374 get_footnote_grobs_in_range (system->footnote_grobs_, st, end); | |
375 | 409 |
376 system->set_bound (LEFT, c[0]); | 410 system->set_bound (LEFT, c[0]); |
377 system->set_bound (RIGHT, c.back ()); | 411 system->set_bound (RIGHT, c.back ()); |
378 SCM system_labels = SCM_EOL; | 412 SCM system_labels = SCM_EOL; |
379 for (vsize j = 0; j < c.size (); j++) | 413 for (vsize j = 0; j < c.size (); j++) |
380 { | 414 { |
381 c[j]->translate_axis (breaking[i].config_[j], X_AXIS); | 415 c[j]->translate_axis (breaking[i].config_[j], X_AXIS); |
382 dynamic_cast<Paper_column *> (c[j])->set_system (system); | 416 dynamic_cast<Paper_column *> (c[j])->set_system (system); |
383 /* collect the column labels */ | 417 /* collect the column labels */ |
384 collect_labels (c[j], &system_labels); | 418 collect_labels (c[j], &system_labels); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 ga->add (p); | 457 ga->add (p); |
424 Axis_group_interface::add_element (this, p); | 458 Axis_group_interface::add_element (this, p); |
425 } | 459 } |
426 | 460 |
427 void | 461 void |
428 System::pre_processing () | 462 System::pre_processing () |
429 { | 463 { |
430 for (vsize i = 0; i < all_elements_->size (); i++) | 464 for (vsize i = 0; i < all_elements_->size (); i++) |
431 all_elements_->grob (i)->discretionary_processing (); | 465 all_elements_->grob (i)->discretionary_processing (); |
432 | 466 |
433 if (be_verbose_global) | 467 debug_output (_f ("Grob count %d", element_count ())); |
434 message (_f ("Grob count %d", element_count ())); | |
435 | 468 |
436 /* | 469 /* |
437 order is significant: broken grobs are added to the end of the | 470 order is significant: broken grobs are added to the end of the |
438 array, and should be processed before the original is potentially | 471 array, and should be processed before the original is potentially |
439 killed. | 472 killed. |
440 */ | 473 */ |
441 for (vsize i = all_elements_->size (); i--;) | 474 for (vsize i = all_elements_->size (); i--;) |
442 all_elements_->grob (i)->handle_prebroken_dependencies (); | 475 all_elements_->grob (i)->handle_prebroken_dependencies (); |
443 | 476 |
444 fixup_refpoints (all_elements_->array ()); | 477 fixup_refpoints (all_elements_->array ()); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 Prob *pl = make_paper_system (prop_init); | 597 Prob *pl = make_paper_system (prop_init); |
565 paper_system_set_stencil (pl, sys_stencil); | 598 paper_system_set_stencil (pl, sys_stencil); |
566 | 599 |
567 /* information that the page breaker might need */ | 600 /* information that the page breaker might need */ |
568 Grob *right_bound = this->get_bound (RIGHT); | 601 Grob *right_bound = this->get_bound (RIGHT); |
569 pl->set_property ("vertical-skylines", this->get_property ("vertical-skylines"
)); | 602 pl->set_property ("vertical-skylines", this->get_property ("vertical-skylines"
)); |
570 pl->set_property ("page-break-permission", right_bound->get_property ("page-br
eak-permission")); | 603 pl->set_property ("page-break-permission", right_bound->get_property ("page-br
eak-permission")); |
571 pl->set_property ("page-turn-permission", right_bound->get_property ("page-tur
n-permission")); | 604 pl->set_property ("page-turn-permission", right_bound->get_property ("page-tur
n-permission")); |
572 pl->set_property ("page-break-penalty", right_bound->get_property ("page-break
-penalty")); | 605 pl->set_property ("page-break-penalty", right_bound->get_property ("page-break
-penalty")); |
573 pl->set_property ("page-turn-penalty", right_bound->get_property ("page-turn-p
enalty")); | 606 pl->set_property ("page-turn-penalty", right_bound->get_property ("page-turn-p
enalty")); |
| 607 |
| 608 if (right_bound->original () == dynamic_cast<System*> (original ())->get_bound
(RIGHT)) |
| 609 pl->set_property ("last-in-score", SCM_BOOL_T); |
574 | 610 |
575 Interval staff_refpoints; | 611 Interval staff_refpoints; |
576 if (Grob *align = get_vertical_alignment ()) | 612 if (Grob *align = get_vertical_alignment ()) |
577 { | 613 { |
578 extract_grob_set (align, "elements", staves); | 614 extract_grob_set (align, "elements", staves); |
579 for (vsize i = 0; i < staves.size (); i++) | 615 for (vsize i = 0; i < staves.size (); i++) |
580 if (staves[i]->is_live () | 616 if (staves[i]->is_live () |
581 && Page_layout_problem::is_spaceable (staves[i])) | 617 && Page_layout_problem::is_spaceable (staves[i])) |
582 staff_refpoints.add_point (staves[i]->relative_coordinate (this, | 618 staff_refpoints.add_point (staves[i]->relative_coordinate (this, |
583 Y_AXIS)); | 619 Y_AXIS)); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 { | 744 { |
709 if (Hara_kiri_group_spanner::has_interface (elts[i])) | 745 if (Hara_kiri_group_spanner::has_interface (elts[i])) |
710 Hara_kiri_group_spanner::consider_suicide (elts[i]); | 746 Hara_kiri_group_spanner::consider_suicide (elts[i]); |
711 | 747 |
712 Interval intersection = elts[i]->extent (this, X_AXIS); | 748 Interval intersection = elts[i]->extent (this, X_AXIS); |
713 intersection.intersect (iv); | 749 intersection.intersect (iv); |
714 if (elts[i]->is_live () && !intersection.is_empty ()) | 750 if (elts[i]->is_live () && !intersection.is_empty ()) |
715 return elts[i]; | 751 return elts[i]; |
716 } | 752 } |
717 return 0; | 753 return 0; |
| 754 } |
| 755 |
| 756 vector<Simple_spacer> |
| 757 System::get_simple_spacers (Real line_len, Real indent, bool ragged) |
| 758 { |
| 759 if (!simple_spacers_.size ()) |
| 760 gen_simple_spacers (line_len, indent, ragged); |
| 761 |
| 762 return simple_spacers_; |
| 763 } |
| 764 |
| 765 void |
| 766 System::gen_simple_spacers (Real line_len, Real indent, bool ragged) |
| 767 { |
| 768 vector<vsize> breaks; |
| 769 vector<Grob *> non_loose; |
| 770 vector<Column_description> cols; |
| 771 SCM force_break = ly_symbol2scm ("force"); |
| 772 vector<Grob *> columns = used_columns (); |
| 773 |
| 774 for (vsize i = 0; i < columns.size (); i++) |
| 775 if (!Paper_column::is_loose (columns[i]) |
| 776 || Paper_column::is_breakable (columns[i])) |
| 777 non_loose.push_back (columns[i]); |
| 778 |
| 779 breaks.clear (); |
| 780 breaks.push_back (0); |
| 781 cols.push_back (Column_description ()); |
| 782 for (vsize i = 1; i + 1 < non_loose.size (); i++) |
| 783 { |
| 784 if (Paper_column::is_breakable (non_loose[i])) |
| 785 breaks.push_back (cols.size ()); |
| 786 |
| 787 cols.push_back (Column_description::get_column_description (non_loose, i,
false)); |
| 788 } |
| 789 breaks.push_back (cols.size ()); |
| 790 simple_spacers_.resize (breaks.size () * breaks.size (), Simple_spacer ()); |
| 791 |
| 792 for (vsize b = 0; b + 1 < breaks.size (); b++) |
| 793 { |
| 794 cols[breaks[b]] = Column_description::get_column_description (non_loose, b
reaks[b], true); |
| 795 vsize st = breaks[b]; |
| 796 |
| 797 for (vsize c = b + 1; c < breaks.size (); c++) |
| 798 { |
| 799 vsize end = breaks[c]; |
| 800 Simple_spacer spacer; |
| 801 |
| 802 for (vsize i = breaks[b]; i < end - 1; i++) |
| 803 spacer.add_spring (cols[i].spring_); |
| 804 spacer.add_spring (cols[end - 1].end_spring_); |
| 805 |
| 806 for (vsize i = breaks[b]; i < end; i++) |
| 807 { |
| 808 for (vsize r = 0; r < cols[i].rods_.size (); r++) |
| 809 if (cols[i].rods_[r].r_ < end) |
| 810 spacer.add_rod (i - st, cols[i].rods_[r].r_ - st, cols[i].rods
_[r].dist_); |
| 811 for (vsize r = 0; r < cols[i].end_rods_.size (); r++) |
| 812 if (cols[i].end_rods_[r].r_ == end) |
| 813 spacer.add_rod (i - st, end - st, cols[i].end_rods_[r].dist_); |
| 814 if (!cols[i].keep_inside_line_.is_empty ()) |
| 815 { |
| 816 spacer.add_rod (i - st, end - st, cols[i].keep_inside_line_[RI
GHT]); |
| 817 spacer.add_rod (0, i - st, -cols[i].keep_inside_line_[LEFT]); |
| 818 } |
| 819 } |
| 820 spacer.solve ((b == 0) ? line_len - indent : line_len, ragged); |
| 821 spacer.minimal_ = c == b + 1; |
| 822 simple_spacers_[b * breaks.size () + c] = spacer; |
| 823 |
| 824 if (!spacer.fits () |
| 825 || (end < cols.size () |
| 826 && cols[end].break_permission_ == force_break)) |
| 827 break; |
| 828 } |
| 829 } |
718 } | 830 } |
719 | 831 |
720 Interval | 832 Interval |
721 System::pure_refpoint_extent (vsize start, vsize end) | 833 System::pure_refpoint_extent (vsize start, vsize end) |
722 { | 834 { |
723 Interval ret; | 835 Interval ret; |
724 Grob *alignment = get_vertical_alignment (); | 836 Grob *alignment = get_vertical_alignment (); |
725 if (!alignment) | 837 if (!alignment) |
726 return Interval (); | 838 return Interval (); |
727 | 839 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
865 else | 977 else |
866 return 0; | 978 return 0; |
867 } | 979 } |
868 | 980 |
869 Grob * | 981 Grob * |
870 System::get_maybe_pure_bound (Direction d, bool pure, int start, int end) | 982 System::get_maybe_pure_bound (Direction d, bool pure, int start, int end) |
871 { | 983 { |
872 return pure ? get_pure_bound (d, start, end) : get_bound (d); | 984 return pure ? get_pure_bound (d, start, end) : get_bound (d); |
873 } | 985 } |
874 | 986 |
| 987 enum { |
| 988 SPACEABLE_STAVES, |
| 989 NONSPACEABLE_STAVES, |
| 990 ALL_STAVES |
| 991 }; |
| 992 |
| 993 static SCM |
| 994 get_maybe_spaceable_staves (SCM smob, int filter) |
| 995 { |
| 996 System *me = dynamic_cast<System*> (unsmob_grob (smob)); |
| 997 Grob *align = me->get_vertical_alignment (); |
| 998 SCM ret = SCM_EOL; |
| 999 |
| 1000 if (align) |
| 1001 { |
| 1002 SCM *tail = &ret; |
| 1003 extract_grob_set (align, "elements", staves); |
| 1004 |
| 1005 for (vsize i = 0; i < staves.size (); ++i) |
| 1006 { |
| 1007 bool spaceable = Page_layout_problem::is_spaceable (staves[i]); |
| 1008 if (staves[i]->is_live () && |
| 1009 ((filter == ALL_STAVES) |
| 1010 || (filter == SPACEABLE_STAVES && spaceable) |
| 1011 || (filter == NONSPACEABLE_STAVES && !spaceable))) |
| 1012 { |
| 1013 *tail = scm_cons (staves[i]->self_scm (), SCM_EOL); |
| 1014 tail = SCM_CDRLOC (*tail); |
| 1015 } |
| 1016 } |
| 1017 } |
| 1018 |
| 1019 return ret; |
| 1020 } |
| 1021 |
| 1022 MAKE_SCHEME_CALLBACK (System, get_staves, 1) |
| 1023 SCM |
| 1024 System::get_staves (SCM smob) |
| 1025 { |
| 1026 return get_maybe_spaceable_staves (smob, ALL_STAVES); |
| 1027 } |
| 1028 |
| 1029 MAKE_SCHEME_CALLBACK (System, get_spaceable_staves, 1) |
| 1030 SCM |
| 1031 System::get_spaceable_staves (SCM smob) |
| 1032 { |
| 1033 return get_maybe_spaceable_staves (smob, SPACEABLE_STAVES); |
| 1034 } |
| 1035 |
| 1036 MAKE_SCHEME_CALLBACK (System, get_nonspaceable_staves, 1) |
| 1037 SCM |
| 1038 System::get_nonspaceable_staves (SCM smob) |
| 1039 { |
| 1040 return get_maybe_spaceable_staves (smob, NONSPACEABLE_STAVES); |
| 1041 } |
| 1042 |
| 1043 |
875 ADD_INTERFACE (System, | 1044 ADD_INTERFACE (System, |
876 "This is the top-level object: Each object in a score" | 1045 "This is the top-level object: Each object in a score" |
877 " ultimately has a @code{System} object as its X and" | 1046 " ultimately has a @code{System} object as its X and" |
878 " Y@tie{}parent.", | 1047 " Y@tie{}parent.", |
879 | 1048 |
880 /* properties */ | 1049 /* properties */ |
881 "all-elements " | 1050 "all-elements " |
882 "columns " | 1051 "columns " |
| 1052 "footnote-stencil " |
| 1053 "footnotes-before-line-breaking " |
| 1054 "footnotes-after-line-breaking " |
| 1055 "in-note-direction " |
| 1056 "in-note-padding " |
| 1057 "in-note-stencil " |
883 "labels " | 1058 "labels " |
884 "pure-Y-extent " | 1059 "pure-Y-extent " |
885 "skyline-horizontal-padding " | 1060 "skyline-horizontal-padding " |
886 ); | 1061 ); |
LEFT | RIGHT |