lilypond-devel
[Top][All Lists]
Advanced

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

(no subject)


From: Han-Wen Nienhuys
Subject: (no subject)
Date: Wed, 6 Mar 2002 23:36:24 +0100

Subject: Re: wrapping long textual markup 
In-Reply-To: <address@hidden>
References: <address@hidden>
        <address@hidden>
X-Mailer: VM 6.96 under Emacs 20.7.1
FCC: ~/persoonlijk/Mail/sent

address@hidden writes:
> > Of course, a clumsy solution to your problem is to hard-code
> > the line breaks of the music using \break commands and then
> > splitting the sonnet into several text scripts, one for each
> > line. This will of course be more troublesome if you want it
> > typeset both in the score and in the separate parts.
> >
> > In principle, Lilypond has all the knowledge needed to do
> > the requested line breaking, it's just a matter of implementing
> > the mechanism.
> 
> I don't mind hacking at it a bit.  But since lilypond is mixture
> of 4+ languages, it would be helpful if you could point me in
> the right direction...


ok, I'm taking this to lilypond-devel, which is more appropriate.
Hacking it in shouldn't be too tough:

  * Your objective is to make a spanner, similar to TextSpanner (used
    for cresc.... ).

  * The code will be easiest in C++. (Although, if you prefer Scheme,
    I can provide the necessary callbacks.)

  * You let the spanner start somewhere manually, and end it somewhere
    else, in the input. The line breaking process will break it into
    pieces (like slurs that cross line breaks). The tricky part is
    then to decide which words go on which broken part; this is done
    as follows:

  * You have to make an after_line_breaking () callback.

  * From this callback, find all of the pieces by examining
    dynamic_cast<Spanner*> (spanner->origin_l_)->broken_into_l_arr_

  * You can find the length of each piece by examining

    common = spanner->get_bound (RIGHT)
      ->common_refpoint(spanner->get_bound (LEFT));
    spanner->get_bound (RIGHT)->relative_coordinate (common, X_AXIS)
      - spanner->get_bound (LEFT)->relative_coordinate (common, X_AXIS)

  * Then you have to find the dimensions of each word, using
    Font_metric::text_dimension(), and do a standard word wrap
    insert the appropriate words using set_grob_property ("text",
    ly_str02scm (words));

  * A simple brew_molecule callback should take care of getting the
    text and making it into a molecule.

  * For instantiating the stuff, use TextSpanner for now (see the
    refman example). You can install your own functions by doing

    TextSpanner \override #'after-line-rbeaking-callback =
      #Running_text::after_line_breaking()
    TextSpanner \override #'molecule-callback =
      #Running_text::brew_molecule()

On second thought, it would be rather nice if the code were done in
Scheme, so if you're fluent in Scheme, I'd love to add the appropriate
functions to make this possible.


-- 

Han-Wen Nienhuys   |   address@hidden    | http://www.cs.uu.nl/~hanwen/




reply via email to

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