diff options
-rw-r--r-- | Documentation/changes.tely | 25 | ||||
-rw-r--r-- | input/regression/markup-line-styles.ly | 75 | ||||
-rw-r--r-- | scm/define-markup-commands.scm | 81 |
3 files changed, 178 insertions, 3 deletions
diff --git a/Documentation/changes.tely b/Documentation/changes.tely index 24e973e4fd..c943a1a64e 100644 --- a/Documentation/changes.tely +++ b/Documentation/changes.tely @@ -62,6 +62,31 @@ which scares away people. @end ignore @item +Markup-command @code{\draw-squiggle-line} is now available. +Customizing is possible with overrides of @code{thickness}, @code{angularity}, +@code{height} and @code{orientation} +@lilypond[quote,verbatim] +\markup + \overlay { + \draw-squiggle-line #0.5 #'(3 . 3) ##t + + \translate #'(3 . 3) + \override #'(thickness . 4) + \draw-squiggle-line #0.5 #'(3 . -3) ##t + + \translate #'(6 . 0) + \override #'(angularity . -5) + \draw-squiggle-line #0.5 #'(-3 . -3) ##t + + \translate #'(3 . -3) + \override #'(angularity . 2) + \override #'(height . 0.3) + \override #'(orientation . -1) + \draw-squiggle-line #0.2 #'(-3 . 3) ##t + } +@end lilypond + +@item Markup-commands @code{\undertie} and @code{\overtie} are now available, as well the generic markup-command @code{\tie}. @lilypond[quote,verbatim] diff --git a/input/regression/markup-line-styles.ly b/input/regression/markup-line-styles.ly index ac15fa78ad..aa718e4f5c 100644 --- a/input/regression/markup-line-styles.ly +++ b/input/regression/markup-line-styles.ly @@ -1,11 +1,13 @@ \version "2.19.22" \header { - texidoc = "The markup-commands @code{\\draw-dashed-line} and - @code{\\draw-dotted-line} should print the same visual length as - @code{\\draw-line}." + texidoc = "The markup-commands @code{\\draw-dashed-line}, + @code{\\draw-dotted-line} and @code{\\draw-squiggle-line} should print the + same visual length as @code{\\draw-line}. + Also testing possible overrides for @code{\\draw-squiggle-line}" } +%% draw-dotted-line and draw-dashed-line test = #(define-scheme-function (x-nmbr y-nmbr)(number? number?) (let* ((lst (map @@ -57,4 +59,71 @@ test = (iota (abs x-nmbr))))) lst)) +%% draw-squiggle-line +mrkp = +\markup + \override #'(word-space . 2) + \column { + \line { \draw-squiggle-line #0.5 #'(6 . 0) ##t \tiny \vcenter "default" } + \line { + \override #'(orientation . -1) \draw-squiggle-line #0.5 #'(6 . 0) ##t + \tiny \vcenter "different orientation" + } + \line { + \draw-squiggle-line #0.5 #'(6 . 0) ##f + \tiny \vcenter "\"eq-end?\" set #f" + } + \line { + \override #'(height . 1) \draw-squiggle-line #0.5 #'(6 . 0) ##t + \tiny \vcenter "different height" + } + \line { + \override #'(thickness . 5) \draw-squiggle-line #0.5 #'(6 . 0) ##t + \tiny \vcenter "different thickness" + } + \line { + \override #'(angularity . 2) \draw-squiggle-line #0.5 #'(6 . 0) ##t + \tiny \vcenter "different angularity" + } + } + +test-draw-squiggle-line = +#(define-scheme-function (steps) (integer?) +;; Puts out a markup combining draw-line-markup and draw-squiggle-line-markup +;; in a helix-like mannor + (define (val-pts-list steps) + ;; Puts out a list, with each element being a pair of a numerical value + ;; and a number-pair + ;; The numerical value is used for first-bow-length and its height + ;; The number-pair is the destination-point of the line. + ;; Those points are on a simple helix around '(0 . 0) + (map + (lambda (n r) + (let* ((y (* (sin n) r)) + (x (* (cos n) r))) + (if (< (abs x) 0.00001) + (set! x 0)) + (if (< (abs y) 0.00001) + (set! y 0)) + (cons (max 0.1 (- 0.5 (/ 1 r))) (cons x y )))) + (iota steps 0 (/ TWO-PI steps)) + (iota steps 3 0.5))) + + (let ((args + (map + (lambda (arg) + #{ + \markup + \combine + \draw-line $(cdr arg) + \override #`(height . , (car arg)) + \draw-squiggle-line + #(car arg) + $(cdr arg) ##f + #}) + (val-pts-list steps)))) + #{ \markup { \hspace #10 \overlay $args \hspace #5 \vcenter \mrkp } #})) + \test #15 #0 + +\test-draw-squiggle-line #12 #10 diff --git a/scm/define-markup-commands.scm b/scm/define-markup-commands.scm index e22e467f1e..edd70f216d 100644 --- a/scm/define-markup-commands.scm +++ b/scm/define-markup-commands.scm @@ -306,6 +306,87 @@ line-length. new-props (markup #:draw-dashed-line dest)))) +(define-markup-command (draw-squiggle-line layout props sq-length dest eq-end?) + (number? number-pair? boolean?) + #:category graphic + #:properties ((thickness 0.5) + (angularity 0) + (height 0.5) + (orientation 1)) + " +@cindex drawing squiggled lines within text + +A squiggled line. + +If @code{eq-end?} is set to @code{#t}, it is ensured the squiggled line ends +with a bow in same direction as the starting one. @code{sq-length} is the +length of the first bow. @code{dest} is the end point of the squiggled line. +To match @code{dest} the squiggled line is scaled accordingly. +Its appearance may be customized by overrides for @code{thickness}, +@code{angularity}, @code{height} and @code{orientation}. +@lilypond[verbatim,quote] +\\markup + \\column { + \\draw-squiggle-line #0.5 #'(6 . 0) ##t + \\override #'(orientation . -1) + \\draw-squiggle-line #0.5 #'(6 . 0) ##t + \\draw-squiggle-line #0.5 #'(6 . 0) ##f + \\override #'(height . 1) + \\draw-squiggle-line #0.5 #'(6 . 0) ##t + \\override #'(thickness . 5) + \\draw-squiggle-line #0.5 #'(6 . 0) ##t + \\override #'(angularity . 2) + \\draw-squiggle-line #0.5 #'(6 . 0) ##t + } +@end lilypond" + (let* ((line-thickness (ly:output-def-lookup layout 'line-thickness)) + (thick (* thickness line-thickness)) + (x (car dest)) + (y (cdr dest)) + (length-to-print (magnitude (make-rectangular x y))) + ;; Make a guess how many bows may be needed + (guess (max 1 (truncate (/ length-to-print sq-length)))) + ;; If `eq-end?' is set #t, make sure squiggle-line starts and ends + ;; with a bow in same direction + (amount (if (and (even? guess) eq-end?) (1+ guess) guess)) + ;; The lined-up bows needs to fit `length-to-print' + ;; Thus scale the length of first bow accordingly + ;; Other bows are copies + (guessed-squiggle-line-length (* amount sq-length)) + (line-length-diff (- length-to-print guessed-squiggle-line-length)) + (line-length-diff-for-each-squiggle + (/ line-length-diff amount)) + (first-bow-length (+ sq-length line-length-diff-for-each-squiggle)) + ;; Get first bows + ;; TODO two bows are created via `make-bow-stencil' + ;; cheaper to use `ly:stencil-scale'? + (first-bow-end-coord + (cons + (/ (* first-bow-length x) length-to-print) + (/ (* first-bow-length y) length-to-print))) + (init-bow + (lambda (o) + (make-bow-stencil + '(0 . 0) + first-bow-end-coord + thick angularity height o))) + (init-bow-up (init-bow orientation)) + (init-bow-down (init-bow (- orientation))) + ;; Get a list of starting-points for the bows + (list-of-starts + (map + (lambda (n) + (cons + (* n (car first-bow-end-coord)) + (* n (cdr first-bow-end-coord)))) + (iota amount)))) + ;; The final stencil: lined-up bows + (apply ly:stencil-add + (map + (lambda (stil pt) (ly:stencil-translate stil pt)) + (circular-list init-bow-up init-bow-down) + list-of-starts)))) + (define-markup-command (draw-hline layout props) () #:category graphic |