X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fsystem.cc;h=0551b85cbccda5286e770fdc238722edda48aec7;hb=5d84bfad4626892bcffd05adcced53c8a2329047;hp=fdcc2b133d1b056f78482087218aac7abbc559ff;hpb=46e296f5381495ce30108aa981e549d61e55a009;p=lilypond.git diff --git a/lily/system.cc b/lily/system.cc index fdcc2b133d..0551b85cbc 100644 --- a/lily/system.cc +++ b/lily/system.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 1996--2012 Han-Wen Nienhuys + Copyright (C) 1996--2015 Han-Wen Nienhuys LilyPond is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -36,9 +36,11 @@ #include "pointer-group-interface.hh" #include "skyline-pair.hh" #include "staff-symbol-referencer.hh" +#include "system-start-delimiter.hh" #include "text-interface.hh" #include "warn.hh" #include "unpure-pure-container.hh" +#include "lily-imports.hh" System::System (System const &src) : Spanner (src) @@ -61,7 +63,7 @@ void System::init_elements () { SCM scm_arr = Grob_array::make_array (); - all_elements_ = unsmob_grob_array (scm_arr); + all_elements_ = unsmob (scm_arr); all_elements_->set_ordered (false); set_object ("all-elements", scm_arr); } @@ -104,16 +106,9 @@ System::typeset_grob (Grob *elem) void System::derived_mark () const { - if (!all_elements_->empty ()) - { - Grob **ptr = &all_elements_->array_reference ()[0]; - Grob **end = ptr + all_elements_->size (); - while (ptr < end) - { - scm_gc_mark ((*ptr)->self_scm ()); - ptr++; - } - } + const vector &arr = all_elements_->array (); + for (vsize i = arr.size (); i--;) + scm_gc_mark (arr[i]->self_scm ()); if (pscore_) scm_gc_mark (pscore_->self_scm ()); @@ -179,7 +174,7 @@ System::do_break_substitution_and_fixup_refpoints () handle_broken_dependencies (); - /* Because the this->get_property (all-elements) contains items in 3 + /* Because the get_property (all-elements) contains items in 3 versions, handle_broken_dependencies () will leave duplicated items in all-elements. Strictly speaking this is harmless, but it leads to duplicated symbols in the output. uniq makes sure @@ -222,7 +217,7 @@ System::get_paper_systems () scm_vector_set_x (lines, scm_from_int (i), system->get_paper_system ()); - debug_output (to_string (i) + "]", false); + debug_output (::to_string (i) + "]", false); } return lines; } @@ -254,6 +249,12 @@ System::get_footnote_grobs_in_range (vsize start, vsize end) if (Item *item = dynamic_cast(at_bat)) { + /* + We use this to weed out grobs that fall at the end + of the line when we want grobs at the beginning. + */ + end_of_line_visible = item->break_status_dir () == LEFT; + if (!Item::break_visible (item)) continue; // safeguard to bring down the column rank so that end of line footnotes show up on the correct line @@ -275,6 +276,14 @@ System::get_footnote_grobs_in_range (vsize start, vsize end) continue; if (!at_bat->is_live ()) continue; + /* + TODO + Sometimes, there are duplicate entries in the all_elements_ + list. In a separate patch, this practice should be squashed + so that the check below can be eliminated. + */ + if (find (out.begin (), out.end (), at_bat) != out.end ()) + continue; out.push_back (at_bat); } @@ -312,13 +321,13 @@ System::internal_get_note_heights_in_range (vsize start, vsize end, bool foot) if (!Text_interface::is_markup (footnote_markup)) continue; - SCM props = scm_call_1 (ly_lily_module_constant ("layout-extract-page-properties"), - pscore_->layout ()->self_scm ()); + SCM props = + Lily::layout_extract_page_properties (pscore_->layout ()->self_scm ()); SCM footnote_stl = Text_interface::interpret_markup (pscore_->layout ()->self_scm (), props, footnote_markup); - Stencil *footnote_stencil = unsmob_stencil (footnote_stl); + Stencil *footnote_stencil = unsmob (footnote_stl); out.push_back (footnote_stencil->extent (Y_AXIS).length ()); } @@ -363,7 +372,7 @@ MAKE_SCHEME_CALLBACK (System, footnotes_before_line_breaking, 1); SCM System::footnotes_before_line_breaking (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = unsmob (smob); vector footnotes; SCM grobs_scm = Grob_array::make_array (); extract_grob_set (me, "all-elements", elts); @@ -371,7 +380,7 @@ System::footnotes_before_line_breaking (SCM smob) if (elts[i]->internal_has_interface (ly_symbol2scm ("footnote-interface"))) footnotes.push_back (elts[i]); - unsmob_grob_array (grobs_scm)->set_array (footnotes); + unsmob (grobs_scm)->set_array (footnotes); return grobs_scm; } @@ -379,14 +388,45 @@ MAKE_SCHEME_CALLBACK (System, footnotes_after_line_breaking, 1); SCM System::footnotes_after_line_breaking (SCM smob) { - Spanner *sys_span = unsmob_spanner (smob); + Spanner *sys_span = unsmob (smob); System *sys = dynamic_cast (sys_span); Interval_t sri = sys->spanned_rank_interval (); vector footnote_grobs = sys->get_footnote_grobs_in_range (sri[LEFT], sri[RIGHT]); vector_sort (footnote_grobs, grob_2D_less); SCM grobs_scm = Grob_array::make_array (); - unsmob_grob_array (grobs_scm)->set_array (footnote_grobs); + unsmob (grobs_scm)->set_array (footnote_grobs); + return grobs_scm; +} + +MAKE_SCHEME_CALLBACK (System, vertical_skyline_elements, 1); +SCM +System::vertical_skyline_elements (SCM smob) +{ + Grob *me_grob = unsmob (smob); + vector vertical_skyline_grobs; + extract_grob_set (me_grob, "elements", my_elts); + for (vsize i = 0; i < my_elts.size (); i++) + if (has_interface (my_elts[i])) + vertical_skyline_grobs.push_back (my_elts[i]); + + System *me = dynamic_cast (me_grob); + Grob *align = unsmob (me->get_object ("vertical-alignment")); + if (!align) + { + SCM grobs_scm = Grob_array::make_array (); + unsmob (grobs_scm)->set_array (vertical_skyline_grobs); + return grobs_scm; + } + + extract_grob_set (align, "elements", elts); + + for (vsize i = 0; i < elts.size (); i++) + if (has_interface (elts[i])) + vertical_skyline_grobs.push_back (elts[i]); + + SCM grobs_scm = Grob_array::make_array (); + unsmob (grobs_scm)->set_array (vertical_skyline_grobs); return grobs_scm; } @@ -403,7 +443,7 @@ System::break_into_pieces (vector const &breaking) int st = Paper_column::get_rank (c[0]); int end = Paper_column::get_rank (c.back ()); - Interval iv (pure_height (this, st, end)); + Interval iv (pure_y_extent (this, st, end)); system->set_property ("pure-Y-extent", ly_interval2scm (iv)); system->set_bound (LEFT, c[0]); @@ -443,12 +483,12 @@ void System::add_column (Paper_column *p) { Grob *me = this; - Grob_array *ga = unsmob_grob_array (me->get_object ("columns")); + Grob_array *ga = unsmob (me->get_object ("columns")); if (!ga) { SCM scm_ga = Grob_array::make_array (); me->set_object ("columns", scm_ga); - ga = unsmob_grob_array (scm_ga); + ga = unsmob (scm_ga); } p->set_rank (ga->size ()); @@ -502,9 +542,8 @@ System::post_processing () anyway. */ vector all_elts_sorted (all_elements_->array ()); - vector_sort (all_elts_sorted, std::less ()); - uniq (all_elts_sorted); - this->get_stencil (); + uniquify (all_elts_sorted); + get_stencil (); for (vsize i = all_elts_sorted.size (); i--;) { Grob *g = all_elts_sorted[i]; @@ -549,7 +588,7 @@ System::get_paper_system () Grob *g = entries[j].grob_; Stencil st = g->get_print_stencil (); - if (st.expr () == SCM_EOL) + if (scm_is_null (st.expr ())) continue; Offset o; @@ -579,7 +618,7 @@ System::get_paper_system () exprs)); if (debug_skylines) { - Skyline_pair *skylines = Skyline_pair::unsmob (get_property ("vertical-skylines")); + Skyline_pair *skylines = unsmob (get_property ("vertical-skylines")); if (skylines) { Stencil up @@ -591,14 +630,14 @@ System::get_paper_system () } } - Grob *left_bound = this->get_bound (LEFT); + Grob *left_bound = get_bound (LEFT); SCM prop_init = left_bound->get_property ("line-break-system-details"); Prob *pl = make_paper_system (prop_init); paper_system_set_stencil (pl, sys_stencil); /* information that the page breaker might need */ - Grob *right_bound = this->get_bound (RIGHT); - pl->set_property ("vertical-skylines", this->get_property ("vertical-skylines")); + Grob *right_bound = get_bound (RIGHT); + pl->set_property ("vertical-skylines", get_property ("vertical-skylines")); pl->set_property ("page-break-permission", right_bound->get_property ("page-break-permission")); pl->set_property ("page-turn-permission", right_bound->get_property ("page-turn-permission")); pl->set_property ("page-break-penalty", right_bound->get_property ("page-break-penalty")); @@ -608,7 +647,7 @@ System::get_paper_system () pl->set_property ("last-in-score", SCM_BOOL_T); Interval staff_refpoints; - if (Grob *align = get_vertical_alignment ()) + if (Grob *align = unsmob (get_object ("vertical-alignment"))) { extract_grob_set (align, "elements", staves); for (vsize i = 0; i < staves.size (); i++) @@ -619,7 +658,7 @@ System::get_paper_system () } pl->set_property ("staff-refpoint-extent", ly_interval2scm (staff_refpoints)); - pl->set_property ("system-grob", this->self_scm ()); + pl->set_property ("system-grob", self_scm ()); return pl->unprotect (); } @@ -709,22 +748,27 @@ get_root_system (Grob *me) return dynamic_cast (system_grob); } -Grob * -System::get_vertical_alignment () +MAKE_SCHEME_CALLBACK (System, get_vertical_alignment, 1); +SCM +System::get_vertical_alignment (SCM smob) { - extract_grob_set (this, "elements", elts); + Grob *me = unsmob (smob); + extract_grob_set (me, "elements", elts); Grob *ret = 0; for (vsize i = 0; i < elts.size (); i++) - if (Align_interface::has_interface (elts[i])) + if (has_interface (elts[i])) { if (ret) - programming_error ("found multiple vertical alignments in this system"); + me->programming_error ("found multiple vertical alignments in this system"); ret = elts[i]; } if (!ret) - programming_error ("didn't find a vertical alignment in this system"); - return ret; + { + me->programming_error ("didn't find a vertical alignment in this system"); + return SCM_EOL; + } + return ret->self_scm (); } // Finds the furthest staff in the given direction whose x-extent @@ -732,7 +776,7 @@ System::get_vertical_alignment () Grob * System::get_extremal_staff (Direction dir, Interval const &iv) { - Grob *align = get_vertical_alignment (); + Grob *align = unsmob (get_object ("vertical-alignment")); if (!align) return 0; @@ -741,7 +785,7 @@ System::get_extremal_staff (Direction dir, Interval const &iv) vsize end = (dir == UP) ? elts.size () : VPOS; for (vsize i = start; i != end; i += dir) { - if (Hara_kiri_group_spanner::has_interface (elts[i])) + if (has_interface (elts[i])) Hara_kiri_group_spanner::consider_suicide (elts[i]); Interval intersection = elts[i]->extent (this, X_AXIS); @@ -756,7 +800,7 @@ System::get_extremal_staff (Direction dir, Interval const &iv) Grob * System::get_neighboring_staff (Direction dir, Grob *vertical_axis_group, Interval_t bounds) { - Grob *align = get_vertical_alignment (); + Grob *align = unsmob (get_object ("vertical-alignment")); if (!align) return 0; @@ -771,7 +815,7 @@ System::get_neighboring_staff (Direction dir, Grob *vertical_axis_group, Interva if (elts[i] == vertical_axis_group) return out; - if (Hara_kiri_group_spanner::has_interface (elts[i])) + if (has_interface (elts[i])) Hara_kiri_group_spanner::consider_suicide (elts[i]); bounds.intersect (elts[i]->spanned_rank_interval ()); @@ -786,7 +830,7 @@ Interval System::pure_refpoint_extent (vsize start, vsize end) { Interval ret; - Grob *alignment = get_vertical_alignment (); + Grob *alignment = unsmob (get_object ("vertical-alignment")); if (!alignment) return Interval (); @@ -813,7 +857,7 @@ System::pure_refpoint_extent (vsize start, vsize end) Interval System::part_of_line_pure_height (vsize start, vsize end, bool begin) { - Grob *alignment = get_vertical_alignment (); + Grob *alignment = unsmob (get_object ("vertical-alignment")); if (!alignment) return Interval (); @@ -859,25 +903,23 @@ MAKE_SCHEME_CALLBACK (System, calc_pure_relevant_grobs, 1); SCM System::calc_pure_relevant_grobs (SCM smob) { - Grob *me = unsmob_grob (smob); + Grob *me = unsmob (smob); extract_grob_set (me, "elements", elts); vector relevant_grobs; - SCM pure_relevant_p = ly_lily_module_constant ("pure-relevant?"); for (vsize i = 0; i < elts.size (); ++i) { - if (!Axis_group_interface::has_interface (elts[i])) + if (!has_interface (elts[i])) { - if (to_boolean (scm_apply_1 (pure_relevant_p, elts[i]->self_scm (), SCM_EOL))) - relevant_grobs.push_back (elts[i]); + relevant_grobs.push_back (elts[i]); if (Item *it = dynamic_cast (elts[i])) { for (LEFT_and_RIGHT (d)) { Item *piece = it->find_prebroken_piece (d); - if (piece && to_boolean (scm_apply_1 (pure_relevant_p, piece->self_scm (), SCM_EOL))) + if (piece && piece->is_live ()) relevant_grobs.push_back (piece); } } @@ -886,7 +928,7 @@ System::calc_pure_relevant_grobs (SCM smob) SCM grobs_scm = Grob_array::make_array (); - unsmob_grob_array (grobs_scm)->set_array (relevant_grobs); + unsmob (grobs_scm)->set_array (relevant_grobs); return grobs_scm; } @@ -901,7 +943,7 @@ MAKE_SCHEME_CALLBACK (System, calc_pure_height, 3); SCM System::calc_pure_height (SCM smob, SCM start_scm, SCM end_scm) { - System *me = dynamic_cast (unsmob_grob (smob)); + System *me = unsmob (smob); int start = scm_to_int (start_scm); int end = scm_to_int (end_scm); @@ -945,8 +987,8 @@ enum static SCM get_maybe_spaceable_staves (SCM smob, int filter) { - System *me = dynamic_cast (unsmob_grob (smob)); - Grob *align = me->get_vertical_alignment (); + System *me = unsmob (smob); + Grob *align = unsmob (me->get_object ("vertical_alignment")); SCM ret = SCM_EOL; if (align) @@ -1008,5 +1050,5 @@ ADD_INTERFACE (System, "in-note-stencil " "labels " "pure-Y-extent " - "skyline-horizontal-padding " + "vertical-alignment " );