X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scm%2Fstencil.scm;h=047c0d0bb9622a2d514da8360bcca871e14f636b;hb=5b4b0d6e9a197e8f9eb085b7c2ad78b8be3e5cfc;hp=e4c15978b4fb6288b589a96f5648a8fa9a42637d;hpb=8c00ef0a0eb95417f6db5056c0c03b7cfa2e7571;p=lilypond.git diff --git a/scm/stencil.scm b/scm/stencil.scm index e4c15978b4..047c0d0bb9 100644 --- a/scm/stencil.scm +++ b/scm/stencil.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2003--2007 Han-Wen Nienhuys +;;;; (c) 2003--2008 Han-Wen Nienhuys (define-public (stack-stencils axis dir padding stils) "Stack stencils STILS in direction AXIS, DIR, using PADDING." @@ -70,6 +70,17 @@ (ly:stencil-combine-at-edge stil (other-axis axis) -1 rb padding)) stil)) +(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))) + (yext (cons (min starty endy) (max starty endy)))) + (ly:make-stencil + (list 'draw-line width startx starty endx endy) + ; Since the line has rounded edges, we have to / can safely add half the + ; width to all coordinates! + (interval-widen xext (/ width 2)) + (interval-widen yext (/ width 2))))) + (define-public (make-filled-box-stencil xext yext) "Make a filled box." @@ -80,10 +91,38 @@ (define-public (make-circle-stencil radius thickness fill) "Make a circle of radius @var{radius} and thickness @var{thickness}" + (let* + ((out-radius (+ radius (/ thickness 2.0)))) + (ly:make-stencil (list 'circle radius thickness fill) - (cons (- radius) radius) - (cons (- radius) radius))) + (cons (- out-radius) out-radius) + (cons (- out-radius) out-radius)))) + +(define-public (make-oval-stencil x-radius y-radius thickness fill) + "Make an oval from two Bezier curves, of x radius @var{x-radius}, + y radius @code{y-radius}, + and thickness @var{thickness} with fill defined by @code{fill}." + (let* + ((x-out-radius (+ x-radius (/ thickness 2.0))) + (y-out-radius (+ y-radius (/ thickness 2.0))) ) + + (ly:make-stencil + (list 'oval x-radius y-radius thickness fill) + (cons (- x-out-radius) x-out-radius) + (cons (- y-out-radius) y-out-radius)))) + +(define-public (make-ellipse-stencil x-radius y-radius thickness fill) + "Make an ellipse of x radius @var{x-radius}, y radius @code{y-radius}, + and thickness @var{thickness} with fill defined by @code{fill}." + (let* + ((x-out-radius (+ x-radius (/ thickness 2.0))) + (y-out-radius (+ y-radius (/ thickness 2.0))) ) + + (ly:make-stencil + (list 'ellipse x-radius y-radius thickness fill) + (cons (- x-out-radius) x-out-radius) + (cons (- y-out-radius) y-out-radius)))) (define-public (box-grob-stencil grob) "Make a box of exactly the extents of the grob. The box precisely @@ -91,8 +130,8 @@ encloses the contents. " (let* ((xext (ly:grob-extent grob grob 0)) (yext (ly:grob-extent grob grob 1)) - (thick 0.1)) - + (thick 0.01)) + (ly:stencil-add (make-filled-box-stencil xext (cons (- (car yext) thick) (car yext))) (make-filled-box-stencil xext (cons (cdr yext) (+ (cdr yext) thick))) @@ -115,10 +154,10 @@ encloses the contents. (define-public (circle-stencil stencil thickness padding) "Add a circle around STENCIL, producing a new stencil." - (let* ((x-ext (ly:stencil-extent stencil 0)) - (y-ext (ly:stencil-extent stencil 1)) - (diameter (max (- (cdr x-ext) (car x-ext)) - (- (cdr y-ext) (car y-ext)))) + (let* ((x-ext (ly:stencil-extent stencil X)) + (y-ext (ly:stencil-extent stencil Y)) + (diameter (max (interval-length x-ext) + (interval-length y-ext))) (radius (+ (/ diameter 2) padding thickness)) (circle (make-circle-stencil radius thickness #f))) @@ -129,6 +168,64 @@ encloses the contents. (interval-center x-ext) (interval-center y-ext)))))) +(define-public (oval-stencil stencil thickness x-padding y-padding) + "Add an oval around @code{stencil}, padded by the padding pair, + producing a new stencil." + (let* ((x-ext (ly:stencil-extent stencil X)) + (y-ext (ly:stencil-extent stencil Y)) + (x-length (+ (interval-length x-ext) x-padding thickness)) + (y-length (+ (interval-length y-ext) y-padding thickness)) + (x-radius (* 0.707 x-length) ) + (y-radius (* 0.707 y-length) ) + (oval (make-oval-stencil x-radius y-radius thickness #f))) + + (ly:stencil-add + stencil + (ly:stencil-translate oval + (cons + (interval-center x-ext) + (interval-center y-ext)))))) + +(define-public (ellipse-stencil stencil thickness x-padding y-padding) + "Add an ellipse around STENCIL, padded by the padding pair, + producing a new stencil." + (let* ((x-ext (ly:stencil-extent stencil X)) + (y-ext (ly:stencil-extent stencil Y)) + (x-length (+ (interval-length x-ext) x-padding thickness)) + (y-length (+ (interval-length y-ext) y-padding thickness)) + ;(aspect-ratio (/ x-length y-length)) + (x-radius (* 0.707 x-length) ) + (y-radius (* 0.707 y-length) ) + ;(diameter (max (- (cdr x-ext) (car x-ext)) + ; (- (cdr y-ext) (car y-ext)))) + ;(radius (+ (/ diameter 2) padding thickness)) + (ellipse (make-ellipse-stencil x-radius y-radius thickness #f))) + + (ly:stencil-add + stencil + (ly:stencil-translate ellipse + (cons + (interval-center x-ext) + (interval-center y-ext)))))) + +(define-public (rounded-box-stencil stencil thickness padding blot) + "Add a rounded box around STENCIL, producing a new stencil." + + (let* ((xext (interval-widen (ly:stencil-extent stencil 0) padding)) + (yext (interval-widen (ly:stencil-extent stencil 1) padding)) + (min-ext (min (-(cdr xext) (car xext)) (-(cdr yext) (car yext)))) + (ideal-blot (min blot (/ min-ext 2))) + (ideal-thickness (min thickness (/ min-ext 2))) + (outer (ly:round-filled-box + (interval-widen xext ideal-thickness) + (interval-widen yext ideal-thickness) + ideal-blot)) + (inner (ly:make-stencil (list 'color (x11-color 'white) + (ly:stencil-expr (ly:round-filled-box + xext yext (- ideal-blot ideal-thickness))))))) + (set! stencil (ly:stencil-add outer inner)) + stencil)) + (define-public (fontify-text font-metric text) "Set TEXT with font FONT-METRIC, returning a stencil."