Dear developers,

following a feature request on -user I tried my hand at implementing a feature enabling non-quadratic form for box-whiteouts.

As I never participated in developing before (and only rarely get down to coding these days), I'm pretty sure that what I did is substandard. Urs Liska was kind enough to point me to the LilyPond repository on GitHub (and comment on some aspects of my changes), but I unterstand that is not really the right place.

So I just post a patch here in case anyone would be interested in helping me bring my small contribution up to scratch.

Basically it adds to the 'whiteout property - which, at the moment, can either be a boolean or a number indicating the dimension of a quadratic whiteout box - a third possibility, namely a number pair giving x- and y-dimension separately. For instance:

\version "2.21"

\new Staff {
  \override NoteHead.whiteout = #'(5 . 40)   % Pair of X-thickness and Y-thickness
  g'4
  r2
  \override NoteHead.whiteout = #'(40 . 5)
  g'4
}

Best
Lukas

>From c8f83ad9d480bd8c6ba4ed45c8e167ed32bc52b9 Mon Sep 17 00:00:00 2001
From: Lukas-Fabian Moser <[email protected]>
Date: Thu, 13 Sep 2018 23:41:33 +0200
Subject: [PATCH] Non-quadratic whiteouts

---
 lily/grob.cc                   |  1 +
 scm/c++.scm                    |  3 +++
 scm/define-grob-properties.scm | 20 +++++++++++---------
 scm/stencil.scm                | 30 ++++++++++++++++++------------
 4 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/lily/grob.cc b/lily/grob.cc
index fddef87..24494be 100644
--- a/lily/grob.cc
+++ b/lily/grob.cc
@@ -147,6 +147,7 @@ Grob::get_print_stencil () const
       /* A grob has to be visible, otherwise the whiteout property has no effect. */
       /* Calls the scheme procedure stencil-whiteout in scm/stencils.scm */
       if (!transparent && (scm_is_number (get_property ("whiteout"))
+                           || is_number_pair (get_property ("whiteout"))
                            || to_boolean (get_property ("whiteout"))))
         {
           Real line_thickness = layout ()->get_dimension (ly_symbol2scm ("line-thickness"));
diff --git a/scm/c++.scm b/scm/c++.scm
index cd2806f..4b2f555 100644
--- a/scm/c++.scm
+++ b/scm/c++.scm
@@ -57,6 +57,9 @@
 (define-public (boolean-or-number? x)
   (or (boolean? x) (number? x)))
 
+(define-public (boolean-or-number-or-number-pair? x)
+ (or (boolean? x) (number? x) (number-pair? x)))
+
 (define-public (boolean-or-symbol? x)
   (or (boolean? x) (symbol? x)))
 
diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm
index f6952d9..a95cafd 100644
--- a/scm/define-grob-properties.scm
+++ b/scm/define-grob-properties.scm
@@ -1168,15 +1168,17 @@ one below this grob.")
 ;;; w
 ;;;
      (when ,ly:moment? "Global time step associated with this column.")
-     (whiteout ,boolean-or-number? "If a number or true, the grob is
-printed over a white background to white-out underlying material, if
-the grob is visible.  A number indicates how far the white background
-extends beyond the bounding box of the grob as a multiple of the
-staff-line thickness.  The @code{LyricHyphen} grob uses a special
-implementation of whiteout:  A positive number indicates how far the
-white background extends beyond the bounding box in multiples of
-@code{line-thickness}.  The shape of the background is determined by
-@code{whiteout-style}.  Usually @code{#f} by default. ")
+     (whiteout ,boolean-or-number-or-number-pair? "If a number,
+number-pair or true, the grob is printed over a white background to
+white-out underlying material, if the grob is visible.  A number
+indicates how far the white background extends beyond the bounding 
+box of the grob as a multiple of the staff-line thickness.  A number
+pair is interpreted as giving X- and Y-extent separately.  The
+@code{LyricHyphen} grob uses a special implementation of whiteout:  
+A positive number indicates how far the white background extends
+beyond the bounding box in multiples of @code{line-thickness}.  
+The shape of the background is determined by @code{whiteout-style}.  
+Usually @code{#f} by default. ")
      (whiteout-style ,symbol? "Determines the shape of the
 @code{whiteout} background.  Available are @code{'outline},
 @code{'rounded-box}, and the default @code{'box}.  There is one
diff --git a/scm/stencil.scm b/scm/stencil.scm
index cc61a13..dcee256 100644
--- a/scm/stencil.scm
+++ b/scm/stencil.scm
@@ -782,13 +782,13 @@ of the white stencil we make between 0 and 2*pi."
             stil)))))
 
 (define*-public (stencil-whiteout-box stil
-                 #:optional (thickness 0) (blot 0) (color white))
-  "@var{thickness} is how far, as a multiple of line-thickness,
-the white outline extends past the extents of stencil @var{stil}."
+                 #:optional (thickness '(0 . 0)) (blot 0) (color white))
+  "@var{thickness} is a pair giving how far, as a multiple of line-thickness,
+the white outline extends past the extents of stencil @var{stil}
+horizontally/vertically."
   (let*
-   ((x-ext (interval-widen (ly:stencil-extent stil X) thickness))
-    (y-ext (interval-widen (ly:stencil-extent stil Y) thickness)))
-
+   ((x-ext (interval-widen (ly:stencil-extent stil X) (car thickness)))
+    (y-ext (interval-widen (ly:stencil-extent stil Y) (cdr thickness))))
    (ly:stencil-add
     (stencil-with-color (ly:round-filled-box x-ext y-ext blot) color)
     stil)))
@@ -806,18 +806,24 @@ specified it determines how far, as a multiple of @var{line-thickness},
 the white background extends past the extents of stencil @var{stil}.  If
 @var{thickness} has not been specified, an appropriate default is chosen
 based on @var{style}."
-  (let ((thick (* line-thickness
-                 (if (number? thickness)
-                     thickness
+  (let* ((finalize-thickness (lambda (x)
+             (* line-thickness
+                 (if (number? x)
+                     x
                      (cond
                       ((eq? style 'outline) 3)
                       ((eq? style 'rounded-box) 3)
                       (else 0))))))
+         (X-thick (finalize-thickness (if (pair? thickness) (car thickness) thickness)))
+         (Y-thick (finalize-thickness (if (pair? thickness) (cdr thickness) thickness))))
+
     (cond
      ((eq? style 'special) stil)
-     ((eq? style 'outline) (stencil-whiteout-outline stil thick))
-     ((eq? style 'rounded-box) (stencil-whiteout-box stil thick (* 2 thick)))
-     (else (stencil-whiteout-box stil thick)))))
+     ; giving thickness as a number-pair makes no sense for style 'outline, so only X dimension is used
+     ((eq? style 'outline) (stencil-whiteout-outline stil X-thick))
+     ; the blot value for rounded quadratic boxes used to be 2*thick, so now we use X-thick + Y-thick
+     ((eq? style 'rounded-box) (stencil-whiteout-box stil (cons X-thick Y-thick) (+ X-thick Y-thick)))
+     (else (stencil-whiteout-box stil (cons X-thick Y-thick))))))
 
 (define-public (arrow-stencil-maker start? end?)
   "Return a function drawing a line from current point to @code{destination},
-- 
1.9.1

_______________________________________________
lilypond-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to