Am 21.03.2012 11:03, schrieb David Kastrup:
Marc Hohl<[email protected]> writes:
Am 21.03.2012 03:20, schrieb David Kastrup:
Marc Hohl<[email protected]> writes:
Is this a feasible approach? What am I currently doing wrong?
#(define bar-line-stencil-alist
'(("|" . thin-stil)
("." . thick-stil)
("" . empty-stil)
))
(thin-stil (bar-line::simple-bar-line grob hair extent rounded))
(thick-stil (bar-line::simple-bar-line grob fatline extent rounded))
(empty-stil (make-filled-box-stencil (cons 0 0) (cons 0 extent)))
(stencil (assoc-get glyph bar-line-stencil-alist empty-stil))
)
stencil
))
That does not work. stencil is set to a symbol, and that symbol is
never converted to a value. When the function is being executed, the
_symbols_ thin-stil, stick-stil and empty-stil have long lost any
connection with the expressions that they were associated with while the
let-statement was being compiled.
You could write (local-eval stencil (the-environment)) to let the
lexical environment of the function compilation linger over long enough
to make this work, but you would earn a reward for the unnecessarily
most ugly and unstable code imaginable.
Instead, try using a case statement. There is no need to calculate all
stencils and throwing most of them away.
That's what I originally did, but my idea was to provide an easy way to
add new stencils/bar lines without fiddling with bar-line::print.
But if this way is a no-go, I'll use case.
thin-stil and thick-stil are internals of the function. The way to make
this work is as an association list of functions (I don't know the
problem well enough to know what parameter list they should be getting,
but they would likely return a stencil, and so it would probably make
sense to have them get the same parameter list that a stencil callback
would) and/or finished stencils. If the variability is likely to be
restricted to the thickness, you can provide something like
(define ((bar-line::simple-bar-line-maker thickness) grob)
[...]
(bar-line::simple-bar-line grob thickness extent rounded))
And then put (bar-line::simple-bar-line-maker 1.5) as the function into
the association list.
Ah, ok, but there are more bar line styles, so this won't solve the problem.
Anyway, I don't get the case statement right - am I too stupid?
Please have a look at the attached file; I don't get a stencil back,
the case statement always uses the else clause.
A (string? glyph) returns #t, so glyph is obviously a string ... ??
Regards,
Marc
\version "2.15.34"
#(define (bar-line::calc-bar-extent grob)
(let ((staff-symbol (ly:grob-object grob 'staff-symbol))
(staff-extent (cons 0 0)))
(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))
(line-thickness (ly:staff-symbol-line-thickness grob)))
(set! staff-extent (ly:staff-symbol::height staff-symbol))
(if (and (eq? bar-line-color staff-color)
radius)
(interval-widen staff-extent
(- 1 (* 1/2 (/ line-thickness radius)))))))
staff-extent))
#(define-public (bar-line::print grob)
(let* ((glyph (ly:grob-property grob 'glyph-name))
(bar-extent (ly:grob-property grob 'bar-extent '(0 . 0)))
(extent (interval-length bar-extent))
(stencil (if (and (not (eq? glyph '()))
(> extent 0))
(bar-line::compound-bar-line grob glyph extent #f))))
stencil))
#(define (bar-line::simple-bar-line grob width extent rounded)
(let ((blot (if rounded
(ly:output-def-lookup layout 'blot-diameter)
0)))
(ly:round-filled-box (cons 0 width)
(cons (* -0.5 extent) (* 0.5 extent))
blot)))
#(define (bar-line::tick-bar-line grob height rounded)
(let ((half-staff (* 1/2 (ly:staff-symbol-staff-space grob)))
(stafflinethick (ly:staff-symbol-line-thickness grob))
(blot (if rounded
(ly:output-def-lookup layout 'blot-diameter)
0)))
(ly:round-filled-box (cons 0 stafflinethick)
(cons (- height half-staff) (+ height half-staff))
blot)))
#(define (bar-line::compound-bar-line grob glyph extent rounded)
(let* ((staff-symbol (ly:grob-object grob 'staff-symbol))
(line-count (if (ly:grob? staff-symbol)
(ly:grob-property staff-symbol 'line-count)
0))
(staff-space (ly:staff-symbol-staff-space grob))
(stafflinethick (ly:staff-symbol-line-thickness grob))
(dist (if (or (odd? line-count)
(zero? line-count))
1
(* staff-space (if (< staff-space 2) 2 1/2))))
(font (ly:grob-default-font grob))
(dot (ly:font-get-glyph font "dots.dot"))
(kern (* (ly:grob-property grob 'kern 1) stafflinethick))
(thinkern (* (ly:grob-property grob 'thinkern 1) stafflinethick))
(hair (* (ly:grob-property grob 'hair-thickness 1) stafflinethick))
(fatline (* (ly:grob-property grob 'thick-thickness 1) stafflinethick))
(thin-stil (bar-line::simple-bar-line grob hair extent rounded))
(thick-stil (bar-line::simple-bar-line grob fatline extent rounded))
(stencil (case glyph
(("|") thin-stil)
((".") thick-stil)
(("'") (bar-line::tick-bar-line grob extent rounded))
(else (make-filled-box-stencil (cons 0 0) (cons 0 extent))))))
stencil
))
music = \relative f {
c'4 d e f | f f f f \bar "" | g g g g \bar "." g a b c \bar "||" c c c c \bar "'" c b a g \bar "|:" f e d c \bar "|."
}
\score {
\new Staff {
\new Voice { \music }
}
}
\score {
\new Staff {
\new Voice {
\override Staff.BarLine #'bar-extent = #bar-line::calc-bar-extent
\override Staff.BarLine #'stencil = #bar-line::print
\music
}
}
}_______________________________________________
lilypond-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-devel