Or even an oval stencil with 4 control points: %% #(define-public (make-oval-stencil-var x-radius y-radius thickness fill) "Make an oval from two Bezier curves, of x@tie{}radius @var{x-radius}, y@tie{}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))) (x-max x-radius) (x-min (- x-radius)) (y-max y-radius) (y-min (- y-radius)) (commands `(,(list 'moveto x-max 0) ,(list 'curveto x-max (/ y-max 1.8) (/ x-max 1.8) y-max 0 y-max) ,(list 'curveto (/ x-min 1.8) y-max x-min (/ y-max 1.8) x-min 0) ,(list 'curveto x-min (/ y-min 1.8) (/ x-min 1.8) y-min 0 y-min) ,(list 'curveto (/ x-max 1.8) y-min x-max (/ y-min 1.8) x-max 0) ,(list 'closepath))) (command-list (fold-right append '() commands))) (ly:make-stencil `(path ,thickness `(,@',command-list) 'round 'round ,fill) (cons (- x-out-radius) x-out-radius) (cons (- y-out-radius) y-out-radius)))) %%
Cheers, Pierre Le jeu. 4 avr. 2019 à 17:33, Pierre Perol-Schneider < pierre.schneider.pa...@gmail.com> a écrit : > Hi Dev Team, > Here's some thougts: > > %%%%%% > \version "2.19.83" > > %% The oval stencil commands uses beziers curves that cause some side > effects: > \markuplist { > \line\vcenter { > "Circle, radius = 2 : " > \stencil #(make-circle-stencil 2 .13 #f) > } > \line\vcenter { > "Oval, x-radius = y-radius = 2 : " > \stencil #(make-oval-stencil 2 2 .13 #f) > } > \line\vcenter { > "Oval extents, x-radius = y-radius = 2 : " > \box\stencil #(make-oval-stencil 2 2 .13 #f) > } > } > > %% Here's a suggestion with a corrected y-radius in order to reach a quasi > circle: > #(define-public (make-oval-stencil-var x-radius y-radius thickness fill) > "Make an oval from two Bezier curves, of x@tie{}radius @var{x-radius}, > y@tie{}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))) > (x-max x-radius) > (x-min (- x-radius)) > (y-max (* y-radius (+ 1 (/ 1 3)))) ; <= max deviation < 1% > (y-min (* (- y-radius) (+ 1 (/ 1 3)))) ; <= max deviation < 1% > (commands `(,(list 'moveto x-max 0) > ,(list 'curveto x-max y-max x-min y-max x-min 0) > ,(list 'curveto x-min y-min x-max y-min x-max 0) > ,(list 'closepath) > )) > (command-list (fold-right append '() commands))) > (ly:make-stencil > `(path ,thickness `(,@',command-list) 'round 'round ,fill) > (cons (- x-out-radius) x-out-radius) > (cons (- y-out-radius) y-out-radius)))) > > > \markuplist { > % Test #1: > \line\vcenter { > "make-oval-stencil-var: " > \box\stencil #(make-oval-stencil-var 2 2 .13 #f) > " v.s. make-circle-stencil: " > \box\stencil #(make-circle-stencil 2 .13 #f) > } > % Test #2: > \vspace #1 "make-oval-stencil-var & make-circle-stencil combined:" > \vspace #.3 > \translate #'(8 . 0) > \line { > \scale #'(5 . 5) { > \combine > \with-color #blue > \draw-circle #2 #.13 ##f > \with-color #red > \stencil #(make-oval-stencil-var 2 2 .13 #f) > } > \scale #'(5 . 5) { > \combine > \with-color #red > \stencil #(make-oval-stencil-var 2 2 .13 #f) > \with-color #blue > \draw-circle #2 #.13 ##f > } > } > \vspace #1 > } > > %% Here comes a suggestion for the markup command: > #(define-public (oval-stencil-var stencil thickness x-padding y-padding) > "Add an oval around @code{stencil}, padded by the padding pair, > producing a var 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-var x-radius y-radius thickness #f))) > > (ly:stencil-add > stencil > (ly:stencil-translate oval > (cons > (interval-center x-ext) > (interval-center y-ext)))))) > > #(define-markup-command (oval-var layout props arg) > (markup?) > #:category graphic > #:properties ((thickness 1) > (font-size 0) > (x-padding .1) ; <= possible corrected padding > (y-padding .1)) ; <= possible corrected padding > " > @cindex drawing oval around text > > Draw an oval around @var{arg}. Use @code{thickness}, > @code{x-padding}, @code{x-padding} and @code{font-size} properties to > determine > line thickness and padding around the markup. > > @lilypond[verbatim,quote] > \\markup { > \\oval-var { > Hi > } > } > @end lilypond" > (let ((th (* (ly:output-def-lookup layout 'line-thickness) > thickness)) > (pad-x (* (magstep font-size) x-padding)) > (pad-y (* (magstep font-size) y-padding)) > (m (interpret-markup layout props arg))) > (oval-stencil-var m th pad-x pad-y))) > > > %% Comparative test: > \markup { > "oval: " > \box\oval "Hi" > " v.s. oval-var markups: " > \box\oval-var "Hi" > } > > %%%%% > > Cheers, > Pierre > _______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel