-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Am Sonntag, 17. August 2008 schrieb Carl D. Sorensen:
> On 8/17/08 9:18 AM, "Reinhold Kainhofer" <[EMAIL PROTECTED]> wrote:
> > 1) It seems that the diagram has zero extent, so that it overlaps with
> > the staff and other diagrams. How can I make the stencil (created by
> > stencil-add) use the bounding box off all combined stencils?
>
> I think you are not putting extents on your stencils when you create them.

Actually, make-filled-box-stencil does that automatically. The problem was 
that I got the order of the y-coordinates wrong, i.e. (1.56 . 0.36) instead 
of (0.36 . 1.56). Although Lilypond correctly prints the box, for the extents 
this wrong order causes the stencil to have a height of 0...

For the two lines you are correct, though. It seems that there is currently no 
function to create a stencil for a simple line. Rather, one has to construct 
the contents of the stencil and its extent manually, meaning that one has to 
give the coordinates twice.

Attached is a patch for stencil.scm, which adds a make-line-stencil that does 
exactly that: You call it as 
    (make-line-stencil linewidth xstart ystart xend yend) 
and it will create the stencil and correctly set its extent (adding half the 
line width to all coordinates, too).

Okay to apply to master?

> > 2) How can I draw an ellipse around an object in lilypond? I only cound
> > find (circle-stencil stencil linewidth padding)... However, this places
> > the circle always at the horizontal line, even if the box stencil is
> > placed higher/lower. Furthermore its radius is too small to surround the
> > box. And of course, I don't want a circle but rather a vertical ellipse.
> > See the last diagram in the .ly file...
>
> circle-stencil will work if the extent of the stencil is correct. -- but it
> will be a circle.

Yeah, for now I suppose, I can live with the circle...
If I'll ever get bored (as if that could ever happen!), I'll add an ellipse 
stencil.

I tried using a rounded box, but unfortunately the rounded box will be filled, 
thus overprinting the box for the pedal...

> > 3) To make it more customizable, I'd like the user to be able to tweak
> > the linethickness, the spacing between the boxes, the box offsets and the
> > box width/heights. What's the proper way to do this?
>
> You should already have these coded in as variables.  Now you just need to
> get them from the calling string.

I'd rather not have them in the string, but inside a separate variable, just 
like you suggest.

> In fret-diagrams, I started out by adding a bunch of properties, because
> there are lots of things to vary in a fret diagram.  Han-Wen was concerned
> about the pollution of the LilyPond namespace with lots of variables that
> only had application to fret diagrams.  We solved this issue by putting
> all of the properties into a single property fret-diagram-details.
>
> Given the uniqueness of harp pedal diagrams, I think it would make sense to
> define a property harp-pedal-details that would be a place to stash all the
> harp-pedal-specific properties.

Okay, I'll try that.

BTW, the current version of harp_pedals.ly (which already requires that 
patch...) is attached, together with the pdf output (showing no overlaps, but 
working circled pedals; the harp-pedal-details are not yet implemented).

Cheers,
Reinhold

- -- 
- ------------------------------------------------------------------
Reinhold Kainhofer, Vienna University of Technology, Austria
email: [EMAIL PROTECTED], http://reinhold.kainhofer.com/
 * Financial and Actuarial Mathematics, TU Wien, http://www.fam.tuwien.ac.at/
 * K Desktop Environment, http://www.kde.org, KOrganizer maintainer
 * Chorvereinigung "Jung-Wien", http://www.jung-wien.at/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFIqL3/TqjEwhXvPN0RAo+OAKCfL/rsKzKjHFR2Hytg18kmraq8qQCfdSn5
lg24TRG9SnDuDCAU8/H+Ixc=
=q077
-----END PGP SIGNATURE-----
From 7196bb0e2e96f10b66575ed6bb036a2c01d90bcd Mon Sep 17 00:00:00 2001
From: Reinhold Kainhofer <[EMAIL PROTECTED]>
Date: Mon, 18 Aug 2008 01:45:17 +0200
Subject: [PATCH 1/1] Add a make-line-stencil function, which correctly sets stencil extents

So far, one had to create line stencils manually using
   (ly:make-stencil (list 'draw-line ...) xext yext)
Unfortunately that meant that one had to specify the x- and y- coordinates
twice. This new make-line-stencil function takes the coordinates once,
creates the stencil and properly sets its extent (adding half the line
width to all coordinates of the x- and y-intervals).
---
 scm/stencil.scm |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/scm/stencil.scm b/scm/stencil.scm
index 6a4b88d..311c1d8 100644
--- a/scm/stencil.scm
+++ b/scm/stencil.scm
@@ -70,6 +70,17 @@
 	  (ly:stencil-combine-at-edge stil (other-axis axis) -1 rb padding))
     stil))
 
+(define-public (make-line-stencil width startx starty endx endy)
+  "Make a line stencil of given linewidth and set its extents accordingly"
+  (let* ((xext (cons (min startx endx) (max startx endx)))
+         (yext (cons (min starty endy) (max starty endy))))
+    (ly:make-stencil
+      (list 'draw-line width startx starty endx endy)
+      ; Since the line has rounded edges, we have to / can safely add half the 
+      ; width to all coordinates!
+      (interval-widen xext (/ width 2))
+      (interval-widen yext (/ width 2)))))
+
 (define-public (make-filled-box-stencil xext yext)
   "Make a filled box."
   
-- 
1.5.4.3

\version "2.11. 55"

% The following defines a new markup command 
%      \harp-pedal #"^-v|--v^" 
% for harp pedal diagrams. Possible values in the string are:
%   ^ ... pedal is up
%   - ... pedal is neutral
%   v ... pedal is down
%   | ... vertical divider line
%   o ... the following pedal should be circled (indicating a change)
% The function also checks if the string has the typical form of three
% pedals, then the divider and then the remaining four pedals. If not it
% prints out a warning. However, in any case, it will also print each symbol 
% in the order as given. This means you can place the divider (even multiple 
% dividers) anywhere you want, but you'll have to live with the warnings.
% 
% There is also a \harp-pedal-verbose version, which 
% takes a list of directions and a possible |. Unfortunately, it has some
% caveats:
%   1) the | cannot be given as a string "|", but as a character #\|. Similarly,
%      the "o" has to be given as #\o.
%   2) if one wants to use directions like UP, CENTER or DOWN, one cannot use
%      '(UP DOWN CENTER #\| ....), because the contents of that list are 
%      never evaluated. Instead one has to explicitly create a list like
%      (list UP DOWN CENTER #\| ....)

#(define-markup-command (harp-pedal-verbose layout props pedal-list) (list?)
  "Make a harp pedal diagram containing the directions indicated in @var{pedal-list}.

  For example,

@example
\\markup \\pedal-diagram-verbose #'(1 0 -1 #\\| 0 0 1 1)
\\markup \\pedal-diagram-verbose #(list UP CENTER DOWN #\\| CENTER CENTER UP UP)
@end example
"
  (make-harp-pedal layout props pedal-list))


#(define-markup-command (harp-pedal layout props definition-string) (string?)
  "Make a harp pedal diagram.  For example, say

@example
\\markup \\harp-pedal #\"^-v|^^^^\"
@end example
"
  (make-harp-pedal layout props (harp-pedals-parse-string definition-string)))


#(define (harp-pedals-parse-string definition-string)
 "Parse a harp pedals diagram string and return a list containing 1, 0, -1 or #\\|"
  (map (lambda (c) 
    (case c
      ((#\^) 1)
      ((#\v) -1)
      ((#\-) 0)
      ((#\| #\o) c)
      (else c)))
    (string->list definition-string)))

#(define (harp-pedal-info pedal-list)
  (let check ((pedals pedal-list)
              (pedalcount 0) 
              (dividerpositions '()))
    (if (null? pedals)
      (cons pedalcount (reverse dividerpositions))
      
      (case (car pedals)
        ((-1 0 1) (check (cdr pedals) (+ pedalcount 1) dividerpositions))
        ((#\|)    (check (cdr pedals) pedalcount (cons pedalcount dividerpositions)))
        (else     (check (cdr pedals) pedalcount dividerpositions))))))

#(define (harp-pedal-check pedal-list)
  "Perform some sanity checks for harp pedals (7 pedals, divider after third)"
  (let ((info (harp-pedal-info pedal-list)))
    ; 7 pedals:
    (if (not (equal? (car info) 7))
      (ly:warning "Harp pedal diagram contains ~a pedals rather than the usual 7." (car info)))
    ; One divider after third pedal:
    (if (null? (cdr info))
      (ly:warning "Harp pedal diagram does not contain a divider (usually after third pedal).")
      (if (not (equal? (cdr info) '(3)))
        (ly:warning "Harp pedal diagram contains dividers at positions ~a. Normally, there is only one divider after the third pedal." (cdr info))))))
      

#(define (make-harp-pedal layout props pedal-list)
  "Make a harp pedals diagram markup"
       
  
  ; FIXME the size variable should be defined by a prop. lookup
  (define sz 1.2)
  (harp-pedal-check pedal-list)
       
  ; TODO is it worth adding a thickness variable here?
  (let* ((x (* sz 4))
        (dy (* sz 0.8)) ; offset of the box center from the line 
        (line-width 0.1)
        (box-width (* sz 0.4))
        (box-hheight (* sz 0.5)) ; half the box-height, saves some divisions by 2
        (spaceafterdivider (* sz 0.8)) ; full space between boxes
        ;(spacebeforedivider (/ (+ box-width (* 8 spaceafterdivider)) 8))
        (spacebeforedivider spaceafterdivider)
        (box-x-dimensions (lambda (prev-x p space) (cons (+ prev-x space) 
                                                   (+ prev-x space box-width))))
        (box-y-dimensions (lambda (prev-x p space) (cons (- (* p dy) box-hheight) 
                                                         (+ (* p dy) box-hheight))))
        (circle-x-dimensions (lambda (prev-x p space) (cons (+ prev-x space) 
                                                   (+ prev-x space box-width))))
        (circle-y-dimensions (lambda (prev-x p space) (cons (+ (* p dy) box-hheight) 
                                                         (- (* p dy) box-hheight))))
        (divider-command-stencil (lambda (xpos) (make-line-stencil line-width xpos (- 0 dy box-hheight) xpos (+ dy box-hheight))))
        (result (let process-pedal  ((remaining pedal-list)
                                     (prev-x 0)
                                     (stencils '())
                                     (circled #f)
                                     (space spacebeforedivider))
          (if (null? remaining)
            (cons (+ prev-x space) stencils) 
      
            (case (car remaining)
              ((1 0 -1) 
                  (let* ((p (car remaining))
                        (stencil (make-filled-box-stencil
                                   (box-x-dimensions prev-x p space) 
                                   (box-y-dimensions prev-x p space)))
                                   ;(circle-stencil (if circled (rounded-box-stencil stencil 0.05 0.3 0.1 ) stencil))
                                   (circle-stencil (if circled (circle-stencil stencil 0.05 0.2 ) stencil))
                        (new-prev-x (+ prev-x space box-width)))
                      (process-pedal (cdr remaining) new-prev-x (cons circle-stencil stencils) #f space)))
              ((#\|)
                  (let* ((xpos (+ prev-x space))
                         ;(box (divider-command-box xpos))
                         (stencil (divider-command-stencil xpos))
                         (new-prev-x (+ prev-x space)))
                    (process-pedal (cdr remaining) new-prev-x (cons stencil stencils) circled spaceafterdivider)))
              ((#\o)
                  (process-pedal (cdr remaining) prev-x stencils #t space))
              (else
                  (ly:warning "Unhandled entry in harp-pedal: ~a" (car remaining))
                  (process-pedal (cdr remaining) prev-x stencils circled space))))))
        (final-x (car result))
        (stencils (reverse (cdr result))))
    ; Add the horizontal line and combine all stencils:
    (apply ly:stencil-add
      (cons
        (make-line-stencil line-width 0 0 final-x 0)
        stencils))))



\relative c'' {
  c1^\markup \harp-pedal #"^v-|vv-^"
  c1_\markup \harp-pedal-verbose #'(1 -1 0 #\| -1 -1 0 1)
  c1^\markup \harp-pedal-verbose #(list UP DOWN CENTER #\| DOWN DOWN CENTER UP)
  % invalid pedal specifications, which still should be handled gracefully:
  c1^\markup \harp-pedal #""
  c1^\markup \harp-pedal #"asfdvx" %\break
  % Sanity checks: #pedals != 7:
  c1^\markup \harp-pedal #"^-v|--"
  % Sanity checks: no divider, multiple dividers, divider on wrong position:
  c1^\markup \harp-pedal #"^-v--v^"
  c1^\markup \harp-pedal #"^|-v|--|v^"
  c1^\markup \harp-pedal #"^-v-|-v^"
  % circled boxes:
  c1^\markup \harp-pedal #"o^ovo-|vovo-o^"
}

Attachment: harp_pedals.pdf
Description: Adobe PDF document

_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to