diff options
author | Michael Käppler <xmichael-k@web.de> | 2009-10-29 11:38:45 +0100 |
---|---|---|
committer | Neil Puttock <n.puttock@gmail.com> | 2009-11-05 23:02:21 +0000 |
commit | 4908afe216a92f70fd6f8c8cd0db8a6aa0a10ec1 (patch) | |
tree | 751aace8d7a99296ab1a607bb71f8019c9fa4170 | |
parent | abb835d326838ab293c99434c5af29015d1e432a (diff) |
New twoside mode.
* This patch allows to specify different margins for odd and even
pages by setting two-sided to true in the \paper block
* The corresponding settings are inner- and outer-margin, there
exists the possibility to set a binding-offset, too
* These values are stored internally as left- and right-margin,
though. Translation is done in page.scm:make-page-stencil
* Small code cleanup in paper.scm:set-paper-dimensions
-rw-r--r-- | input/regression/paper-twosided-bcorr.ly | 20 | ||||
-rw-r--r-- | input/regression/paper-twosided.ly | 19 | ||||
-rw-r--r-- | lily/output-def.cc | 39 | ||||
-rw-r--r-- | ly/paper-defaults-init.ly | 5 | ||||
-rw-r--r-- | scm/page.scm | 67 | ||||
-rw-r--r-- | scm/paper.scm | 115 |
6 files changed, 168 insertions, 97 deletions
diff --git a/input/regression/paper-twosided-bcorr.ly b/input/regression/paper-twosided-bcorr.ly new file mode 100644 index 0000000000..98d0cf4988 --- /dev/null +++ b/input/regression/paper-twosided-bcorr.ly @@ -0,0 +1,20 @@ +\version "2.13.8" + +\header { + texidoc = "In two-sided mode, a binding offset can be specified, which is added +to the inner margin automatically." +} + +someNotes = \relative c' { \repeat unfold 200 { c4 d e f } } + +\paper { + two-sided = ##t + inner-margin = 10 \mm + outer-margin = 20 \mm + binding-offset = 5 \mm +} + +\book { + \score { \someNotes } +} + diff --git a/input/regression/paper-twosided.ly b/input/regression/paper-twosided.ly new file mode 100644 index 0000000000..73764206e1 --- /dev/null +++ b/input/regression/paper-twosided.ly @@ -0,0 +1,19 @@ +\version "2.13.8" + +\header { + texidoc = "Two-sided mode allows you to use different margins for +odd and even pages." +} + +someNotes = \relative c' { \repeat unfold 200 { c4 d e f } } + +\paper { + two-sided = ##t + inner-margin = 10 \mm + outer-margin = 20 \mm +} + +\book { + \score { \someNotes } +} + diff --git a/lily/output-def.cc b/lily/output-def.cc index 3461e3c920..0e29b23fb1 100644 --- a/lily/output-def.cc +++ b/lily/output-def.cc @@ -135,13 +135,24 @@ Output_def::normalize () Real paper_width; SCM scm_paper_width = c_variable ("paper-width"); + bool twosided = to_boolean (c_variable ("two-sided")); + // We don't distinguish between outer-margin / left-margin and so on + // until page-stencil positioning in page.scm Real left_margin, left_margin_default; - SCM scm_left_margin_default = c_variable ("left-margin-default-scaled"); - SCM scm_left_margin = c_variable ("left-margin"); + SCM scm_left_margin_default = (twosided + ? c_variable ("outer-margin-default-scaled") + : c_variable ("left-margin-default-scaled")); + SCM scm_left_margin = (twosided + ? c_variable ("outer-margin") + : c_variable ("left-margin")); Real right_margin, right_margin_default; - SCM scm_right_margin_default = c_variable ("right-margin-default-scaled"); - SCM scm_right_margin = c_variable ("right-margin"); + SCM scm_right_margin_default = (twosided + ? c_variable ("inner-margin-default-scaled") + : c_variable ("right-margin-default-scaled")); + SCM scm_right_margin = (twosided + ? c_variable ("inner-margin") + : c_variable ("right-margin")); if (scm_paper_width == SCM_UNDEFINED || scm_left_margin_default == SCM_UNDEFINED @@ -162,14 +173,18 @@ Output_def::normalize () = paper_width - left_margin_default - right_margin_default; SCM scm_line_width = c_variable ("line-width"); + Real binding_offset = 0; + if (twosided) + binding_offset = robust_scm2double (c_variable ("binding-offset"), 0); + if (scm_line_width == SCM_UNDEFINED) { left_margin = ((scm_left_margin == SCM_UNDEFINED) - ? left_margin_default - : scm_to_double (scm_left_margin)); + ? left_margin_default + : scm_to_double (scm_left_margin)); right_margin = ((scm_right_margin == SCM_UNDEFINED) - ? right_margin_default - : scm_to_double (scm_right_margin)); + ? right_margin_default + : scm_to_double (scm_right_margin)) + binding_offset; line_width = paper_width - left_margin - right_margin; } else @@ -177,15 +192,15 @@ Output_def::normalize () line_width = scm_to_double (scm_line_width); if (scm_left_margin == SCM_UNDEFINED) { - // Vertically center systems if only line-width is given - if (scm_right_margin == SCM_UNDEFINED) + // Vertically center systems if only line-width is given + if (scm_right_margin == SCM_UNDEFINED) { left_margin = (paper_width - line_width) / 2; right_margin = left_margin; } else { - right_margin = scm_to_double (scm_right_margin); + right_margin = scm_to_double (scm_right_margin) + binding_offset; left_margin = paper_width - line_width - right_margin; } } @@ -194,7 +209,7 @@ Output_def::normalize () left_margin = scm_to_double (scm_left_margin); right_margin = ((scm_right_margin == SCM_UNDEFINED) ? (paper_width - line_width - left_margin) - : scm_to_double (scm_right_margin)); + : scm_to_double (scm_right_margin)) + binding_offset; } } diff --git a/ly/paper-defaults-init.ly b/ly/paper-defaults-init.ly index 8be089f618..8089b3be71 100644 --- a/ly/paper-defaults-init.ly +++ b/ly/paper-defaults-init.ly @@ -87,6 +87,7 @@ \include "titling-init.ly" check-consistency = ##t + two-sided = ##f % These margins apply to the default paper format given by (ly:get-option 'paper-size) % and are scaled accordingly for other formats @@ -97,6 +98,10 @@ left-margin-default = 10 \mm right-margin-default = 10 \mm + inner-margin-default = 10 \mm + outer-margin-default = 20 \mm + binding-offset-default = 0 \mm + head-separation-default = 4 \mm foot-separation-default = 4 \mm diff --git a/scm/page.scm b/scm/page.scm index 959402c406..3c81b7bd2e 100644 --- a/scm/page.scm +++ b/scm/page.scm @@ -15,7 +15,7 @@ page-printable-height layout->page-init page-lines - page-force + page-force page-penalty page-configuration page-lines @@ -23,7 +23,7 @@ page-system-numbers page-stencil page-free-height - page? + page? )) (use-modules (lily) @@ -46,9 +46,9 @@ (page-set-property! p 'head-stencil (page-header p)) (page-set-property! p 'foot-stencil (page-footer p)) - + p)) - + (define page-property ly:prob-property) (define page-set-property! ly:prob-set-property!) (define (page-property? page sym) @@ -56,7 +56,7 @@ (define (page? x) (ly:prob-type? x 'page)) -;; define accessors. +;; define accessors. (for-each (lambda (j) (module-define! @@ -64,7 +64,7 @@ (string->symbol (format "page-~a" j)) (lambda (pg) (page-property pg j)))) - + '(page-number prev lines force penalty lines)) (define (page-system-numbers page) @@ -81,7 +81,7 @@ (if (not (number? (ly:prob-property sys 'Y-offset))) (ly:prob-set-property! sys 'Y-offset off)))) - + (zip (page-property page 'lines) (page-property page 'configuration)))) @@ -115,19 +115,19 @@ (ly:stencil-add stencil (ly:stencil-translate-axis y 6 X)))))) (add-stencil - (ly:stencil-translate-axis + (ly:stencil-translate-axis (annotate-y-interval layout "paper-height" (cons (- paper-height) 0) #t) 1 X)) (add-stencil - (ly:stencil-translate-axis + (ly:stencil-translate-axis (annotate-y-interval layout "top-margin" (cons (- top-margin) 0) #t) 2 X)) (add-stencil - (ly:stencil-translate-axis + (ly:stencil-translate-axis (annotate-y-interval layout "bottom-margin" (cons (- paper-height) (- bottom-margin paper-height)) #t) @@ -156,7 +156,7 @@ (define (page-header-or-footer page dir) - (let* + (let* ((paper-book (page-property page 'paper-book)) (layout (ly:paper-book-paper paper-book)) (scopes (ly:paper-book-scopes paper-book)) @@ -168,9 +168,9 @@ 'make-footer)) (header-proc (ly:output-def-lookup layout sym))) - (if (procedure? header-proc) - (header-proc layout scopes number is-last-bookpart is-bookpart-last-page) - #f))) + (if (procedure? header-proc) + (header-proc layout scopes number is-last-bookpart is-bookpart-last-page) + #f))) (define (page-header page) @@ -185,21 +185,23 @@ ((paper-height (ly:output-def-lookup layout 'paper-height)) (paper-width (ly:output-def-lookup layout 'paper-width)) (left-margin (ly:output-def-lookup layout 'left-margin)) + (right-margin (ly:output-def-lookup layout 'right-margin)) (bottom-edge (- paper-height (ly:output-def-lookup layout 'bottom-margin)) ) (top-margin (ly:output-def-lookup layout 'top-margin)) ) - + `((paper-height . ,paper-height) (paper-width . ,paper-width) (left-margin . ,left-margin) + (right-margin . ,right-margin) (top-margin . ,top-margin) (bottom-edge . ,bottom-edge) ))) (define (make-page-stencil page) "Construct a stencil representing the page from PAGE." - + (page-translate-systems page) (let* @@ -211,7 +213,7 @@ (number (page-page-number page)) ;; TODO: naming paper-height/paper-width not analogous to TeX. - + (system-xoffset (ly:output-def-lookup layout 'horizontal-shift 0.0)) (system-separator-markup (ly:output-def-lookup layout 'system-separator-markup)) (system-separator-stencil (if (markup? system-separator-markup) @@ -219,7 +221,7 @@ (layout-extract-page-properties layout) system-separator-markup) #f)) - + (page-stencil (ly:make-stencil '())) (last-system #f) @@ -231,7 +233,7 @@ (cons (+ system-xoffset x) (- 0 y (prop 'top-margin))) - + ))))) (add-system (lambda (system) @@ -298,7 +300,7 @@ (set! page-stencil (ly:stencil-add page-stencil (annotate-space-left page)))) - + (if (and (ly:stencil? foot) (not (ly:stencil-empty? foot))) (set! page-stencil @@ -310,22 +312,29 @@ (+ (- (prop 'bottom-edge)) (- (car (ly:stencil-extent foot Y))))))))) - (set! page-stencil - (ly:stencil-translate page-stencil (cons (prop 'left-margin) 0))) + (if (ly:output-def-lookup layout 'two-sided #f) + (set! page-stencil + (ly:stencil-translate page-stencil + (cons (prop (if (even? number) + 'left-margin + 'right-margin)) + 0))) + (set! page-stencil + (ly:stencil-translate page-stencil (cons (prop 'left-margin) 0)))) ;; annotation. (if (annotate? layout) (set! page-stencil (annotate-page layout page-stencil))) page-stencil)) - + (define-public (page-stencil page) (if (not (ly:stencil? (page-property page 'stencil))) ;; todo: make tweakable. ;; via property + callbacks. - + (page-set-property! page 'stencil (make-page-stencil page))) (page-property page 'stencil)) @@ -335,9 +344,9 @@ ((paper-book (page-property page 'paper-book)) (layout (ly:paper-book-paper paper-book)) (h (- (ly:output-def-lookup layout 'paper-height) - (ly:output-def-lookup layout 'top-margin) - (ly:output-def-lookup layout 'bottom-margin))) - + (ly:output-def-lookup layout 'top-margin) + (ly:output-def-lookup layout 'bottom-margin))) + (head (page-property page 'head-stencil)) (foot (page-property page 'foot-stencil)) (available @@ -347,13 +356,13 @@ (if (ly:stencil? foot) (interval-length (ly:stencil-extent foot Y)) 0)))) - + ;; (display (list "\n available" available head foot)) available)) (define (page-printable-height page) (if (not (number? (page-property page 'printable-height))) (page-set-property! page 'printable-height (calc-printable-height page))) - + (page-property page 'printable-height)) diff --git a/scm/paper.scm b/scm/paper.scm index 0b5a60ec8d..bb529c6c87 100644 --- a/scm/paper.scm +++ b/scm/paper.scm @@ -14,12 +14,16 @@ horizontal-shift in indent + inner-margin + inner-margin-default-scaled ledger-line-thickness left-margin left-margin-default-scaled line-thickness line-width mm + outer-margin + outer-margin-default-scaled paper-height paper-width pt @@ -35,15 +39,15 @@ ;; !! synchronize with feta-params.mf (let* - ((x1 (* 4.125 pt)) - (x0 (* 5 pt)) - (f1 (* 0.47 pt)) - (f0 (* 0.50 pt))) + ((x1 (* 4.125 pt)) + (x0 (* 5 pt)) + (f1 (* 0.47 pt)) + (f0 (* 0.50 pt))) (/ (+ (* f1 (- staff-space x0)) - (* f0 (- x1 staff-space))) + (* f0 (- x1 staff-space))) (- x1 x0)))) (define-public (layout-set-absolute-staff-size-in-module module staff-height) @@ -89,9 +93,9 @@ size. SZ is in points" (in-layout? (or (module-defined? current-mod 'is-paper) (module-defined? current-mod 'is-layout))) - ; maybe not necessary. - ; but let's be paranoid. Maybe someone still refers to the - ; old one. + ;; maybe not necessary. + ;; but let's be paranoid. Maybe someone still refers to the + ;; old one. (new-paper (ly:output-def-clone pap)) (new-scope (ly:output-def-scope new-paper))) @@ -207,68 +211,67 @@ size. SZ is in points" ("pa10" . (cons (* 26 mm) (* 35 mm))) ;; F4 used in southeast Asia and Australia ("f4" . (cons (* 210 mm) (* 330 mm))) - )) + )) -; todo: take dimension arguments. +;; todo: take dimension arguments. (define (set-paper-dimensions m w h) "M is a module (i.e. layout->scope_ )" (let* - ;; page layout - what to do with (printer specific!) margin settings? - ((paper-default (eval-carefully - (assoc-get + ;; page layout - what to do with (printer specific!) margin settings? + ((paper-default (eval-carefully + (assoc-get (ly:get-option 'paper-size) paper-alist #f #t) - m - (cons w h))) - (scaleable-values `(("left-margin" . ,w) - ("right-margin" . ,w) - ("top-margin" . ,h) - ("bottom-margin" . ,h) - ("head-separation" . ,h) - ("foot-separation" . ,h) - ("indent" . ,w) - ("short-indent" . ,w))) - (scaled-values - (map + m + (cons w h))) + ;; Horizontal margins, marked with 'preserve, are stored + ;; in renamed variables because they must not be overwritten. + ;; Output_def::normalize () needs to know + ;; whether the user set the value or not. + (scaleable-values `((("left-margin" . ,w) . preserve) + (("right-margin" . ,w) . preserve) + (("inner-margin" . ,w) . preserve) + (("outer-margin" . ,w) . preserve) + (("binding-offset" . ,w) . '()) + (("top-margin" . ,h) . '()) + (("bottom-margin" . ,h) . '()) + (("head-separation" . ,h) . '()) + (("foot-separation" . ,h) . '()) + (("indent" . ,w) . '()) + (("short-indent" . ,w) . '()))) + (scaled-values + (map (lambda (entry) (let ((entry-symbol - (string->symbol - (string-append (car entry) "-default"))) - (orientation (cdr entry))) - (if paper-default - (cons (car entry) - (round (* orientation - (/ (eval-carefully entry-symbol m 0) - (if (= orientation w) - (car paper-default) - (cdr paper-default)))))) - entry))) + (string->symbol + (string-append (caar entry) "-default"))) + (orientation (cdar entry))) + (if paper-default + (cons (if (eq? (cdr entry) 'preserve) + (string-append (caar entry) "-default-scaled") + (caar entry)) + (round (* orientation + (/ (eval-carefully entry-symbol m 0) + (if (= orientation w) + (car paper-default) + (cdr paper-default)))))) + entry))) scaleable-values))) - (module-define! m 'paper-width w) - (module-define! m 'paper-height h) - ;; Left and right margin are stored in renamed variables because - ;; they must not be overwritten. - ;; Output_def::normalize () needs to know - ;; whether the user set the value or not. - (module-define! m 'left-margin-default-scaled - (assoc-get "left-margin" scaled-values 0 #t)) - (module-define! m 'right-margin-default-scaled - (assoc-get "right-margin" scaled-values 0 #t)) - ;; Sometimes, lilypond-book doesn't estimate a correct line-width. - ;; Therefore, we need to unset line-width. - (module-remove! m 'line-width) - (set! scaled-values (assoc-remove! - (assoc-remove! scaled-values "left-margin") - "right-margin")) - (for-each + (module-define! m 'paper-width w) + (module-define! m 'paper-height h) + ;; Sometimes, lilypond-book doesn't estimate a correct line-width. + ;; Therefore, we need to unset line-width. + (module-remove! m 'line-width) + + (for-each (lambda (value) - (let ((value-symbol (string->symbol (car value))) - (number (cdr value))) - (module-define! m value-symbol number))) + (let ((value-symbol (string->symbol (car value))) + (number (cdr value))) + (module-define! m value-symbol number))) scaled-values))) (define (internal-set-paper-size module name landscape?) |