lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bug? getting the stencil of the stem removes the beam


From: Lucas Werkmeister
Subject: Re: Bug? getting the stencil of the stem removes the beam
Date: Fri, 16 Mar 2018 00:50:40 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0

Hi,

thanks a lot for looking into this and finding a better implementation!

On 15.03.2018 23:33, Thomas Morley wrote:
Hi Lucas,

all below under the condition 'if I understand correctly' ;)

2018-03-15 18:38 GMT+01:00 Lucas Werkmeister <address@hidden>:
Hi everyone,

I was trying to use the \displaceHeads function from snippet 861 [1] [2] on
an eight-note chord, but found that it completely removes the beam for some
reason.
Not exactly true.
The beam _is_ there: this very small line at the very right of the
resulting pdf (you've cut it off in your image)
Well spotted, and sorry for the incorrect crop :)

I reduced it down to the following code:

\version "2.18.2"

{
  \tweak before-line-breaking #(lambda (grob)
                                 (ly:grob-property (ly:grob-object grob
'stem) 'stencil))
  c'8[ c']
}
That I call a tiny example. I'd love to see more people doing so ;)

You can find a screenshot of the result at [3]. The function here doesn’t
mutate anything,
Not exactly. The stem-stencil _is_ evaluated!

but apparently just accessing the stem is enough to render
the associated beam invisible
Not just assessing but evaluating the stencil before-line-breaking and
the beam is there (see above)
I was thinking in terms of “none of the functions have an exclamation mark”, but I didn’t think of those pesky side effects!

(at a guess, I’d say the beam’s stencil is
being unset somehow – it still influences the layout otherwise). Is that a
bug in LilyPond?
Not really.
The Beam needs to set it's related stem-stencils, if a user does it
'before-line-breaking as the lsr-snippet does, the procedure setting
the beam is disturbed.

So far the lsr-snippet is bad.
Though, in my humble opinion LilyPond should print a meaningful message...

The \displaceHeads problem was previously reported at [4] (and I’ve added
the author to CC for this email), but as far as I can see the thread didn’t
go anywhere. (To answer the question in the reply [5] – changing
before-line-breaking to after-line-breaking fixes the beam, but also removes
the displacement effect, so as far as I can tell you might as well just get
rid of the \displaceHeads completely.) I hope the reduced example above will
help to get this bug (if it is one) fixed :)

Probably below will help.
I avoided any stencil-call (not sure whether calling 'direction will
turn out to be a problem, though)
The functions `setOtherScriptParent' and `adjustStem' from the
lsr-snippet would work, but are not used in the example.


\version "2.19.65"


#(define ((positioning-done move-values) grob)
;; TODO whole and longer notes are not special cased
;; probably exclude them form the procedure by uncommenting the condition
;;
;  (if (< (ly:grob-property grob 'duration-log) 1)
;      #f
      (let* ((nc (ly:grob-parent grob X))
             (grob-ext
               (ly:grob-extent grob nc X))
             (dir (ly:grob-property grob 'direction))
             (thick (ly:grob-property grob 'thickness))
             (stem-ext
               (if (interval-sane? grob-ext)
                   grob-ext
                   '(0 . 0)))
             (stem-thick
               (if (zero? (interval-length stem-ext))
                   thick
                   (* -1 dir (interval-length stem-ext))))
             (note-heads-array
               (ly:grob-object grob 'note-heads))
             (note-heads-list
               (if (ly:grob-array? note-heads-array)
                   (ly:grob-array->list note-heads-array)
                   '())))

        (for-each
          (lambda (note-head v)
            (let* ((nh-ext (ly:grob-extent note-head nc X))
                   (nh-x-length (- (cdr nh-ext) (car nh-ext))))

            (ly:grob-translate-axis!
              note-head
              (* v (+ nh-x-length (* dir (/ stem-thick 2))))
              X)))
          note-heads-list
          move-values))
          ;)
      #t)


chrd =
<
  \tweak color #green
  cis'
  \tweak color #red
  dis'
  \tweak color #blue
  eis'
8
{
  \cadenzaOn
  \override NoteHead.layer = 500
  \accidentalStyle forget

  <>^"DEFAULTS"
  \chrd^[]
  \chrd_[]
  <
    \tweak color #green
    cis'
    \tweak color #red
    dis'
    \tweak color #blue
    eis'
  >1

  \bar "||"

  <>^"TWEAKED"
  \once \override Stem.positioning-done =
    #(positioning-done
      '(1 0 1)
      ;'(0 1 0)
      )
  \chrd^[]

  \once \override Stem.positioning-done =
    #(positioning-done
      ;'(-1 0 -1)
      ;'(0 -1 0)
      '(-1 0 -1)
      )
  \chrd_[]

  \once \override Stem.positioning-done =
    #(positioning-done
      ;'(-1 0 -1)
      ;'(0 -1 0)
      '(0 -0.668 0)
      )
  <
    \tweak color #green
    cis'
    \tweak color #red
    dis'
    \tweak color #blue
    eis'
  >1
}
Wow, thanks a lot! I like that this version positions the heads absolutely, not relative to where LilyPond originally places them – feels more stable that way. I feel like this could be useful for whole-note chords as well, but might be tricky if that constant 0.668 isn’t identical for all cases :/

Here’s a variation of your example that works on LilyPond 2.18.2 as well (where the parser complains about \chrd^[]):

{
  \cadenzaOn
  \override NoteHead.layer = 500
  \accidentalStyle forget

  <>^"DEFAULTS"
  <
    \tweak color #green
    cis'
    \tweak color #red
    dis'
    \tweak color #blue
    eis'
  > 8^[]
  q_[]
  q1

  \bar "||"

  <>^"TWEAKED"
  \once \override Stem.positioning-done =
    #(positioning-done
      '(1 0 1)
      ;'(0 1 0)
      )
  q8^[]

  \once \override Stem.positioning-done =
    #(positioning-done
      ;'(-1 0 -1)
      ;'(0 -1 0)
      '(-1 0 -1)
      )
  q8_[]

  \once \override Stem.positioning-done =
    #(positioning-done
      ;'(-1 0 -1)
      ;'(0 -1 0)
      '(0 -0.668 0)
      )
  q1
}

Perhaps we can submit this as an update for the snippet repository? (I’d be happy to do the paperwork if you’re okay with it.)
Not tested beyond the given examples, though.
FWIW, it seems to work fine in the larger score where I encountered this issue (though the situation there isn’t really more complicated than in these examples).

Cheers,
Lucas

reply via email to

[Prev in Thread] Current Thread [Next in Thread]