/*
- system.cc -- implement System
+ This file is part of LilyPond, the GNU music typesetter.
- source file of the GNU LilyPond music typesetter
+ Copyright (C) 1996--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
- (c) 1996--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ LilyPond is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ LilyPond is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
*/
#include "system.hh"
}
static void
-fixup_refpoints (vector<Grob*> const &grobs)
+fixup_refpoints (vector<Grob *> const &grobs)
{
for (vsize i = grobs.size (); i--;)
grobs[i]->fixup_refpoint ();
that no duplicates are in the list. */
for (vsize i = 0; i < broken_intos_.size (); i++)
{
- System *child = dynamic_cast<System*> (broken_intos_[i]);
+ System *child = dynamic_cast<System *> (broken_intos_[i]);
child->all_elements_->remove_duplicates ();
for (vsize j = 0; j < child->all_elements_->size (); j++)
{
System *system = dynamic_cast<System *> (clone ());
system->rank_ = broken_intos_.size ();
- vector<Grob*> c (breaking[i].cols_);
+ vector<Grob *> c (breaking[i].cols_);
pscore_->typeset_system (system);
int st = Paper_column::get_rank (c[0]);
for (vsize j = 0; j < c.size (); j++)
{
c[j]->translate_axis (breaking[i].config_[j], X_AXIS);
- dynamic_cast<Paper_column *> (c[j])->system_ = system;
+ dynamic_cast<Paper_column *> (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));
}
system->set_property ("labels", system_labels);
-
+
set_loose_columns (system, &breaking[i]);
broken_intos_.push_back (system);
}
ga = unsmob_grob_array (scm_ga);
}
- p->rank_ = ga->size ();
+ p->set_rank (ga->size ());
ga->add (p);
Axis_group_interface::add_element (this, p);
This might seem inefficient, but Stencils are cached per grob
anyway. */
- vector<Grob*> all_elts_sorted (all_elements_->array ());
- vector_sort (all_elts_sorted, std::less<Grob*> ());
+ vector<Grob *> all_elts_sorted (all_elements_->array ());
+ vector_sort (all_elts_sorted, std::less<Grob *> ());
uniq (all_elts_sorted);
this->get_stencil ();
for (vsize i = all_elts_sorted.size (); i--;)
return a.layer_ < b.layer_;
}
-
SCM
System::get_paper_system ()
{
Layer_entry e;
e.grob_ = all_elements_->grob (j);
e.layer_ = robust_scm2int (e.grob_->get_property ("layer"), 1);
-
- entries.push_back (e);
+
+ entries.push_back (e);
}
vector_sort (entries, std::less<Layer_entry> ());
if (st.expr () == SCM_EOL)
continue;
-
+
Offset o;
for (int a = X_AXIS; a < NO_AXES; a++)
o[Axis (a)] = g->relative_coordinate (this, Axis (a));
pl->set_property ("page-turn-penalty", right_bound->get_property ("page-turn-penalty"));
Interval staff_refpoints;
- extract_grob_set (this, "spaceable-staves", staves);
- for (vsize i = 0; i < staves.size (); i++)
- if (staves[i]->is_live ())
- staff_refpoints.add_point (staves[i]->relative_coordinate (this, Y_AXIS));
+ if (Grob *align = get_vertical_alignment ())
+ {
+ extract_grob_set (align, "elements", staves);
+ for (vsize i = 0; i < staves.size (); i++)
+ if (staves[i]->is_live ()
+ && Page_layout_problem::is_spaceable (staves[i]))
+ staff_refpoints.add_point (staves[i]->relative_coordinate (this,
+ Y_AXIS));
+ }
pl->set_property ("staff-refpoint-extent", ly_interval2scm (staff_refpoints));
- pl->set_property ("system-grob", this->self_scm ());
+ pl->set_property ("system-grob", this->self_scm ());
return pl->unprotect ();
}
-vector<Item*>
+vector<Item *>
System::broken_col_range (Item const *left, Item const *right) const
{
- vector<Item*> ret;
+ vector<Item *> ret;
left = left->get_column ();
right = right->get_column ();
-
extract_grob_set (this, "columns", cols);
vsize i = Paper_column::get_rank (left);
&& Paper_column::get_rank (cols[i]) < end_rank)
{
Paper_column *c = dynamic_cast<Paper_column *> (cols[i]);
- if (Paper_column::is_breakable (c) && !c->system_)
+ if (Paper_column::is_breakable (c) && !c->get_system ())
ret.push_back (c);
i++;
}
return ret;
}
-
/** Return all columns, but filter out any unused columns , since they might
disrupt the spacing problem. */
-vector<Grob*>
+vector<Grob *>
System::used_columns () const
{
extract_grob_set (this, "columns", ro_columns);
break;
}
- vector<Grob*> columns;
+ vector<Grob *> columns;
for (int i = 0; i <= last_breakable; i++)
{
if (Paper_column::is_used (ro_columns[i]))
extract_grob_set (this, "columns", columns);
if (which >= columns.size ())
return 0;
-
- return dynamic_cast<Paper_column*> (columns[which]);
+
+ return dynamic_cast<Paper_column *> (columns[which]);
}
-Paper_score*
+Paper_score *
System::paper_score () const
{
return pscore_;
}
System *
-get_root_system (Grob *me)
+get_root_system (Grob *me)
{
Grob *system_grob = me;
-
+
while (system_grob->get_parent (Y_AXIS))
system_grob = system_grob->get_parent (Y_AXIS);
- return dynamic_cast<System*> (system_grob);
+ return dynamic_cast<System *> (system_grob);
}
Grob *
return 0;
}
+Interval
+System::part_of_line_pure_height (vsize start, vsize end, bool begin)
+{
+ Grob *alignment = get_vertical_alignment ();
+ if (!alignment)
+ return Interval ();
+
+ extract_grob_set (alignment, "elements", staves);
+ vector<Real> offsets = Align_interface::get_minimum_translations (alignment, staves, Y_AXIS, true, start, end);
+
+ Interval ret;
+ for (vsize i = 0; i < staves.size (); ++i)
+ {
+ Interval iv = begin
+ ? Axis_group_interface::begin_of_line_pure_height (staves[i], start)
+ : Axis_group_interface::rest_of_line_pure_height (staves[i], start, end);
+ if (i < offsets.size ())
+ iv.translate (offsets[i]);
+ ret.unite (iv);
+ }
+
+ Interval other_elements = begin
+ ? Axis_group_interface::begin_of_line_pure_height (this, start)
+ : Axis_group_interface::rest_of_line_pure_height (this, start, end);
+
+ ret.unite (other_elements);
+
+ return ret;
+}
+
+Interval
+System::begin_of_line_pure_height (vsize start, vsize end)
+{
+ return part_of_line_pure_height (start, end, true);
+}
+
+Interval
+System::rest_of_line_pure_height (vsize start, vsize end)
+{
+ return part_of_line_pure_height (start, end, false);
+}
+
+// This differs from Axis_group_interface::calc_pure_relevant_grobs
+// because here, we are only interested in those few elements that aren't
+// descended from VerticalAlignment (ie. things like RehearsalMark, BarLine).
+MAKE_SCHEME_CALLBACK (System, calc_pure_relevant_grobs, 1);
+SCM
+System::calc_pure_relevant_grobs (SCM smob)
+{
+ Grob *me = unsmob_grob (smob);
+
+ extract_grob_set (me, "elements", elts);
+ vector<Grob *> 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 (to_boolean (scm_apply_1 (pure_relevant_p, elts[i]->self_scm (), SCM_EOL)))
+ relevant_grobs.push_back (elts[i]);
+
+ if (Item *it = dynamic_cast<Item*> (elts[i]))
+ {
+ Direction d = LEFT;
+ do
+ {
+ Item *piece = it->find_prebroken_piece (d);
+ if (piece && to_boolean (scm_apply_1 (pure_relevant_p, piece->self_scm (), SCM_EOL)))
+ relevant_grobs.push_back (piece);
+ }
+ while (flip (&d) != LEFT);
+ }
+ }
+ }
+
+ SCM grobs_scm = Grob_array::make_array ();
+
+ unsmob_grob_array (grobs_scm)->set_array (relevant_grobs);
+ return grobs_scm;
+}
+
+MAKE_SCHEME_CALLBACK (System, height, 1);
+SCM
+System::height (SCM smob)
+{
+ return Axis_group_interface::height (smob);
+}
+
+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<System *> (unsmob_grob (smob));
+ int start = scm_to_int (start_scm);
+ int end = scm_to_int (end_scm);
+
+ Interval begin = me->begin_of_line_pure_height (start, end);
+ Interval rest = me->rest_of_line_pure_height (start, end);
+ begin.unite (rest);
+
+ return ly_interval2scm (begin);
+}
+
ADD_INTERFACE (System,
"This is the top-level object: Each object in a score"
" ultimately has a @code{System} object as its X and"
"columns "
"labels "
"pure-Y-extent "
- "spaceable-staves "
- "skyline-distance "
"skyline-horizontal-padding "
- )
+ );