lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Drawing boxes around grobs


From: Aaron Hill
Subject: Re: Drawing boxes around grobs
Date: Mon, 10 Feb 2020 02:13:23 -0800
User-agent: Roundcube Webmail/1.4.2

On 2020-02-09 6:54 am, Paolo Prete wrote:
At this point, is there a way to extend the box by setting four parameters
separately:

top, bottom, left, right

..., instead of the "padding" one ?
Something like:

 #(make-stencil-boxer 0.1 #paddingLeft #paddingRight #paddingTop
#paddingBottom ly:script-interface::print cyan)

I've probably over-engineered this, but I adapted the CSS model for padding [1] so you can specify it with anywhere from one to four values. Additionally, I made it an option whether you want the extents to be expanded to contain the new stencil or to preserve the original extents.

[1]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding

%%%%
\version "2.19.83"

#(define (box-stencil stencil thickness padding color expand?)
  "Add a box around @var{stencil}, producing a new stencil."
  (define (css-style-padding padding)
    ;; padding => (top right bottom left)
    (cond
      ((or (null? padding) (eqv? #f padding)) '(0 0 0 0))
      ((number? padding) (make-list 4 padding))
      ((number-pair? padding)
        (list (car padding) (cdr padding)
              (car padding) (cdr padding)))
      ((and (number-list? padding) (<= (length padding) 4))
        (case (length padding)
          ((1) (make-list 4 (first padding)))
          ((2) (list (first padding) (second padding)
                     (first padding) (second padding)))
          ((3) (list (first padding) (second padding)
                     (third padding) (second padding)))
          (else padding)))
      (else
        (begin (ly:warning "Ignoring invalid padding: ~a" padding)
               '(0 0 0 0)))))
  (let* ((padding (css-style-padding padding))
         (padding-top (first padding))
         (padding-right (second padding))
         (padding-bottom (third padding))
         (padding-left (fourth padding))

         (x-ext-orig (ly:stencil-extent stencil X))
         (y-ext-orig (ly:stencil-extent stencil Y))
         (x-ext-inner
           (cons (- (interval-start x-ext-orig) padding-left)
                 (+ (interval-end x-ext-orig) padding-right)))
         (y-ext-inner
           (cons (- (interval-start y-ext-orig) padding-bottom)
                 (+ (interval-end y-ext-orig) padding-top)))
         (x-ext-outer (interval-widen x-ext-inner thickness))
         (y-ext-outer (interval-widen y-ext-inner thickness))
         (x-ext-new (if expand? x-ext-outer x-ext-orig))
         (y-ext-new (if expand? y-ext-outer y-ext-orig))

(x-rule (make-filled-box-stencil (cons 0 thickness) y-ext-inner)) (y-rule (make-filled-box-stencil x-ext-outer (cons 0 thickness)))
         (box (stencil-with-color
           (ly:stencil-add
(ly:stencil-translate-axis y-rule (interval-end y-ext-inner) Y) (ly:stencil-translate-axis x-rule (interval-end x-ext-inner) X) (ly:stencil-translate-axis y-rule (interval-start y-ext-outer) Y) (ly:stencil-translate-axis x-rule (interval-start x-ext-outer) X))
           color)))
    (ly:make-stencil
      (ly:stencil-expr (ly:stencil-add stencil box))
      x-ext-new y-ext-new)))

#(define* (make-stencil-boxer thickness padding callback
           #:optional (color red) (expand? #t))
  "Return function that adds a box around the grob passed as argument."
  (lambda (grob)
    (box-stencil (callback grob) thickness padding color expand?)))

{
  \override TextScript.stencil =
#(make-stencil-boxer 0.2 '(0.2 1.4 0.6) ly:text-interface::print magenta)
  \override Script.stencil =
#(make-stencil-boxer 0.2 '(1.4 1 0.6 0.2) ly:script-interface::print)
  \override NoteHead.stencil =
    #(make-stencil-boxer 0.2 '(0.6 0.2) ly:note-head::print cyan #f)
    c'4^"foo"->
  \override TupletBracket.stencil =
    #(make-stencil-boxer 0.4 0 ly:tuplet-bracket::print)
    \tuplet 3/2 { b4 4 4 }
}
%%%%


-- Aaron Hill

Attachment: box-stencil.cropped.png
Description: PNG image


reply via email to

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