lilypond-devel
[Top][All Lists]
Advanced

[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”
}






reply via email to

[Prev in Thread] Current Thread [Next in Thread]