--- /dev/null
+\version "2.13.4"
+
+\header {
+ texidoc = "The space taken up by rehearsal marks is correctly
+accounted for, even though they live in the Score context."
+}
+
+#(set-default-paper-size "a6")
+
+\book {
+ \paper {
+ oddHeaderMarkup = "header"
+ ragged-last-bottom = ##f
+ }
+ \score {
+ <<
+ \new Staff { \mark \markup \column { T A L L M A R K } c'1 \break
+ \mark \markup \column { T A L L M A R K } c'1 }
+ \new Staff { c'1 \break c'1 }
+ >>
+ }
+}
#include <cstring>
#include "align-interface.hh"
+#include "axis-group-interface.hh"
#include "input.hh"
#include "international.hh"
#include "item.hh"
return false;
}
+
friend SCM ly_grob_basic_properties (SCM);
/* standard callbacks */
- DECLARE_SCHEME_CALLBACK(x_parent_positioning, (SCM));
- DECLARE_SCHEME_CALLBACK(y_parent_positioning, (SCM));
+ DECLARE_SCHEME_CALLBACK (x_parent_positioning, (SCM));
+ DECLARE_SCHEME_CALLBACK (y_parent_positioning, (SCM));
DECLARE_SCHEME_CALLBACK (stencil_height, (SCM smob));
DECLARE_SCHEME_CALLBACK (stencil_width, (SCM smob));
SCM find_system_offsets ();
void distribute_loose_lines (vector<Grob*> const&, vector<Real> const&, Real, Real);
- static Grob* find_vertical_alignment (System*);
static void build_system_skyline (vector<Grob*> const&, vector<Real> const&, Skyline* up, Skyline* down);
static vector<Grob*> filter_dead_elements (vector<Grob*> const&);
DECLARE_SCHEME_CALLBACK (y_aligned_side, (SCM element, SCM current));
DECLARE_SCHEME_CALLBACK (pure_y_aligned_side, (SCM element, SCM start, SCM end, SCM current));
DECLARE_SCHEME_CALLBACK (calc_cross_staff, (SCM element));
+ DECLARE_SCHEME_CALLBACK (move_to_extremal_staff, (SCM));
static SCM aligned_side (Grob*me, Axis a, bool pure, int start, int end, Real *current_off_ptr);
public:
Paper_score *paper_score () const;
+ Grob *get_vertical_alignment ();
+ Grob *get_extremal_staff (Direction dir, Interval const&);
int get_rank () const;
void do_break_substitution_and_fixup_refpoints ();
void post_processing ();
footer_height_ = height;
}
-Grob*
-Page_layout_problem::find_vertical_alignment (System *sys)
-{
- extract_grob_set (sys, "elements", elts);
- for (vsize i = 0; i < elts.size (); ++i)
- if (Align_interface::has_interface (elts[i]))
- return elts[i];
-
- return 0;
-}
-
void
Page_layout_problem::append_system (System *sys, Spring const& spring, Real padding)
{
- Grob *align = find_vertical_alignment (sys);
+ Grob *align = sys->get_vertical_alignment ();
if (!align)
- {
- sys->programming_error ("no VerticalAlignment in system: can't do vertical spacing");
- return;
- }
+ return;
align->set_property ("positioning-done", SCM_BOOL_T);
using namespace std;
+#include "axis-group-interface.hh"
#include "directional-element-interface.hh"
#include "grob.hh"
#include "main.hh"
#include "staff-symbol.hh"
#include "stem.hh"
#include "string-convert.hh"
+#include "system.hh"
#include "warn.hh"
void
return NO_AXES;
}
+MAKE_SCHEME_CALLBACK (Side_position_interface, move_to_extremal_staff, 1);
+SCM
+Side_position_interface::move_to_extremal_staff (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+ System *sys = dynamic_cast<System*> (me->get_system ());
+ Direction dir = Side_position_interface::get_direction (me);
+ if (dir != DOWN)
+ dir = UP;
+
+ Grob *top_staff = sys->get_extremal_staff (dir, me->extent (sys, X_AXIS));
+
+ if (!top_staff)
+ return SCM_BOOL_F;
+
+ // Only move this grob if it is a direct child of the system. We
+ // are not interested in moving marks from other staves to the top
+ // staff; we only want to move marks from the system to the top
+ // staff.
+ if (sys != me->get_parent (Y_AXIS))
+ return SCM_BOOL_F;
+
+ me->set_parent (top_staff, Y_AXIS);
+ me->flush_extent_cache (Y_AXIS);
+ Axis_group_interface::add_element (top_staff, me);
+ return SCM_BOOL_T;
+}
+
+
ADD_INTERFACE (Side_position_interface,
"Position a victim object (this one) next to other objects"
" (the support). The property @code{direction} signifies where"
#include "all-font-metrics.hh"
#include "axis-group-interface.hh"
#include "grob-array.hh"
+#include "hara-kiri-group-spanner.hh"
#include "international.hh"
#include "lookup.hh"
#include "main.hh"
#include "output-def.hh"
+#include "page-layout-problem.hh"
#include "paper-column.hh"
#include "paper-score.hh"
#include "paper-system.hh"
{
System *child = dynamic_cast<System*> (broken_intos_[i]);
child->all_elements_->remove_duplicates ();
+ for (vsize j = 0; j < child->all_elements_->size (); j++)
+ {
+ Grob *g = child->all_elements_->grob (j);
+
+ (void) g->get_property ("after-line-breaking");
+ }
}
if (be_verbose_global)
void
System::post_processing ()
{
- for (vsize i = 0; i < all_elements_->size (); i++)
- {
- Grob *g = all_elements_->grob (i);
-
- (void) g->get_property ("after-line-breaking");
- }
-
Interval iv (extent (this, Y_AXIS));
if (iv.is_empty ())
programming_error ("system with empty extent");
return dynamic_cast<System*> (system_grob);
}
+Grob *
+System::get_vertical_alignment ()
+{
+ extract_grob_set (this, "elements", elts);
+ Grob *ret = 0;
+ for (vsize i = 0; i < elts.size (); i++)
+ if (Align_interface::has_interface (elts[i]))
+ {
+ if (ret)
+ 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;
+}
+
+// Finds the furthest staff in the given direction whose x-extent
+// overlaps with the given interval.
+Grob *
+System::get_extremal_staff (Direction dir, Interval const &iv)
+{
+ Grob *align = get_vertical_alignment ();
+ if (!align)
+ return 0;
+
+ extract_grob_set (align, "elements", elts);
+ vsize start = (dir == UP) ? 0 : elts.size () - 1;
+ vsize end = (dir == UP) ? elts.size () : VPOS;
+ for (vsize i = start; i != end; i += dir)
+ {
+ if (Hara_kiri_group_spanner::has_interface (elts[i]))
+ Hara_kiri_group_spanner::consider_suicide (elts[i]);
+
+ Interval intersection = elts[i]->extent (this, X_AXIS);
+ intersection.intersect (iv);
+ if (elts[i]->is_live () && !intersection.is_empty ())
+ return elts[i];
+ }
+ return 0;
+}
+
ADD_INTERFACE (System,
"This is the top-level object: Each object in a score"
" ultimately has a @code{System} object as its X and"
/*
vertically-spaced-contexts-engraver.cc -- implement Vertically_spaced_contexts_engraver
+ TODO: junk this, since we now determine spaceability using Page_layout_problem::is_spaceable.
source file of the GNU LilyPond music typesetter
(BarNumber
. (
+ (after-line-breaking . ,ly:side-position-interface::move-to-extremal-staff)
;; want the bar number before the clef at line start.
(break-align-symbols . (left-edge staff-bar))
(MetronomeMark
. (
+ (after-line-breaking . ,ly:side-position-interface::move-to-extremal-staff)
(direction . ,UP)
(extra-spacing-width . (+inf.0 . -inf.0))
(outside-staff-priority . 1000)
(RehearsalMark
. (
+ (after-line-breaking . ,ly:side-position-interface::move-to-extremal-staff)
(baseline-skip . 2)
(break-align-symbols . (staff-bar clef))
(break-visibility . ,end-of-line-invisible)
(VoltaBracket
. (
+ (after-line-breaking . ,ly:side-position-interface::move-to-extremal-staff)
(direction . ,UP)
(edge-height . (2.0 . 2.0)) ;; staff-space;
(font-encoding . fetaNumber)