[Top][All Lists]

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

Re: Distance of a grob from its reference point

From: Paolo Prete
Subject: Re: Distance of a grob from its reference point
Date: Tue, 14 Jan 2020 21:37:36 +0100

Hi Aaron,

thanks for the detailed reply.

Why do I need to move a grob?
For the simple fact that any score, in order to have a * professional * appearance, needs HUNDREDS of these adjustments.
Even the simplest ones.
I am a convinced open source developer and already 10 years ago I used Lilypond to create my scores, because I wanted to avoid Finale, Sibelius and other proprietary software (which I used before). In the end, I was forced to use the Lilypond + Inkscape combination, and here is an example of my scores:

This type of music requires so many adjustments that it is impossible to achieve with Lilypond, unless you spend a very very very long time with the trial and error process. But I can assure you that the same adjustments are also necessary for nineteenth-century scores, if you want to give them a professional look. I can show you many and many examples.

This year I started writing music again and I didn't want to abandon the idea of using Lilypond. Because I needed something less time consuming than Finale, because I don't use proprietary software and because I use Linux. So I decided to go back to Lilypond by writing an editor that allows you to make all these adjustments and at the same time guarantees you the power of Lilypond. Without having to use the combination with Inkscape, because it also has many disadvantages. Fortunately, thanks to the script I created for the curves, I understood that my idea could also be extended to the other grobs. So I dedicated myself to the LilyJSSVG editor.

Here is what came out:

Try making these micro- (or big) adjustments with just the text editor. You will go crazy.

Note one * very important * thing. This Editor adds nothing and nothing to Lilypond's logic. And it doesn't add any new feature. None at all. It simply allows you to modify the properties of the grobs * exactly as you do with Lilypond *. Except that the positions of these properties are calculated with the mouse instead of the tedious trial and error method.

Then, in your .ly file you will have

\ jsBeam "id" "positions" # '(1. 3)

instead of

\ override Beam.positions = # '(1 .3)

TBH I don't understand what's strange or what's "misuse" in all of this (I'm not referring to you: it's a general discussion). And in any case, I continue on my way, even if I will not receive general support for the project: in fact I am already using this project for my compositions and I am getting a result absolutely identical to that of the above pdf extract of my score.

A GUI for cross-staff editing has already been implemented in the editor. And in the next few days I will show you how it is possible to edit very complex piano scores with this feature.

Now, going back to my initial question, since you have given me very kind help, I am trying to pull out from Lilypond (and put in my editor) also properties like X-offset, padding etc. I can accomplish all this in a short time. I just need to know what is the offset of the objects from their reference point, depending on the property.

It is also very important to me if someone helps me clean up the Scheme code, because I don't have time to learn the details of the language. The code works, but needs to be cleaned up of very noisy (and long) statements which can be replaced by better syntax.

And of course it is also useful if someone helps me prepare the documentation for the editor. But first of all, I want to implement the properties discussed above.

Thanks again.

On Tue, Jan 14, 2020 at 9:35 AM Aaron Hill <address@hidden> wrote:
On 2020-01-13 7:05 pm, Paolo Prete wrote:
> 1) its *calculated* distance from its reference point? (from what I
> see,
> the reference Y of an OttavaBracket is the middle line of the
> associated
> staff...)
> I tried ly:grob-staff-position (see the snippet below), but it doesn't
> seem
> to give this info (and it's not documented)

Well, "staff-position" is likely not the metric you want, as its units
appear to be in half staff-spaces rather than staff-spaces like other
metrics, making its result twice as much as you might expect.  It might
even be impacted by things like \magnifyStaff, making its value even
less useful.

But put that aside.  If we borrow some of the underlying logic, we get
the following:

\version "2.19"

drawRelativePosition = #(define-music-function
   (grob-path) (symbol-list?)
   (define (proc grob)
     (let* ((ss (ly:grob-object grob 'staff-symbol))
            (refp (ly:grob-common-refpoint grob ss Y))
            (y (- (ly:grob-relative-coordinate grob refp Y)
                  (ly:grob-relative-coordinate ss refp Y)))
            (orig (ly:grob-property grob 'stencil))
            (sten (grob-interpret-markup grob #{
              \markup \with-dimensions-from \stencil #orig
                \overlay { \stencil #orig \with-color #red
                  \translate #(cons 0 (- y)) \path #0.1 #`(
                    (moveto -1 ,y) (lineto 1 ,y)
                    (moveto 0 ,y) (lineto 0 0)
                    (moveto -1 0) (lineto 1 0)
                    (moveto -0.5 1) (lineto 0 0) (lineto 0.5 1))
                } #})))
       (ly:grob-set-property! grob 'stencil sten)))
   #{ \override $grob-path .after-line-breaking = #proc #})

   \drawRelativePosition Staff.OttavaBracket
   \ottava #1 c''''8 c'''' \ottava 0 c'''4
   \ottava #1 a'''8 a''' \ottava 0 a''4
   \ottava #1 a'''8( a''' \ottava 0 a''4)

The above would seem to "fail" on the third bracket.  This is because
the slur pushes the bracket out of the way at a time *after*
after-line-breaking.  This suggests it is unlikely for user code to
reliably discern the truly final position of a grob.

While I would never claim to fully grok all of the wily machinations of
LilyPond, this particular detail does make some sense to me.

Consider that the layout engine has to be able to draw a line in the
sand and say "That's it!  All grobs are in the place where they'll be. 
Let's just write this thing to a file and be done with it."  As such, it
becomes uninteresting to allow user logic to run after that point since
nothing is permitted to change.

In fact, the layout engine seems to draw a few such lines during its
work, with line breaking being another example.  The
before-line-breaking procedure allows user code to manipulate items that
could impact how lines eventually break.  But after-line-breaking
happens once lines are locked in and only content within the line could
still be adjusted.


Going back to your prior ask of "how do I move a grob?", I think we need
to shift perspective on the issue.  It is less important to dwell on
*how* to move something; rather, we should inquire of you *why* you want
to move something.  What purpose does it serve, for instance, to move an
OttavaBracket upward precisely two staff spaces?  (I apologize if that
is coming across sarcastically, but I am afraid I lack better

The goal of such questioning is to best improve how LilyPond's layout
engine works without user intervention.  There likely exists sufficient
logic within LilyPond to accommodate your needs; but it is certainly
possible such logic still needs to be invented.  However, I think
focusing on details like final grob positioning might be putting the
cart before the horse.

Consider the recent work done on curve editing.  (By the way, that is a
*very* cool contribution; and if I can find time, I may be able to help
with Scheme and _javascript_ should that still be required.)  Having such
a nice curve editor should in no way be a replacement for improving
LilyPond.  Ideally, the software will engrave beautiful curves without
the user needing to lift a finger.  At the very least, the user might
have to provide a few hints to get the job done to their satisfaction. 
Only as a last resort should one have to position curve points manually.


Sorry for my long ramblings.  At this rate, I should become a novelist
or something.  (:

-- Aaron Hill

reply via email to

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