X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;ds=sidebyside;f=lily%2Fpage-layout-problem.cc;h=562f0aeb901c98e1eaa121af331ff0d8af45d9c5;hb=7ee874c5682fead016f10a3f5a0ef7f8841fe7b5;hp=c9301ff3843f6812c1c39a129df9511c01817aca;hpb=4a401ca1c60f428daa242dbdd102fdb3f327ebfb;p=lilypond.git diff --git a/lily/page-layout-problem.cc b/lily/page-layout-problem.cc index c9301ff384..562f0aeb90 100644 --- a/lily/page-layout-problem.cc +++ b/lily/page-layout-problem.cc @@ -67,16 +67,52 @@ Page_layout_problem::get_footnote_count (SCM lines) return fn_count; } +SCM +Page_layout_problem::get_footnotes_from_lines (SCM lines) +{ + if (!scm_is_pair (lines)) + return SCM_EOL; + + bool footnotes_added; + if (Grob *g = unsmob_grob (scm_car (lines))) + footnotes_added = !scm_is_null (g->get_property ("footnote-stencil")); + else if (Prob *p = unsmob_prob (scm_car (lines))) + footnotes_added = !scm_is_null (p->get_property ("footnote-stencil")); + else + { + programming_error ("Systems on a page must be a prob or grob."); + return SCM_EOL; + } + if (!footnotes_added) + { + programming_error ("Footnotes must be added to lines before they are retrieved."); + return SCM_EOL; + } + + SCM out = SCM_EOL; + for (SCM s = lines; scm_is_pair (s); s = scm_cdr (s)) + { + if (Grob *g = unsmob_grob (scm_car (s))) + out = scm_cons (g->get_property ("footnote-stencil"), out); + else if (Prob *p = unsmob_prob (scm_car (s))) + out = scm_cons (p->get_property ("footnote-stencil"), out); + else + programming_error ("Systems on a page must be a prob or grob."); + } + + return scm_reverse (out); +} + /* - Returns a stencil for the footnote of each system. This stencil may + Adds a footnote stencil to each system. This stencil may itself be comprised of several footnotes. This is a long function, but it seems better to keep it intact rather than splitting it into parts. */ -SCM -Page_layout_problem::get_footnotes_from_lines (SCM lines, int counter, Paper_book *pb) +void +Page_layout_problem::add_footnotes_to_lines (SCM lines, int counter, Paper_book *pb) { /* first, we have to see how many footnotes are on this page. @@ -88,7 +124,7 @@ Page_layout_problem::get_footnotes_from_lines (SCM lines, int counter, Paper_boo if (!paper) { programming_error ("Cannot get footnotes because there is no valid paper block."); - return SCM_EOL; + return; } SCM number_footnote_table = pb->top_paper ()->c_variable ("number-footnote-table"); @@ -106,8 +142,6 @@ Page_layout_problem::get_footnotes_from_lines (SCM lines, int counter, Paper_boo // now, make the footnote stencils with the numbering function SCM numbers = SCM_EOL; SCM in_text_numbers = SCM_EOL; - bool do_numbering = to_boolean (paper->c_variable ("footnote-auto-numbering")); - // if there's no numbering, skip all this /* TODO: This recalculates numbering every time this function is called, including once after the balloon prints are called. Although it is not a huge computational drain, @@ -118,50 +152,47 @@ Page_layout_problem::get_footnotes_from_lines (SCM lines, int counter, Paper_boo in duplicated work, either by making this process less complicated or (preferably) by passing its results downstream. */ - if (do_numbering) + vector footnote_number_markups; // Holds the numbering markups. + vector footnote_number_stencils; // Holds translated versions of the stencilized numbering markups. + for (vsize i = 0; i < fn_count; i++) { - vector footnote_number_markups; // Holds the numbering markups. - vector footnote_number_stencils; // Holds translated versions of the stencilized numbering markups. - for (vsize i = 0; i < fn_count; i++) + SCM markup = scm_call_1 (numbering_function, scm_from_int (counter)); + Stencil *s = unsmob_stencil (Text_interface::interpret_markup (layout, props, markup)); + if (!s) { - SCM markup = scm_call_1 (numbering_function, scm_from_int (counter)); - Stencil *s = unsmob_stencil (Text_interface::interpret_markup (layout, props, markup)); - if (!s) - { - programming_error ("Your numbering function needs to return a stencil."); - markup = SCM_EOL; - s = new Stencil (Box (Interval (0, 0), Interval (0, 0)), SCM_EOL); - } - footnote_number_markups.push_back (markup); - footnote_number_stencils.push_back (s); - counter++; + programming_error ("Your numbering function needs to return a stencil."); + markup = SCM_EOL; + s = new Stencil (Box (Interval (0, 0), Interval (0, 0)), SCM_EOL); } + footnote_number_markups.push_back (markup); + footnote_number_stencils.push_back (s); + counter++; + } - // find the maximum X_AXIS length - Real max_length = -infinity_f; - for (vsize i = 0; i < fn_count; i++) - max_length = max (max_length, footnote_number_stencils[i]->extent (X_AXIS).length ()); + // find the maximum X_AXIS length + Real max_length = -infinity_f; + for (vsize i = 0; i < fn_count; i++) + max_length = max (max_length, footnote_number_stencils[i]->extent (X_AXIS).length ()); - /* - translate each stencil such that it attains the correct maximum length and bundle the - footnotes into a scheme object. - */ - SCM *tail = &numbers; - SCM *in_text_tail = &in_text_numbers; + /* + translate each stencil such that it attains the correct maximum length and bundle the + footnotes into a scheme object. + */ + SCM *tail = &numbers; + SCM *in_text_tail = &in_text_numbers; - for (vsize i = 0; i < fn_count; i++) - { - *in_text_tail = scm_cons (footnote_number_markups[i], SCM_EOL); - in_text_tail = SCM_CDRLOC (*in_text_tail); - footnote_number_stencils[i]->translate_axis (max_length - footnote_number_stencils[i]->extent (X_AXIS).length (), X_AXIS); - *tail = scm_cons (footnote_number_stencils[i]->smobbed_copy (), SCM_EOL); - tail = SCM_CDRLOC (*tail); - } + for (vsize i = 0; i < fn_count; i++) + { + *in_text_tail = scm_cons (footnote_number_markups[i], SCM_EOL); + in_text_tail = SCM_CDRLOC (*in_text_tail); + footnote_number_stencils[i]->translate_axis ((max_length + - footnote_number_stencils[i]->extent (X_AXIS).length ()), + X_AXIS); + *tail = scm_cons (footnote_number_stencils[i]->smobbed_copy (), SCM_EOL); + tail = SCM_CDRLOC (*tail); } // build the footnotes - SCM footnotes = SCM_EOL; - for (SCM s = lines; scm_is_pair (s); s = scm_cdr (s)) { // Take care of musical systems. @@ -174,7 +205,7 @@ Page_layout_problem::get_footnotes_from_lines (SCM lines, int counter, Paper_boo continue; } Stencil mol; - + Stencil in_note_mol; for (vsize i = 0; i < sys->footnote_grobs ()->size (); i++) { Grob *footnote = sys->footnote_grobs ()->at (i); @@ -183,9 +214,6 @@ Page_layout_problem::get_footnotes_from_lines (SCM lines, int counter, Paper_boo 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"), paper->self_scm ()); @@ -193,6 +221,14 @@ Page_layout_problem::get_footnotes_from_lines (SCM lines, int counter, Paper_boo props, footnote_markup); Stencil *footnote_stencil = unsmob_stencil (footnote_stl); + bool do_numbering = to_boolean (footnote->get_property ("automatically-numbered")); + if (Spanner *orig = dynamic_cast(footnote)) + { + if (orig->is_broken ()) + for (vsize i = 0; i < orig->broken_intos_.size (); i++) + do_numbering = do_numbering + || to_boolean (orig->broken_intos_[i]->get_property ("automatically-numbered")); + } if (do_numbering) { SCM annotation_scm = scm_car (in_text_numbers); @@ -206,53 +242,67 @@ Page_layout_problem::get_footnotes_from_lines (SCM lines, int counter, Paper_boo } Stencil *annotation = unsmob_stencil (scm_car (numbers)); - annotation->translate_axis (footnote_stencil->extent (Y_AXIS)[UP] + number_raise - annotation->extent (Y_AXIS)[UP], Y_AXIS); + annotation->translate_axis ((footnote_stencil->extent (Y_AXIS)[UP] + + number_raise + - annotation->extent (Y_AXIS)[UP]), + Y_AXIS); footnote_stencil->add_at_edge (X_AXIS, LEFT, *annotation, 0.0); numbers = scm_cdr (numbers); in_text_numbers = scm_cdr (in_text_numbers); } - mol.add_at_edge (Y_AXIS, DOWN, *footnote_stencil, padding); + if (!footnote_stencil->is_empty ()) + { + if (to_boolean (footnote->get_property ("footnote"))) + mol.add_at_edge (Y_AXIS, DOWN, *footnote_stencil, padding); + else + in_note_mol.add_at_edge (Y_AXIS, DOWN, *footnote_stencil, padding); + } } - footnotes = scm_cons (mol.smobbed_copy (), footnotes); + sys->set_property ("in-note-stencil", in_note_mol.smobbed_copy ()); + sys->set_property ("footnote-stencil", mol.smobbed_copy ()); } // Take care of top-level markups else if (Prob *p = unsmob_prob (scm_car (s))) { SCM stencils = p->get_property ("footnotes"); - if (stencils == SCM_EOL) - continue; - Stencil footnote_stencil; + Stencil mol; for (SCM st = stencils; scm_is_pair (st); st = scm_cdr (st)) { - Stencil mol; - Stencil *footnote = unsmob_stencil (scm_cadar (st)); - mol.add_stencil (*footnote); + Stencil footnote_stencil; + Stencil *footnote = unsmob_stencil (scm_caddar (st)); + footnote_stencil.add_stencil (*footnote); + bool do_numbering = to_boolean (scm_cadar (st)); + SCM in_text_stencil = Stencil ().smobbed_copy (); if (do_numbering) { Stencil *annotation = unsmob_stencil (scm_car (numbers)); SCM in_text_annotation = scm_car (in_text_numbers); - SCM in_text_stencil = Text_interface::interpret_markup (layout, props, in_text_annotation); + in_text_stencil = Text_interface::interpret_markup (layout, + props, + in_text_annotation); if (!unsmob_stencil (in_text_stencil)) in_text_stencil = SCM_EOL; - number_footnote_table = scm_cons (scm_cons (scm_caar (st), in_text_stencil), number_footnote_table); - annotation->translate_axis (mol.extent (Y_AXIS)[UP] + number_raise - annotation->extent (Y_AXIS)[UP], Y_AXIS); - mol.add_at_edge (X_AXIS, LEFT, *annotation, 0.0); + annotation->translate_axis ((footnote_stencil.extent (Y_AXIS)[UP] + + number_raise + - annotation->extent (Y_AXIS)[UP]), + Y_AXIS); + footnote_stencil.add_at_edge (X_AXIS, LEFT, *annotation, 0.0); numbers = scm_cdr (numbers); in_text_numbers = scm_cdr (in_text_numbers); } - footnote_stencil.add_at_edge (Y_AXIS, DOWN, mol, padding); + number_footnote_table = scm_cons (scm_cons (scm_caar (st), + in_text_stencil), + number_footnote_table); + if (!footnote_stencil.is_empty ()) + mol.add_at_edge (Y_AXIS, DOWN, footnote_stencil, padding); } - footnotes = scm_cons (footnote_stencil.smobbed_copy (), footnotes); + p->set_property ("footnote-stencil", mol.smobbed_copy ()); } } // note that this line of code doesn't do anything if numbering isn't turned on pb->top_paper ()->set_variable (ly_symbol2scm ("number-footnote-table"), number_footnote_table); - if (!scm_is_pair (footnotes)) - return SCM_EOL; - - return scm_reverse (footnotes); } Stencil * @@ -277,6 +327,11 @@ Page_layout_problem::get_footnote_separator_stencil (Output_def *paper) void Page_layout_problem::add_footnotes_to_footer (SCM footnotes, Stencil *foot, Paper_book *pb) { + if (!foot && scm_is_pair (footnotes)) + { + warning ("Must have a footer to add footnotes."); + return; + } bool footnotes_found = false; Real footnote_padding = robust_scm2double (pb->paper_->c_variable ("footnote-padding"), 0.0); Real footnote_footer_padding = robust_scm2double (pb->paper_->c_variable ("footnote-footer-padding"), 0.0); @@ -305,7 +360,7 @@ Page_layout_problem::add_footnotes_to_footer (SCM footnotes, Stencil *foot, Pape } } -Page_layout_problem::Page_layout_problem (Paper_book *pb, SCM page_scm, SCM systems, int footnote_count) +Page_layout_problem::Page_layout_problem (Paper_book *pb, SCM page_scm, SCM systems) : bottom_skyline_ (DOWN) { Prob *page = unsmob_prob (page_scm); @@ -322,9 +377,7 @@ Page_layout_problem::Page_layout_problem (Paper_book *pb, SCM page_scm, SCM syst if (pb && pb->paper_) { - if (to_boolean (pb->paper_->c_variable ("reset-footnotes-on-new-page"))) - footnote_count = 0; - SCM footnotes = get_footnotes_from_lines (systems, footnote_count, pb); + SCM footnotes = get_footnotes_from_lines (systems); add_footnotes_to_footer (footnotes, foot, pb); } else @@ -373,6 +426,8 @@ Page_layout_problem::Page_layout_problem (Paper_book *pb, SCM page_scm, SCM syst read_spacing_spec (top_system_spacing, &header_padding_, ly_symbol2scm ("padding")); read_spacing_spec (last_bottom_spacing, &footer_padding_, ly_symbol2scm ("padding")); + in_note_padding_ = robust_scm2double (paper->c_variable ("in-note-padding"), 0.5); + in_note_direction_ = robust_scm2dir (paper->c_variable ("in-note-direction"), UP); } bool last_system_was_title = false; @@ -481,6 +536,18 @@ Page_layout_problem::append_system (System *sys, Spring const &spring, Real inde build_system_skyline (elts, minimum_offsets_with_min_dist, &up_skyline, &down_skyline); up_skyline.shift (indent); down_skyline.shift (indent); + Stencil *in_note_stencil = unsmob_stencil (sys->get_property ("in-note-stencil")); + + if (in_note_stencil && in_note_stencil->extent (Y_AXIS).length () > 0) + { + sys->set_property ("in-note-padding", scm_from_double (in_note_padding_)); + sys->set_property ("in-note-direction", scm_from_int (in_note_direction_)); + Skyline *sky = in_note_direction_ == UP ? &up_skyline : &down_skyline; + sky->set_minimum_height (sky->max_height () + + in_note_direction_ + * (in_note_padding_ + + in_note_stencil->extent (Y_AXIS).length ())); + } /* We need to call distance with skyline-horizontal-padding because @@ -488,7 +555,10 @@ Page_layout_problem::append_system (System *sys, Spring const &spring, Real inde of an individual staff. So we add the padding for the distance check at the time of adding in the system. */ - Real minimum_distance = up_skyline.distance (bottom_skyline_, robust_scm2double (sys->get_property ("skyline-horizontal-padding"), 0)) + padding; + Real minimum_distance = up_skyline.distance (bottom_skyline_, + robust_scm2double (sys->get_property ("skyline-horizontal-padding"), + 0)) + + padding; Spring spring_copy = spring; spring_copy.ensure_min_distance (minimum_distance);