Jump to content

Encapsulated text

From LilyPond wiki

\capsule arg (markup).

Draw a capsule around arg.

Use thickness, x-padding, y-padding and font-size properties to determine line thickness and padding around the markup.

\version "2.24.0"

\paper { tagline = ##f }

%% http://lsr.di.unimi.it/LSR/Item?id=1092
%% Add by P.P.Schneider on Apr. 2019.

%%%% Defs:
#(define-public (make-capsule-stencil lgth radius thickness fill)
  "Make an capsule from four Bézier curves and two lines, of radius @var{radius},
   length @var{lgth}, and thickness @var{thickness} with fill
   defined by @code{fill}."
    (let*
        ((k 0.551915)
         (r-max radius)
         (r-min (- r-max))
         (l-max (- lgth r-max)) 
         (l-min (- l-max))
         (commands `(,(list 'moveto lgth 0)
                     ,(list 'curveto lgth (* r-max k) (+ (* r-max k) l-max) r-max l-max r-max)
                     ,(list 'lineto l-min r-max)
                     ,(list 'curveto (+ (* r-min k) l-min) r-max (+ l-min r-min) (* r-max k) (+ l-min r-min) 0)
                     ,(list 'curveto (- lgth) (* r-min k) (+ (* r-min k) l-min) r-min l-min r-min)
                     ,(list 'lineto l-max r-min)
                     ,(list 'curveto (+ (* r-max k) l-max) r-min lgth (* r-min k) lgth 0)
                     ,(list 'closepath)))
         (command-list (fold-right append '() commands)))
      ;; after Harm:
      (make-path-stencil
       command-list
       thickness 1 1 fill)))

#(define-public (capsule-stencil stencil thickness x-padding y-padding)
  "Add a capsule 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.5 x-length) )
         (y-radius (* 0.52 y-length) )
         (capsule (make-capsule-stencil x-radius y-radius thickness #f)))
    (ly:stencil-add
     stencil
     (ly:stencil-translate capsule
                           (cons
                            (interval-center x-ext)
                            (interval-center y-ext))))))

#(define-markup-command (capsule layout props arg)
  (markup?)
  #:category graphic
  #:properties ((thickness 1)
                (font-size 0)
                (x-padding 1)
                (y-padding .4))
"
@cindex drawing capsule around text

Draw a capsule 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 {
  \\capsule {
    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)))
    (capsule-stencil m th pad-x pad-y)))

%%%% Defs end %%%%%%%%%%

%%%% Tests:
\markup { \italic "Default:" \capsule "Hi" }
\markuplist {
  \vspace #1 \italic "With some overrides:" \vspace #.5
  \override #'(font-size . 3)
  \override #'(y-padding . 2)
  \override #'(x-padding . 2)
  \override #'(thickness . 5)
  \with-color #(rgb-color 1 0.3 0.2) 
  \capsule "This is an encapsulated text"
}