X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fsystem.cc;h=1cd582de7525bc2d628b24cb062ddfc188ac7904;hb=5b7dd34a8b708432c2c44bd6a8ef2121ca0c0f6a;hp=9e33cc52b8c02163fb3dbb860c163a4016051553;hpb=235de94b7408e9badc7b82c8e0dae8f05009adc3;p=lilypond.git diff --git a/lily/system.cc b/lily/system.cc index 9e33cc52b8..1cd582de75 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--2010 Han-Wen Nienhuys + Copyright (C) 1996--2011 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 @@ -22,6 +22,7 @@ #include "align-interface.hh" #include "all-font-metrics.hh" #include "axis-group-interface.hh" +#include "break-align-interface.hh" #include "grob-array.hh" #include "hara-kiri-group-spanner.hh" #include "international.hh" @@ -35,6 +36,7 @@ #include "pointer-group-interface.hh" #include "skyline-pair.hh" #include "staff-symbol-referencer.hh" +#include "text-interface.hh" #include "warn.hh" System::System (System const &src) @@ -43,6 +45,7 @@ System::System (System const &src) all_elements_ = 0; pscore_ = 0; rank_ = 0; + checked_footnotes_ = false; init_elements (); } @@ -51,6 +54,7 @@ System::System (SCM s) { all_elements_ = 0; rank_ = 0; + checked_footnotes_ = false; init_elements (); } @@ -162,7 +166,7 @@ System::do_break_substitution_and_fixup_refpoints () Grob *g = all_elts[j]; g->fixup_refpoint (); } - + count += all_elts.size (); } @@ -226,6 +230,114 @@ System::get_paper_systems () return lines; } +void +System::populate_footnote_grob_vector () +{ + extract_grob_set (this, "all-elements", all_elts); + for (vsize i = 0; i < all_elts.size (); i++) + if (all_elts[i]->internal_has_interface (ly_symbol2scm ("footnote-interface"))) + footnote_grobs_.push_back (all_elts[i]); + + sort (footnote_grobs_.begin (), footnote_grobs_.end (), Grob::less); + checked_footnotes_ = true; +} + +void +System::get_footnote_grobs_in_range (vector &out, vsize start, vsize end) +{ + if (!checked_footnotes_) + populate_footnote_grob_vector (); + + for (vsize i = 0; i < footnote_grobs_.size (); i++) + { + int pos = footnote_grobs_[i]->spanned_rank_interval ()[LEFT]; + bool end_of_line_visible = true; + if (Spanner *s = dynamic_cast(footnote_grobs_[i])) + { + Direction spanner_placement = robust_scm2dir (s->get_property ("spanner-placement"), LEFT); + if (spanner_placement == CENTER) + spanner_placement = LEFT; + + pos = s->spanned_rank_interval ()[spanner_placement]; + } + + if (Item *item = dynamic_cast(footnote_grobs_[i])) + { + 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 + end_of_line_visible = (LEFT == item->break_status_dir ()); + } + + if (pos < int (start)) + continue; + if (pos > int (end)) + break; + if (pos == int (start) && end_of_line_visible) + continue; + if (pos == int (end) && !end_of_line_visible) + continue; + if (!footnote_grobs_[i]->is_live ()) + continue; + + out.push_back (footnote_grobs_[i]); + } +} + +vector +System::get_footnotes_in_range (vsize start, vsize end) +{ + vector footnote_grobs; + get_footnote_grobs_in_range (footnote_grobs, start, end); + vector out; + + for (vsize i = 0; i < footnote_grobs.size (); i++) + { + SCM footnote_markup = footnote_grobs[i]->get_property ("footnote-text"); + + 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 footnote_stl = Text_interface::interpret_markup (pscore_->layout ()->self_scm (), + props, footnote_markup); + + Stencil *footnote_stencil = unsmob_stencil (footnote_stl); + out.push_back (footnote_stencil); + } + + return out; +} + +Stencil +System::make_footnote_stencil (Real padding) +{ + Stencil mol; + + for (vsize i = 0; i < footnote_grobs_.size (); i++) + { + SCM footnote_markup = footnote_grobs_[i]->get_property ("footnote-text"); + if (Spanner *orig = dynamic_cast(footnote_grobs_[i])) + if (orig->is_broken ()) + footnote_markup = orig->broken_intos_[0]->get_property ("footnote-text"); + + 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 footnote_stl = Text_interface::interpret_markup (pscore_->layout ()->self_scm (), + props, footnote_markup); + + mol.add_at_edge (Y_AXIS, DOWN, *unsmob_stencil (footnote_stl), padding); + } + + return mol; +} + void System::break_into_pieces (vector const &breaking) { @@ -242,6 +354,8 @@ System::break_into_pieces (vector const &breaking) Interval iv (pure_height (this, st, end)); system->set_property ("pure-Y-extent", ly_interval2scm (iv)); + get_footnote_grobs_in_range (system->footnote_grobs_, st, end); + system->set_bound (LEFT, c[0]); system->set_bound (RIGHT, c.back ()); SCM system_labels = SCM_EOL; @@ -250,10 +364,16 @@ System::break_into_pieces (vector const &breaking) c[j]->translate_axis (breaking[i].config_[j], X_AXIS); dynamic_cast (c[j])->set_system (system); /* collect the column labels */ - SCM col_labels = c[j]->get_property ("labels"); - if (scm_is_pair (col_labels)) - system_labels = scm_append (scm_list_2 (col_labels, system_labels)); + collect_labels (c[j], &system_labels); } + /* + Collect labels from any loose columns too: theses will be set on + an empty bar line or a column which is otherwise unused mid-line + */ + vector loose (breaking[i].loose_cols_); + for (vsize j = 0; j < loose.size (); j++) + collect_labels (loose[j], &system_labels); + system->set_property ("labels", system_labels); set_loose_columns (system, &breaking[i]); @@ -261,6 +381,14 @@ System::break_into_pieces (vector const &breaking) } } +void +System::collect_labels (Grob const *col, SCM *labels) +{ + SCM col_labels = col->get_property ("labels"); + if (scm_is_pair (col_labels)) + *labels = scm_append (scm_list_2 (col_labels, *labels)); +} + void System::add_column (Paper_column *p) {