;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
+;;;; (c) 1998--2009 Jan Nieuwenhuizen <janneke@gnu.org>
;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
(lambda (grob) (circle-stencil (callback grob) thickness padding)))
(define-public (print-circled-text-callback grob)
- (let* ((text (ly:grob-property grob 'text))
-
- (layout (ly:grob-layout grob))
- (defs (ly:output-def-lookup layout 'text-font-defaults))
- (props (ly:grob-alist-chain grob defs))
- (circle (ly:text-interface::interpret-markup
- layout props (make-circle-markup text))))
- circle))
-
-(define-public (music-cause grob)
- (let*
- ((event (event-cause grob)))
-
- (if (ly:stream-event? event)
- (ly:event-property event 'music-cause)
- #f)))
+ (grob-interpret-markup grob (make-circle-markup
+ (ly:grob-property grob 'text))
+ ))
(define-public (event-cause grob)
(let*
(ly:duration-dot-count
(ly:event-property (event-cause grob) 'duration)))
+(define-public (dots::calc-staff-position grob)
+ (let*
+ ((head (ly:grob-parent grob Y))
+ (log (ly:grob-property head 'duration-log)))
+
+ (cond
+ ((or (not (grob::has-interface head 'rest-interface))
+ (not (integer? log))) 0)
+ ((= log 7) 4)
+ ((> log 4) 3)
+ ((= log 0) -1)
+ ((= log 1) 1)
+ ((= log -1) 1)
+ (else 0))))
+
(define (note-head::calc-tablature-stem-attachment grob)
(cons 0.0 1.35))
;; statement. -- jr
((xcircle) "2xcircle")
((harmonic) "0harmonic")
+ ((harmonic-black) "2harmonic")
+ ((harmonic-mixed) (if (<= log 1) "0harmonic"
+ "2harmonic"))
((baroque)
;; Oops, I actually would not call this "baroque", but, for
;; backwards compatibility to 1.4, this is supposed to take
(define-public (first-bar-number-invisible barnum) (> barnum 1))
+(define-public (all-bar-numbers-visible barnum) #t)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; percent repeat counters
+
+(define-public ((every-nth-repeat-count-visible n) count context) (= 0 (modulo count n)))
+
+(define-public (all-repeat-counts-visible count context) #t)
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; break visibility
-(define-public begin-of-line-visible
- #(#f #f #t))
-(define-public end-of-line-visible
- #(#t #f #f))
-(define-public end-of-line-invisible
- #(#f #t #t))
+(define-public all-visible #(#t #t #t))
+(define-public begin-of-line-invisible #(#t #t #f))
+(define-public center-invisible #(#t #f #t))
+(define-public end-of-line-invisible #(#f #t #t))
+(define-public begin-of-line-visible #(#f #f #t))
+(define-public center-visible #(#f #t #f))
+(define-public end-of-line-visible #(#t #f #f))
+(define-public all-invisible #(#f #f #f))
+
(define-public spanbar-begin-of-line-invisible
#(#t #f #f))
-(define-public all-visible #(#t #t #t))
-(define-public all-invisible #(#f #f #f))
-(define-public begin-of-line-invisible
- #(#t #t #f))
-(define-public center-invisible #(#t #f #t))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Bar lines.
;;
;; How should a bar line behave at a break?
-;;
-;; Why prepend `default-' to every scm identifier?
+(define bar-glyph-alist
+ '((":|:" . (":|" . "|:"))
+ (":|.|:" . (":|" . "|:"))
+ (":|.:" . (":|" . "|:"))
+ ("||:" . ("||" . "|:"))
+ ("dashed" . ("dashed" . '()))
+ ("|" . ("|" . ()))
+ ("||:" . ("||" . "|:"))
+ ("|s" . (() . "|"))
+ ("|:" . ("|" . "|:"))
+ ("|." . ("|." . ()))
+
+ ;; hmm... should we end with a bar line here?
+ (".|" . ("|" . ".|"))
+ (":|" . (":|" . ()))
+ ("||" . ("||" . ()))
+ (".|." . (".|." . ()))
+ ("|.|" . ("|.|" . ()))
+ ("" . ("" . ""))
+ (":" . (":" . ""))
+ ("." . ("." . ()))
+ ("'" . ("'" . ()))
+ ("empty" . (() . ()))
+ ("brace" . (() . "brace"))
+ ("bracket" . (() . "bracket"))
+ ))
+
(define-public (bar-line::calc-glyph-name grob)
(let* (
(glyph (ly:grob-property grob 'glyph))
(dir (ly:item-break-dir grob))
- (result (assoc glyph
- '((":|:" . (":|" . "|:"))
- ("||:" . ("||" . "|:"))
- ("dashed" . ("dashed" . '()))
- ("|" . ("|" . ()))
- ("||:" . ("||" . "|:"))
- ("|s" . (() . "|"))
- ("|:" . ("|" . "|:"))
- ("|." . ("|." . ()))
-
- ;; hmm... should we end with a bar line here?
- (".|" . ("|" . ".|"))
- (":|" . (":|" . ()))
- ("||" . ("||" . ()))
- (".|." . (".|." . ()))
- ("" . ("" . ""))
- (":" . (":" . ""))
- ("." . ("." . ()))
- ("empty" . (() . ()))
- ("brace" . (() . "brace"))
- ("bracket" . (() . "bracket")) )))
+ (result (assoc glyph bar-glyph-alist))
(glyph-name (if (= dir CENTER)
glyph
(if (and result (string? (index-cell (cdr result) dir)))
(index-cell (cdr result) dir)
#f)))
)
-
- (if (not glyph-name)
- (ly:grob-suicide! grob))
-
glyph-name))
+(define-public (bar-line::calc-break-visibility grob)
+ (let* ((glyph (ly:grob-property grob 'glyph))
+ (result (assoc glyph bar-glyph-alist)))
+ (if result
+ (vector (string? (cadr result)) #t (string? (cddr result)))
+ #(#f #f #f))))
+
(define-public (shift-right-at-line-begin g)
"Shift an item to the right, but only at the start of the line."
(ly:event-property ev 'denominator)
(ly:event-property ev 'numerator))))
+
+; a formatter function, which is simply a wrapper around an existing
+; tuplet formatter function. It takes the value returned by the given
+; function and appends a note of given length.
+(define-public ((tuplet-number::append-note-wrapper function note) grob)
+ (let* ((txt (if function (function grob) #f)))
+ (if txt
+ (markup txt #:fontsize -5 #:note note UP)
+ (markup #:fontsize -5 #:note note UP))))
+
+; Print a tuplet denominator with a different number than the one derived from
+; the actual tuplet fraction
+(define-public ((tuplet-number::non-default-tuplet-denominator-text denominator) grob)
+(number->string (if denominator
+ denominator
+ (ly:event-property (event-cause grob) 'denominator))))
+
+; Print a tuplet fraction with different numbers than the ones derived from
+; the actual tuplet fraction
+(define-public ((tuplet-number::non-default-tuplet-fraction-text denominator numerator) grob)
+ (let* ((ev (event-cause grob))
+ (den (if denominator denominator (ly:event-property ev 'denominator)))
+ (num (if numerator numerator (ly:event-property ev 'numerator))))
+ (format "~a:~a" den num)))
+
+; Print a tuplet fraction with note durations appended to the numerator and the
+; denominator
+(define-public ((tuplet-number::fraction-with-notes denominatornote numeratornote) grob)
+ (let* ((ev (event-cause grob))
+ (denominator (ly:event-property ev 'denominator))
+ (numerator (ly:event-property ev 'numerator)))
+ ((tuplet-number::non-default-fraction-with-notes denominator denominatornote numerator numeratornote) grob)))
+
+; Print a tuplet fraction with note durations appended to the numerator and the
+; denominator
+(define-public ((tuplet-number::non-default-fraction-with-notes denominator denominatornote numerator numeratornote) grob)
+ (let* ((ev (event-cause grob))
+ (den (if denominator denominator (ly:event-property ev 'denominator)))
+ (num (if numerator numerator (ly:event-property ev 'numerator))))
+ (make-concat-markup (list
+ (make-simple-markup (format "~a" den))
+ (markup #:fontsize -5 #:note denominatornote UP)
+ (make-simple-markup " : ")
+ (make-simple-markup (format "~a" num))
+ (markup #:fontsize -5 #:note numeratornote UP)))))
+
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Color
(define-public color? list?)
+(define-public (rgb-color r g b) (list r g b))
; predefined colors
(define-public black '(0.0 0.0 0.0))
(define-public (accidental-interface::calc-alteration grob)
(ly:pitch-alteration (ly:event-property (event-cause grob) 'pitch)))
+
+(define-public cancellation-glyph-name-alist
+ '((0 . "accidentals.natural")))
+
(define-public standard-alteration-glyph-name-alist
- '((1 . "accidentals.doublesharp")
- (3/4 . "accidentals.sharp.slashslash.stemstemstem")
+ '(
+ ;; ordered for optimal performance.
+ (0 . "accidentals.natural")
+ (-1/2 . "accidentals.flat")
(1/2 . "accidentals.sharp")
+
+ (1 . "accidentals.doublesharp")
+ (-1 . "accidentals.flatflat")
+
+ (3/4 . "accidentals.sharp.slashslash.stemstemstem")
(1/4 . "accidentals.sharp.slashslash.stem")
- (0 . "accidentals.natural")
(-1/4 . "accidentals.mirroredflat")
- (-1/2 . "accidentals.flat")
(-3/4 . "accidentals.mirroredflat.flat")
- (-1 . "accidentals.flatflat")
))
+;; FIXME: standard vs default, alteration-FOO vs FOO-alteration
+(define-public alteration-default-glyph-name-alist standard-alteration-glyph-name-alist)
+
(define-public makam-alteration-glyph-name-alist
'((1 . "accidentals.doublesharp")
(8/9 . "accidentals.sharp.slashslashslash.stemstem")
))
(define-public alteration-hufnagel-glyph-name-alist
- '((1/2 . "accidentals.hufnagel-1")
+ '((-1/2 . "accidentals.hufnagelM1")
(0 . "accidentals.vaticana0")
- (-1/2 . "accidentals.mensural1")))
+ (1/2 . "accidentals.mensural1")))
-(define-public alteration-medicae-glyph-name-alist
- '((1/2 . "accidentals.medicaea-1")
+(define-public alteration-medicaea-glyph-name-alist
+ '((-1/2 . "accidentals.medicaeaM1")
(0 . "accidentals.vaticana0")
- (-1/2 . "accidentals.mensural1")))
+ (1/2 . "accidentals.mensural1")))
(define-public alteration-vaticana-glyph-name-alist
- '((1/2 . "accidentals.vaticana-1")
+ '((-1/2 . "accidentals.vaticanaM1")
(0 . "accidentals.vaticana0")
- (-1/2 . "accidentals.mensural1")))
+ (1/2 . "accidentals.mensural1")))
(define-public alteration-mensural-glyph-name-alist
- '((1/2 . "accidentals.mensural-1")
+ '((-1/2 . "accidentals.mensuralM1")
(0 . "accidentals.vaticana0")
- (-1/2 . "accidentals.mensural1")))
+ (1/2 . "accidentals.mensural1")))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(list lp rp)))
-(define (grob-text grob text)
+(define-public (grob-interpret-markup grob text)
(let*
((layout (ly:grob-layout grob))
(defs (ly:output-def-lookup layout 'text-font-defaults))
(define-public (parentheses-item::calc-angled-bracket-stencils grob)
(let* (
(font (ly:grob-default-font grob))
- (lp (ly:stencil-aligned-to (ly:stencil-aligned-to (grob-text grob (ly:wide-char->utf-8 #x2329))
+ (lp (ly:stencil-aligned-to (ly:stencil-aligned-to (grob-interpret-markup grob (ly:wide-char->utf-8 #x2329))
Y CENTER) X RIGHT))
- (rp (ly:stencil-aligned-to (ly:stencil-aligned-to (grob-text grob (ly:wide-char->utf-8 #x232A))
+ (rp (ly:stencil-aligned-to (ly:stencil-aligned-to (grob-interpret-markup grob (ly:wide-char->utf-8 #x232A))
Y CENTER) X LEFT))
)
left-span X)
X))
(common-y (ly:grob-common-refpoint spanner left-span Y))
+ (minimum-length (ly:grob-property spanner 'minimum-length 0.5))
+
(left-x (+ padding
(max (interval-end (ly:grob-robust-relative-extent
left-span common X))
(interval-end (ly:grob-robust-relative-extent dots common X))
-10000) ;; TODO: use real infinity constant.
)))
- (right-x (- (interval-start
- (ly:grob-robust-relative-extent right-span common X))
- padding))
+ (right-x (max (- (interval-start (ly:grob-robust-relative-extent right-span common X))
+ padding)
+ (+ left-x minimum-length)))
(self-x (ly:grob-relative-coordinate spanner common X))
(dx (- right-x left-x))
(exp (list 'path thickness
"Allow interpretation of tildes as lyric tieing marks."
(let*
- ((text (ly:grob-property grob 'text))
- (layout (ly:grob-layout grob))
- (defs (ly:output-def-lookup layout 'text-font-defaults))
- (props (ly:grob-alist-chain grob defs)))
+ ((text (ly:grob-property grob 'text)))
- (ly:text-interface::interpret-markup layout
- props
- (if (string? text)
- (make-tied-lyric-markup text)
- text))))
+ (grob-interpret-markup grob
+ (if (string? text)
+ (make-tied-lyric-markup text)
+ text))))
(define-public ((grob::calc-property-by-copy prop) grob)
(ly:event-property (event-cause grob) prop))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; fret boards
-(define (string-frets->description string-frets string-count)
- (let*
- ((desc (list->vector
- (map (lambda (x) (list 'mute (1+ x)))
- (iota string-count)))))
-
- (for-each (lambda (sf)
- (let*
- ((string (car sf))
- (fret (cadr sf))
- (finger (caddr sf)))
-
-
- (vector-set! desc (1- string)
- (if (= 0 fret)
- (list 'open string)
- (if finger
- (list 'place-fret string fret finger)
- (list 'place-fret string fret))
-
-
- ))
- ))
- string-frets)
-
- (vector->list desc)))
-
(define-public (fret-board::calc-stencil grob)
- (let* ((string-frets (ly:grob-property grob 'string-fret-finger-combinations))
- (string-count (ly:grob-property grob 'string-count))
- (layout (ly:grob-layout grob))
- (defs (ly:output-def-lookup layout 'text-font-defaults))
- (props (ly:grob-alist-chain grob defs)))
-
- (make-fret-diagram layout props
- (string-frets->description string-frets 6))))
+ (grob-interpret-markup
+ grob
+ (make-fret-diagram-verbose-markup
+ (ly:grob-property grob 'dot-placement-list))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; scripts
+
+(define-public (script-interface::calc-x-offset grob)
+ (ly:grob-property grob 'positioning-done)
+ (let* ((shift (ly:grob-property grob 'toward-stem-shift 0.0))
+ (note-head-location (ly:self-alignment-interface::centered-on-x-parent grob))
+ (note-head-grob (ly:grob-parent grob X))
+ (stem-grob (ly:grob-object note-head-grob 'stem)))
+ (+ note-head-location
+ ;; If the property 'toward-stem-shift is defined and the script has the
+ ;; same direction as the stem, move the script accordingly. Since scripts can
+ ;; also be over skips, we need to check whether the grob has a stem at all.
+ (if (ly:grob? stem-grob)
+ (let ((dir1 (ly:grob-property grob 'direction))
+ (dir2 (ly:grob-property stem-grob 'direction)))
+ (if (equal? dir1 dir2)
+ (let* ((common-refp (ly:grob-common-refpoint grob stem-grob X))
+ (stem-location (ly:grob-relative-coordinate stem-grob common-refp X)))
+ (* shift (- stem-location
+ note-head-location)))
+ 0.0))
+ 0.0))))