(ly:round-filled-box
xext yext blot))
+(define-markup-command (rotate layout props ang arg) (number? markup?)
+ "Rotate object with @var{ang} degrees around its center."
+ (let* ((stil (interpret-markup layout props arg)))
+ (ly:stencil-rotate stil ang 0 0)))
+
+
(define-markup-command (whiteout layout props arg) (markup?)
"Provide a white underground for @var{arg}"
- (let* ((stil (interpret-markup layout props
- (make-with-color-markup black arg)))
+ (let* ((stil (interpret-markup layout props arg))
(white
(interpret-markup layout props
(make-with-color-markup
(text-width (apply + text-widths))
(text-dir (chain-assoc-get 'text-direction props RIGHT))
(word-count (length stencils))
- (word-space (chain-assoc-get 'word-space props))
- (line-width (chain-assoc-get 'line-width props))
+ (word-space (chain-assoc-get 'word-space props 1))
+ (prop-line-width (chain-assoc-get 'line-width props #f))
+ (line-width (if prop-line-width prop-line-width
+ (ly:output-def-lookup layout 'line-width)))
(fill-space
(cond
((= word-count 1)
(define (wordwrap-markups layout props args justify)
(let*
((baseline-skip (chain-assoc-get 'baseline-skip props))
- (line-width (chain-assoc-get 'line-width props))
+ (prop-line-width (chain-assoc-get 'line-width props #f))
+ (line-width (if prop-line-width prop-line-width
+ (ly:output-def-lookup layout 'line-width)))
(word-space (chain-assoc-get 'word-space props))
(text-dir (chain-assoc-get 'text-direction props RIGHT))
(lines (wordwrap-stencils
x y)))
-(define-markup-command (pad-to-box layout props x-ext y-ext arg) (number-pair? number-pair? markup?)
+(define-markup-command (pad-to-box layout props x-ext y-ext arg)
+ (number-pair? number-pair? markup?)
"Make @var{arg} take at least @var{x-ext}, @var{y-ext} space"
(let*
(interval-union y-ext y))))
+(define-markup-command (hcenter-in layout props length arg)
+ (number? markup?)
+ "Center @var{arg} horizontally within a box of extending
+@var{length}/2 to the left and right."
+
+ (interpret-markup layout props
+ (make-pad-to-box-markup
+ (cons (/ length -2) (/ length 2))
+ '(0 . 0)
+ (make-hcenter-markup arg))))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; property
"Set @code{font-shape} to @code{caps}."
(interpret-markup layout (prepend-alist-chain 'font-shape 'caps props) arg))
+;; Poor man's caps
+(define-markup-command (smallCaps layout props text) (markup?)
+ "Turn @code{text}, which should be a string, to small caps.
+@example
+\\markup \\smallCaps \"Text between double quotes\"
+@end example
+"
+ (define (make-small-caps-markup chars)
+ (cond ((null? chars)
+ (markup))
+ ((char-whitespace? (car chars))
+ (markup #:fontsize -2 #:simple (string-upcase (list->string (cdr chars)))))
+ (else
+ (markup #:hspace -1
+ #:fontsize -2 #:simple (string-upcase (list->string chars))))))
+ (define (make-not-small-caps-markup chars)
+ (cond ((null? chars)
+ (markup))
+ ((char-whitespace? (car chars))
+ (markup #:simple (list->string (cdr chars))))
+ (else
+ (markup #:hspace -1
+ #:simple (list->string chars)))))
+ (define (small-caps-aux done-markups current-chars rest-chars small? after-space?)
+ (cond ((null? rest-chars)
+ ;; the end of the string: build the markup
+ (make-line-markup (reverse! (cons ((if small?
+ make-small-caps-markup
+ make-not-small-caps-markup)
+ (reverse! current-chars))
+ done-markups))))
+ ((char-whitespace? (car rest-chars))
+ ;; a space char.
+ (small-caps-aux done-markups current-chars (cdr rest-chars) small? #t))
+ ((or (and small? (char-lower-case? (car rest-chars)))
+ (and (not small?) (not (char-lower-case? (car rest-chars)))))
+ ;; same case
+ ;; add the char to the current char list
+ (small-caps-aux done-markups
+ (cons (car rest-chars)
+ (if after-space?
+ (cons #\space current-chars)
+ current-chars))
+ (cdr rest-chars)
+ small?
+ #f))
+ (else
+ ;; case change
+ ;; make a markup with current chars, and start a new list with new char
+ (small-caps-aux (cons ((if small?
+ make-small-caps-markup
+ make-not-small-caps-markup)
+ (reverse! current-chars))
+ done-markups)
+ (if after-space?
+ (list (car rest-chars) #\space)
+ (list (car rest-chars)))
+ (cdr rest-chars)
+ (not small?)
+ #f))))
+ (interpret-markup layout props (small-caps-aux (list)
+ (list)
+ (cons #\space (string->list text))
+ #f
+ #f)))
+
(define-markup-command (dynamic layout props arg) (markup?)
"Use the dynamic font. This font only contains @b{s}, @b{f}, @b{m},
@b{z}, @b{p}, and @b{r}. When producing phrases, like ``pi@`{u} @b{f}'', the
(define-markup-command (note-by-number layout props log dot-count dir) (number? number? number?)
"Construct a note symbol, with stem. By using fractional values for
@var{dir}, you can obtain longer or shorter stems."
+ (define (get-glyph-name-candidates dir log style)
+ (map (lambda (dir-name)
+ (format "noteheads.~a~a~a" dir-name (min log 2)
+ (if (and (symbol? style)
+ (not (equal? 'default style)))
+ (symbol->string style)
+ "")))
+ (list (if (= dir UP) "u" "d")
+ "s")))
+
+ (define (get-glyph-name font cands)
+ (if (null? cands)
+ ""
+ (if (ly:stencil-empty? (ly:font-get-glyph font (car cands)))
+ (get-glyph-name font (cdr cands))
+ (car cands))))
+
(let* ((font (ly:paper-get-font layout (cons '((font-encoding . fetaMusic)) props)))
- (size (chain-assoc-get 'font-size props 0))
- (stem-length (* (magstep size) (max 3 (- log 1))))
- (head-glyph (ly:font-get-glyph
- font
- (string-append "noteheads.s" (number->string (min log 2)))))
- (stem-thickness 0.13)
+ (size-factor (magstep (chain-assoc-get 'font-size props 0)))
+ (style (chain-assoc-get 'style props '()))
+ (stem-length (* size-factor (max 3 (- log 1))))
+ (head-glyph-name (get-glyph-name font (get-glyph-name-candidates dir log style)))
+ (head-glyph (ly:font-get-glyph font head-glyph-name))
+ (attach-indices (ly:note-head::stem-attachment font head-glyph-name))
+ (stem-thickness (* size-factor 0.13))
(stemy (* dir stem-length))
- (attachx (if (> dir 0)
- (- (cdr (ly:stencil-extent head-glyph X)) stem-thickness)
- 0))
- (attachy (* dir 0.28))
+ (attach-off (cons (interval-index
+ (ly:stencil-extent head-glyph X)
+ (* dir (car attach-indices)))
+ (* dir ; fixme, this is inconsistent between X & Y.
+ (interval-index
+ (ly:stencil-extent head-glyph Y)
+ (cdr attach-indices)))))
(stem-glyph (and (> log 0)
(ly:round-filled-box
- (cons attachx (+ attachx stem-thickness))
- (cons (min stemy attachy)
- (max stemy attachy))
+ (ordered-cons (car attach-off)
+ (+ (car attach-off) (* (- dir) stem-thickness)))
+ (cons (min stemy (cdr attach-off))
+ (max stemy (cdr attach-off)))
(/ stem-thickness 3))))
+
(dot (ly:font-get-glyph font "dots.dot"))
(dotwid (interval-length (ly:stencil-extent dot X)))
(dots (and (> dot-count 0)
(string-append "flags."
(if (> dir 0) "u" "d")
(number->string log)))
- (cons (+ attachx (/ stem-thickness 2)) stemy)))))
+ (cons (+ (car attach-off) (/ stem-thickness 2)) stemy)))))
(if flaggl
(set! stem-glyph (ly:stencil-add flaggl stem-glyph)))
(if (ly:stencil? stem-glyph)
(- amount) Y))
+(define-markup-command (translate-scaled layout props offset arg) (number-pair? markup?)
+ "Translate @var{arg} by @var{offset}, scaling the offset by the @code{font-size}."
+
+ (let*
+ ((factor (magstep (chain-assoc-get 'font-size props 0)))
+ (scaled (cons (* factor (car offset))
+ (* factor (cdr offset)))))
+
+ (ly:stencil-translate (interpret-markup layout props arg)
+ scaled)))
+
(define-markup-command (raise layout props amount arg) (number? markup?)
"
Raise @var{arg}, by the distance @var{amount}.