+
+(define (oval x-radius y-radius thick fill)
+ (ly:format
+ "~a ~4f ~4f ~4f draw_oval"
+ (if fill
+ "true"
+ "false")
+ x-radius y-radius thick))
+
+(define (placebox x y s)
+ (if (not (string-null? s))
+ (ly:format "~4f ~4f moveto ~a\n" x y s)
+ ""))
+
+(define (polygon points blot-diameter filled?)
+ (ly:format "~a ~4l ~a ~4f draw_polygon"
+ (if filled? "true" "false")
+ points
+ (- (/ (length points) 2) 1)
+ blot-diameter))
+
+(define (repeat-slash width slope beam-thickness)
+ (define (euclidean-length x y)
+ (sqrt (+ (* x x) (* y y))))
+
+ (let ((x-width (euclidean-length beam-thickness (/ beam-thickness slope)))
+ (height (* width slope)))
+ (ly:format "~4l draw_repeat_slash"
+ (list x-width width height))))
+
+
+(define (round-filled-box left right bottom top blotdiam)
+ (let* ((halfblot (/ blotdiam 2))
+ (x (- halfblot left))
+ (width (- right (+ halfblot x)))
+ (y (- halfblot bottom))
+ (height (- top (+ halfblot y))))
+ (ly:format "~4l draw_round_box"
+ (list width height x y blotdiam))))
+
+;; save current color on stack and set new color
+(define (setcolor r g b)
+ (ly:format "gsave ~4l setrgbcolor\n"
+ (list r g b)))
+
+;; restore color from stack
+(define (resetcolor) "grestore\n")
+
+;; rotation around given point
+(define (setrotation ang x y)
+ (ly:format "gsave ~4l translate ~a rotate ~4l translate\n"
+ (list x y)
+ ang
+ (list (* -1 x) (* -1 y))))
+
+(define (resetrotation ang x y)
+ "grestore ")
+
+(define (unknown)
+ "\n unknown\n")
+
+(define (url-link url x y)
+ (ly:format "~a ~a currentpoint vector_add ~a ~a currentpoint vector_add (~a) mark_URI"
+ (car x)
+ (car y)
+ (cdr x)
+ (cdr y)
+ url))
+
+(define* (path thickness exps #:optional (cap 'round) (join 'round) (fill? #f))
+ (define (convert-path-exps exps)
+ (if (pair? exps)
+ (let*
+ ((head (car exps))
+ (rest (cdr exps))
+ (arity
+ (cond
+ ((memq head '(rmoveto rlineto lineto moveto)) 2)
+ ((memq head '(rcurveto curveto)) 6)
+ ((eq? head 'closepath) 0)
+ (else 1)))
+ (args (take rest arity))
+ )
+
+ ;; WARNING: this is a vulnerability: a user can output arbitrary PS code here.
+ (cons (ly:format
+ "~l ~a "
+ args
+ head)
+ (convert-path-exps (drop rest arity))))
+ '()))
+
+ (let ((cap-numeric (case cap ((butt) 0) ((round) 1) ((square) 2)
+ (else (begin
+ (ly:warning (_ "unknown line-cap-style: ~S")
+ (symbol->string cap))
+ 1))))
+ (join-numeric (case join ((miter) 0) ((round) 1) ((bevel) 2)
+ (else (begin
+ (ly:warning (_ "unknown line-join-style: ~S")
+ (symbol->string join))
+ 1)))))
+ (ly:format
+ "gsave currentpoint translate
+~a setlinecap ~a setlinejoin ~a setlinewidth
+~l gsave stroke grestore ~a grestore"
+ cap-numeric
+ join-numeric
+ thickness
+ (convert-path-exps exps)
+ (if fill? "fill" ""))))
+
+(define (setscale x y)
+ (ly:format "gsave ~4l scale\n"
+ (list x y)))
+
+(define (resetscale)
+ "grestore\n")