From: Han-Wen Nienhuys Date: Tue, 27 Sep 2005 10:01:15 +0000 (+0000) Subject: * lily/book.cc (process): bugfix: flip ?: cases. X-Git-Tag: release/2.7.11~15 X-Git-Url: https://git.donarmstrong.com/lilypond.git?a=commitdiff_plain;h=89c96b5833d2e0bb9d1781e6d88246992aeaef99;p=lilypond.git * lily/book.cc (process): bugfix: flip ?: cases. * Documentation/user/changing-defaults.itely (Difficult tweaks): add outputProperty. * ly/music-functions-init.ly: add outputProperty music function. * scm/paper.scm (set-paper-dimension-variables): add pagetopspace * scm/page-layout.scm (ly:optimal-page-breaks): read next-space and next-padding. (optimal-page-breaks): rename from ly:optimal-page-breaks. * lily/paper-system-scheme.cc (LY_DEFINE): new function. * lily/paper-system.cc (internal_get_property): new function. * Documentation/user/global.itely (Vertical spacing): refer to page-spacing.ly * scm/page-layout.scm (ly:optimal-page-breaks): add support for pagetopspace * input/regression/page-spacing.ly: new file. * input/regression/page-top-space.ly: new file. * lily/paper-system.cc (read_left_bound): new function. Read line-break-system-details from left bound to determine extents. * Documentation/user/programming-interface.itely (Using LilyPond syntax inside Scheme): change applyxxx -> applyXxx. * ly/music-functions-init.ly: add outputProperty music function. * ly/music-functions-init.ly: applyxxx -> applyXxx --- diff --git a/ChangeLog b/ChangeLog index 243c3eeecc..07c2ccdb47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,31 @@ 2005-09-27 Han-Wen Nienhuys + * lily/book.cc (process): bugfix: flip ?: cases. + + * Documentation/user/changing-defaults.itely (Difficult tweaks): + add outputProperty. + + * ly/music-functions-init.ly: add outputProperty music function. + + * scm/paper.scm (set-paper-dimension-variables): add pagetopspace + + * scm/page-layout.scm (ly:optimal-page-breaks): read next-space + and next-padding. + (optimal-page-breaks): rename from ly:optimal-page-breaks. + + * lily/paper-system-scheme.cc (LY_DEFINE): new function. + + * lily/paper-system.cc (internal_get_property): new function. + + * Documentation/user/global.itely (Vertical spacing): refer to page-spacing.ly + + * scm/page-layout.scm (ly:optimal-page-breaks): add support for + pagetopspace + + * input/regression/page-spacing.ly: new file. + + * input/regression/page-top-space.ly: new file. + * lily/spacing-spanner.cc: cmath -> math.h * lily/paper-system.cc (read_left_bound): new function. Read diff --git a/Documentation/user/changing-defaults.itely b/Documentation/user/changing-defaults.itely index c6f94f01ec..a6ef7ee4df 100644 --- a/Documentation/user/changing-defaults.itely +++ b/Documentation/user/changing-defaults.itely @@ -229,20 +229,20 @@ This is similar to @code{\context} with @code{= @var{id}}, but matches any context of type @var{type}, regardless of its given name. This variant is used with music expressions that can be interpreted at -several levels. For example, the @code{\applyoutput} command (see +several levels. For example, the @code{\applyOutput} command (see @ref{Running a function on all layout objects}). Without an explicit @code{\context}, it is usually applied to @context{Voice} @example -\applyoutput #@var{function} % apply to Voice +\applyOutput #@var{function} % apply to Voice @end example To have it interpreted at the @context{Score} or @context{Staff} level use these forms @example -\context Score \applyoutput #@var{function} -\context Staff \applyoutput #@var{function} +\context Score \applyOutput #@var{function} +\context Staff \applyOutput #@var{function} @end example @@ -1226,11 +1226,16 @@ Fingering_engraver is part of contexts: @dots{} @b{@internalsref{Voice}} @node Difficult tweaks @subsection Difficult tweaks -There are two classes of difficult adjustments. First, when there are +There are a few classes of difficult adjustments. + +@itemize @bullet +First, when there are several of the same objects at one point, and you want to adjust only -one. For example, if you want to change only one note head in a chord. +one. + +For example, if you want to change only one note head in a chord. -In this case, the @code{\applyoutput} function must be used. The +In this case, the @code{\applyOutput} function must be used. The next example defines a Scheme function @code{set-position-font-size} that sets the @code{font-size} property, but only on objects that have @internalsref{note-head-interface} and are at the @@ -1254,7 +1259,7 @@ right Y-position. \relative { c - \applyoutput #(set-position-font-size -2 4) + \applyOutput #(set-position-font-size -2 4) } @end lilypond @@ -1263,6 +1268,7 @@ right Y-position. A similar technique can be used for accidentals. In that case, the function should check for @code{accidental-interface}. +@item Another difficult adjustment is the appearance of spanner objects, such as slur and tie. Initially, only one of these objects is created, and they can be adjusted with the normal mechanism. However, in some @@ -1323,3 +1329,18 @@ should also call the old @code{after-line-breaking-callback}, if there is one. For example, if using this with @code{Slur}, @code{Slur::after_line_breaking} should also be called. + +@item Some objects cannot be changed with @code{\override} for +technical reasons. Examples of those are @code{NonMusicalPaperColumn} +and @code{PaperColumn}. They can be changed with the +@code{\outputProperty} function, which works similar to @code{\once +\override}, but uses a different syntax, + +@example +\outputProperty +#"Score.NonMusicalPaperColumn" % Grob name +#'line-break-system-details % Property name +#'((next-padding . 20)) % Value +@end example + +@end itemize diff --git a/Documentation/user/global.itely b/Documentation/user/global.itely index 0d1c9c5ccd..4408687e2b 100644 --- a/Documentation/user/global.itely +++ b/Documentation/user/global.itely @@ -298,6 +298,12 @@ Distance between the top-most music system and the page header. @item footsep Distance between the bottom-most music system and the page footer. +@cindex @code{pagetopspace} +Distance from the top of the printable area to the center of the first +staff. This only works for staves which are vertically small. Big staves +are set with the top of their bounding box aligned to the top of the +printable area. + @cindex @code{raggedbottom} @item raggedbottom If set to true, systems will not be spread across the page. @@ -513,6 +519,13 @@ then use the following @end example +@c let's wait for a some comments before writing more. + +The vertical spacing on a page can also be changed for each system individually. +Some examples are found in the example file +@inputfileref{input/regression/,page-spacing.ly}. + + @seealso Internals: Vertical alignment of staves is handled by the @@ -520,6 +533,9 @@ Internals: Vertical alignment of staves is handled by the specifying the vertical extent are described in connection with the @internalsref{Axis_group_engraver}. +Example files: @inputfileref{input/regression/,page-spacing.ly}. + + @refbugs @code{minimumVerticalExtent} is syntactic sugar for setting @@ -576,16 +592,15 @@ The difference is demonstrated in the following example, @code{forced-distance} cannot be changed per system. - @node Horizontal spacing @subsection Horizontal Spacing -The spacing engine translates differences in durations into -stretchable distances (``springs'') of differring lengths. Longer -durations get more space, shorter durations get less. The shortest -durations get a fixed amount of space (which is controlled by -@code{shortest-duration-space} in the @internalsref{SpacingSpanner} object). -The longer the duration, the more space it gets: doubling a +The spacing engine translates differences in durations into stretchable +distances (``springs'') of differring lengths. Longer durations get +more space, shorter durations get less. The shortest durations get a +fixed amount of space (which is controlled by +@code{shortest-duration-space} in the @internalsref{SpacingSpanner} +object). The longer the duration, the more space it gets: doubling a duration adds a fixed amount (this amount is controlled by @code{spacing-increment}) of space to the note. diff --git a/Documentation/user/introduction.itely b/Documentation/user/introduction.itely index 3ddd091208..78bc0220aa 100644 --- a/Documentation/user/introduction.itely +++ b/Documentation/user/introduction.itely @@ -340,11 +340,11 @@ fragment. \once \override NoteHead #'style = #'cross - \applyoutput #mc-squared + \applyOutput #mc-squared << { d8[ es-( fis^^ g] fis2-) } - \repeat unfold 5 { \applyoutput #mc-squared s8 } + \repeat unfold 5 { \applyOutput #mc-squared s8 } >> } @end lilypond diff --git a/Documentation/user/programming-interface.itely b/Documentation/user/programming-interface.itely index b5058b609b..e62d864f82 100644 --- a/Documentation/user/programming-interface.itely +++ b/Documentation/user/programming-interface.itely @@ -746,13 +746,13 @@ current bar number on the standard output during the compile: @cindex calling code on layout objects -@cindex @code{\applyoutput} +@cindex @code{\applyOutput} -The most versatile way of tuning an object is @code{\applyoutput}. Its +The most versatile way of tuning an object is @code{\applyOutput}. Its syntax is @example -\applyoutput @var{proc} +\applyOutput @var{proc} @end example @noindent @@ -763,7 +763,7 @@ object found in the context, with the following arguments: @itemize @bullet @item the layout object itself, @item the context where the layout object was created, and -@item the context where @code{\applyoutput} is processed. +@item the context where @code{\applyOutput} is processed. @end itemize @@ -773,7 +773,7 @@ object property @code{cause}. For example, for a note head, this is a @internalsref{NoteHead} event, and for a @internalsref{Stem} object, this is a @internalsref{NoteHead} object. -Here is a function to use for @code{\applyoutput}; it blanks +Here is a function to use for @code{\applyOutput}; it blanks note-heads on the center-line: @example diff --git a/input/regression/page-spacing.ly b/input/regression/page-spacing.ly new file mode 100644 index 0000000000..928659a643 --- /dev/null +++ b/input/regression/page-spacing.ly @@ -0,0 +1,59 @@ + +\header { + + texidoc = "By setting properties in NonMusicalPaperColumn, vertical +spacing of page layout can be adjusted. + +For technical reasons, @code{outputProperty} has to be used for +setting properties on individual object. @code{\override} may still be +used for global overrides. + +" + +} + +\version "2.7.10" + +#(set-global-staff-size 11) + +\book { + \score { + \relative c'' \new StaffGroup << + \new Voice { + c1\break + + \outputProperty + #"Score.NonMusicalPaperColumn" + #'line-break-system-details + #'((Y-extent . (-30 . 10))) + c^"This system has big extents (property Y-extent)"\break + + c\break + \outputProperty + #"Score.NonMusicalPaperColumn" + #'line-break-system-details + #'((next-padding . 20)) + + c^"This system is followed by padding, ie unstretchable space. (property next-padding)" \break + \outputProperty + #"Score.NonMusicalPaperColumn" + #'line-break-system-details + #'((next-space . 20)) + c^"This system is followed by stretchable space (property next-space)"\break + c\break + c\break + \outputProperty + #"Score.NonMusicalPaperColumn" #'line-break-system-details + #'((bottom-space . 25.0)) + c^"This system has 25 staff space to the bottom of the page. (property bottom-space)"\break + + + } + { c1 c c c c c c c } + >> + } + \paper { + raggedlastbottom = ##f + betweensystemspace = 1.0 + } +} diff --git a/input/regression/page-top-space.ly b/input/regression/page-top-space.ly new file mode 100644 index 0000000000..154def9de8 --- /dev/null +++ b/input/regression/page-top-space.ly @@ -0,0 +1,26 @@ +\header { + + texidoc = "By setting @code{pagetopspace,} the Y position of the +first system can be forced to be uniform." + +} +\version "2.7.11" + +\book { + \score { + + \relative { + c1\break\pageBreak + c1\break\pageBreak + c1 + \break\pageBreak + \override TextScript #'padding = #20 + c1^"bla" + } + } + + \paper { + pagetopspace = 3 \cm + } +} + diff --git a/lily/book.cc b/lily/book.cc index f007e62630..bfd57d222e 100644 --- a/lily/book.cc +++ b/lily/book.cc @@ -86,7 +86,7 @@ Book::process (Output_def *default_paper, if (score->error_found_) return 0; - Output_def *paper = paper_ ? default_paper : paper_; + Output_def *paper = paper_ ? paper_ : default_paper; if (!paper) return 0; diff --git a/lily/include/paper-system.hh b/lily/include/paper-system.hh index c292d96413..c2640e6548 100644 --- a/lily/include/paper-system.hh +++ b/lily/include/paper-system.hh @@ -22,7 +22,7 @@ class Paper_system DECLARE_SMOBS (Paper_system,); Stencil stencil_; bool is_title_; - + SCM details_; public: Interval staff_refpoints_; Real break_before_penalty_; @@ -32,6 +32,7 @@ public: void read_left_bound (Item*); Stencil to_stencil () const; SCM stencils () const; + SCM internal_get_property (SCM sym) const; bool is_title () const; Real break_before_penalty () const; Interval staff_refpoints () const; diff --git a/lily/multi-measure-rest-engraver.cc b/lily/multi-measure-rest-engraver.cc index 004b8f7622..0e973b19bf 100644 --- a/lily/multi-measure-rest-engraver.cc +++ b/lily/multi-measure-rest-engraver.cc @@ -252,5 +252,11 @@ ADD_TRANSLATOR (Multi_measure_rest_engraver, "should use a whole rest or a breve rest to represent 1 measure ", /* create */ "MultiMeasureRest MultiMeasureRestNumber MultiMeasureRestText", /* accept */ "multi-measure-rest-event multi-measure-text-event", - /* read */ "currentBarNumber restNumberThreshold breakableSeparationItem currentCommandColumn measurePosition measureLength", + /* read */ + "currentBarNumber " + "restNumberThreshold " + "breakableSeparationItem " + "currentCommandColumn " + "measurePosition " + "measureLength", /* write */ ""); diff --git a/lily/paper-system-scheme.cc b/lily/paper-system-scheme.cc index 97bb947afe..ee393e0eeb 100644 --- a/lily/paper-system-scheme.cc +++ b/lily/paper-system-scheme.cc @@ -64,3 +64,26 @@ LY_DEFINE (ly_paper_system_staff_extent, "ly:paper-system-staff-extents", return ly_interval2scm (ps->staff_refpoints ()); } + + +LY_DEFINE (ly_paper_system_property, "ly:paper-system-property", + 2, 1, 0, (SCM system, SCM sym, SCM dfault), + "Return the value for @var{sym}. Properties may be set by " + "setting the @code{line-break-system-details} property of " + "NonMusicalPaperColumn. If the property is not found, " + "return @var{dfault}, " + "or @code{'()} if undefined.") +{ + Paper_system *ps = unsmob_paper_system (system); + SCM_ASSERT_TYPE (ps, system, SCM_ARG1, __FUNCTION__, "paper-system"); + if (dfault == SCM_UNDEFINED) + dfault = SCM_EOL; + + SCM retval = ps->internal_get_property (sym); + if (retval == SCM_EOL) + return dfault; + else + return retval; +} + + diff --git a/lily/paper-system.cc b/lily/paper-system.cc index 5f5e1702c9..87925402d4 100644 --- a/lily/paper-system.cc +++ b/lily/paper-system.cc @@ -33,6 +33,7 @@ SCM Paper_system::mark_smob (SCM smob) { Paper_system *system = (Paper_system *) SCM_CELL_WORD_1 (smob); + scm_gc_mark (system->details_); return system->stencil_.expr (); } @@ -76,14 +77,14 @@ Paper_system::read_left_bound (Item *left) break_before_penalty_ = robust_scm2double (left->get_property ("page-penalty"), 0.0); - SCM details + details_ = left->get_property ("line-break-system-details"); SCM yext - = scm_assoc (ly_symbol2scm ("Y-extent"), details); + = scm_assq (ly_symbol2scm ("Y-extent"), details_); SCM staff_ext - = scm_assoc (ly_symbol2scm ("refpoint-Y-extent"), details); + = scm_assq (ly_symbol2scm ("refpoint-Y-extent"), details_); if (scm_is_pair (yext) && is_number_pair (scm_cdr (yext))) @@ -101,6 +102,19 @@ Paper_system::read_left_bound (Item *left) } } +SCM +Paper_system::internal_get_property (SCM sym) const +{ + SCM handle = scm_assq (sym, details_); + if (scm_is_pair (handle)) + return scm_cdr (handle); + else + return SCM_EOL; +} + +/* + todo: move to Paper_system property. + */ Interval Paper_system::staff_refpoints () const { diff --git a/lily/piano-pedal-engraver.cc b/lily/piano-pedal-engraver.cc index 5fb5c37321..997ce06895 100644 --- a/lily/piano-pedal-engraver.cc +++ b/lily/piano-pedal-engraver.cc @@ -515,7 +515,10 @@ ADD_TRANSLATOR (Piano_pedal_engraver, /* create */ "SostenutoPedal SustainPedal UnaCordaPedal SostenutoPedalLineSpanner SustainPedalLineSpanner UnaCordaPedalLineSpanner", /* accept */ "pedal-event", /* read */ "currentCommandColumn " - "pedalSostenutoStrings pedalSustainStrings " - "pedalUnaCordaStrings pedalSostenutoStyle " - "pedalSustainStyle pedalUnaCordaStyle", + "pedalSostenutoStrings " + "pedalSustainStrings " + "pedalUnaCordaStrings " + "pedalSostenutoStyle " + "pedalSustainStyle " + "pedalUnaCordaStyle", /* write */ ""); diff --git a/lily/separating-line-group-engraver.cc b/lily/separating-line-group-engraver.cc index 7b8ce78cc6..c2b6be3b02 100644 --- a/lily/separating-line-group-engraver.cc +++ b/lily/separating-line-group-engraver.cc @@ -73,7 +73,6 @@ Separating_line_group_engraver::Separating_line_group_engraver () void Separating_line_group_engraver::process_music () { - if (!sep_span_) { sep_span_ = make_spanner ("SeparatingGroupSpanner", SCM_EOL); @@ -218,7 +217,11 @@ Separating_line_group_engraver::stop_translation_timestep () ADD_ACKNOWLEDGER (Separating_line_group_engraver, item); ADD_TRANSLATOR (Separating_line_group_engraver, /* doc */ "Generates objects for computing spacing parameters.", - /* create */ "SeparationItem SeparatingGroupSpanner StaffSpacing", + + /* create */ + "SeparationItem " + "SeparatingGroupSpanner " + "StaffSpacing", /* accept */ "", /* read */ "createSpacing", /* write */ "breakableSeparationItem"); diff --git a/lily/spacing-engraver.cc b/lily/spacing-engraver.cc index 3dee97aad9..05244d1cd0 100644 --- a/lily/spacing-engraver.cc +++ b/lily/spacing-engraver.cc @@ -204,5 +204,9 @@ ADD_TRANSLATOR (Spacing_engraver, /* create */ "SpacingSpanner", /* accept */ "", - /* read */ "currentMusicalColumn currentCommandColumn proportionalNotationDuration", + /* read */ + "currentMusicalColumn " + "currentCommandColumn " + "proportionalNotationDuration", + /* write */ ""); diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index d32a540f76..d14bc4a8b5 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -65,21 +65,37 @@ applyOutput = 'procedure proc)) outputProperty = -#(def-music-function (parser location name prop value) - (symbol? symbol? scheme?) +#(def-music-function (parser location name property value) + (string? symbol? scheme?) - "Set @var{prop} to @var{value} in all grobs named @var{name} " + "Set @var{property} to @var{value} in all grobs named @var{name}. +The @var{name} argument is a string of the form @code{\"Context.GrobName\"} +or @code{\"GrobName\"}" - (make-music 'ApplyOutputEvent - 'origin location - 'procedure - (lambda (grob orig-context context) - (if (equal? - (cdr (assoc 'name (ly:grob-property grob 'meta))) - name) - (set! (ly:grob-property grob prop) value) - )))) + (let* + ((name-components (string-split name #\.)) + (context-name 'Bottom) + (grob-name #f)) + + (if (> 2 (length name-components)) + (set! grob-name (string->symbol (car name-components))) + (begin + (set! grob-name (string->symbol (list-ref name-components 1))) + (set! context-name (string->symbol (list-ref name-components 0))))) + + (context-spec-music + (make-music 'ApplyOutputEvent + 'origin location + 'procedure + (lambda (grob orig-context context) + (if (equal? + (cdr (assoc 'name (ly:grob-property grob 'meta))) + grob-name) + (set! (ly:grob-property grob property) value) + ))) + + context-name))) breathe = #(def-music-function (parser location) () diff --git a/ly/paper-defaults.ly b/ly/paper-defaults.ly index 855c161bec..11ded37f58 100644 --- a/ly/paper-defaults.ly +++ b/ly/paper-defaults.ly @@ -40,7 +40,8 @@ %% staves themselves. %% betweensystemspace = #(* 20 mm) - + + %% %% fixed space between systems. %% @@ -50,6 +51,14 @@ beforetitlespace = 10 \mm betweentitlespace = 2 \mm + + %% + %% Small staves are aligned so they come out on the same place on + %% across different pages. + %% + pagetopspace = #(* 12 mm) + + raggedbottom = ##f %% @@ -75,7 +84,7 @@ (baseline-skip . 3) (word-space . 0.6))) - #(define page-breaking ly:optimal-page-breaks) + #(define page-breaking optimal-page-breaks) #(define page-music-height default-page-music-height ) #(define page-make-stencil default-page-make-stencil ) diff --git a/scm/page-layout.scm b/scm/page-layout.scm index 98044b870d..7dcdd8bd53 100644 --- a/scm/page-layout.scm +++ b/scm/page-layout.scm @@ -185,8 +185,7 @@ create offsets. ;; - separate function for word-wrap style breaking? ;; - raggedbottom? raggedlastbottom? -(define-public (ly:optimal-page-breaks - lines paper-book) +(define-public (optimal-page-breaks lines paper-book) "Return pages as a list starting with 1st page. Each page is a list of lines. " @@ -230,90 +229,120 @@ is what have collected so far, and has ascending page numbers." user))) (define (space-systems page-height lines ragged?) - (let* ((inter-system-space + (let* ((global-inter-system-space (ly:output-def-lookup paper 'betweensystemspace)) + (top-space + (ly:output-def-lookup paper 'pagetopspace)) + (global-fixed-dist (ly:output-def-lookup paper 'betweensystempadding)) + (system-vector (list->vector (append lines (if (= (length lines) 1) '(#f) '())))) - (staff-extents - (list->vector - (append (map ly:paper-system-staff-extents lines) - (if (= (length lines) 1) - '((0 . 0)) - '())))) - (real-extents - (list->vector - (append - (map - (lambda (sys) (ly:paper-system-extent sys Y)) lines) - (if (= (length lines) 1) - '((0 . 0)) - '())))) - (no-systems (vector-length real-extents)) - (topskip (interval-end (vector-ref real-extents 0))) - (space-left (- page-height - (apply + (map interval-length (vector->list real-extents))))) - - (space (- page-height - topskip - (- (interval-start (vector-ref real-extents (1- no-systems)))))) - - (fixed-dist (ly:output-def-lookup paper 'betweensystempadding)) - (calc-spring - (lambda (idx) - (let* ((this-system-ext (vector-ref staff-extents idx)) - (next-system-ext (vector-ref staff-extents (1+ idx))) - (fixed (max 0 (- (+ (interval-end next-system-ext) - fixed-dist) - (interval-start this-system-ext)))) - (title1? (and (vector-ref system-vector idx) - (ly:paper-system-title? (vector-ref system-vector idx)))) - (title2? (and - (vector-ref system-vector (1+ idx)) - (ly:paper-system-title? (vector-ref system-vector (1+ idx))))) - (ideal (+ - (cond - ((and title2? title1?) - (ly:output-def-lookup paper 'betweentitlespace)) - (title1? - (ly:output-def-lookup paper 'aftertitlespace)) - (title2? - (ly:output-def-lookup paper 'beforetitlespace)) - (else inter-system-space)) - fixed)) - (hooke (/ 1 (- ideal fixed)))) - (list ideal hooke)))) - - (springs (map calc-spring (iota (1- no-systems)))) - (calc-rod - (lambda (idx) - (let* ((this-system-ext (vector-ref real-extents idx)) - (next-system-ext (vector-ref real-extents (1+ idx))) - (distance (max (- (+ (interval-end next-system-ext) - fixed-dist) - (interval-start this-system-ext) - ) 0)) - (entry (list idx (1+ idx) distance))) - entry))) - (rods (map calc-rod (iota (1- no-systems)))) - - ;; we don't set ragged based on amount space left. - ;; raggedbottomlast = ##T is much more predictable - (result (ly:solve-spring-rod-problem - springs rods space - ragged?)) - - (force (car result)) - (positions - (map (lambda (y) - (+ y topskip)) - (cdr result)))) + (staff-extents + (list->vector + (append (map ly:paper-system-staff-extents lines) + (if (= (length lines) 1) + '((0 . 0)) + '())))) + + (real-extents + (list->vector + (append + (map + (lambda (sys) (ly:paper-system-extent sys Y)) lines) + (if (= (length lines) 1) + '((0 . 0)) + '())))) + + (system-count (vector-length real-extents)) + (topskip (max + (+ + top-space + (interval-end (vector-ref staff-extents 0))) + (interval-end (vector-ref real-extents 0)) + )) + (last-system (vector-ref system-vector (1- system-count))) + (bottom-space (if (ly:paper-system? last-system) + (ly:paper-system-property last-system 'bottom-space 0.0) + 0.0)) + (space-left (- page-height + bottom-space + (apply + (map interval-length + (vector->list real-extents))))) + + (space (- page-height + topskip + bottom-space + (- (interval-start + (vector-ref real-extents (1- system-count)))))) + + (calc-spring + (lambda (idx) + (let* ( + (upper-system (vector-ref system-vector idx)) + (between-space (ly:paper-system-property upper-system 'next-space + global-inter-system-space)) + (fixed-dist (ly:paper-system-property upper-system 'next-padding + global-fixed-dist)) + + (this-system-ext (vector-ref staff-extents idx)) + (next-system-ext (vector-ref staff-extents (1+ idx))) + (fixed (max 0 (- (+ (interval-end next-system-ext) + fixed-dist) + (interval-start this-system-ext)))) + (title1? (and (vector-ref system-vector idx) + (ly:paper-system-title? (vector-ref system-vector idx)))) + (title2? (and + (vector-ref system-vector (1+ idx)) + (ly:paper-system-title? (vector-ref system-vector (1+ idx))))) + (ideal (+ + (cond + ((and title2? title1?) + (ly:output-def-lookup paper 'betweentitlespace)) + (title1? + (ly:output-def-lookup paper 'aftertitlespace)) + (title2? + (ly:output-def-lookup paper 'beforetitlespace)) + (else between-space)) + fixed)) + (hooke (/ 1 (- ideal fixed)))) + (list ideal hooke)))) + + (springs (map calc-spring (iota (1- system-count)))) + (calc-rod + (lambda (idx) + (let* ( + (upper-system (vector-ref system-vector idx)) + (fixed-dist (ly:paper-system-property upper-system 'next-padding + global-fixed-dist)) + (this-system-ext (vector-ref real-extents idx)) + (next-system-ext (vector-ref real-extents (1+ idx))) + + (distance (max (- (+ (interval-end next-system-ext) + fixed-dist) + (interval-start this-system-ext) + ) 0)) + (entry (list idx (1+ idx) distance))) + entry))) + (rods (map calc-rod (iota (1- system-count)))) + + ;; we don't set ragged based on amount space left. + ;; raggedbottomlast = ##T is much more predictable + (result (ly:solve-spring-rod-problem + springs rods space + ragged?)) + + (force (car result)) + (positions + (map (lambda (y) + (+ y topskip)) + (cdr result)))) (if #f ;; debug. (begin - (display (list "\n# systems: " no-systems + (display (list "\n# systems: " system-count "\nreal-ext" real-extents "\nstaff-ext" staff-extents "\ninterscore" inter-system-space "\nspace-letf" space-left diff --git a/scm/paper.scm b/scm/paper.scm index d0d3a56a71..2b3512b04f 100644 --- a/scm/paper.scm +++ b/scm/paper.scm @@ -7,6 +7,7 @@ (define-public (set-paper-dimension-variables mod) (module-define! mod 'dimension-variables '(pt mm cm in staffheight staff-space + pagetopspace betweensystemspace betweensystempadding linewidth indent hsize vsize horizontalshift staffspace linethickness ledgerlinethickness