]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/bar-line.scm
Add '-dcrop' option to ps and svg backends
[lilypond.git] / scm / bar-line.scm
index b432386372589e78b246014ff56be8064d3752a5..3fad8f8912949bf96a9944b6a1019432be850cb3 100644 (file)
@@ -1,6 +1,6 @@
 ;;;; This file is part of LilyPond, the GNU music typesetter.
 ;;;;
-;;;; Copyright (C) 2009--2012 Marc Hohl <marc@hohlart.de>
+;;;; Copyright (C) 2009--2015 Marc Hohl <marc@hohlart.de>
 ;;;;
 ;;;; LilyPond is free software: you can redistribute it and/or modify
 ;;;; it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; helper functions for staff and layout properties
 
-(define (calc-blot thickness extent grob)
+(define (bar-line::calc-blot thickness extent grob)
   "Calculate the blot diameter by taking @code{'rounded}
 and the dimensions of the extent into account."
   (let* ((rounded (ly:grob-property grob 'rounded #f))
@@ -39,9 +39,18 @@ and the dimensions of the extent into account."
                            ((< height blot-diameter) height)
                            (else blot-diameter)))
                    0)))
-
     blot))
 
+(define-public (bar-line::draw-filled-box x-ext y-ext thickness extent grob)
+  "Return a straight bar-line created by @code{ly:round-filled-box} looking at
+@var{x-ext}, @var{y-ext}, @var{thickness}.  The blot is calculated by
+@code{bar-line::calc-blot}, which needs @var{extent} and @var{grob}.
+@var{y-ext} is not necessarily of same value as @var{extent}."
+  (ly:round-filled-box
+    x-ext
+    y-ext
+    (bar-line::calc-blot thickness extent grob)))
+
 (define (get-span-glyph bar-glyph)
   "Get the corresponding span glyph from the @code{span-glyph-bar-alist}.
 Pad the string with @code{annotation-char}s to the length of the
@@ -88,10 +97,10 @@ Pad the string with @code{annotation-char}s to the length of the
     (if (pair? line-pos)
         (begin
           (set! iv (cons (car line-pos) (car line-pos)))
-          (map (lambda (x)
-                 (set! iv (cons (min (car iv) x)
-                                (max (cdr iv) x))))
-               (cdr line-pos)))
+          (for-each (lambda (x)
+                      (set! iv (cons (min (car iv) x)
+                                     (max (cdr iv) x))))
+                    (cdr line-pos)))
 
         (let ((line-count (ly:grob-property grob 'line-count 0)))
 
@@ -179,18 +188,18 @@ annotation char from string @var{str}."
          (last-pos (1- (length sorted-elts)))
          (idx 0))
 
-    (map (lambda (g)
-           (ly:grob-set-property!
-            g
-            'has-span-bar
-            (cons (if (eq? idx last-pos)
-                      #f
-                      grob)
-                  (if (zero? idx)
-                      #f
-                      grob)))
-           (set! idx (1+ idx)))
-         sorted-elts)))
+    (for-each (lambda (g)
+                (ly:grob-set-property!
+                 g
+                 'has-span-bar
+                 (cons (if (eq? idx last-pos)
+                           #f
+                           grob)
+                       (if (zero? idx)
+                           #f
+                           grob)))
+                (set! idx (1+ idx)))
+              sorted-elts)))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Line break decisions.
@@ -250,35 +259,38 @@ is not used within the routine."
   (let* ((line-thickness (layout-line-thickness grob))
          (thickness (* (ly:grob-property grob 'hair-thickness 1)
                        line-thickness))
-         (blot (calc-blot thickness extent grob))
          (extent (bar-line::widen-bar-extent-on-span grob extent)))
-
-    (ly:round-filled-box (cons 0 thickness)
-                         extent
-                         blot)))
+    (bar-line::draw-filled-box
+      (cons 0 thickness)
+      extent
+      thickness
+      extent
+      grob)))
 
 (define (make-thick-bar-line grob extent)
   "Draw a thick bar line."
   (let* ((line-thickness (layout-line-thickness grob))
          (thickness (* (ly:grob-property grob 'thick-thickness 1)
                        line-thickness))
-         (blot (calc-blot thickness extent grob))
          (extent (bar-line::widen-bar-extent-on-span grob extent)))
-
-    (ly:round-filled-box (cons 0 thickness)
-                         extent
-                         blot)))
+    (bar-line::draw-filled-box
+      (cons 0 thickness)
+      extent
+      thickness
+      extent
+      grob)))
 
 (define (make-tick-bar-line grob extent)
   "Draw a tick bar line."
   (let* ((half-staff (* 1/2 (ly:staff-symbol-staff-space grob)))
          (staff-line-thickness (ly:staff-symbol-line-thickness grob))
-         (height (interval-end extent))
-         (blot (calc-blot staff-line-thickness extent grob)))
-
-    (ly:round-filled-box (cons 0 staff-line-thickness)
-                         (cons (- height half-staff) (+ height half-staff))
-                         blot)))
+         (height (interval-end extent)))
+    (bar-line::draw-filled-box
+      (cons 0 staff-line-thickness)
+      (cons (- height half-staff) (+ height half-staff))
+      staff-line-thickness
+      extent
+      grob)))
 
 (define (make-colon-bar-line grob extent)
   "Draw repeat dots."
@@ -400,21 +412,21 @@ is not used within the routine."
               (half-thick (/ line-thickness 2.0))
               (stencil empty-stencil))
 
-          (map (lambda (i)
-                 (let ((top-y (min (* (+ i dash-size) half-space)
-                                   (+ (* (1- line-count) half-space)
-                                      half-thick)))
-                       (bot-y (max (* (- i dash-size) half-space)
-                                   (- 0 (* (1- line-count) half-space)
-                                      half-thick))))
-
-                   (set! stencil
-                         (ly:stencil-add
-                          stencil
-                          (ly:round-filled-box (cons 0 thickness)
-                                               (cons bot-y top-y)
-                                               blot)))))
-               (iota line-count (1- line-count) (- 2)))
+          (for-each (lambda (i)
+                      (let ((top-y (min (* (+ i dash-size) half-space)
+                                        (+ (* (1- line-count) half-space)
+                                           half-thick)))
+                            (bot-y (max (* (- i dash-size) half-space)
+                                        (- 0 (* (1- line-count) half-space)
+                                           half-thick))))
+
+                        (set! stencil
+                              (ly:stencil-add
+                               stencil
+                               (ly:round-filled-box (cons 0 thickness)
+                                                    (cons bot-y top-y)
+                                                    blot)))))
+                    (iota line-count (1- line-count) (- 2)))
           stencil)
         (let* ((dashes (/ height staff-space))
                (total-dash-size (/ height dashes))
@@ -440,14 +452,14 @@ is not used within the routine."
 the segno sign is drawn over the double bar line; otherwise, it
 draws the span bar variant, i.e. without the segno sign."
   (let* ((line-thickness (layout-line-thickness grob))
-         (thinkern (* (ly:grob-property grob 'thin-kern 1) line-thickness))
+         (segno-kern (* (ly:grob-property grob 'segno-kern 1) line-thickness))
          (thin-stil (make-simple-bar-line grob extent))
          (double-line-stil (ly:stencil-combine-at-edge
                             thin-stil
                             X
                             LEFT
                             thin-stil
-                            thinkern))
+                            segno-kern))
          (segno (ly:font-get-glyph (ly:grob-default-font grob)
                                    "scripts.varsegno"))
          (stencil (ly:stencil-add
@@ -459,7 +471,7 @@ draws the span bar variant, i.e. without the segno sign."
                         (cons 0 0)))
                    (ly:stencil-translate-axis
                     double-line-stil
-                    (* 1/2 thinkern)
+                    (* 1/2 segno-kern)
                     X))))
 
     stencil))
@@ -467,11 +479,11 @@ draws the span bar variant, i.e. without the segno sign."
 (define (make-kievan-bar-line grob extent)
   "Draw a kievan bar line."
   (let* ((font (ly:grob-default-font grob))
-         (stencil (stencil-whiteout
+         (stencil (stencil-whiteout-box
                    (ly:font-get-glyph font "scripts.barline.kievan"))))
 
     ;; the kievan bar line has no staff lines underneath,
-    ;; so we whiteout them and move the grob to a higher layer
+    ;; so we whiteout-box them and move the grob to a higher layer
     (ly:grob-set-property! grob 'layer 1)
     stencil))
 
@@ -500,7 +512,7 @@ opening bracket will be drawn, for @code{RIGHT} we get the closing bracket."
                                               (interval-start extent)
                                               Y))))
 
-    (if (eq? dir LEFT)
+    (if (eqv? dir LEFT)
         stencil
         (ly:stencil-scale stencil -1 1))))
 
@@ -801,7 +813,7 @@ no elements."
 ;; the size of the staff lines is evaluated as 0, which results in a
 ;; solid span bar line with faulty y coordinate.
 ;;
-;; This routine was originally by Juergen Reuter, but it was on the
+;; This routine was originally by Juergen Reuter, but it was on the
 ;; bulky side. Rewritten by Han-Wen. Ported from c++ to Scheme by Marc Hohl.
 (define-public (ly:span-bar::print grob)
   "The print routine for span bars."
@@ -823,26 +835,26 @@ no elements."
           ;; we compute the extents of each system and store them
           ;; in a list; dito for the 'allow-span-bar property.
           ;; model-bar takes the bar grob, if given.
-          (map (lambda (bar)
-                 (let ((ext (bar-line::bar-y-extent bar refp))
-                       (staff-symbol (ly:grob-object bar 'staff-symbol)))
-
-                   (if (ly:grob? staff-symbol)
-                       (let ((refp-extent (ly:grob-extent staff-symbol refp Y)))
-
-                         (set! ext (interval-union ext refp-extent))
-
-                         (if (> (interval-length ext) 0)
-                             (begin
-                               (set! extents (append extents (list ext)))
-                               (set! model-bar bar)
-                               (set! make-span-bars
-                                     (append make-span-bars
-                                             (list (ly:grob-property
-                                                    bar
-                                                    'allow-span-bar
-                                                    #t))))))))))
-               elts)
+          (for-each (lambda (bar)
+                      (let ((ext (bar-line::bar-y-extent bar refp))
+                            (staff-symbol (ly:grob-object bar 'staff-symbol)))
+
+                        (if (ly:grob? staff-symbol)
+                            (let ((refp-extent (ly:grob-extent staff-symbol refp Y)))
+
+                              (set! ext (interval-union ext refp-extent))
+
+                              (if (> (interval-length ext) 0)
+                                  (begin
+                                    (set! extents (append extents (list ext)))
+                                    (set! model-bar bar)
+                                    (set! make-span-bars
+                                          (append make-span-bars
+                                                  (list (ly:grob-property
+                                                         bar
+                                                         'allow-span-bar
+                                                         #t))))))))))
+                    elts)
           ;; if there is no bar grob, we use the callback argument
           (if (not model-bar)
               (set! model-bar grob))
@@ -910,50 +922,51 @@ of the volta brackets relative to the bar lines."
                                        line-thickness
                                        1/2))
          (bar-array (ly:grob-object grob 'bars))
-         (bar-array-length (ly:grob-array-length bar-array))
          ;; the bar-array starts with the uppermost bar line grob that is
          ;; covered by the left edge of the volta bracket; more (span)
          ;; bar line grobs from other staves may follow
-         (left-bar-line (if (> bar-array-length 0)
-                            (ly:grob-array-ref bar-array 0)
-                            '()))
+         (left-bar-line (and (ly:grob-array? bar-array)
+                             (positive? (ly:grob-array-length bar-array))
+                             (ly:grob-array-ref bar-array 0)))
          ;; we need the vertical-axis-group-index of the left-bar-line
          ;; to find the corresponding right-bar-line
-         (vag-index (if (null? left-bar-line)
-                        -1
-                        (ly:grob-get-vertical-axis-group-index left-bar-line)))
+         (vag-index (and left-bar-line
+                         (ly:grob-get-vertical-axis-group-index left-bar-line)))
          ;; the bar line corresponding to the right edge of the volta bracket
          ;; is the last entry with the same vag-index, so we transform the array to a list,
-         ;; reverse it and search for suitable entries:
-         (filtered-grobs (filter (lambda (e)
-                                   (eq? (ly:grob-get-vertical-axis-group-index e)
-                                        vag-index))
-                                 (reverse (ly:grob-array->list bar-array))))
-         ;; we need the first one (if any)
-         (right-bar-line (if (pair? filtered-grobs)
-                             (car filtered-grobs)
-                             '()))
+         ;; reverse it and search for the first suitable entry from
+         ;; the back
+         (right-bar-line (and left-bar-line
+                              (find (lambda (e)
+                                      (eqv? (ly:grob-get-vertical-axis-group-index e)
+                                            vag-index))
+                                    (reverse (ly:grob-array->list bar-array)))))
          ;; the left-bar-line may be a #'<Grob Item >,
          ;; so we add "" as a fallback return value
-         (left-bar-glyph-name (if (null? left-bar-line)
-                                  (string annotation-char)
-                                  (ly:grob-property left-bar-line 'glyph-name "")))
-         (right-bar-glyph-name (if (null? right-bar-line)
-                                   (string annotation-char)
-                                   (ly:grob-property right-bar-line 'glyph-name "")))
-         (left-bar-broken (or (null? left-bar-line)
-                              (not (zero? (ly:item-break-dir left-bar-line)))))
-         (right-bar-broken (or (null? right-bar-line)
-                               (not (zero? (ly:item-break-dir right-bar-line)))))
+         (left-bar-glyph-name (if left-bar-line
+                                  (ly:grob-property left-bar-line 'glyph-name "")
+                                  (string annotation-char)))
+         (right-bar-glyph-name (if right-bar-line
+                                   (ly:grob-property right-bar-line 'glyph-name "")
+                                   (string annotation-char)))
+         ;; This is the original logic.  It flags left-bar-broken if
+         ;; there is no left-bar-line.  That seems strange.
+         (left-bar-broken (not (and left-bar-line
+                                    (zero? (ly:item-break-dir left-bar-line)))))
+         (right-bar-broken (not (and right-bar-line
+                                     (zero? (ly:item-break-dir
+                                             right-bar-line)))))
+         ;; Revert to current grob for getting layout info if no
+         ;; left-bar-line available
          (left-span-stencil-extent (ly:stencil-extent
                                     (span-bar::compound-bar-line
-                                     left-bar-line
+                                     (or left-bar-line grob)
                                      left-bar-glyph-name
                                      dummy-extent)
                                     X))
          (right-span-stencil-extent (ly:stencil-extent
                                      (span-bar::compound-bar-line
-                                      right-bar-line
+                                      (or right-bar-line grob)
                                       right-bar-glyph-name
                                       dummy-extent)
                                      X))
@@ -968,7 +981,7 @@ of the volta brackets relative to the bar lines."
               (- (max 0 (interval-end left-span-stencil-extent))
                  (max 0 (interval-end (ly:stencil-extent
                                        (bar-line::compound-bar-line
-                                        left-bar-line
+                                        (or left-bar-line grob)
                                         left-bar-glyph-name
                                         dummy-extent)
                                        X)))
@@ -1048,7 +1061,7 @@ of the volta brackets relative to the bar lines."
 (define-bar-line ":|." ":|." #f " |.")
 (define-bar-line ".|:" "|" ".|:" ".|")
 (define-bar-line "[|:" "|" "[|:" " |")
-(define-bar-line ":|]" ":|]" #f " |")
+(define-bar-line ":|]" ":|]" #f " | ")
 (define-bar-line ":|][|:" ":|]" "[|:" " |  |")
 (define-bar-line ".|:-||" "||" ".|:" ".|")