+(define (make-fret-diagram layout props marking-list)
+ "Make a fret diagram markup"
+ (let* (
+ ; note: here we get items from props that are needed in this routine,
+ ; or that are needed in more than one of the procedures
+ ; called from this routine. If they're only used in one of the
+ ; sub-procedure, they're obtained in that procedure
+ (size (chain-assoc-get 'size props 1.0)) ; needed for everything
+ ;TODO -- get string-count directly from length of stringTunings;
+ ; from FretBoard engraver, but not from markup call
+ (details (merge-details 'fret-diagram-details props '()))
+ (string-count
+ (assoc-get 'string-count details 6)) ; needed for everything
+ (my-fret-count
+ (assoc-get 'fret-count details 4)) ; needed for everything
+ (orientation
+ (assoc-get 'orientation details 'normal)) ; needed for everything
+ (finger-code
+ (assoc-get
+ 'finger-code details 'none)) ; needed for draw-dots and draw-barre
+ (default-dot-radius
+ (if (eq? finger-code 'in-dot) 0.425 0.25)) ; bigger dots if labeled
+ (default-dot-position
+ (if (eq? finger-code 'in-dot)
+ (- 0.95 default-dot-radius)
+ 0.6)) ; move up to make room for bigger dot if labeled
+ (dot-radius
+ (assoc-get
+ 'dot-radius details default-dot-radius)) ; needed for draw-dots
+ ; and draw-barre
+ (dot-position
+ (assoc-get
+ 'dot-position details default-dot-position)) ; needed for
+ ; draw-dots and draw-barre
+ (th
+ (* (ly:output-def-lookup layout 'line-thickness)
+ (chain-assoc-get 'thickness props 0.5))) ; needed for draw-frets
+ ; and draw-strings
+ (sth (* size th))
+ (thickness-factor (assoc-get 'string-thickness-factor details 0))
+ (alignment
+ (chain-assoc-get 'align-dir props -0.4)) ; needed only here
+ (xo-padding
+ (* size (assoc-get 'xo-padding details 0.2))) ; needed only here
+ (parameters (fret-parse-marking-list marking-list my-fret-count))
+ (capo-fret (assoc-get 'capo-fret parameters 0))
+ (dot-list (assoc-get 'dot-list parameters))
+ (xo-list (assoc-get 'xo-list parameters))
+ (fret-range (assoc-get 'fret-range parameters))
+ (my-fret-count (fret-count fret-range))
+ (barre-list (assoc-get 'barre-list parameters))
+ (barre-type
+ (assoc-get 'barre-type details 'curved))
+ (fret-diagram-stencil '()))
+ ;
+ ;; Here are the fret diagram helper functions that depend on the
+ ;; fret diagram parameters. The functions are here because the
+ ;; diagram parameters are part of the lexical scope here.
+
+ (define (stencil-coordinates fret-coordinate string-coordinate)
+ "Return a pair @code{(x-coordinate . y-coordinate)}
+ in stencil coordinate system."
+ (cond
+ ((eq? orientation 'landscape)
+ (cons fret-coordinate
+ (- string-coordinate (1- string-count))))
+ ((eq? orientation 'opposing-landscape)
+ (cons (- fret-coordinate) (- string-coordinate)))
+ (else
+ (cons string-coordinate (- fret-coordinate)))))
+
+ (define (stencil-coordinate-offset fret-offset string-offset)
+ "Return a pair @code{(x-offset . y-offset)}
+ for translation in stencil coordinate system."
+ (cond
+ ((eq? orientation 'landscape)
+ (cons fret-offset (- string-offset)))
+ ((eq? orientation 'opposing-landscape)
+ (cons (- fret-offset) string-offset))
+ (else
+ (cons string-offset (- fret-offset)))))
+
+
+
+ (define (make-bezier-sandwich-list start stop base height
+ half-thickness)
+ "Make the argument list for a bezier sandwich from
+string coordinate @var{start} to string-coordinate @var{stop} with a
+baseline at fret coordinate @var{base}, a height of
+@var{height}, and a half thickness of @var{half-thickness}."
+ (let* ((width (+ (- stop start) 1))
+ (cp-left-width (+ (* width half-thickness) start))
+ (cp-right-width (- stop (* width half-thickness)))
+ (bottom-control-point-height
+ (- base (- height half-thickness)))
+ (top-control-point-height
+ (- base height))
+ (left-end-point
+ (stencil-coordinates base start))
+ (right-end-point
+ (stencil-coordinates base stop))
+ (left-upper-control-point
+ (stencil-coordinates
+ top-control-point-height cp-left-width))
+ (left-lower-control-point
+ (stencil-coordinates
+ bottom-control-point-height cp-left-width))
+ (right-upper-control-point
+ (stencil-coordinates
+ top-control-point-height cp-right-width))
+ (right-lower-control-point
+ (stencil-coordinates
+ bottom-control-point-height cp-right-width)))
+ ; order of bezier control points is:
+ ; left cp low, right cp low, right end low, left end low
+ ; right cp high, left cp high, left end high, right end high.
+ ;
+ (list left-lower-control-point
+ right-lower-control-point
+ right-end-point
+ left-end-point
+ right-upper-control-point
+ left-upper-control-point
+ left-end-point
+ right-end-point)))
+
+ (define (draw-strings)
+ "Draw the string lines for a fret diagram with