Hi,

On Tue, Aug 18, 2015 at 3:43 PM, Heikki Junes <heikki.ju...@gmail.com>
wrote:

> Thanks David!
>
> Yes, it provides the exactly the desired result!
>

Glad I could help!  See the attached for a completed adaptation.

I wonder if this function would better be defined in Scheme than C++.  If
someone wanted to do something like you're doing, it wouldn't be a trivial
matter to first redo the function in Scheme to make the necessary changes.


>
> With this kind of approach, where the note height in the staff is being
> used instead of
> the pitch of the note, the Staff.keySignature.stencil needs to be
> redefined on each clef change:
>
>     \override Staff.KeySignature.stencil =
>     #(key-signature::special-print *treble-key-signature-colors*)
>     \override Staff.KeyCancellation.stencil =
>     #(key-signature::special-print *treble-key-signature-colors*)
>     \clef *treble*
>
>     \override Staff.KeySignature.stencil =
>     #(key-signature::special-print *bass-key-signature-colors*)
>     \override Staff.KeyCancellation.stencil =
>     #(key-signature::special-print *bass-key-signature-colors*)
>     \clef *bass*
>
> Would there be any idea in developing the idea even a bit further, and to
> connect the accidentals in the signature to
> their pitch in stead of their vertical position?
>
> So instead of
>
>   \override Staff.KeySignature.stencil =
>   #(key-signature::special-print `((4 . ,green) (-3 . ,red) (1 . ,blue)))
>
>   \override Staff.KeyCancellation.stencil =
>   #(key-signature::special-print `((-3 . ,magenta) (1 . ,cyan)))
>
> One could have something more explicit which would work with all clefs,
> like
>
> #(define key-signature-colors `(
>    (ly:make-pitch 2 3 SHARP) . ,green)
>    (ly:make-pitch 1 3 SHARP) . ,green)
>    (ly:make-pitch 0 3 SHARP) . ,green)
>    (ly:make-pitch -1 3 SHARP) . ,green)
>    (ly:make-pitch 2 3 FLAT) . ,red)
>    (ly:make-pitch 1 3 FLAT) . ,red)
>    (ly:make-pitch 0 3 FLAT) . ,red)
>    (ly:make-pitch -1 3 FLAT) . ,red)
>    (ly:make-pitch 2 0 SHARP) . ,blue)
>    (ly:make-pitch 1 0 SHARP) . ,blue)
>    (ly:make-pitch 0 0 SHARP) . ,blue)
>    (ly:make-pitch -1 0 SHARP) . ,blue)
>    (ly:make-pitch 2 0 FLAT) . ,blue)
>    (ly:make-pitch 1 0 FLAT) . ,blue)
>    (ly:make-pitch 0 0 FLAT) . ,blue)
>    (ly:make-pitch -1 0 FLAT) . ,blue)
>    (ly:make-pitch 2 3 NATURAL) . ,magenta)
>    (ly:make-pitch 1 3 NATURAL) . ,magenta)
>    (ly:make-pitch 0 3 NATURAL) . ,magenta)
>    (ly:make-pitch -1 3 NATURAL) . ,magenta)
>    (ly:make-pitch 2 0 NATURAL) . ,cyan)
>    (ly:make-pitch 1 0 NATURAL) . ,cyan)
>    (ly:make-pitch 0 0 NATURAL) . ,cyan)
>    (ly:make-pitch -1 0 NATURAL) . ,cyan)
>   ))
>
>   \override Staff.KeySignature.stencil =
>   #(key-signature::special-print key-signature-colors)
>
>   \override Staff.KeyCancellation.stencil =
>   #(key-signature::special-print key-signature-colors )
>
> ?
>
>
Yes, this should be possible.

In the attached key-sig-color-by-pitch.ly, I've done something like this.
You'll notice that I modified your key-signature-colors list.  It might be
nice to be able to specify the octave--for example, color an F-sharp in a
certain octave blue, ired in another--but I couldn't make that work.

A strange thing: the F-sharp in the last key-signature should be colored
red.  It isn't.  Yet in the other file--key-sig-color-by-position.ly--it
works.  Don't know why this is.  Of course, this is a bit of a corner case
:)

Something else I can't explain: the spacing appears to be slightly
different between the default and modified stencils in both files. This
only affects the positioning of naturals: Padding should only be added in
case of an overlap.  The rewrite finds overlaps in m. 2 where the original
function doesn't apparently.  Any ideas what causes this?

Best,
David
\version "2.19.23"

#(define key-signature-colors `(
   ((3 . ,SHARP) . ,green) ; F
   ((3 . ,FLAT) . ,red)
   ((0 . ,SHARP) . ,blue) ; C
   ((0 . ,FLAT) . ,blue)
   ((3 . ,NATURAL) . ,magenta) ; F
   ((0 . ,NATURAL) . ,cyan) ; C
   ((6 . ,FLAT) . ,darkred)
  ))


#(define key-signature::special-print
   (lambda (grob)
     (let* ((inter (/ (ly:staff-symbol-staff-space grob) 2.0))
            (mol empty-stencil)
            (c0s (ly:grob-property grob 'c0-position))
            (is-cancellation? (grob::has-interface grob 'key-cancellation-interface))
            (pos empty-interval)
            (overlapping-pos empty-interval)
            (padding-pairs (ly:grob-property grob 'padding-pairs))
            (fm (ly:grob-default-font grob))
            (alist (ly:grob-property grob 'glyph-name-alist))) (display (ly:grob-property grob 'alteration-alist)) (newline)
       (let loop ((s (ly:grob-property grob 'alteration-alist))
                  (stil mol)
                  (last-glyph-name #f))
         (if (pair? s)
             (let* ((alt (if is-cancellation? 0 (cdar s)))
                    (glyph-name (ly:assoc-get alt alist)))
               (if (not (string? glyph-name))
                   (begin
                    (ly:warning "No glyph found for alteration: ~a" alt)
                    (loop (cdr s) stil last-glyph-name))
                   (let ((acc (ly:font-get-glyph fm glyph-name)))
                     (if (equal? acc empty-stencil)
                         (begin 
                          (ly:warning "alteration not found")
                          (loop (cdr s) stil last-glyph-name))
                         (let ((column empty-stencil)
                               (pos empty-interval))
                           (let inner ((pos-list
                                        (key-signature-interface::alteration-positions
                                         (car s) c0s grob)))
                             (if (pair? pos-list)
                                 (let* ((p (car pos-list))
                                        (pitch (car s))
                                        (color (assoc-get pitch key-signature-colors))
                                        (acc
                                         (if (color? color)
                                             (stencil-with-color acc color)
                                             acc)))
                                   (set! pos (add-point pos p))
                                   (set! column
                                         (ly:stencil-add column
                                           (ly:stencil-translate-axis acc (* p inter) Y)))
                                   (inner (cdr pos-list))))
                             (let* ((padding (ly:grob-property grob 'padding 0.0))
                                    (handle (assoc (cons glyph-name last-glyph-name) padding-pairs))
                                    (padding
                                     (cond
                                      ((pair? handle) (cdr handle))
                                      ((and
                                        (string=? glyph-name "accidentals.natural")
                                        (not (interval-empty?
                                              (interval-intersection overlapping-pos pos))))
                                       (+ padding 0.3))
                                      (else padding))))
                         
                               (set! pos (interval-widen pos 4))
                               (set! overlapping-pos (coord-translate pos 2))
                               (loop (cdr s)
                                 (ly:stencil-combine-at-edge
                                  stil
                                  X
                                  LEFT
                                  column
                                  padding)
                                 glyph-name))))))))
             (ly:stencil-aligned-to stil X LEFT))))))


music =
{
  \key ces \major
  ces'1
  \key a \major
  a'1
  \key g \major
  g'1
  
  \override Staff.KeySignature.flat-positions = #'((-5 . 5))
  \override Staff.KeyCancellation.flat-positions = #'((-5 . 5))
  \clef bass \key es \major es g bes d
  \clef treble \bar "||" \key es \major es g bes d

  \override Staff.KeySignature.sharp-positions = #'(2)
  \bar "||" \key b \major b fis b2
  \override Staff.KeySignature.padding-pairs = #'((("accidentals.flat" . "accidentals.sharp") . 2)) 
  \set Staff.keyAlterations = #`(((0 . 6) . ,FLAT)
                                 ((0 . 5) . ,FLAT)
                                 ((0 . 3) . ,SHARP))
  c4 d e fis
  aes4 bes c'1
}

%% DEFAULT:

{
  \music
}

%% WITH OVERRIDES:

{
  \override Staff.KeySignature.stencil =
  #key-signature::special-print

  \override Staff.KeyCancellation.stencil =
  #key-signature::special-print

  \music
}

{
  \override Staff.KeySignature.stencil =
  #key-signature::special-print

  \override Staff.KeyCancellation.stencil =
  #key-signature::special-print

  \clef bass
  \music
}
\version "2.19.23"

#(define (key-signature::special-print alt-color-list)
   (lambda (grob)
     (let* ((inter (/ (ly:staff-symbol-staff-space grob) 2.0))
            (mol empty-stencil)
            (c0s (ly:grob-property grob 'c0-position))
            (is-cancellation? (grob::has-interface grob 'key-cancellation-interface))
            (pos empty-interval)
            (overlapping-pos empty-interval)
            (padding-pairs (ly:grob-property grob 'padding-pairs))
            (fm (ly:grob-default-font grob))
            (alist (ly:grob-property grob 'glyph-name-alist)))
       (let loop ((s (ly:grob-property grob 'alteration-alist))
                  (stil mol)
                  (last-glyph-name #f))
         (if (pair? s)
             (let* ((alt (if is-cancellation? 0 (cdar s)))
                    (glyph-name (ly:assoc-get alt alist)))
               (if (not (string? glyph-name))
                   (begin
                    (ly:warning "No glyph found for alteration: ~a" alt)
                    (loop (cdr s) stil last-glyph-name))
                   (let ((acc (ly:font-get-glyph fm glyph-name)))
                     (if (equal? acc empty-stencil)
                         (begin 
                          (ly:warning "alteration not found")
                          (loop (cdr s) stil last-glyph-name))
                         (let ((column empty-stencil)
                               (pos empty-interval))
                           (let inner ((pos-list
                                        (key-signature-interface::alteration-positions
                                         (car s) c0s grob)))
                             (if (pair? pos-list)
                                 (let* ((p (car pos-list))
                                        (color (assoc-get p alt-color-list))
                                        (acc
                                         (if (color? color)
                                             (stencil-with-color acc color)
                                             acc)))
                                   (set! pos (add-point pos p))
                                   (set! column
                                         (ly:stencil-add column
                                           (ly:stencil-translate-axis acc (* p inter) Y)))
                                   (inner (cdr pos-list))))
                             (let* ((padding (ly:grob-property grob 'padding 0.0))
                                    (handle (assoc (cons glyph-name last-glyph-name) padding-pairs))
                                    (padding
                                     (cond
                                      ((pair? handle) (cdr handle))
                                      ((and
                                        (string=? glyph-name "accidentals.natural")
                                        (not (interval-empty?
                                              (interval-intersection overlapping-pos pos))))
                                       (+ padding 0.3))
                                      (else padding))))
                         
                               (set! pos (interval-widen pos 4))
                               (set! overlapping-pos (coord-translate pos 2))
                               (loop (cdr s)
                                 (ly:stencil-combine-at-edge
                                  stil
                                  X
                                  LEFT
                                  column
                                  padding)
                                 glyph-name))))))))
             (ly:stencil-aligned-to stil X LEFT))))))

music =
{
  \key ces \major
  ces'1
  \key a \major
  a'1
  \key g \major
  g'1
  
  \override Staff.KeySignature.flat-positions = #'((-5 . 5))
  \override Staff.KeyCancellation.flat-positions = #'((-5 . 5))
  \clef bass \key es \major es g bes d
  \clef treble \bar "||" \key es \major es g bes d

  \override Staff.KeySignature.sharp-positions = #'(2)
  \bar "||" \key b \major b fis b2
  \override Staff.KeySignature.padding-pairs = #'((("accidentals.flat" . "accidentals.sharp") . 2)) 
  \set Staff.keyAlterations = #`(((0 . 6) . ,FLAT)
                                 ((0 . 5) . ,FLAT)
                                 ((0 . 3) . ,SHARP))
  c4 d e fis
  aes4 bes c'1
}

%% DEFAULT:

{
  \music
}

%% WITH OVERRIDES:

{
  \override Staff.KeySignature.stencil =
  #(key-signature::special-print `((4 . ,green) (-3 . ,red) (1 . ,blue)))

  \override Staff.KeyCancellation.stencil =
  #(key-signature::special-print `((-3 . ,magenta) (1 . ,cyan)))

  \music
}


_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to