Skip to content

Commit cc3845f

Browse files
committed
Refactor naturals in key signatures
1 parent edf1a87 commit cc3845f

File tree

1 file changed

+42
-91
lines changed

1 file changed

+42
-91
lines changed

src/engraving/rendering/score/tlayout.cpp

Lines changed: 42 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -3602,6 +3602,7 @@ void TLayout::layoutKeySig(const KeySig* item, KeySig::LayoutData* ldata, const
36023602
// return;
36033603
// }
36043604

3605+
Segment* s = item->segment();
36053606
double spatium = item->spatium();
36063607
double step = spatium * (item->staff() ? item->staff()->staffTypeForElement(item)->lineDistance().val() * 0.5 : 0.5);
36073608

@@ -3617,11 +3618,10 @@ void TLayout::layoutKeySig(const KeySig* item, KeySig::LayoutData* ldata, const
36173618
if (item->staff()) {
36183619
// Look for a clef before the key signature at the same tick
36193620
Clef* c = nullptr;
3620-
if (item->segment()) {
3621-
for (Segment* seg = item->segment()->prev1(); !c && seg && seg->tick() == item->tick(); seg = seg->prev1()) {
3622-
const bool isClefSeg
3623-
= (seg->isClefType() || seg->isHeaderClefType()
3624-
|| (seg->isClefRepeatAnnounceType() && item->segment()->isKeySigRepeatAnnounceType()));
3621+
if (s) {
3622+
for (Segment* seg = s->prev1(); !c && seg && seg->tick() == item->tick(); seg = seg->prev1()) {
3623+
const bool isClefSeg = seg->isClefType() || seg->isHeaderClefType()
3624+
|| (seg->isClefRepeatAnnounceType() && s->isKeySigRepeatAnnounceType());
36253625
if (seg->enabled() && isClefSeg) {
36263626
c = toClef(seg->element(item->track()));
36273627
}
@@ -3631,7 +3631,7 @@ void TLayout::layoutKeySig(const KeySig* item, KeySig::LayoutData* ldata, const
36313631
clef = c->clefType();
36323632
} else {
36333633
// no clef found, so get the clef type from the clefs list, using the previous tick
3634-
clef = item->staff()->clef(item->tick() - Fraction::fromTicks(1));
3634+
clef = item->staff()->clef(item->tick() - Fraction::eps());
36353635
}
36363636
}
36373637

@@ -3705,62 +3705,41 @@ void TLayout::layoutKeySig(const KeySig* item, KeySig::LayoutData* ldata, const
37053705
}
37063706
}
37073707
} else {
3708-
int accidentals = 0, naturals = 0;
3709-
switch (std::abs(t1)) {
3710-
case 7: accidentals = 0x7f;
3711-
break;
3712-
case 6: accidentals = 0x3f;
3713-
break;
3714-
case 5: accidentals = 0x1f;
3715-
break;
3716-
case 4: accidentals = 0xf;
3717-
break;
3718-
case 3: accidentals = 0x7;
3719-
break;
3720-
case 2: accidentals = 0x3;
3721-
break;
3722-
case 1: accidentals = 0x1;
3723-
break;
3724-
case 0: accidentals = 0;
3725-
break;
3726-
default:
3727-
LOGD("illegal t1 key %d", t1);
3728-
break;
3729-
}
3730-
3731-
// manage display of naturals:
3732-
// naturals are shown if there is some natural AND prev. measure has no section break
3733-
// AND style says they are not off
3734-
// OR key sig is CMaj/Amin (in which case they are always shown)
3735-
3736-
bool naturalsOn = false;
3737-
Measure* prevMeasure = item->measure() ? item->measure()->prevMeasure() : 0;
3738-
3739-
// If we're not force hiding naturals (Continuous panel), use score style settings
3740-
if (!item->hideNaturals()) {
3741-
const bool newSection = (!item->segment()
3742-
|| (item->segment()->rtick().isZero() && (!prevMeasure || prevMeasure->sectionBreak()))
3743-
);
3744-
naturalsOn = !newSection && (conf.styleI(Sid::keySigNaturals) != int(KeySigNatural::NONE) || (t1 == 0));
3745-
}
3746-
3747-
// Don't repeat naturals if shown in courtesy
3748-
if (item->measure() && item->measure()->system() && item->measure()->isFirstInSystem()
3749-
&& prevMeasure && prevMeasure->findSegment(SegmentType::KeySigAnnounce, item->tick())
3750-
&& !item->segment()->isKeySigAnnounceType()) {
3751-
naturalsOn = false;
3752-
}
3753-
if (item->track() == muse::nidx) {
3754-
naturalsOn = false;
3755-
}
3708+
auto key2accidentals = [](int key) -> int {
3709+
switch (std::abs(key)) {
3710+
case 7: return 0x7f;
3711+
case 6: return 0x3f;
3712+
case 5: return 0x1f;
3713+
case 4: return 0xf;
3714+
case 3: return 0x7;
3715+
case 2: return 0x3;
3716+
case 1: return 0x1;
3717+
case 0: return 0;
3718+
default:
3719+
LOGD("illegal key %d", key);
3720+
return 0;
3721+
}
3722+
};
3723+
int accidentals = key2accidentals(t1);
3724+
int naturals = 0;
3725+
3726+
// Naturals are shown if:
3727+
// Key signature is courtesy, mid-measure or prev. measure has no section break and no courtesy keysig.
3728+
// AND we're not force hiding naturals (continuous mode)
3729+
// AND key sig is CMaj/Amin OR style says they are on
3730+
Measure* prevMeasure = item->measure() ? item->measure()->prevMeasureMM() : nullptr;
3731+
bool naturalsOn = !item->hideNaturals() && item->track() != muse::nidx
3732+
&& (conf.styleI(Sid::keySigNaturals) != int(KeySigNatural::NONE) || (t1 == 0))
3733+
&& ((s && (s->isType(SegmentType::CourtesyKeySigType) || !s->rtick().isZero()))
3734+
|| (prevMeasure && !prevMeasure->sectionBreak() && !prevMeasure->hasCourtesyKeySig()));
37563735

37573736
int coffset = 0;
3758-
Key t2 = Key::C;
3737+
Key t2 = Key::C;
37593738
if (naturalsOn) {
37603739
if (item->staff()) {
3761-
t2 = item->staff()->key(item->tick() - Fraction(1, 480 * 4));
3740+
t2 = item->staff()->key(item->tick() - Fraction::eps());
37623741
}
3763-
if (item->segment() && item->segment()->isType(SegmentType::KeySigStartRepeatAnnounce)) {
3742+
if (s && s->isType(SegmentType::KeySigStartRepeatAnnounce)) {
37643743
// Handle naturals in continuation courtesy
37653744
Segment* prevCourtesySeg
37663745
= prevMeasure ? prevMeasure->findSegmentR(SegmentType::KeySigRepeatAnnounce, prevMeasure->ticks()) : nullptr;
@@ -3770,27 +3749,7 @@ void TLayout::layoutKeySig(const KeySig* item, KeySig::LayoutData* ldata, const
37703749
if (t2 == Key::C) {
37713750
naturalsOn = false;
37723751
} else {
3773-
switch (std::abs(int(t2))) {
3774-
case 7: naturals = 0x7f;
3775-
break;
3776-
case 6: naturals = 0x3f;
3777-
break;
3778-
case 5: naturals = 0x1f;
3779-
break;
3780-
case 4: naturals = 0xf;
3781-
break;
3782-
case 3: naturals = 0x7;
3783-
break;
3784-
case 2: naturals = 0x3;
3785-
break;
3786-
case 1: naturals = 0x1;
3787-
break;
3788-
case 0: naturals = 0;
3789-
break;
3790-
default:
3791-
LOGD("illegal t2 key %d", int(t2));
3792-
break;
3793-
}
3752+
naturals = key2accidentals(int(t2));
37943753
// remove redundant naturals
37953754
if (!((t1 > 0) ^ (t2 > 0))) {
37963755
naturals &= ~accidentals;
@@ -3801,19 +3760,13 @@ void TLayout::layoutKeySig(const KeySig* item, KeySig::LayoutData* ldata, const
38013760
}
38023761
}
38033762

3804-
// naturals should go BEFORE accidentals if style says so
3805-
// OR going from sharps to flats or vice versa (i.e. t1 & t2 have opposite signs)
3806-
3807-
bool prefixNaturals = naturalsOn
3808-
&& (conf.styleI(Sid::keySigNaturals) == int(KeySigNatural::BEFORE)
3809-
|| t1 * int(t2) < 0);
3810-
3811-
// naturals should go AFTER accidentals if they should not go before!
3812-
bool suffixNaturals = naturalsOn && !prefixNaturals;
3763+
// Naturals should go BEFORE accidentals if style says so
3764+
// or going from sharps to flats or vice versa (i.e. t1 & t2 have opposite signs)
3765+
const bool natBefore = conf.styleI(Sid::keySigNaturals) == int(KeySigNatural::BEFORE) || t1 * int(t2) < 0;
38133766

38143767
const signed char* lines = ClefInfo::lines(clef);
38153768

3816-
if (prefixNaturals) {
3769+
if (naturalsOn && natBefore) {
38173770
for (int i = 0; i < 7; ++i) {
38183771
if (naturals & (1 << i)) {
38193772
keySigAddLayout(item, conf, SymId::accidentalNatural, lines[i + coffset], ldata);
@@ -3829,9 +3782,7 @@ void TLayout::layoutKeySig(const KeySig* item, KeySig::LayoutData* ldata, const
38293782
} else {
38303783
LOGD("illegal t1 key %d", t1);
38313784
}
3832-
3833-
// add suffixed naturals, if any
3834-
if (suffixNaturals) {
3785+
if (naturalsOn && !natBefore) {
38353786
for (int i = 0; i < 7; ++i) {
38363787
if (naturals & (1 << i)) {
38373788
keySigAddLayout(item, conf, SymId::accidentalNatural, lines[i + coffset], ldata);

0 commit comments

Comments
 (0)