summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Morgan <tlm@ziiuu.com>2009-07-06 16:08:06 +0200
committerCarl Sorensen <c_sorensen@byu.edu>2010-02-15 20:40:06 -0700
commit1ae286a5dde706e6b30084dee6affc2ea250d7ac (patch)
tree0c63c222007e80394d3ba7ea04680e45a59893f9
parentde15e1feb7e3096f4b41e259c90b416a846e16d1 (diff)
New markup command `parenthesize' in `scm/define-markup-commands.scm'. This works like the `bracket' markup command but makes parentheses instead of brackets.
New public procedure `parenthesize-stencil' and subroutine `make-parenthesis-stencil' in `scm/stencil.scm'. Thanks to Carl Sorensen and Neil Puttock for their great advice and criticism.
-rw-r--r--input/regression/parenthesize-markup.ly21
-rw-r--r--scm/define-markup-commands.scm37
-rw-r--r--scm/stencil.scm78
3 files changed, 136 insertions, 0 deletions
diff --git a/input/regression/parenthesize-markup.ly b/input/regression/parenthesize-markup.ly
new file mode 100644
index 0000000000..0699587ec8
--- /dev/null
+++ b/input/regression/parenthesize-markup.ly
@@ -0,0 +1,21 @@
+\version "2.13.13"
+
+\header{
+
+ texidoc="
+The parenthesize markup will place parentheses
+around any stencil.
+
+The angularity of the parentheses can be adjusted.
+"
+
+}
+
+\score {
+ c''^\markup {
+ \parenthesize {
+ \column { "A" "B" "C" }
+ }
+ }
+}
+
diff --git a/scm/define-markup-commands.scm b/scm/define-markup-commands.scm
index 302b08fbc7..4a7a6a0fdf 100644
--- a/scm/define-markup-commands.scm
+++ b/scm/define-markup-commands.scm
@@ -3149,6 +3149,43 @@ Draw vertical brackets around @var{arg}.
(m (interpret-markup layout props arg)))
(bracketify-stencil m Y th (* 2.5 th) th)))
+(define-markup-command (parenthesize layout props arg)
+ (markup?)
+ #:category graphic
+ #:properties ((angularity 0)
+ (padding)
+ (size 1)
+ (thickness 1)
+ (width 0.25))
+ "
+@cindex placing parentheses around text
+
+Draw parentheses around @var{arg}. This is useful for parenthesizing
+a column containing several lines of text.
+
+@lilypond[verbatim,quote]
+\\markup {
+ \\parenthesize {
+ \\column {
+ foo
+ bar
+ }
+ }
+}
+@end lilypond"
+ (let* ((markup (interpret-markup layout props arg))
+ (scaled-width (* size width))
+ (scaled-thickness
+ (* (chain-assoc-get 'line-thickness props 0.1)
+ thickness))
+ (half-thickness
+ (min (* size 0.5 scaled-thickness)
+ (* (/ 4 3.0) scaled-width)))
+ (padding (chain-assoc-get 'padding props half-thickness)))
+ (parenthesize-stencil
+ markup half-thickness scaled-width angularity padding)))
+
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Delayed markup evaluation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/scm/stencil.scm b/scm/stencil.scm
index 19e8f5b189..60a9e1541a 100644
--- a/scm/stencil.scm
+++ b/scm/stencil.scm
@@ -81,6 +81,84 @@
(ly:stencil-combine-at-edge lb (other-axis axis) 1 stil padding))
stil))
+(define (make-parenthesis-stencil
+ y-extent half-thickness width angularity)
+ "Create a parenthesis stencil.
+@var{y-extent} is the Y extent of the markup inside the parenthesis.
+@var{half-thickness} is the half thickness of the parenthesis.
+@var{width} is the width of a parenthesis.
+The higher the value of number @var{angularity},
+the more angular the shape of the parenthesis."
+ (let* ((line-width 0.1)
+ ;; Horizontal position of baseline that end points run through.
+ (base-x
+ (if (< width 0)
+ (- width)
+ 0))
+ ;; Farthest X value (in relation to baseline)
+ ;; on the outside of the curve.
+ (outer-x (+ base-x width))
+ (x-extent (ordered-cons base-x outer-x))
+ (bottom-y (interval-start y-extent))
+ (top-y (interval-end y-extent))
+
+ (lower-end-point (cons base-x bottom-y))
+ (upper-end-point (cons base-x top-y))
+
+ (outer-control-x (+ base-x (* 4/3 width)))
+ (inner-control-x (+ outer-control-x
+ (if (< width 0)
+ half-thickness
+ (- half-thickness))))
+
+ ;; Vertical distance between a control point
+ ;; and the end point it connects to.
+ (offset-index (- (* 0.6 angularity) 0.8))
+ (lower-control-y (interval-index y-extent offset-index))
+ (upper-control-y (interval-index y-extent (- offset-index)))
+
+ (lower-outer-control-point
+ (cons outer-control-x lower-control-y))
+ (upper-outer-control-point
+ (cons outer-control-x upper-control-y))
+ (upper-inner-control-point
+ (cons inner-control-x upper-control-y))
+ (lower-inner-control-point
+ (cons inner-control-x lower-control-y)))
+
+ (ly:make-stencil
+ (list 'bezier-sandwich
+ `(quote ,(list
+ ;; Step 4: curve through inner control points
+ ;; to lower end point.
+ upper-inner-control-point
+ lower-inner-control-point
+ lower-end-point
+ ;; Step 3: move to upper end point.
+ upper-end-point
+ ;; Step 2: curve through outer control points
+ ;; to upper end point.
+ lower-outer-control-point
+ upper-outer-control-point
+ upper-end-point
+ ;; Step 1: move to lower end point.
+ lower-end-point))
+ line-width)
+ x-extent
+ y-extent)))
+
+(define-public (parenthesize-stencil
+ stencil half-thickness width angularity padding)
+ "Add parentheses around @var{stencil}, returning a new stencil."
+ (let* ((y-extent (ly:stencil-extent stencil Y))
+ (lp (make-parenthesis-stencil
+ y-extent half-thickness (- width) angularity))
+ (rp (make-parenthesis-stencil
+ y-extent half-thickness width angularity)))
+ (set! stencil (ly:stencil-combine-at-edge lp X RIGHT stencil padding))
+ (set! stencil (ly:stencil-combine-at-edge stencil X RIGHT rp padding))
+ stencil))
+
(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)))