[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: partially parenthizing a chord
From: |
Aaron Hill |
Subject: |
Re: partially parenthizing a chord |
Date: |
Sat, 08 Aug 2020 04:58:32 -0700 |
User-agent: |
Roundcube Webmail/1.4.2 |
On 2020-08-08 3:59 am, Werner LEMBERG wrote:
I would like to parenthesize the lower two notes of the chord.
There should be a single parenthesis to the left and right
(contrary to what `\parenthesize` does).
Does something like this help?
Yes, very nice!
(The logic here is for the engraver to generate a single
ParenthesesItem for any given timestep, while also modifying the
print routine to vertically scale the stencil to encapsulate the
elements. For demonstration purposes, I have \consisted the
engraver at the Voice level so that each one can have its own set of
parentheses.)
I have one wish to improve the appearance of the parentheses: Would it
be possible to scale the parentheses glyphs (i.e., scaling
`ParenthesisItem.font-size`) according to the `y-scale` value? Right
now, the parentheses are very thin horizontally.
This was a little tricky because there is a cart-and-horse problem. We
need to know how big the parens are to determine scaling, but that locks
in the font-size.
Here is a version that still relies on scaling, but does so in a
hopefully more visually appealing manner. Note that I am using the
square root of the y-scaling factor for the x-scaling factor, as 1:1
scaling made the parens too fat in my opinion.
%%%%
\version "2.20.0"
Grouping_Parenthesis_engraver =
#(lambda (context)
(let ((paren #f))
(define (process-item engraver grob)
(let* ((cause (ly:grob-property grob 'cause))
(paren? (and (ly:prob? cause)
(ly:event-property cause 'parenthesize #f))))
(if paren?
(begin
(or (ly:grob? paren)
(set! paren (ly:engraver-make-grob
engraver 'ParenthesesItem '())))
(ly:pointer-group-interface::add-grob
paren 'elements grob)))))
(define (finalize-paren engraver)
(if (ly:grob? paren)
(let* ((elems-array (ly:grob-object paren 'elements))
(elems-list (ly:grob-array->list elems-array))
(refp (ly:grob-common-refpoint-of-array
(car elems-list) elems-array Y)))
(ly:grob-set-parent! paren Y refp)
(ly:grob-set-property! paren 'font-size
(+ (ly:grob-property paren 'font-size 0)
(apply max
(map
(lambda (grob)
(ly:grob-property grob 'font-size 0))
elems-list))))
(set! paren #f))))
(make-engraver
(acknowledgers
((item-interface engraver grob source)
(process-item engraver grob)))
((process-acknowledged engraver)
(finalize-paren engraver)))))
%% Code copied from output-lib.scm and *modified*:
#(define (parenthesize-elements-scaled x y grob . rest)
(let* ((refp (if (null? rest)
grob
(car rest)))
(elts (ly:grob-array->list (ly:grob-object grob 'elements)))
(get-friends
(lambda (g)
(let ((syms (ly:grob-property g 'parenthesis-friends '()))
(get-friend (lambda (s)
(let ((f (ly:grob-object g s)))
(cond
((ly:grob? f) (list f))
((ly:grob-array? f)
(ly:grob-array->list f))
(else '()))))))
(apply append (map get-friend syms)))))
(friends (apply append elts (map get-friends elts)))
(x-ext (ly:relative-group-extent friends refp X))
(stencils (ly:grob-property grob 'stencils))
(lp (ly:stencil-scale (car stencils) x y))
(rp (ly:stencil-scale (cadr stencils) x y))
(padding (ly:grob-property grob 'padding 0.1)))
(ly:stencil-add
(ly:stencil-translate-axis lp (- (car x-ext) padding) X)
(ly:stencil-translate-axis rp (+ (cdr x-ext) padding) X))))
%% Code copied from output-lib.scm and *modified*:
#(define (parentheses-item::print-scaled me)
(let* ((elts (ly:grob-object me 'elements))
(y-ref (ly:grob-common-refpoint-of-array me elts Y))
(x-ref (ly:grob-common-refpoint-of-array me elts X))
(stencil (parenthesize-elements-scaled 1 1 me x-ref))
(sten-y-ext (ly:stencil-extent stencil Y))
(elt-y-ext (ly:relative-group-extent elts y-ref Y))
(y-center (interval-center elt-y-ext))
(y-scale (/ (interval-length elt-y-ext)
(interval-length sten-y-ext))))
(ly:stencil-translate
(parenthesize-elements-scaled
(sqrt y-scale) y-scale me x-ref)
(cons
(- (ly:grob-relative-coordinate me x-ref X))
(- y-center (ly:grob-relative-coordinate me y-ref Y))))))
\layout {
\context {
\Score
\remove "Parenthesis_engraver"
}
\context {
\Voice
\consists \Grouping_Parenthesis_engraver
\override ParenthesesItem.stencil =
#parentheses-item::print-scaled
}
}
soprano = \fixed c'' {
\override ParenthesesItem.color = #red
\parenthesize dis4
\parenthesize <b, e gis>2
<\parenthesize a, \parenthesize c ees>4
}
alto = \fixed c' {
\override ParenthesesItem.color = #blue
<cis \parenthesize e \parenthesize a>4
\parenthesize <d fis>2
\parenthesize c4
}
\new Staff \voices 1,2 << \soprano \\ \alto >>
%%%%
-- Aaron Hill
paren-engraver.cropped.png
Description: PNG image