]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/book.cc (process): bugfix: flip ?: cases.
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Tue, 27 Sep 2005 10:01:15 +0000 (10:01 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Tue, 27 Sep 2005 10:01:15 +0000 (10:01 +0000)
* 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

19 files changed:
ChangeLog
Documentation/user/changing-defaults.itely
Documentation/user/global.itely
Documentation/user/introduction.itely
Documentation/user/programming-interface.itely
input/regression/page-spacing.ly [new file with mode: 0644]
input/regression/page-top-space.ly [new file with mode: 0644]
lily/book.cc
lily/include/paper-system.hh
lily/multi-measure-rest-engraver.cc
lily/paper-system-scheme.cc
lily/paper-system.cc
lily/piano-pedal-engraver.cc
lily/separating-line-group-engraver.cc
lily/spacing-engraver.cc
ly/music-functions-init.ly
ly/paper-defaults.ly
scm/page-layout.scm
scm/paper.scm

index 243c3eeecc0bb57baa8d62add51dbe3df9995680..07c2ccdb479e58be2212b37a621dac242cf561c7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,31 @@
 2005-09-27  Han-Wen Nienhuys  <hanwen@xs4all.nl>
 
+       * 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
index c6f94f01ec65083b10671411606690d21c09cd86..a6ef7ee4dff703fd9e7d3a6ce7c2f46bc87e1ca4 100644 (file)
@@ -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)
   <c e g>
 }
 @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
index 0d1c9c5ccd0b408d3eaf2a4380d41f8846831d78..4408687e2b1cd2f0a0c61c5620cec52a3bab3846 100644 (file)
@@ -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.
 
index 3ddd09120800aaddc5f1b4e82924fd581edc9607..78bc0220aa5317b0d51d0bdb38285d4e92ccf25f 100644 (file)
@@ -340,11 +340,11 @@ fragment.
    <d f g>
    \once \override NoteHead #'style = #'cross
    <d f g>
-   \applyoutput #mc-squared
+   \applyOutput #mc-squared
    <d f g>
    <<
       { d8[ es-( fis^^ g] fis2-) }
-      \repeat unfold 5 { \applyoutput #mc-squared s8 }
+      \repeat unfold 5 { \applyOutput #mc-squared s8 }
    >>
 }
 @end lilypond
index b5058b609b70ac633aeeaffe7f9a5b1112b32cd4..e62d864f82c201585fc77db5e300728559f65c2f 100644 (file)
@@ -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 (file)
index 0000000..928659a
--- /dev/null
@@ -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 (file)
index 0000000..154def9
--- /dev/null
@@ -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
+  }
+}
+
index f007e6263077f88a1e108856f4bc5c38eae98c64..bfd57d222e6b81f762a847e715f338c77d7a2cd0 100644 (file)
@@ -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;
   
index c292d9641319f96ab03ec7fd4ba00bc9f364b2d5..c2640e6548e16af4047d59087a912f539208c95d 100644 (file)
@@ -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;
index 004b8f762226661b28d1ac14b24f1831014d38a0..0e973b19bf701ce78f6d9130539c34fe3e67f21b 100644 (file)
@@ -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 */ "");
index 97bb947afe32cd10fc5d9cb6508a108df7fd78dc..ee393e0eeb4b73d07ce983b10641ebfe7a736b4c 100644 (file)
@@ -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;
+}
+
+
index 5f5e1702c965bfb425953d49cd5334a3c1aa3cab..87925402d467edefa6c04925bf88529a0c395faf 100644 (file)
@@ -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
 {
index 5fb5c37321c9681bcbadc48159ca26b0d7bfb7ab..997ce0689512778ad2d99287679e254a9451bce6 100644 (file)
@@ -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 */ "");
index 7b8ce78cc63534c8f50bdefca894ea9e5ce8da61..c2b6be3b02fcb342e31be8ceed7b4309533a8230 100644 (file)
@@ -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");
index 3dee97aad9060b3f21afd625b56be9d9f595e6c2..05244d1cd0175c17414be248e7c796a07053eab3 100644 (file)
@@ -204,5 +204,9 @@ ADD_TRANSLATOR (Spacing_engraver,
 
                /* create */ "SpacingSpanner",
                /* accept */ "",
-               /* read */ "currentMusicalColumn currentCommandColumn proportionalNotationDuration",
+               /* read */
+               "currentMusicalColumn "
+               "currentCommandColumn "
+               "proportionalNotationDuration",
+               
                /* write */ "");
index d32a540f761d622a8a2b9ba65c1d8199420c7002..d14bc4a8b5fd88ccd484954247ca4c76e21506ef 100644 (file)
@@ -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) ()
index 855c161beccc33ec129da205f9c60f02b18a8ba2..11ded37f58368c326e988b53659ef4b14a934b50 100644 (file)
@@ -40,7 +40,8 @@
     %% staves themselves.
     %%
     betweensystemspace = #(* 20 mm)
-
+    
+    
     %%
     %% fixed space between systems.
     %%
     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 )
 
index 98044b870ddbaef42965d03c6a57f652eb9f07ac..7dcdd8bd53a63236f8351d20e6cbd0d407312ec2 100644 (file)
@@ -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
index d0d3a56a71158621ce9d5e0857c6411b97a2792e..2b3512b04f72a89a0ddc326f073e1868f75b57fa 100644 (file)
@@ -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