From 5003ea937ca2d718fbbfb8479457d6b68f10f122 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 19 Nov 2007 23:10:38 -0200 Subject: [PATCH] Oops - did not see the following changes during the previous merge. --- input/regression/musicxml/GNUmakefile | 2 + input/regression/page-breaking-page-count1.ly | 13 +++ input/regression/page-breaking-page-count2.ly | 14 +++ input/regression/page-breaking-page-count3.ly | 14 +++ lily/axis-group-interface.cc | 2 +- lily/beaming-pattern.cc | 1 - lily/constrained-breaking.cc | 2 +- lily/include/page-breaking.hh | 2 + lily/optimal-page-breaking.cc | 36 +++++--- lily/page-breaking.cc | 34 +++++-- lily/page-spacing.cc | 40 +++++++-- po/GNUmakefile | 2 +- po/README | 88 +++++++++++++++++++ po/TODO | 2 + smart-configure.sh | 4 +- 15 files changed, 224 insertions(+), 32 deletions(-) create mode 100644 input/regression/page-breaking-page-count1.ly create mode 100644 input/regression/page-breaking-page-count2.ly create mode 100644 input/regression/page-breaking-page-count3.ly create mode 100644 po/README diff --git a/input/regression/musicxml/GNUmakefile b/input/regression/musicxml/GNUmakefile index 53ecd0eca3..3240bceae3 100644 --- a/input/regression/musicxml/GNUmakefile +++ b/input/regression/musicxml/GNUmakefile @@ -6,3 +6,5 @@ LOCALSTEPMAKE_TEMPLATES=lilypond ly lysdoc musicxml include $(depth)/make/stepmake.make TITLE=Lilypond musicxml2ly Regression Tests +MXL_FILES := $(call src-wildcard,*.mlx) +EXTRA_DIST_FILES += $(MXL_FILES) \ No newline at end of file diff --git a/input/regression/page-breaking-page-count1.ly b/input/regression/page-breaking-page-count1.ly new file mode 100644 index 0000000000..ecbfcbb537 --- /dev/null +++ b/input/regression/page-breaking-page-count1.ly @@ -0,0 +1,13 @@ +\version "2.11.34" + +\header { + texidoc = "The number of pages in a score can be forced by setting +@code{page-count} in the (book-level) paper block." +} + +#(set-default-paper-size "a6") + +\book { + \paper { page-count = 2} + \score { {c'1 c'1} } +} \ No newline at end of file diff --git a/input/regression/page-breaking-page-count2.ly b/input/regression/page-breaking-page-count2.ly new file mode 100644 index 0000000000..c7e01a3517 --- /dev/null +++ b/input/regression/page-breaking-page-count2.ly @@ -0,0 +1,14 @@ +\version "2.11.34" + +\header { + texidoc = "The number of pages in a score can be forced by setting +@code{page-count} in the (book-level) paper block. If there are too +few systems for the number of pages, we append blank pages." +} + +#(set-default-paper-size "a6") + +\book { + \paper { page-count = 3} + \score { {c'1 c'1} } +} \ No newline at end of file diff --git a/input/regression/page-breaking-page-count3.ly b/input/regression/page-breaking-page-count3.ly new file mode 100644 index 0000000000..5f5b8b62ec --- /dev/null +++ b/input/regression/page-breaking-page-count3.ly @@ -0,0 +1,14 @@ +\version "2.11.34" + +\header { + texidoc = "The number of pages in a score can be forced by setting +@code{page-count} in the (book-level) paper block. Even if there are +too many systems for that number of pages, we will squeeze them in." +} + +#(set-default-paper-size "a6") + +\book { + \paper { page-count = 1} + \score { { \repeat unfold 10 {c'1 \break} } } +} \ No newline at end of file diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 05536316bb..0a82fe6713 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -97,7 +97,7 @@ Axis_group_interface::cached_pure_height (Grob *me, int start, int end) for (vsize i = 0; i + 1 < breaks.size (); i++) { int r = Paper_column::get_rank (cols[breaks[i]]); - if (r > end) + if (r >= end) break; if (r >= start) diff --git a/lily/beaming-pattern.cc b/lily/beaming-pattern.cc index 0f6f1e1b8f..37ef6ee614 100644 --- a/lily/beaming-pattern.cc +++ b/lily/beaming-pattern.cc @@ -69,7 +69,6 @@ Beaming_pattern::best_splitpoint_index (bool *at_boundary) const int min_den = INT_MAX; int min_index = -1; - Moment beat_pos; for (vsize i = 1; i < infos_.size (); i++) { Moment dt = infos_[i].start_moment_ - infos_[i].beat_start_; diff --git a/lily/constrained-breaking.cc b/lily/constrained-breaking.cc index 0838dea031..1efae87e12 100644 --- a/lily/constrained-breaking.cc +++ b/lily/constrained-breaking.cc @@ -265,7 +265,7 @@ Constrained_breaking::min_system_count (vsize start, vsize end) int Constrained_breaking::max_system_count (vsize start, vsize end) { - vsize brk = (end >= start_.size ()) ? breaks_.size () : starting_breakpoints_[end]; + vsize brk = (end >= start_.size ()) ? breaks_.size () - 1 : starting_breakpoints_[end]; return brk - starting_breakpoints_[start]; } diff --git a/lily/include/page-breaking.hh b/lily/include/page-breaking.hh index 18704fd36b..b14c780ba5 100644 --- a/lily/include/page-breaking.hh +++ b/lily/include/page-breaking.hh @@ -102,6 +102,7 @@ public: bool is_last () const; Real page_height (int page_number, bool last) const; Real page_top_space () const; + vsize system_count () const; protected: Paper_book *book_; @@ -149,6 +150,7 @@ private: bool ragged_; bool ragged_last_; Real page_top_space_; + vsize system_count_; vector current_configurations_; vector current_chunks_; diff --git a/lily/optimal-page-breaking.cc b/lily/optimal-page-breaking.cc index 34ff7f1b18..fa1e72b31a 100644 --- a/lily/optimal-page-breaking.cc +++ b/lily/optimal-page-breaking.cc @@ -39,24 +39,38 @@ Optimal_page_breaking::solve () vsize end = last_break_position (); vsize max_sys_count = max_system_count (0, end); vsize first_page_num = robust_scm2int (book_->paper_->c_variable ("first-page-number"), 1); + SCM forced_page_count = book_->paper_->c_variable ("page-count"); - /* find out the ideal number of pages */ - message (_ ("Finding the ideal number of pages...")); set_to_ideal_line_configuration (0, end); - - Page_spacing_result best = space_systems_on_best_pages (0, first_page_num); - vsize page_count = best.systems_per_page_.size (); + + Page_spacing_result best; + vsize page_count = robust_scm2int (forced_page_count, 1); Line_division ideal_line_division = current_configuration (0); Line_division best_division = ideal_line_division; + vsize min_sys_count = 1; + vsize ideal_sys_count = system_count (); + + if (!scm_is_integer (forced_page_count)) + { + /* find out the ideal number of pages */ + message (_ ("Finding the ideal number of pages...")); + + best = space_systems_on_best_pages (0, first_page_num); + page_count = best.systems_per_page_.size (); - vsize ideal_sys_count = best.system_count (); - vsize min_sys_count = ideal_sys_count - best.systems_per_page_.back (); + ideal_sys_count = best.system_count (); + min_sys_count = ideal_sys_count - best.systems_per_page_.back (); - if (page_count > 1 && best.systems_per_page_[page_count - 2] > 1) - min_sys_count -= best.systems_per_page_[page_count - 2]; + if (page_count > 1 && best.systems_per_page_[page_count - 2] > 1) + min_sys_count -= best.systems_per_page_[page_count - 2]; + } + else + best = space_systems_on_n_pages (0, page_count, first_page_num); if (page_count == 1) message (_ ("Fitting music on 1 page...")); + else if (scm_is_integer (forced_page_count)) + message (_f ("Fitting music on %d pages...", (int)page_count)); else message (_f ("Fitting music on %d or %d pages...", (int)page_count-1, (int)page_count)); @@ -72,9 +86,7 @@ Optimal_page_breaking::solve () vsize min_p_count = min_page_count (i, first_page_num); Page_spacing_result cur; - if (min_p_count > page_count) - continue; - else if (min_p_count == page_count) + if (min_p_count == page_count) cur = space_systems_on_n_pages (i, page_count, first_page_num); else cur = space_systems_on_n_or_one_more_pages (i, page_count-1, first_page_num); diff --git a/lily/page-breaking.cc b/lily/page-breaking.cc index be11ffa3ea..d3a2762bbb 100644 --- a/lily/page-breaking.cc +++ b/lily/page-breaking.cc @@ -98,6 +98,7 @@ Page_breaking::next_system (Break_position const &break_pos) const Page_breaking::Page_breaking (Paper_book *pb, Break_predicate is_break) { book_ = pb; + system_count_ = 0; ragged_ = to_boolean (pb->paper_->c_variable ("ragged-bottom")); ragged_last_ = to_boolean (pb->paper_->c_variable ("ragged-last-bottom")); page_top_space_ = robust_scm2double (pb->paper_->c_variable ("page-top-space"), 0); @@ -127,6 +128,12 @@ Page_breaking::page_top_space () const return page_top_space_; } +vsize +Page_breaking::system_count () const +{ + return system_count_; +} + /* translate indices into breaks_ into start-end parameters for the line breaker */ void Page_breaking::line_breaker_args (vsize sys, @@ -451,6 +458,7 @@ Page_breaking::set_current_breakpoints (vsize start, Line_division lower_bound, Line_division upper_bound) { + system_count_ = system_count; current_chunks_ = chunk_list (start, end); current_start_breakpoint_ = start; current_end_breakpoint_ = end; @@ -506,6 +514,7 @@ Page_breaking::set_to_ideal_line_configuration (vsize start, vsize end) current_start_breakpoint_ = start; current_end_breakpoint_ = end; clear_line_details_cache (); + system_count_ = 0; Line_division div; for (vsize i = 0; i+1 < current_chunks_.size (); i++) @@ -518,6 +527,8 @@ Page_breaking::set_to_ideal_line_configuration (vsize start, vsize end) } else div.push_back (1); + + system_count_ += div.back (); } current_configurations_.clear (); current_configurations_.push_back (div); @@ -676,16 +687,19 @@ Page_spacing_result Page_breaking::space_systems_on_n_pages (vsize configuration, vsize n, vsize first_page_num) { Page_spacing_result ret; - assert (n >= min_page_count (configuration, first_page_num)); cache_line_details (configuration); - if (n > cached_line_details_.size ()) - return Page_spacing_result (); - if (n == 1) + bool valid_n = (n >= min_page_count (configuration, first_page_num) + && n <= cached_line_details_.size ()); + + if (!valid_n) + programming_error ("number of pages is out of bounds"); + + if (n == 1 && valid_n) ret = space_systems_on_1_page (cached_line_details_, page_height (first_page_num, is_last ()), ragged () || (is_last () && ragged_last ())); - else if (n == 2) + else if (n == 2 && valid_n) ret = space_systems_on_2_pages (configuration, first_page_num); else { @@ -711,8 +725,12 @@ Page_breaking::space_systems_on_n_or_one_more_pages (vsize configuration, vsize cache_line_details (configuration); vsize min_p_count = min_page_count (configuration, first_page_num); + bool valid_n = n >= min_p_count || n <= cached_line_details_.size (); + + if (!valid_n) + programming_error ("both page counts are out of bounds"); - if (n == 1) + if (n == 1 && valid_n) { bool rag = ragged () || (is_last () && ragged_last ()); Real height = page_height (first_page_num, is_last ()); @@ -726,9 +744,9 @@ Page_breaking::space_systems_on_n_or_one_more_pages (vsize configuration, vsize { Page_spacer ps (cached_line_details_, first_page_num, this); - if (n >= min_p_count) + if (n >= min_p_count || !valid_n) n_res = ps.solve (n); - if (n < cached_line_details_.size ()) + if (n < cached_line_details_.size () || !valid_n) m_res = ps.solve (n+1); } diff --git a/lily/page-spacing.cc b/lily/page-spacing.cc index 384ce44022..19129b3c17 100644 --- a/lily/page-spacing.cc +++ b/lily/page-spacing.cc @@ -92,11 +92,10 @@ Page_spacer::solve (vsize page_count) resize (page_count); Page_spacing_result ret; - ret.force_.resize (page_count); - ret.systems_per_page_.resize (page_count); vsize system = lines_.size () - 1; - vsize tack_onto_the_end = 0; + vsize extra_systems = 0; + vsize extra_pages = 0; if (isinf (state_.at (system, page_count-1).demerits_)) { @@ -112,13 +111,28 @@ Page_spacer::solve (vsize page_count) if (i) { - tack_onto_the_end = system - i; + extra_systems = system - i; system = i; } else - return Page_spacing_result (); /* couldn't salvage it -- probably going to crash */ + { + /* try chopping off pages from the end */ + vsize j; + for (j = page_count; j && isinf (state_.at (system, j-1).demerits_); j--) + ; + + if (j) + { + extra_pages = page_count - j; + page_count = j; + } + else + return Page_spacing_result (); /* couldn't salvage it -- probably going to crash */ + } } + ret.force_.resize (page_count); + ret.systems_per_page_.resize (page_count); ret.penalty_ = state_.at (system, page_count-1).penalty_ + lines_.back ().page_penalty_ + lines_.back ().turn_penalty_; @@ -133,9 +147,23 @@ Page_spacer::solve (vsize page_count) if (p == 0) ret.systems_per_page_[p] = system + 1; else - ret.systems_per_page_[p] = system - ps.prev_ + tack_onto_the_end; + ret.systems_per_page_[p] = system - ps.prev_; system = ps.prev_; } + + if (extra_systems) + { + ret.systems_per_page_.back () += extra_systems; + ret.demerits_ += 200000; + } + if (extra_pages) + { + ret.force_.insert (ret.force_.end (), extra_pages, 200000); + ret.systems_per_page_.insert (ret.systems_per_page_.end (), extra_pages, 0); + ret.demerits_ += 200000; + } + + ret.demerits_ += ret.penalty_; return ret; } diff --git a/po/GNUmakefile b/po/GNUmakefile index c277ee920c..1907a2c2ee 100644 --- a/po/GNUmakefile +++ b/po/GNUmakefile @@ -6,7 +6,7 @@ depth = .. NAME = lilypond MODULE_NAME = po DOMAIN = $(NAME) -EXTRA_DIST_FILES = TODO +EXTRA_DIST_FILES = TODO README STEPMAKE_TEMPLATES=podir include $(depth)/make/stepmake.make diff --git a/po/README b/po/README new file mode 100644 index 0000000000..7b9c400308 --- /dev/null +++ b/po/README @@ -0,0 +1,88 @@ +LilyPond program strings translation + +Addresses +========= + +Free Translation Project (FTP) + http://translationproject.org + +LilyPond page on FTP + http://translationproject.org/domain/lilypond.html + +FTP coordinator + + + +Instructions +============ + +Program strings are translated in PO files in this directory. + +This kind of translation is managed through the Free Translation +Project (FTP) -- see rationale below. + +The only changes that should be made to this directory are + +1) applying changes made on the FTP. These changes should be +automatically notified to lilypond-devel@gnu.org list by the FTP +robot; you can also see LilyPond page on FTP. + + +2) updating lilypond.pot: run 'make po-replace' at toplevel, clean up +lilypond.pot header to make it look like its previous state, commit +only lilypond.pot to Git and reset all .po files, roll a tarball with +'make dist', upload it somewhere on the web (or wait for the release), +and send a notification to FTP coordinator with a link to the tarball. + + +Rationale +========= +Why should we use the FTP? + +The FTP is designed to make software usable in more languages and +reduce software packagers work and responsability for translations, as +it organizes translations by language teams, rather than by packages. +This benefits to both users and developers; for example, translators +often volunteer without the developers need to spend time and energy +to find them, and all translation maintaining issues can be discussed +by the language team. + +In a short-circuit method, translators usually send their work +directly to the developers who commit it to the sources. The FTP is +not significantly slower, it can even be made as quick; for example, +translators in 4 languages updated 2.11.34 PO between 2 and 8 days +after I sent the notification update. + +We still don't use FTP for translating the documentation, because it +has currently no infrastructure for this. + + +Common issues +============= + +-- I'd like to commit fixes in .po for all languages +(e.g. punctuation, formatting), is it possible? + +This should be avoided. If it really saves translators' time, apply +changes to Git and notice both FTP coordinator (so he can apply the +changes to FTP too) and LilyPond translation meister (at +lilypond-devel@gnu.org). + + +-- The translation in my language could be improved, how can I propose +changes? + +Prepare a polite request with your changes in diff format, or better +with inline comments to the original translation, and send it to the +translator assigned to LilyPond in your language, with CC to your +language team (you cand find their email addresses on LilyPond FTP +page). + +If you get no reply within a reasonable timescale (2 weeks or so), or +a negative reply, and if you still think your suggestions are +worthwhile, please notice the developers at lilypond-devel@gnu.org. +We can always discuss with FTP coordinators to see what we can do. + + +For any other question, ask LilyPond translation meister at +lilypond-devel@gnu.org. diff --git a/po/TODO b/po/TODO index 01f6a80509..bf0e29e069 100644 --- a/po/TODO +++ b/po/TODO @@ -1,5 +1,7 @@ TODO +See also README for general instructions. + FIX OR STANDARDISE TARGETS * extract translatable strings from source code to `po/out/': at toplevel, do: diff --git a/smart-configure.sh b/smart-configure.sh index fa27ed8462..f82c085745 100755 --- a/smart-configure.sh +++ b/smart-configure.sh @@ -5,10 +5,10 @@ set -ux MAKEFILE_MD5=`find $srcdir -name GNUmakefile | grep -v '^./GNUmakefile$' | sort | md5sum | cut -b 1-32` CONFIGURE_INPUT_MD5=`cat $srcdir/config.make.in $srcdir/config.hh.in $srcdir/GNUmakefile.in | md5sum | cut -b 1-32` - +CONFIGURE_OPTIONS_MD5=`echo "$@" | tr ' ' '\n' | sed 's/ */ /g' | grep '.' | sort -u | md5sum | cut -b 1-32` CONFIGURE_CHECKSUM_FILE=configure.checksum -CONFIGURE_CHECKSUM="$MAKEFILE_MD5$CONFIGURE_INPUT_MD5" +CONFIGURE_CHECKSUM="$MAKEFILE_MD5$CONFIGURE_INPUT_MD5$CONFIGURE_OPTIONS_MD5" if test `cat $CONFIGURE_CHECKSUM_FILE` = "$CONFIGURE_CHECKSUM" ; then exit 0 -- 2.39.2