/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 2009--2012 Joe Neeman <joeneeman@gmail.com>
+ Copyright (C) 2009--2014 Joe Neeman <joeneeman@gmail.com>
LilyPond is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
in duplicated work, either by making this process less complicated or (preferably)
by passing its results downstream.
*/
- vector<SCM> footnote_number_markups; // Holds the numbering markups.
- vector<Stencil> footnote_number_stencils; // Holds translated versions of the stencilized numbering markups.
+
+ // find the maximum X_AXIS length
+ Real max_length = -infinity_f;
+
for (vsize i = 0; i < fn_count; i++)
{
if (fn_grobs[i])
(void) scm_call_1 (assertion_function, scm_from_int (counter));
}
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 stencil = Text_interface::interpret_markup (layout, props, markup);
+ Stencil *st = unsmob_stencil (stencil);
+ if (!st)
{
programming_error ("Your numbering function needs to return a stencil.");
- footnote_number_markups.push_back (SCM_EOL);
- footnote_number_stencils.push_back (Stencil (Box (Interval (0, 0), Interval (0, 0)), SCM_EOL));
- }
- else
- {
- footnote_number_markups.push_back (markup);
- footnote_number_stencils.push_back (*s);
+ markup = SCM_EOL;
+ stencil = Stencil (Box (Interval (0, 0), Interval (0, 0)), SCM_EOL).smobbed_copy ();
+ st = unsmob_stencil (stencil);
}
+ in_text_numbers = scm_cons (markup, in_text_numbers);
+ numbers = scm_cons (stencil, numbers);
+
+ if (!st->extent (X_AXIS).is_empty ())
+ max_length = max (max_length, st->extent (X_AXIS)[RIGHT]);
+
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 ());
+ in_text_numbers = scm_reverse_x (in_text_numbers, SCM_EOL);
+ numbers = scm_reverse_x (numbers, SCM_EOL);
/*
translate each stencil such that it attains the correct maximum length and bundle the
footnotes into a scheme object.
*/
- for (vsize i = 0; i < fn_count; i++)
+ for (SCM p = numbers; scm_is_pair (p); p = scm_cdr (p))
{
- in_text_numbers = scm_cons (footnote_number_markups[i], in_text_numbers);
- footnote_number_stencils[i].translate_axis ((max_length
- - footnote_number_stencils[i].extent (X_AXIS).length ()),
- X_AXIS);
- numbers = scm_cons (footnote_number_stencils[i].smobbed_copy (), numbers);
+ Stencil *st = unsmob_stencil (scm_car (p));
+ if (!st->extent (X_AXIS).is_empty ())
+ st->translate_axis ((max_length - st->extent (X_AXIS)[RIGHT]),
+ X_AXIS);
}
- in_text_numbers = scm_reverse_x (in_text_numbers, SCM_EOL);
- numbers = scm_reverse_x (numbers, SCM_EOL);
-
// build the footnotes
for (SCM s = lines; scm_is_pair (s); s = scm_cdr (s))
foot_stencil = add_footnotes_to_footer (footnotes, foot_stencil, pb);
}
else
- warning ("A page layout problem has been initiated that cannot accommodate footnotes.");
+ warning (_ ("A page layout problem has been initiated that cannot accommodate footnotes."));
header_height_ = head ? head->extent (Y_AXIS).length () : 0;
footer_height_ = foot_stencil.extent (Y_AXIS).length ();
void
Page_layout_problem::append_system (System *sys, Spring const &spring, Real indent, Real padding)
{
- Grob *align = sys->get_vertical_alignment ();
+ Grob *align = unsmob_grob (sys->get_object ("vertical-alignment"));
if (!align)
return;
spring_copy.ensure_min_distance (minimum_distance);
springs_.push_back (spring_copy);
+ if (elts.size () && !is_spaceable (elts[0]))
+ {
+ // store the minimum distance, considering relative indents,
+ // for a loose line
+ Skyline first_skyline (UP);
+ Skyline_pair *sky = Skyline_pair::unsmob (elts[0]->get_property ("vertical-skylines"));
+ if (sky)
+ first_skyline.merge ((*sky)[UP]);
+ first_skyline.shift (indent);
+ minimum_distance = first_skyline.distance (bottom_skyline_) - bottom_loose_baseline_;
+ }
bottom_skyline_ = down_skyline;
- elements_.push_back (Element (elts, minimum_offsets, padding));
+ elements_.push_back (Element (elts, minimum_offsets, minimum_distance, padding));
// Add the springs for the VerticalAxisGroups in this system.
: 0;
// Corner case: there was only one staff, and it wasn't spaceable.
- // Mark it spaceable, because we do not allow non-spaceable staves
- // to be at the top or bottom of a system.
if (!found_spaceable_staff && elts.size ())
mark_as_spaceable (elts[0]);
}
if (sky)
{
- minimum_distance = (*sky)[UP].distance (bottom_skyline_);
+ minimum_distance = max ((*sky)[UP].distance (bottom_skyline_),
+ bottom_loose_baseline_);
bottom_skyline_ = (*sky)[DOWN];
}
else if (Stencil *sten = unsmob_stencil (prob->get_property ("stencil")))
bottom_skyline_.clear ();
bottom_skyline_.set_minimum_height (iv[DOWN]);
}
+ bottom_loose_baseline_ = 0.0;
Spring spring_copy = spring;
if (tight_spacing)
Real overflow = spacer.configuration_length (spacer.force ())
- page_height_;
if (ragged && overflow < 1e-6)
- warning (_ ("cannot fit music on page: ragged-spacing was requested, but page was compressed"));
+ warning (_ ("ragged-bottom was specified, but page must be compressed"));
else
{
- warning (_f ("cannot fit music on page: overflow is %f",
+ warning (_f ("compressing over-full page by %.1f staff-spaces",
overflow));
- warning (_ ("compressing music to fit"));
+ force_ = -infinity_f;
vsize space_count = solution_.size ();
Real spacing_increment = overflow / (space_count - 2);
for (vsize i = 2; i < space_count; i++)
found_spaceable_staff = true;
spring_idx++;
}
- else
+ else // ! is_spaceable
{
+ if (staff->extent (staff, Y_AXIS).is_empty ())
+ continue;
+
if (loose_lines.empty ())
loose_lines.push_back (last_spaceable_line);
{
// distance to the final line in the preceding system,
// including 'system-system-spacing 'padding
- min_dist = (Axis_group_interface::minimum_distance (loose_lines.back (),
- staff, Y_AXIS)
- + elements_[i].padding);
+ min_dist = elements_[i].min_distance + elements_[i].padding;
// A null line to break any staff-affinity for the previous system
loose_line_min_distances.push_back (0.0);
loose_lines.push_back (0);
}
else if (!last_title_extent.is_empty ())
// distance to the preceding title,
- // including 'markup-system-spacing 'padding
+ // including 'markup-system-wg 'padding
min_dist = (staff->extent (staff, Y_AXIS)[UP] - last_title_extent[DOWN]
+ elements_[i].padding);
else // distance to the top margin