@@ -1509,7 +1509,7 @@ double MeasureLayout::createEndBarLines(Measure* m, bool isLastMeasureInSystem,
15091509 visibleInt = 1 ;
15101510 }
15111511 } else {
1512- TLayout::layoutClef (clef, clef->mutldata ());
1512+ TLayout::layoutClef (clef, clef->mutldata (), ctx. conf () );
15131513 clefSeg->createShape (staffIdx);
15141514 visibleInt = 2 ;
15151515 }
@@ -1552,6 +1552,147 @@ double MeasureLayout::createEndBarLines(Measure* m, bool isLastMeasureInSystem,
15521552 return m->width () - oldWidth;
15531553}
15541554
1555+ Segment* MeasureLayout::addHeaderClef (Measure* m, bool isFirstClef, const Staff* staff, LayoutContext& ctx)
1556+ {
1557+ const staff_idx_t staffIdx = staff->idx ();
1558+ const track_idx_t track = staffIdx * VOICES;
1559+ Segment* cSegment = m->findFirstR (SegmentType::HeaderClef, Fraction (0 , 1 ));
1560+ const StaffType* staffType = staff->staffType (m->tick ());
1561+
1562+ const bool hideClef = staffType->isTabStaff () ? ctx.conf ().styleB (Sid::hideTabClefAfterFirst) : !ctx.conf ().styleB (Sid::genClef);
1563+
1564+ // find the clef type at the previous tick
1565+ ClefTypeList cl = staff->clefType (m->tick () - Fraction::fromTicks (1 ));
1566+ bool showCourtesy = true ;
1567+ Segment* s = nullptr ;
1568+ if (m->prevMeasure ()) {
1569+ // look for a clef change at the end of the previous measure
1570+ s = m->prevMeasure ()->findSegment (SegmentType::Clef, m->tick ());
1571+ } else if (m->isMMRest ()) {
1572+ // look for a header clef at the beginning of the first underlying measure
1573+ s = m->mmRestFirst ()->findFirstR (SegmentType::HeaderClef, Fraction (0 , 1 ));
1574+ }
1575+ if (s) {
1576+ Clef* c = toClef (s->element (track));
1577+ if (c) {
1578+ cl = c->clefTypeList ();
1579+ showCourtesy = c->showCourtesy ();
1580+ }
1581+ }
1582+ Clef* clef = nullptr ;
1583+ if (cSegment) {
1584+ clef = toClef (cSegment->element (track));
1585+ }
1586+ if (staff->staffTypeForElement (m)->genClef () && (isFirstClef || !hideClef)) {
1587+ if (!cSegment) {
1588+ cSegment = Factory::createSegment (m, SegmentType::HeaderClef, Fraction (0 , 1 ));
1589+ cSegment->setHeader (true );
1590+ m->add (cSegment);
1591+ }
1592+ if (!clef) {
1593+ //
1594+ // create missing clef
1595+ //
1596+ clef = Factory::createClef (cSegment);
1597+ clef->setTrack (track);
1598+ clef->setGenerated (true );
1599+ clef->setParent (cSegment);
1600+ clef->setIsHeader (true );
1601+ clef->setShowCourtesy (showCourtesy);
1602+ cSegment->add (clef);
1603+ }
1604+ if (clef->generated ()) {
1605+ clef->setClefType (cl);
1606+ }
1607+ clef->setSmall (false );
1608+ clef->mutldata ()->reset ();
1609+ TLayout::layoutClef (clef, clef->mutldata (), ctx.conf ());
1610+ cSegment->setEnabled (true );
1611+ } else if (clef) {
1612+ clef->parentItem ()->remove (clef);
1613+ if (clef->generated ()) {
1614+ delete clef;
1615+ }
1616+ }
1617+
1618+ return cSegment;
1619+ }
1620+
1621+ Segment* MeasureLayout::addHeaderKeySig (Measure* m, bool isFirstKeysig, const Staff* staff, LayoutContext& ctx)
1622+ {
1623+ const staff_idx_t staffIdx = staff->idx ();
1624+ const track_idx_t track = staffIdx * VOICES;
1625+ Segment* kSegment = m->findFirstR (SegmentType::KeySig, Fraction (0 , 1 ));
1626+ // If we need a Key::C KeySig (which would be invisible) and there is
1627+ // a courtesy key sig, don’t create it and switch generated flags.
1628+ // This avoids creating an invisible KeySig which can distort layout.
1629+
1630+ KeySigEvent keyIdx = staff->keySigEvent (m->tick ());
1631+ KeySig* ksAnnounce = 0 ;
1632+ if ((isFirstKeysig || ctx.conf ().styleB (Sid::genKeysig)) && (keyIdx.key () == Key::C)) {
1633+ Measure* pm = m->prevMeasure ();
1634+ if (pm && pm->hasCourtesyKeySig ()) {
1635+ Segment* ks = pm->first (SegmentType::KeySigAnnounce);
1636+ if (ks) {
1637+ ksAnnounce = toKeySig (ks->element (track));
1638+ if (ksAnnounce) {
1639+ isFirstKeysig = false ;
1640+ // if (keysig) {
1641+ // ksAnnounce->setGenerated(false);
1642+ // TODO keysig->setGenerated(true);
1643+ // }
1644+ }
1645+ }
1646+ }
1647+ }
1648+
1649+ bool isPitchedStaff = staff->isPitchedStaff (m->tick ());
1650+
1651+ KeySig* keysig = nullptr ;
1652+ if (kSegment ) {
1653+ keysig = toKeySig (kSegment ->element (track));
1654+ }
1655+ // keep key sigs in TABs: TABs themselves should hide them
1656+ if ((isFirstKeysig || ctx.conf ().styleB (Sid::genKeysig)) && isPitchedStaff) {
1657+ if (!kSegment ) {
1658+ kSegment = Factory::createSegment (m, SegmentType::KeySig, Fraction (0 , 1 ));
1659+ kSegment ->setHeader (true );
1660+ m->add (kSegment );
1661+ }
1662+ if (!keysig) {
1663+ //
1664+ // create missing key signature
1665+ //
1666+ keysig = Factory::createKeySig (kSegment );
1667+ keysig->setTrack (track);
1668+ keysig->setGenerated (true );
1669+ keysig->setParent (kSegment );
1670+ kSegment ->add (keysig);
1671+ }
1672+ keysig->setKeySigEvent (keyIdx);
1673+ keysig->mutldata ()->reset ();
1674+ TLayout::layoutKeySig (keysig, keysig->mutldata (), ctx.conf ());
1675+ kSegment ->setEnabled (true );
1676+ } else if (keysig && isPitchedStaff) {
1677+ // do not remove user modified keysigs
1678+ bool remove = true ;
1679+ EngravingItem* e = kSegment ->element (staffIdx * VOICES);
1680+ Key key = staff->key (m->tick ());
1681+ if ((e && !e->generated ()) || (key != keyIdx.key ())) {
1682+ remove = false ;
1683+ }
1684+
1685+ if (remove) {
1686+ keysig->parentItem ()->remove (keysig);
1687+ if (keysig->generated ()) {
1688+ delete keysig;
1689+ }
1690+ }
1691+ }
1692+
1693+ return kSegment ;
1694+ }
1695+
15551696// -------------------------------------------------------------------
15561697// addSystemHeader
15571698// / Add elements to make this measure suitable as the first measure
@@ -1563,145 +1704,57 @@ double MeasureLayout::createEndBarLines(Measure* m, bool isLastMeasureInSystem,
15631704void MeasureLayout::addSystemHeader (Measure* m, bool isFirstSystem, LayoutContext& ctx)
15641705{
15651706 int staffIdx = 0 ;
1566- Segment* kSegment = m-> findFirstR (SegmentType::KeySig, Fraction ( 0 , 1 )) ;
1567- Segment* cSegment = m-> findFirstR (SegmentType::HeaderClef, Fraction ( 0 , 1 )) ;
1707+ Segment* kSegment = nullptr ;
1708+ Segment* cSegment = nullptr ;
15681709
15691710 for (const Staff* staff : ctx.dom ().staves ()) {
15701711 const int track = staffIdx * VOICES;
15711712
1572- if (isFirstSystem || ctx.conf ().styleB (Sid::genClef)) {
1573- // find the clef type at the previous tick
1574- ClefTypeList cl = staff->clefType (m->tick () - Fraction::fromTicks (1 ));
1575- bool showCourtesy = true ;
1576- Segment* s = nullptr ;
1577- if (m->prevMeasure ()) {
1578- // look for a clef change at the end of the previous measure
1579- s = m->prevMeasure ()->findSegment (SegmentType::Clef, m->tick ());
1580- } else if (m->isMMRest ()) {
1581- // look for a header clef at the beginning of the first underlying measure
1582- s = m->mmRestFirst ()->findFirstR (SegmentType::HeaderClef, Fraction (0 , 1 ));
1583- }
1584- if (s) {
1585- Clef* c = toClef (s->element (track));
1586- if (c) {
1587- cl = c->clefTypeList ();
1588- showCourtesy = c->showCourtesy ();
1589- }
1590- }
1591- Clef* clef = nullptr ;
1592- if (!cSegment) {
1593- cSegment = Factory::createSegment (m, SegmentType::HeaderClef, Fraction (0 , 1 ));
1594- cSegment->setHeader (true );
1595- m->add (cSegment);
1596- } else {
1597- clef = toClef (cSegment->element (track));
1598- }
1599- if (staff->staffTypeForElement (m)->genClef ()) {
1600- if (!clef) {
1601- //
1602- // create missing clef
1603- //
1604- clef = Factory::createClef (cSegment);
1605- clef->setTrack (track);
1606- clef->setGenerated (true );
1607- clef->setParent (cSegment);
1608- clef->setIsHeader (true );
1609- clef->setShowCourtesy (showCourtesy);
1610- cSegment->add (clef);
1611- }
1612- if (clef->generated ()) {
1613- clef->setClefType (cl);
1614- }
1615- clef->setSmall (false );
1616- clef->mutldata ()->reset ();
1617- TLayout::layoutClef (clef, clef->mutldata ());
1618- } else if (clef) {
1619- clef->parentItem ()->remove (clef);
1620- if (clef->generated ()) {
1621- delete clef;
1713+ // Check if this is the first VISIBLE appearance
1714+ bool isFirstClef = true ;
1715+ bool isFirstKeySig = true ;
1716+ if (!isFirstSystem) {
1717+ const Fraction clefTick = staff->currentClefTick (m->tick ());
1718+ const Fraction keySigTick = staff->currentKeyTick (m->tick ());
1719+ // Get first measure whether MMR or not
1720+ Measure* searchMeasure = ctx.mutDom ().tick2measure (std::min (clefTick, keySigTick));
1721+ searchMeasure = searchMeasure->hasMMRest ()
1722+ && ctx.conf ().styleB (Sid::createMultiMeasureRests) ? searchMeasure->mmRest () : searchMeasure;
1723+ while (searchMeasure->tick () < m->tick () && (isFirstClef || isFirstKeySig)) {
1724+ const System* sys = searchMeasure->system ();
1725+ if (isFirstClef && searchMeasure->tick () >= clefTick) {
1726+ // Need to check previous measure for clef change if one not found in this measure
1727+ Segment* clefSeg = searchMeasure->findFirstR (SegmentType::Clef | SegmentType::HeaderClef, Fraction (0 , 0 ));
1728+ if (Measure* prevMeas = searchMeasure->prevMeasure (); !clefSeg) {
1729+ clefSeg = prevMeas->findSegment (SegmentType::Clef, m->tick ());
1730+ }
1731+ if (clefSeg && clefSeg->enabled ()) {
1732+ const Clef* c = toClef (clefSeg->element (track));
1733+ if (c && sys && sys->staff (staffIdx)->show ()) {
1734+ isFirstClef = false ;
1735+ }
1736+ }
16221737 }
1623- }
1624- // cSegment->createShape(staffIdx);
1625- cSegment->setEnabled (true );
1626- } else {
1627- if (cSegment) {
1628- cSegment->setEnabled (false );
1629- }
1630- }
1631-
1632- // keep key sigs in TABs: TABs themselves should hide them
1633- bool needKeysig = isFirstSystem || ctx.conf ().styleB (Sid::genKeysig);
1634-
1635- // If we need a Key::C KeySig (which would be invisible) and there is
1636- // a courtesy key sig, don’t create it and switch generated flags.
1637- // This avoids creating an invisible KeySig which can distort layout.
1638-
1639- KeySigEvent keyIdx = staff->keySigEvent (m->tick ());
1640- KeySig* ksAnnounce = 0 ;
1641- if (needKeysig && (keyIdx.key () == Key::C)) {
1642- Measure* pm = m->prevMeasure ();
1643- if (pm && pm->hasCourtesyKeySig ()) {
1644- Segment* ks = pm->first (SegmentType::KeySigAnnounce);
1645- if (ks) {
1646- ksAnnounce = toKeySig (ks->element (track));
1647- if (ksAnnounce) {
1648- needKeysig = false ;
1649- // if (keysig) {
1650- // ksAnnounce->setGenerated(false);
1651- // TODO keysig->setGenerated(true);
1652- // }
1738+ if (isFirstKeySig && searchMeasure->tick () >= keySigTick) {
1739+ const Segment* ksSeg = searchMeasure->findSegment (SegmentType::KeySig, searchMeasure->tick ());
1740+ if (ksSeg && ksSeg->enabled ()) {
1741+ const KeySig* ks = toKeySig (ksSeg->element (track));
1742+ if (ks && sys && sys->staff (staffIdx)->show ()) {
1743+ isFirstKeySig = false ;
1744+ }
16531745 }
16541746 }
1747+ // Get next measure, factoring in MMRs
1748+ searchMeasure = searchMeasure->nextMeasure ();
1749+ if (searchMeasure && searchMeasure->hasMMRest ()) {
1750+ searchMeasure = searchMeasure->mmRest ();
1751+ }
16551752 }
16561753 }
16571754
1658- bool isPitchedStaff = staff-> isPitchedStaff (m-> tick () );
1755+ cSegment = addHeaderClef (m, isFirstSystem || isFirstClef, staff, ctx );
16591756
1660- if (needKeysig && isPitchedStaff) {
1661- KeySig* keysig;
1662- if (!kSegment ) {
1663- kSegment = Factory::createSegment (m, SegmentType::KeySig, Fraction (0 , 1 ));
1664- kSegment ->setHeader (true );
1665- m->add (kSegment );
1666- keysig = 0 ;
1667- } else {
1668- keysig = toKeySig (kSegment ->element (track));
1669- }
1670- if (!keysig) {
1671- //
1672- // create missing key signature
1673- //
1674- keysig = Factory::createKeySig (kSegment );
1675- keysig->setTrack (track);
1676- keysig->setGenerated (true );
1677- keysig->setParent (kSegment );
1678- kSegment ->add (keysig);
1679- }
1680- keysig->setKeySigEvent (keyIdx);
1681- TLayout::layoutKeySig (keysig, keysig->mutldata (), ctx.conf ());
1682- // kSegment->createShape(staffIdx);
1683- kSegment ->setEnabled (true );
1684- } else if (kSegment && isPitchedStaff) {
1685- // do not disable user modified keysigs
1686- bool disable = true ;
1687- for (size_t i = 0 ; i < ctx.dom ().nstaves (); ++i) {
1688- EngravingItem* e = kSegment ->element (i * VOICES);
1689- Key key = ctx.dom ().staff (i)->key (m->tick ());
1690- if ((e && !e->generated ()) || (key != keyIdx.key ())) {
1691- disable = false ;
1692- }
1693- }
1694-
1695- if (disable) {
1696- kSegment ->setEnabled (false );
1697- } else {
1698- EngravingItem* e = kSegment ->element (track);
1699- if (e && e->isKeySig ()) {
1700- KeySig* keysig = toKeySig (e);
1701- TLayout::layoutKeySig (keysig, keysig->mutldata (), ctx.conf ());
1702- }
1703- }
1704- }
1757+ kSegment = addHeaderKeySig (m, isFirstSystem || isFirstKeySig, staff, ctx);
17051758
17061759 ++staffIdx;
17071760 }
0 commit comments