From: Mike Solomon Date: Wed, 18 Jan 2012 07:25:09 +0000 (+0100) Subject: Reverts smobification of simple spanners. X-Git-Tag: release/2.15.27-1~29 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=072d33dbc1f31fafa96c24ac579b1ba4422d2eee;p=lilypond.git Reverts smobification of simple spanners. This saves time in the compliation of scores with long line widths. --- diff --git a/lily/column-description.cc b/lily/column-description.cc deleted file mode 100644 index 20ecc758fa..0000000000 --- a/lily/column-description.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - This file is part of LilyPond, the GNU music typesetter. - - Copyright (C) 2011--2012 Mike Solomon - - 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 . -*/ - -#include - -#include "column-description.hh" -#include "paper-column.hh" -#include "simple-spacer.hh" -#include "spaceable-grob.hh" -#include "spring.hh" - -static Grob * -next_spaceable_column (vector const &list, vsize starting) -{ - for (vsize i = starting + 1; i < list.size (); i++) - if (!Paper_column::is_loose (list[i])) - return list[i]; - return 0; -} - -Column_description -Column_description::get_column_description (vector const &cols, vsize col_index, bool line_starter) -{ - Grob *col = cols[col_index]; - if (line_starter) - col = Item::maybe_find_prebroken_piece (dynamic_cast (col), RIGHT); - - Column_description description; - Grob *next_col = next_spaceable_column (cols, col_index); - if (next_col) - description.spring_ = Spaceable_grob::get_spring (col, next_col); - - Grob *end_col = dynamic_cast (cols[col_index + 1])->find_prebroken_piece (LEFT); - if (end_col) - description.end_spring_ = Spaceable_grob::get_spring (col, end_col); - - for (SCM s = Spaceable_grob::get_minimum_distances (col); - scm_is_pair (s); s = scm_cdr (s)) - { - Grob *other = unsmob_grob (scm_caar (s)); - vsize j = binary_search (cols, other, Paper_column::less_than, col_index); - if (j != VPOS) - { - if (cols[j] == other) - description.rods_.push_back (Rod_description (j, scm_to_double (scm_cdar (s)))); - else /* it must end at the LEFT prebroken_piece */ - description.end_rods_.push_back (Rod_description (j, scm_to_double (scm_cdar (s)))); - } - } - - if (!line_starter && to_boolean (col->get_property ("keep-inside-line"))) - description.keep_inside_line_ = col->extent (col, X_AXIS); - - description.break_permission_ = col->get_property ("line-break-permission"); - return description; -} \ No newline at end of file diff --git a/lily/constrained-breaking.cc b/lily/constrained-breaking.cc index b3236a518c..c8b7fc1d74 100644 --- a/lily/constrained-breaking.cc +++ b/lily/constrained-breaking.cc @@ -436,10 +436,10 @@ Constrained_breaking::initialize () breaks_ = pscore_->get_break_indices (); all_ = pscore_->root_system ()->used_columns (); lines_.resize (breaks_.size (), breaks_.size (), Line_details ()); - vector spacers - = pscore_->root_system ()->get_simple_spacers (other_lines.length (), - other_lines.length () - first_line.length (), - ragged_right_); + vector forces = get_line_forces (all_, + other_lines.length (), + other_lines.length () - first_line.length (), + ragged_right_); for (vsize i = 0; i + 1 < breaks_.size (); i++) { for (vsize j = i + 1; j < breaks_.size (); j++) @@ -448,18 +448,9 @@ Constrained_breaking::initialize () bool ragged = ragged_right_ || (last && ragged_last_); Line_details &line = lines_.at (j, i); - line.force_ = spacers[i * breaks_.size () + j].force_penalty (ragged_right_); - if (!spacers[i * breaks_.size () + j].fits ()) - { - if (spacers[i * breaks_.size () + j].minimal_) - line.force_ = -200000; - else - line.force_ = infinity_f; - } + line.force_ = forces[i * breaks_.size () + j]; if (ragged && last && !isinf (line.force_)) line.force_ = (line.force_ < 0 && j > i + 1) ? infinity_f : 0; - if (!line.force_ && !spacers[i * breaks_.size () + j].line_len ()) - line.force_ = infinity_f; if (isinf (line.force_)) break; diff --git a/lily/include/column-description.hh b/lily/include/column-description.hh deleted file mode 100644 index 96d6a35e0c..0000000000 --- a/lily/include/column-description.hh +++ /dev/null @@ -1,67 +0,0 @@ -/* - This file is part of LilyPond, the GNU music typesetter. - - Copyright (C) 2011--2012 Mike Solomon - - 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 . -*/ - -#ifndef COLUMN_DESCRIPTION_HH -#define COLUMN_DESCRIPTION_HH - -#include "lily-proto.hh" -#include "smobs.hh" -#include "spring.hh" - -struct Rod_description -{ - vsize r_; - Real dist_; - - bool operator < (const Rod_description r) - { - return r_ < r.r_; - } - - Rod_description () - { - r_ = 0; - dist_ = 0; - } - - Rod_description (vsize r, Real d) - { - r_ = r; - dist_ = d; - } -}; - -struct Column_description -{ - vector rods_; - vector end_rods_; /* use these if they end at the last column of the line */ - Spring spring_; - Spring end_spring_; - - SCM break_permission_; - Interval keep_inside_line_; - - Column_description () - { - break_permission_ = SCM_EOL; - } - static Column_description get_column_description (vector const &cols, vsize col_index, bool line_starter); -}; - -#endif /* COLUMN_DESCRIPTION_HH */ diff --git a/lily/include/item.hh b/lily/include/item.hh index d38897fc80..c67b160636 100644 --- a/lily/include/item.hh +++ b/lily/include/item.hh @@ -40,7 +40,7 @@ public: static bool is_non_musical (Grob *); static bool break_visible (Grob *); - static Item *maybe_find_prebroken_piece (Item *g, Direction d); + bool is_broken () const; virtual bool pure_is_visible (int start, int end) const; diff --git a/lily/include/paper-column.hh b/lily/include/paper-column.hh index f7baf1010e..01a84d50df 100644 --- a/lily/include/paper-column.hh +++ b/lily/include/paper-column.hh @@ -52,7 +52,6 @@ public: DECLARE_GROB_INTERFACE (); static int get_rank (Grob const *); - static bool is_loose (Grob *); static bool is_musical (Grob *); static Moment when_mom (Grob *); static bool is_used (Grob *); diff --git a/lily/include/simple-spacer.hh b/lily/include/simple-spacer.hh index 64b59363f2..675e3baf54 100644 --- a/lily/include/simple-spacer.hh +++ b/lily/include/simple-spacer.hh @@ -30,8 +30,6 @@ class Simple_spacer public: Simple_spacer (); - bool minimal_; - void solve (Real line_len, bool ragged); void add_rod (int l, int r, Real dist); void add_spring (Spring const &); @@ -42,14 +40,12 @@ public: void set_force (Real force); Real force () const; - Real line_len () const; Real force_penalty (bool ragged) const; bool fits () const; DECLARE_SIMPLE_SMOBS (Simple_spacer); private: - Real expand_line (); Real compress_line (); Real rod_force (int l, int r, Real dist); @@ -61,6 +57,12 @@ private: bool fits_; }; +/* returns a vector of dimensions breaks.size () * breaks.size () */ +vector get_line_forces (vector const &columns, + Real line_len, + Real indent, + bool ragged); + Column_x_positions get_line_configuration (vector const &columns, Real line_len, Real indent, diff --git a/lily/include/system.hh b/lily/include/system.hh index c374c03cd9..b1189769cd 100644 --- a/lily/include/system.hh +++ b/lily/include/system.hh @@ -32,7 +32,6 @@ class System : public Spanner { int rank_; - vector simple_spacers_; Grob_array *all_elements_; void init_elements (); friend class Paper_score; // ugh. @@ -46,8 +45,6 @@ public: Grob *get_pure_bound (Direction dir, int start, int end); Grob *get_maybe_pure_bound (Direction dir, bool pure, int start, int end); int get_rank () const; - vector get_simple_spacers (Real line_len, Real indent, bool ragged); - void gen_simple_spacers (Real line_len, Real indent, bool ragged); vector get_footnote_heights_in_range (vsize st, vsize end); vector get_in_note_heights_in_range (vsize st, vsize end); vector internal_get_note_heights_in_range (vsize st, vsize end, bool foot); diff --git a/lily/item.cc b/lily/item.cc index ff77f5feac..6ea5643a54 100644 --- a/lily/item.cc +++ b/lily/item.cc @@ -127,15 +127,6 @@ Item::find_broken_piece (System *l) const return 0; } -Item * -Item::maybe_find_prebroken_piece (Item *g, Direction d) -{ - Item *ret = g->find_prebroken_piece (d); - if (ret) - return ret; - return g; -} - Item * Item::find_prebroken_piece (Direction d) const { diff --git a/lily/paper-column.cc b/lily/paper-column.cc index 0c7b3f387f..a8c5e0eea8 100644 --- a/lily/paper-column.cc +++ b/lily/paper-column.cc @@ -123,12 +123,6 @@ Paper_column::when_mom (Grob *me) return Moment (0); } -bool -Paper_column::is_loose (Grob *g) -{ - return (scm_is_pair (g->get_object ("between-cols"))); -} - bool Paper_column::is_musical (Grob *me) { diff --git a/lily/simple-spacer.cc b/lily/simple-spacer.cc index 39f9cfa195..fd8c6798c4 100644 --- a/lily/simple-spacer.cc +++ b/lily/simple-spacer.cc @@ -22,7 +22,6 @@ #include -#include "column-description.hh" #include "column-x-positions.hh" #include "dimensions.hh" #include "international.hh" @@ -83,12 +82,6 @@ Simple_spacer::force () const return force_; } -Real -Simple_spacer::line_len () const -{ - return line_len_; -} - bool Simple_spacer::fits () const { @@ -302,6 +295,179 @@ Simple_spacer::force_penalty (bool ragged) const /****************************************************************/ +struct Rod_description +{ + vsize r_; + Real dist_; + + bool operator < (const Rod_description r) + { + return r_ < r.r_; + } + + Rod_description () + { + r_ = 0; + dist_ = 0; + } + + Rod_description (vsize r, Real d) + { + r_ = r; + dist_ = d; + } +}; + +struct Column_description +{ + vector rods_; + vector end_rods_; /* use these if they end at the last column of the line */ + Spring spring_; + Spring end_spring_; + + SCM break_permission_; + Interval keep_inside_line_; + + Column_description () + { + break_permission_ = SCM_EOL; + } +}; + +static bool +is_loose (Grob *g) +{ + return (scm_is_pair (g->get_object ("between-cols"))); +} + +static Grob * +maybe_find_prebroken_piece (Grob *g, Direction d) +{ + Grob *ret = dynamic_cast (g)->find_prebroken_piece (d); + if (ret) + return ret; + return g; +} + +static Grob * +next_spaceable_column (vector const &list, vsize starting) +{ + for (vsize i = starting + 1; i < list.size (); i++) + if (!is_loose (list[i])) + return list[i]; + return 0; +} + +static Column_description +get_column_description (vector const &cols, vsize col_index, bool line_starter) +{ + Grob *col = cols[col_index]; + if (line_starter) + col = maybe_find_prebroken_piece (col, RIGHT); + + Column_description description; + Grob *next_col = next_spaceable_column (cols, col_index); + if (next_col) + description.spring_ = Spaceable_grob::get_spring (col, next_col); + + Grob *end_col = dynamic_cast (cols[col_index + 1])->find_prebroken_piece (LEFT); + if (end_col) + description.end_spring_ = Spaceable_grob::get_spring (col, end_col); + + for (SCM s = Spaceable_grob::get_minimum_distances (col); + scm_is_pair (s); s = scm_cdr (s)) + { + Grob *other = unsmob_grob (scm_caar (s)); + vsize j = binary_search (cols, other, Paper_column::less_than, col_index); + if (j != VPOS) + { + if (cols[j] == other) + description.rods_.push_back (Rod_description (j, scm_to_double (scm_cdar (s)))); + else /* it must end at the LEFT prebroken_piece */ + description.end_rods_.push_back (Rod_description (j, scm_to_double (scm_cdar (s)))); + } + } + + if (!line_starter && to_boolean (col->get_property ("keep-inside-line"))) + description.keep_inside_line_ = col->extent (col, X_AXIS); + + description.break_permission_ = col->get_property ("line-break-permission"); + return description; +} + +vector +get_line_forces (vector const &columns, + Real line_len, Real indent, bool ragged) +{ + vector breaks; + vector force; + vector non_loose; + vector cols; + SCM force_break = ly_symbol2scm ("force"); + + for (vsize i = 0; i < columns.size (); i++) + if (!is_loose (columns[i]) || Paper_column::is_breakable (columns[i])) + non_loose.push_back (columns[i]); + + breaks.clear (); + breaks.push_back (0); + cols.push_back (Column_description ()); + for (vsize i = 1; i + 1 < non_loose.size (); i++) + { + if (Paper_column::is_breakable (non_loose[i])) + breaks.push_back (cols.size ()); + + cols.push_back (get_column_description (non_loose, i, false)); + } + breaks.push_back (cols.size ()); + force.resize (breaks.size () * breaks.size (), infinity_f); + + for (vsize b = 0; b + 1 < breaks.size (); b++) + { + cols[breaks[b]] = get_column_description (non_loose, breaks[b], true); + vsize st = breaks[b]; + + for (vsize c = b + 1; c < breaks.size (); c++) + { + vsize end = breaks[c]; + Simple_spacer spacer; + + for (vsize i = breaks[b]; i < end - 1; i++) + spacer.add_spring (cols[i].spring_); + spacer.add_spring (cols[end - 1].end_spring_); + + for (vsize i = breaks[b]; i < end; i++) + { + for (vsize r = 0; r < cols[i].rods_.size (); r++) + if (cols[i].rods_[r].r_ < end) + spacer.add_rod (i - st, cols[i].rods_[r].r_ - st, cols[i].rods_[r].dist_); + for (vsize r = 0; r < cols[i].end_rods_.size (); r++) + if (cols[i].end_rods_[r].r_ == end) + spacer.add_rod (i - st, end - st, cols[i].end_rods_[r].dist_); + if (!cols[i].keep_inside_line_.is_empty ()) + { + spacer.add_rod (i - st, end - st, cols[i].keep_inside_line_[RIGHT]); + spacer.add_rod (0, i - st, -cols[i].keep_inside_line_[LEFT]); + } + } + spacer.solve ((b == 0) ? line_len - indent : line_len, ragged); + force[b * breaks.size () + c] = spacer.force_penalty (ragged); + + if (!spacer.fits ()) + { + if (c == b + 1) + force[b * breaks.size () + c] = -200000; + else + force[b * breaks.size () + c] = infinity_f; + break; + } + if (end < cols.size () && cols[end].break_permission_ == force_break) + break; + } + } + return force; +} + Column_x_positions get_line_configuration (vector const &columns, Real line_len, @@ -315,7 +481,7 @@ get_line_configuration (vector const &columns, ret.cols_.push_back (dynamic_cast (columns[0])->find_prebroken_piece (RIGHT)); for (vsize i = 1; i + 1 < columns.size (); i++) { - if (Paper_column::is_loose (columns[i])) + if (is_loose (columns[i])) ret.loose_cols_.push_back (columns[i]); else ret.cols_.push_back (columns[i]); @@ -326,7 +492,7 @@ get_line_configuration (vector const &columns, the end_XXX_ fields of our column_description */ for (vsize i = 0; i + 1 < ret.cols_.size (); i++) { - cols.push_back (Column_description::get_column_description (ret.cols_, i, i == 0)); + cols.push_back (get_column_description (ret.cols_, i, i == 0)); spacer.add_spring (cols[i].spring_); } for (vsize i = 0; i < cols.size (); i++) @@ -363,6 +529,7 @@ get_line_configuration (vector const &columns, return ret; } + #include "ly-smobs.icc" IMPLEMENT_SIMPLE_SMOBS (Simple_spacer); diff --git a/lily/system.cc b/lily/system.cc index 2645892ef8..bc59dede88 100644 --- a/lily/system.cc +++ b/lily/system.cc @@ -23,7 +23,6 @@ #include "all-font-metrics.hh" #include "axis-group-interface.hh" #include "break-align-interface.hh" -#include "column-description.hh" #include "grob-array.hh" #include "hara-kiri-group-spanner.hh" #include "international.hh" @@ -783,82 +782,6 @@ System::get_neighboring_staff (Direction dir, Grob *vertical_axis_group, Interva return 0; } -vector -System::get_simple_spacers (Real line_len, Real indent, bool ragged) -{ - if (!simple_spacers_.size ()) - gen_simple_spacers (line_len, indent, ragged); - - return simple_spacers_; -} - -void -System::gen_simple_spacers (Real line_len, Real indent, bool ragged) -{ - vector breaks; - vector non_loose; - vector cols; - SCM force_break = ly_symbol2scm ("force"); - vector columns = used_columns (); - - for (vsize i = 0; i < columns.size (); i++) - if (!Paper_column::is_loose (columns[i]) - || Paper_column::is_breakable (columns[i])) - non_loose.push_back (columns[i]); - - breaks.clear (); - breaks.push_back (0); - cols.push_back (Column_description ()); - for (vsize i = 1; i + 1 < non_loose.size (); i++) - { - if (Paper_column::is_breakable (non_loose[i])) - breaks.push_back (cols.size ()); - - cols.push_back (Column_description::get_column_description (non_loose, i, false)); - } - breaks.push_back (cols.size ()); - simple_spacers_.resize (breaks.size () * breaks.size (), Simple_spacer ()); - - for (vsize b = 0; b + 1 < breaks.size (); b++) - { - cols[breaks[b]] = Column_description::get_column_description (non_loose, breaks[b], true); - vsize st = breaks[b]; - - for (vsize c = b + 1; c < breaks.size (); c++) - { - vsize end = breaks[c]; - Simple_spacer spacer; - - for (vsize i = breaks[b]; i < end - 1; i++) - spacer.add_spring (cols[i].spring_); - spacer.add_spring (cols[end - 1].end_spring_); - - for (vsize i = breaks[b]; i < end; i++) - { - for (vsize r = 0; r < cols[i].rods_.size (); r++) - if (cols[i].rods_[r].r_ < end) - spacer.add_rod (i - st, cols[i].rods_[r].r_ - st, cols[i].rods_[r].dist_); - for (vsize r = 0; r < cols[i].end_rods_.size (); r++) - if (cols[i].end_rods_[r].r_ == end) - spacer.add_rod (i - st, end - st, cols[i].end_rods_[r].dist_); - if (!cols[i].keep_inside_line_.is_empty ()) - { - spacer.add_rod (i - st, end - st, cols[i].keep_inside_line_[RIGHT]); - spacer.add_rod (0, i - st, -cols[i].keep_inside_line_[LEFT]); - } - } - spacer.solve ((b == 0) ? line_len - indent : line_len, ragged); - spacer.minimal_ = c == b + 1; - simple_spacers_[b * breaks.size () + c] = spacer; - - if (!spacer.fits () - || (end < cols.size () - && cols[end].break_permission_ == force_break)) - break; - } - } -} - Interval System::pure_refpoint_extent (vsize start, vsize end) {