]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4722 Introduce new markup-command draw-squiggle-line.
authorThomas Morley <thomasmorley65@gmail.com>
Tue, 5 Jan 2016 15:18:53 +0000 (16:18 +0100)
committerThomas Morley <thomasmorley65@gmail.com>
Tue, 19 Jan 2016 22:15:43 +0000 (23:15 +0100)
Change regtest /input/regression/markup-line-styles.ly accordingly

Documentation/changes.tely
input/regression/markup-line-styles.ly
scm/define-markup-commands.scm

index 24e973e4fd4c89d5ac438acf377c8376593eb5c0..c943a1a64e89ae2e66522bca1a364b91fa6e1e5d 100644 (file)
@@ -61,6 +61,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}.
index ac15fa78adc6b58094220be2ef205b5eaef7176a..aa718e4f5c9c649b1a58bf29d907353345b09588 100644 (file)
@@ -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
index e22e467f1e2258d1daccb00bb9c07a7ebebc6171..edd70f216dc8eaf448987f2e9f81836a4b3f7bd3 100644 (file)
@@ -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