--- /dev/null
+\header {
+
+ texidoc = "If @code{extraNatural} is set then keys that are not
+ altered farther away (eg from sharp to double sharp) are
+ cancelled. Otherwise only keys that does not accur in the new key
+ signature are cancelled." }
+
+
+\version "2.11.2"
+
+\paper {
+ ragged-right = ##t
+}
+{
+ \set Staff.extraNatural = ##f
+ \key fes \major r1
+ \key as \major r1_"No B-natural (#f)"
+ \set Staff.extraNatural = ##t
+ \key gis \major r1
+ \key b \major r1_"with F-natural (#t)"
+
+}
+
SCM last = get_property ("lastKeySignature");
SCM key = get_property ("keySignature");
+ bool extranatural = to_boolean(get_property("extraNatural"));
if ((to_boolean (get_property ("printKeyCancellation"))
|| key == SCM_EOL)
SCM *tail = &restore;
for (SCM s = last; scm_is_pair (s); s = scm_cdr (s))
{
- if (scm_assoc (scm_caar (s), key) == SCM_BOOL_F)
+ SCM new_alter_pair = scm_assoc (scm_caar (s), key);
+ int old_alter = scm_to_int (scm_cdar (s));
+ if (new_alter_pair == SCM_BOOL_F
+ || extranatural
+ && (scm_to_int(scm_cdr(new_alter_pair))-old_alter)*old_alter < 0)
{
- *tail = scm_acons (scm_caar (s),
- scm_from_int (0), *tail);
+ *tail = scm_cons (scm_car (s), *tail);
tail = SCM_CDRLOC (*tail);
}
}
cancellation_ = make_item ("KeyCancellation",
key_event_
? key_event_->self_scm () : SCM_EOL);
-
+
cancellation_->set_property ("alteration-alist", restore);
cancellation_->set_property ("c0-position",
get_property ("middleCPosition"));
/* read */
"createKeyOnClefChange "
"explicitKeySignatureVisibility "
+ "extraNatural "
"keyAlterationOrder "
"keySignature "
"keySignature "
/*
TODO: look this up. I'm not sure where the naturals ought to go.
+
+ COMMENT: Current implementation does not use the NATURAL_TOP_PITCH for anything,
+ always typesets naturals in the same place as the thing they cancel. -rz
*/
const int NATURAL_TOP_PITCH = 4;
if (scm_is_number (c0s))
c0p = scm_to_int (c0s);
+ /* Is this the correct way to determine this? -rz */
+ bool is_cancellation = me->name()=="KeyCancellation";
+
/*
SCM lists are stacks, so we work from right to left, ending with
the cancellation signature.
{
int alteration = scm_to_int (scm_cdar (s));
string font_char
- = Accidental_interface::get_fontcharname (style, alteration);
+ = Accidental_interface::get_fontcharname (style,
+ is_cancellation
+ ? 0
+ : alteration);
Stencil acc (fm->find_by_name ("accidentals." + font_char));
if (acc.is_empty ())
needed to prevent collisions.
*/
Real padding = 0.0;
- if (alteration == 0
+ if (is_cancellation
&& last_pos < pos + 2
&& last_pos > pos - 6)
padding = 0.3;