lilypond-user
[Top][All Lists]
Advanced

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

Re: How to prevent ly:stencil-rotate to modify dimensions


From: Thomas Morley
Subject: Re: How to prevent ly:stencil-rotate to modify dimensions
Date: Sun, 11 Mar 2018 16:57:36 +0100

2018-03-11 15:27 GMT+01:00 Torsten Hämmerle <address@hidden>:
> Hi Harm,
>
> David is right - it's the bounding box being rotated. As bounding boxes can
> only have heights and widths in vertical and horizontal direction (there
> isn't even such a thing as an italic slant in LilyPond), the resulting new
> bounding box's height and width increases.
>
> I usually solve this problem by calculating the desired X-extent and
> Y-extent and set the stencil dimensions.
> In scheme, I use (ly:stencil-outline stencil point-stencil) to rotate
> stencil using the dimensions of point-stencil so that the bounding box isn't
> distorted .
>
> *Example:* I've created a fake slanted markup command by combining rotate,
> scale, rotate back, scale (because there is no shearing) that keeps the
> original stencil extent.
> Without stencil extent manipulations (using point-stencil dimensions etc.)
> the resulting bounding box would be ridiculously high and totally unusable.
>
> %%%%%%%%%%%
>
> \version "2.19.81"
>
> #(define-markup-command
>   (slanted layout props arg)
>   (markup?)
>   #:category font
>   #:properties ((slant-angle 12))
>   "Fake a slanted font"
>   (let* ((alpha-rad (* 0.5 (acos (tan (* (/ PI -180) slant-angle)))))
>           (alpha-deg (* (/ 180 PI) alpha-rad))
>           (stencil (if (markup? arg) (interpret-markup layout props arg)
> empty-stencil))
>           )
>     (ly:stencil-outline
>       (ly:stencil-scale
>        (ly:stencil-rotate
>         (ly:stencil-scale
>          (ly:stencil-rotate (ly:stencil-outline stencil point-stencil) 45 0
> 0)
>          1 (* (tan alpha-rad)))
>         (* (- alpha-deg)) 0 0)
>        (* (sqrt 2) (cos alpha-rad)) (/ 0.5 (sqrt 0.5) (sin alpha-rad)))
>      stencil)))
>
>
> \markup \override #'(box-padding . 0) \box \slanted "Poor man’s slanted
> Text"
>
> poor-mans-slanted.png
> <http://lilypond.1069038.n5.nabble.com/file/t3887/poor-mans-slanted.png>
>
> This is a simple case just keeping the original extents, but in the end, the
> desired new bounding box (i.e. stencil extent) has to be calculated
> explicitly depending on the desired output, I couldn't find an automatic
> solution either.
> Simple trigonometric functions are all you need - it could be worse... ;)
>
> All the best,
> Torsten

Hi Torsten,

yep, David's explanation sounds very reasonable.

To give a bit background:
Currently we have several line-styles to print solid, dashed, and
dotted lines, as well as zigzag-, trill- and squiggle-lines.
They are available via setting the style-property for grobs supporting
a line-style or via different markup-commands.
Additionally not long ago David Nalesnik wrote ly:line-interface.

Though, there are two disadvantages:
Some line-styles may visible end too short because there is no room to
add another item like a dot-, dash-, trillelement, without any
possibility to scale the line-elements accordingly. This holds
especially for the lines predefined in C++.
There is no other possibility for a user to create a new line-style
than doing it all from scratch.

So my thought was to write a scheme-line-interface with the
possibility to scale line-elements (if desired) and to provide a
simple method to create a new line-style.
This could be done by a user-provided init stencil (and probably
padding if wished) and let do the procedure all the rest.

Attached you'll find some exmple-images for a trill- and a clef-style-line.
With the clef-style-line the boundindbox-problem is very prominent.

Having a look at your code, I don't like all the trigonometrics. Guile
and LilyPond doesn't work nicely with them in special cases, so I
always try to avoid them in scheme. I was beaten by this before.
We nowadays have ly:angle, ly:directed and ly:length which serve me well.

Using your code with the following example:

\markup
  \override #'(box-padding . 0)
  \box
  \override #'(slant-angle . 40)
  \slanted
  \musicglyph #"clefs.G"

results in a not matching boundingbox as well.

With '(slant-angle . 70) it produces an error:

item-lines.ly:258:10: In procedure ly:stencil-scale in expression
(ly:stencil-scale (ly:stencil-rotate # 45 ...) 1 ...):
item-lines.ly:258:10: Wrong type (expecting real number):
7.00808368402012e-17-1.46441350735015i

Though, thanks a lot for your code!
It made me see that I need to find a method to reset the boundingboxes.

Something at the lines of
(ly:make-stencil
  whatever-stencil
  x-extent
  y-extent)

Where the challenge will be to get accurate values for x/y-extent,
ofcourse this was clear right from the start lol

Thanks,
  Harm

Attachment: item-lines-trill.png
Description: PNG image

Attachment: item-lines-clef.png
Description: PNG image

Attachment: torsten.png
Description: PNG image


reply via email to

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