From a267db66489cbde49377b31e09c9e0cb33fd5938 Mon Sep 17 00:00:00 2001 From: Marc Hohl Date: Wed, 8 Aug 2012 07:30:59 +0200 Subject: [PATCH] line count issues in scheme --- scm/bar-line.scm | 124 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 33 deletions(-) diff --git a/scm/bar-line.scm b/scm/bar-line.scm index e000178..23a1520 100644 --- a/scm/bar-line.scm +++ b/scm/bar-line.scm @@ -164,28 +164,75 @@ (define (make-colon-bar-line grob) (let* ((staff-space (ly:staff-symbol-staff-space grob)) + (line-thickness (ly:staff-symbol-line-thickness grob)) (dot (ly:font-get-glyph (ly:grob-default-font grob) "dots.dot")) - (staff-symbol (get-staff-symbol grob)) - (lines (staff-symbol-line-count staff-symbol)) + (dot-y-length (interval-length (ly:stencil-extent dot Y))) (stencil empty-stencil) - (dist (* (if (or (odd? lines) - (zero? lines)) - 1 - (if (< staff-space 2) - 2 - 0.5)) - staff-space))) - - (if (zero? staff-space) - (set! staff-space 1.0)) - - (let* ((stencil (ly:stencil-add stencil dot)) - (stencil (ly:stencil-translate-axis - stencil dist Y)) - (stencil (ly:stencil-add stencil dot)) - (stencil (ly:stencil-translate-axis - stencil (/ dist -2) Y))) - stencil))) + ;; the two dots of the repeat sign should be centred at the middle of + ;; the staff and neither should collide with staff lines + ;; + ;; the default distance between centre of dots is composed of + ;; - a staffline (with width line-thickness) + ;; - some space below and above dot + ;; - two half-dots + ;; and we need to measure it as line positions, + ;; i.e. in half staff spaces. + ;; + ;; space between dot and staffline should be comparable to staffline + ;; width so that a relatively common idiom (0.5 staff-size + ;; combined with set-layout-staff-size 10) works ok - + ;; that makes the choice of 1 staffline too big; 3/4 is enough + (center 0.0) + (dist (* 2.0 (+ dot-y-length + (* 2.5 line-thickness))))) + + (if (> staff-space 0) + (begin + (set! dist (/ dist staff-space)) + (let ((staff-symbol (get-staff-symbol grob))) + + (if (ly:grob? staff-symbol) + (let ((line-pos (staff-symbol-line-positions staff-symbol))) + + (if (pair? line-pos) + (begin + (set! center + (interval-center (staff-symbol-line-span staff-symbol))) + ;; fold the staff into two at center and find the + ;; first gap big enough to hold a dot and some space + ;; below and above + (let* ((half-staff + (sort (append (map (lambda (lp) + (abs (- lp center))) + line-pos) + '(0.0)) <)) + (gap-to-find dist) + (found #f)) + + ;; initialize dist for the case when both dots should + ;; be outside the staff + (set! dist (+ (* 2 (car (reverse half-staff))) + gap-to-find)) + + (reduce (lambda (x y) (if (and (> (- x y) gap-to-find) + (not found)) + (begin + (set! found #t) + (set! dist (+ x y)))) + x) + "" + half-staff)))))))) + (set! staff-space 1.0)) + + (let* ((stencil empty-stencil) + (stencil (ly:stencil-add stencil dot)) + (stencil (ly:stencil-translate-axis + stencil (* dist (/ staff-space 2)) Y)) + (stencil (ly:stencil-add stencil dot)) + (stencil (ly:stencil-translate-axis + stencil (* (- center (/ dist 2)) + (/ staff-space 2)) Y))) + stencil))) (define (make-dotted-bar-line grob extent) (let* ((position (round (* (interval-end extent) 2))) @@ -343,21 +390,32 @@ (if (ly:grob? staff-symbol) (let* ((bar-line-color (ly:grob-property grob 'color)) (staff-color (ly:grob-property staff-symbol 'color)) - (radius (ly:staff-symbol-staff-radius grob)) - (staff-line-thickness (ly:staff-symbol-line-thickness grob))) - - ;; Due to rounding problems, bar lines extending to the outermost edges - ;; of the staff lines appear wrongly in on-screen display - ;; (and, to a lesser extent, in print) - they stick out a pixel. - ;; The solution is to extend bar lines only to the middle - ;; of the staff line - unless they have different colors, - ;;when it would be undesirable. + (staff-line-thickness (ly:staff-symbol-line-thickness grob)) + (staff-space (ly:staff-symbol-staff-space grob))) + (set! staff-extent (ly:staff-symbol::height staff-symbol)) - (if (and (eq? bar-line-color staff-color) - radius) + + (if (zero? staff-space) + (set! staff-space 1.0)) + + (if (< (interval-length staff-extent) staff-space) + ;; staff is too small (perhaps consists of a single line); + ;; extend the bar line to make it visible (set! staff-extent - (interval-scale staff-extent - (- 1 (* 1/2 (/ staff-line-thickness radius)))))))) + (interval-widen staff-extent staff-space)) + ;; Due to rounding problems, bar lines extending to the outermost edges + ;; of the staff lines appear wrongly in on-screen display + ;; (and, to a lesser extent, in print) - they stick out a pixel. + ;; The solution is to extend bar lines only to the middle + ;; of the staff line - unless they have different colors, + ;; when it would be undesirable. + ;; + ;; This reduction should not influence whether bar is to be + ;; expanded later, so length is not updated on purpose. + (if (eq? bar-line-color staff-color) + (set! staff-extent + (interval-widen staff-extent + (* -1/2 staff-line-thickness))))))) staff-extent)) (define (bar-line::bar-y-extent grob refpoint) -- 1.7.9.5