lilypond-user
[Top][All Lists]
Advanced

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

Re: Distance of a grob from its reference point


From: Aaron Hill
Subject: Re: Distance of a grob from its reference point
Date: Thu, 16 Jan 2020 18:33:44 -0800
User-agent: Roundcube Webmail/1.3.8

On 2020-01-16 4:01 pm, Paolo Prete wrote:
This gives a clearer overview, thanks, but I would not use it, even if it
produces the wanted result.

Sorry if I implied otherwise, but I thought I was clear that this code was not intended for practical use. This is only test code to demonstrate the underlying mechanisms are actually working properly. I wanted to address what I consider a flawed premise that things are broken. Rather, what should be clear is that things are complicated. And I am uncomfortable with so casually equating the two.


I did not omit them, given that I did not want to reset any property, as I explained in other posts. In practice, you are only making reset of all the properties that add more space between the grob and the reference point. At the end, considering that you have to add a .46 value, you get even a worse procedure than \override Y-offset, while using the same logic (which is: distance from a reference point, and not *offset the result*). So: I think
it's better to use a ruler from the middle of the staff.
No other way, if you want to preserve the avoid-collision algo.

There is no "offset the result" apart from extra-offset. There are many ways to *influence* the positioning of a grob, but only extra-offset operates on the final computed position. Everything else works within the magic that is LilyPond's layout logic, which seems to be designed around keeping as much in relative terms as opposed to absolute terms.

With that in mind, say you want to move an object upward on the page. That is fine, but it is an absolute adjustment. To convert it to a relative one, you must answer why you need to move the object. Is it because it is too close to something? Is it because it does not line up nicely with something else? Is it because the decomposing remains of a donut you forgot about have become sentient and are whispering dark thoughts?

Once you have clarified why something needs to move, then you can best determine which tool is the right one for the job. The goal is to move the object once, and not have to revisit it after other things change. Encoding the logic behind why something needs to move lets LilyPond do it for you. Padding can help with adjusting how near or far objects are from one another, but sometimes alignment suffers. Alignment of grobs requires working from a common reference point, and one will need to consider what constructs exist within LilyPond that can help with this. The Dynamics context, for instance, does not have to be used only for dynamics. Of course, sometimes relative adjustments are just not suitable and you may end up needing to use the absolute extra-offset. As for the donut, that is beyond my pay grade, and I wish you only the best of luck.

(Future headline: Krispy Kreme responsible for zombie outbreak with Halloween-inspired glazed, "raised-from-the-dead" donuts.)

Of course, the tools and constructs available in LilyPond are certainly not exhaustive. Given the discussion, it seems we could benefit greatly with the introduction of a so-called "outside-staff-offset" which moves grobs away from the staff by an absolute amount--think extra padding but only on the side nearest the staff.

If that sounds interesting, know that you can approximate it with a combination of outside-staff-padding and extra-offset to achieve outside-staff-offset. It just takes a little grade-school math:

%%%%
\version "2.19.83"
notes = \fixed c''' { \mark "mark" \ottava 1 f8( 8) 4 \ottava 0 f,2 }

{
  \omit Staff.Clef \omit Staff.TimeSignature
  \override Score.RehearsalMark.self-alignment-X = #LEFT

  % Default behavior.
  \notes

  % Try moving the bracket up by two staff spaces.
  \override Staff.OttavaBracket.outside-staff-padding = 2.46
  \notes

  % Oops, the mark moved too far.
  % Split the difference between padding and offset.
  \override Staff.OttavaBracket.outside-staff-padding = 1.46
  \override Staff.OttavaBracket.extra-offset = #'(0 . 1)
  \notes
}
%%%%

But what happens when outside-staff-padding is *not* the defining property controlling the vertical position? Consider a bracket whose effective Y-offset is large enough that it is positioned too far away from other outside-staff grobs.

This could be handled as followed:

%%%%
\version "2.19.83"

#(define (addRuler color left right)
  (grob-transformer 'stencil (lambda (grob orig)
    (ly:stencil-add
      (grob-interpret-markup grob #{
        \markup \with-dimensions-from \null
        \with-color #color \path #0.1 #`(
          (moveto ,left 0) (lineto ,right 0)
          (moveto ,left 1) (lineto ,right 1)
          (moveto ,left 2) (lineto ,right 2)
        ) #})
      orig))))

notesI = \fixed c''' { \mark "mark" \ottava 1 d8 8 4 \ottava 0 d,2 }
notesII = \fixed c''' { \mark "mark" \ottava 1 a8( 8) 4 \ottava 0 a,2 }

shiftOttavaBracket = #(define-music-function (amount) (number?)
  (let ((half (/ amount 2)))
    #{
      \offset Y-offset #half Staff.OttavaBracket
\override Staff.OttavaBracket.outside-staff-padding = #(+ 0.46 half)
      \override Staff.OttavaBracket.extra-offset = #`(0 . ,half)
    #}))

unshiftOttavaBracket = {
  \revert Staff.OttavaBracket.Y-offset
  \revert Staff.OttavaBracket.outside-staff-padding
  \revert Staff.OttavaBracket.extra-offset
}

{
  \omit Staff.Clef \omit Staff.TimeSignature
  \override Score.RehearsalMark.self-alignment-X = #LEFT

  % Test with bracket that is positioned by Y-offset.
  \override Staff.OttavaBracket.stencil = #(addRuler red -5 10)
  \notesI
  \shiftOttavaBracket 1
  \notesI
  \shiftOttavaBracket 2
  \notesI
  \unshiftOttavaBracket

  % Test with bracket that is positioned by outside-staff.
  \override Staff.OttavaBracket.stencil = #(addRuler blue -5 10)
  \notesII
  \shiftOttavaBracket 1
  \notesII
  \shiftOttavaBracket 2
  \notesII
}
%%%%

And lo and behold: \offset Y-offset is not setting the world ablaze.  (:

To be clear, again, this code is nothing more than a proof of concept. It would need to be adapted for practical use; but I truly hope folks can see that the tools for positioning really are there. They just might not be as specialized as we would like. I would still vote for a *real* outside-staff-offset, as the semantics are more obvious than trying to use a combination of other properties.

Whew, that was a lot of work for one email.  I could go for a donut.


-- Aaron Hill

Attachment: offset.cropped.png
Description: PNG image


reply via email to

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