From 1218da693e22c42b9f78074ad4d8f4a9151855c4 Mon Sep 17 00:00:00 2001 From: Keith OHara Date: Wed, 15 Aug 2012 23:01:36 -0700 Subject: [PATCH] Properties to control placement of accidentals in KeySignatures --- Documentation/changes.tely | 11 ++++- Documentation/notation/pitches.itely | 32 +++++++++++++- input/regression/key-clefs.ly | 18 ++++++-- lily/key-signature-interface.cc | 30 ++++++++----- scm/define-grob-properties.scm | 16 +++++++ scm/define-grobs.scm | 4 ++ scm/output-lib.scm | 66 +++++++++++----------------- 7 files changed, 119 insertions(+), 58 deletions(-) diff --git a/Documentation/changes.tely b/Documentation/changes.tely index e8b385f6fd..06a1378b69 100644 --- a/Documentation/changes.tely +++ b/Documentation/changes.tely @@ -62,7 +62,16 @@ which scares away people. @end ignore @item -[no changes yet] +Accidentals in the key signature may be printed in octaves other +than their traditional positions, or in multiple octaves. +@lilypond[quote,relative=0] +\override Staff.KeySignature #'flat-positions = #'((-5 . 5)) +\override Staff.KeyCancellation #'flat-positions = #'((-5 . 5)) +\clef bass \key es\major es g bes d +\clef treble \bar "||" \key es\major es g bes d +\override Staff.KeySignature #'sharp-positions = #'(2) +\bar "||" \key d\major b fis b2 +@end lilypond @end itemize diff --git a/Documentation/notation/pitches.itely b/Documentation/notation/pitches.itely index c9e99f5eb7..860babdc82 100644 --- a/Documentation/notation/pitches.itely +++ b/Documentation/notation/pitches.itely @@ -1250,6 +1250,37 @@ f fis @end lilypond +Additional modes can be defined, by listing the alterations +for each scale step when the mode starts on C. + +@lilypond[verbatim,quote] +freygish = #`((0 . ,NATURAL) (1 . ,FLAT) (2 . ,NATURAL) + (3 . ,NATURAL) (4 . ,NATURAL) (5 . ,FLAT) (6 . ,FLAT)) + +\relative c' { + \key c\freygish c4 des e f + \bar "||" \key d\freygish d es fis g +} +@end lilypond + +Accidentals in the key signature may be printed in octaves other +than their traditional positions, or in multiple octaves, by +using the @code{flat-positions} and @code{sharp-positions} +properties of @code{KeySignature}. Entries in these properties +specify the range of staff-positions where accidentals will be +printed. If a single position is specified in an entry, the +accidentals are placed within the octave ending at that staff +position. + +@lilypond[verbatim, quote,relative=0] +\override Staff.KeySignature #'flat-positions = #'((-5 . 5)) +\override Staff.KeyCancellation #'flat-positions = #'((-5 . 5)) +\clef bass \key es\major es g bes d +\clef treble \bar "||" \key es\major es g bes d + +\override Staff.KeySignature #'sharp-positions = #'(2) +\bar "||" \key b\major b fis b2 +@end lilypond @snippets @@ -1276,7 +1307,6 @@ Internals Reference: @rinternals{Key_performer}, @rinternals{KeyCancellation}, @rinternals{KeySignature}, -@rinternals{key-cancellation-interface}, @rinternals{key-signature-interface}. diff --git a/input/regression/key-clefs.ly b/input/regression/key-clefs.ly index 44c499e277..58534f078c 100644 --- a/input/regression/key-clefs.ly +++ b/input/regression/key-clefs.ly @@ -1,7 +1,8 @@ \version "2.16.0" \header { texidoc = "Each clef has its own accidental placing -rules. "} +rules, which can be adjusted using @code{sharp-positions} +and @code{flat-positions}." } #(set-global-staff-size 16) @@ -23,7 +24,18 @@ rules. "} \key cis \major cis \key ces \major ces \clef bass \key cis \major cis \key ces \major ces + \break R1 + \tempo "B-sharp on top" + \override Staff.KeySignature #'sharp-positions = #'(6 0 1 2 3 4 5) + \override Staff.KeyCancellation #'sharp-positions = #'(6 0 1 2 3 4 5) + \key cis \major R + \tempo "Flats throughout the staff" + \override Staff.KeySignature #'flat-positions = #'((-5 . 5)) + \override Staff.KeyCancellation #'flat-positions = #'((-5 . 5)) + \key ces \major R + \clef tenor + \key cis \major cis \break \key ces \major ces + \clef treble + \key cis \major cis \key ces \major ces } - - diff --git a/lily/key-signature-interface.cc b/lily/key-signature-interface.cc index a7b65530fc..fb691c00d8 100644 --- a/lily/key-signature-interface.cc +++ b/lily/key-signature-interface.cc @@ -58,7 +58,7 @@ Key_signature_interface::print (SCM smob) the cancellation signature. */ - int last_pos = -1000; + Slice pos, overlapping_pos; SCM last_glyph_name = SCM_BOOL_F; SCM padding_pairs = me->get_property ("padding-pairs"); @@ -87,13 +87,17 @@ Key_signature_interface::print (SCM smob) me->warning (_ ("alteration not found")); else { - SCM what = scm_caar (s); - - SCM proc = ly_lily_module_constant ("key-signature-interface::alteration-position"); - - int pos = scm_to_int (scm_call_3 (proc, what, scm_cdar (s), c0s)); - acc.translate_axis (pos * inter, Y_AXIS); - + SCM proc = ly_lily_module_constant ("key-signature-interface::alteration-positions"); + + pos.set_empty (); + Stencil column; + for (SCM pos_list = scm_call_3 (proc, scm_car (s), c0s, smob); + scm_is_pair (pos_list); pos_list = scm_cdr (pos_list)) + { + int p = scm_to_int (scm_car (pos_list)); + pos.add_point (p); + column.add_stencil (acc.translated (Offset (0, p * inter))); + } /* The natural sign (unlike flat & sharp) has vertical edges on both sides. A little padding is @@ -106,13 +110,13 @@ Key_signature_interface::print (SCM smob) if (scm_is_pair (handle)) padding = robust_scm2double (scm_cdr (handle), 0.0); else if (glyph_name == "accidentals.natural" - && last_pos < pos + 2 - && last_pos > pos - 6) + && !intersection (overlapping_pos, pos).is_empty ()) padding += 0.3; - mol.add_at_edge (X_AXIS, LEFT, acc, padding); + mol.add_at_edge (X_AXIS, LEFT, column, padding); - last_pos = pos; + pos.widen (4); + overlapping_pos = pos + 2; last_glyph_name = glyph_name_scm; } } @@ -129,6 +133,8 @@ ADD_INTERFACE (Key_signature_interface, "alteration-alist " "c0-position " "glyph-name-alist " + "flat-positions " + "sharp-positions " "padding " "padding-pairs " ); diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index 25ad864833..a1417729e9 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -286,6 +286,14 @@ Y@tie{}dimension by this much.") ;; f ;; (flag-count ,number? "The number of tremolo beams.") + (flat-positions ,list? "Flats in key signatures are placed +within the specified ranges of staff-positions. The general form +is a list of pairs, with one pair for each type of clef, in order +of the staff-position at which each clef places C: +@code{(alto treble tenor soprano baritone mezzosoprano bass)}. +If the list contains a single element it applies for all clefs. +A single number in place of a pair sets accidentals within the octave +ending at that staff-position.") (font-encoding ,symbol? "The font encoding is the broadest category for selecting a font. Currently, only lilypond's system fonts (Emmentaler) are using this property. Available @@ -761,6 +769,14 @@ value @w{@code{-1}} means left aligned, @code{0}@tie{}centered, and values may also be specified.") (self-alignment-Y ,number? "Like @code{self-alignment-X} but for the Y@tie{}axis.") + (sharp-positions ,list? "Sharps in key signatures are placed +within the specified ranges of staff-positions. The general form +is a list of pairs, with one pair for each type of clef, in order +of the staff-position at which each clef places C: +@code{(alto treble tenor soprano baritone mezzosoprano bass)}. +If the list contains a single element it applies for all clefs. +A single number in place of a pair sets accidentals within the octave +ending at that staff-position.") (shorten-pair ,number-pair? "The lengths to shorten a text-spanner on both sides, for example a pedal bracket. Positive values shorten the text-spanner, while negative values lengthen it.") diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index c18116db87..9da27ed7c1 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -1112,6 +1112,8 @@ (break-visibility . ,begin-of-line-invisible) (glyph-name-alist . ,cancellation-glyph-name-alist) (non-musical . #t) + (flat-positions . (2 3 4 2 1 2 1)) + (sharp-positions . (4 5 4 2 3 2 3)) (space-alist . ( (time-signature . (extra-space . 1.25)) (staff-bar . (extra-space . 0.6)) @@ -1142,6 +1144,8 @@ (break-visibility . ,begin-of-line-visible) (glyph-name-alist . ,standard-alteration-glyph-name-alist) (non-musical . #t) + (flat-positions . (2 3 4 2 1 2 1)) + (sharp-positions . (4 5 4 2 3 2 3)) (space-alist . ( (time-signature . (extra-space . 1.15)) (staff-bar . (extra-space . 1.1)) diff --git a/scm/output-lib.scm b/scm/output-lib.scm index 5b7d441952..3ced3354cd 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -507,47 +507,31 @@ and duration-log @var{log}." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; key signature -(define-public (key-signature-interface::alteration-position step alter - c0-position) - ;; TODO: memoize - this is mostly constant. - - ;; fes, ges, as and bes typeset in lower octave - (define FLAT_TOP_PITCH 2) - - ;; ais and bis typeset in lower octave - (define SHARP_TOP_PITCH 4) - - (if (pair? step) - (+ (cdr step) (* (car step) 7) c0-position) - (let* ((from-bottom-pos (modulo (+ 4 49 c0-position) 7)) - (p step) - (c0 (- from-bottom-pos 4))) - - (if - (or (and (< alter 0) - (or (> p FLAT_TOP_PITCH) (> (+ p c0) 4)) (> (+ p c0) 1)) - (and (> alter 0) - (or (> p SHARP_TOP_PITCH) (> (+ p c0) 5)) (> (+ p c0) 2))) - - ;; Typeset below c_position - (set! p (- p 7))) - - ;; Provide for the four cases in which there's a glitch - ;; it's a hack, but probably not worth - ;; the effort of finding a nicer solution. - ;; --dl. - (cond - ((and (= c0 2) (= p 3) (> alter 0)) - (set! p (- p 7))) - ((and (= c0 -3) (= p -1) (> alter 0)) - (set! p (+ p 7))) - ((and (= c0 -4) (= p -1) (< alter 0)) - (set! p (+ p 7))) - ((and (= c0 -2) (= p -3) (< alter 0)) - (set! p (+ p 7)))) - - (+ c0 p)))) - +(define-public (key-signature-interface::alteration-positions + entry c0-position grob) + (let ((step (car entry)) + (alter (cdr entry))) + (if (pair? step) + (list (+ (cdr step) (* (car step) 7) c0-position)) + (let* ((c-position (modulo c0-position 7)) + (positions + (if (< alter 0) + ;; See (flat|sharp)-positions in define-grob-properties.scm + (ly:grob-property grob 'flat-positions '(3)) + (ly:grob-property grob 'sharp-positions '(3)))) + (p (list-ref positions + (if (< c-position (length positions)) + c-position 0))) + (max-position (if (pair? p) (cdr p) p)) + (min-position (if (pair? p) (car p) (- max-position 6))) + (first-position (+ (modulo (- (+ c-position step) + min-position) + 7) + min-position))) + (define (prepend x l) (if (> x max-position) + l + (prepend (+ x 7) (cons x l)))) + (prepend first-position '()))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; annotations -- 2.39.2