[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
stencil-flip function
From: |
Paul Morris |
Subject: |
stencil-flip function |
Date: |
Sat, 2 May 2015 16:45:26 -0400 |
Hello dev list,
Recently while working on Jianpu notation (see user list) I needed a function
to flip a stencil. LilyPond doesn’t have one, so I thought it would be worth
adding the one I wrote (see below).
Any thoughts on this before I submit the code for review?
(The other option would be to just revise the ly:stencil-scale function’s doc
string so that it mentions that it can be used to flip a stencil, but that this
"may result in collisions unless the scaled stencil is [manually] realigned".)
-Paul
%%%%%%%%%%%%%%%%
\version "2.19.19"
%{
From the stencil-scale.ly regression test:
"Stencils can be scaled using @code{ly:stencil-scale}.
Negative values will flip or mirror the stencil without changing its origin;
this
may result in collisions unless the scaled stencil is realigned."
The following function effectively flips a stencil *in place*, by using
ly:stencil-scale with a -1 argument and automatically re-aligning the
stencil to its original position. This prevents collisions, etc.
%}
#(define (stencil-flip axis stl)
"Flip stencil @var{stl} in the direction of @var{axis}.
@var{axis} is 0 for X axis, 1 for Y axis."
(let* (
;; scale stencil using -1 to flip it,
;; and calculate how far it was displaced.
(xy (if (= axis X) '(-1 . 1) '(1 . -1)))
(flipped-stl (ly:stencil-scale stl (car xy) (cdr xy)))
(flipped-ext (ly:stencil-extent flipped-stl axis))
(original-ext (ly:stencil-extent stl axis))
(offset (- (car original-ext) (car flipped-ext)))
;; restore flipped stencil to original position
(replaced-stl (ly:stencil-translate-axis flipped-stl offset axis)))
;; for testing...
;; (display original-ext) (display flipped-ext)
;; (display (ly:stencil-extent replaced-stl axis))(newline)
replaced-stl))
%%%%%%%%%%%%%
circleA = #(stencil-with-color (make-circle-stencil 0.3 0.1 #f) blue)
circleB = #(ly:stencil-translate circleA '(2 . 2))
circleC = #(ly:stencil-translate circleA '(0 . 2))
circleD = #(ly:stencil-translate circleA '(2 . 0))
circles = #(ly:stencil-add circleA circleB circleC circleD)
triangle =
#(make-path-stencil
'(moveto 0 0 lineto 2 2 lineto 2 0 closepath)
0.2 1 1 #f)
% This example shows the result of using ly:stencil-scale with
% a -1 argument, and the need for a stencil-flip function to
% flip a stencil in place.
{
g'1^\markup \stencil
#(ly:stencil-add circles triangle)
_\markup \teeny "baseline"
g'1^\markup \stencil
#(ly:stencil-add circles (ly:stencil-scale triangle -1 1))
_\markup \teeny "scale X"
g'1^\markup \stencil
#(ly:stencil-add circles (ly:stencil-scale triangle 1 -1))
_\markup \teeny "scale Y"
g'1^\markup \stencil
#(ly:stencil-add circles (stencil-flip X triangle))
_\markup \teeny "flip X"
g'1^\markup \stencil
#(ly:stencil-add circles (stencil-flip Y triangle))
_\markup \teeny "flip Y”
}
- stencil-flip function,
Paul Morris <=