diff --git a/libmscore/layout.cpp b/libmscore/layout.cpp index 650a16e6ff04..99fb39b1e803 100644 --- a/libmscore/layout.cpp +++ b/libmscore/layout.cpp @@ -1940,67 +1940,78 @@ on first pass in updateNotes() and break occur */ //--------------------------------------------------------- // cautionaryWidth -// Compute the width difference of actual measure m -// and the width of m if it were the last measure in a -// staff. The reason for any difference are courtesy -// time signatures and key signatures. +// Compute the width of required courtesy of time signature +// and key signature elements if m were the last measure +// in a staff. +// Return hasCourtesy == true if courtesy elements are +// already present. The value is undefined if no +// courtesy elements are required. //--------------------------------------------------------- -qreal Score::cautionaryWidth(Measure* m) +qreal Score::cautionaryWidth(Measure* m, bool& hasCourtesy) { - qreal w = 0.0; + hasCourtesy = false; // for debugging if (m == 0) - return w; - Measure* nm = m ? m->nextMeasure() : 0; + return 0.0; + Measure* nm = m->nextMeasure(); if (nm == 0 || (m->sectionBreak() && _layoutMode != LayoutMode::FLOAT)) - return w; + return 0.0; - int tick = m->tick() + m->ticks(); + int tick = m->endTick(); // locate a time sig. in the next measure and, if found, // check if it has caut. sig. turned off Segment* ns = nm->findSegment(Segment::Type::TimeSig, tick); - TimeSig* ts = 0; - bool showCourtesy = styleB(StyleIdx::genCourtesyTimesig) && ns; - if (showCourtesy) { - ts = static_cast(ns->element(0)); - if (ts && !ts->showCourtesySig()) - showCourtesy = false; // this key change has court. sig turned off - } - Segment* s = m->findSegment(Segment::Type::TimeSigAnnounce, tick); + bool showCourtesy = styleB(StyleIdx::genCourtesyTimesig); - if (showCourtesy && !s) - w += ts->space().width(); - else if (!showCourtesy && s && s->element(0)) - w -= static_cast(s->element(0))->space().width(); + qreal w; + if (showCourtesy && ns) { + TimeSig* ts = static_cast(ns->element(0)); + if (ts && ts->showCourtesySig()) { + Segment* s = m->findSegment(Segment::Type::TimeSigAnnounce, tick); + if (s && s->element(0)) { + w = static_cast(s->element(0))->width(); + hasCourtesy = true; + } + else { + ts->layout(); + w = ts->width(); + hasCourtesy = false; + } + } + } + else + w = 0.0; // courtesy key signatures - qreal wwMin = 0.0; - qreal wwMax = 0.0; - int n = _staves.size(); - for (int staffIdx = 0; staffIdx < n; ++staffIdx) { - int track = staffIdx * VOICES; - ns = nm->findSegment(Segment::Type::KeySig, tick); - KeySig* ks = 0; - - showCourtesy = styleB(StyleIdx::genCourtesyKeysig) && ns; - if (showCourtesy) { - ks = static_cast(ns->element(track)); - if (ks && !ks->showCourtesy()) - showCourtesy = false; - } - Segment* s = m->findSegment(Segment::Type::KeySigAnnounce, tick); - - if (showCourtesy && !s && ks) - wwMax = qMax(wwMax, ks->space().width()); - else if (!showCourtesy && s && s->element(track)) - wwMin = qMin(wwMin, -static_cast(s->element(track))->space().width()); - } - if (wwMax > 0.0) - w += wwMax; - else - w += wwMin; + + showCourtesy = styleB(StyleIdx::genCourtesyKeysig); + ns = nm->findSegment(Segment::Type::KeySig, tick); + + qreal wwMax = 0.0; + if (showCourtesy && ns) { + for (int staffIdx = 0; staffIdx < _staves.size(); ++staffIdx) { + int track = staffIdx * VOICES; + + KeySig* nks = static_cast(ns->element(track)); + + if (nks && nks->showCourtesy() && !nks->generated()) { + Segment* s = m->findSegment(Segment::Type::KeySigAnnounce, tick); + + if (s && s->element(track)) { + wwMax = qMax(wwMax, s->element(track)->width()); + hasCourtesy = true; + } + else { + nks->layout(); + wwMax = qMax(wwMax, nks->width()); + hasCourtesy = false; + } + } + } + } + w += wwMax; return w; } @@ -2009,7 +2020,7 @@ qreal Score::cautionaryWidth(Measure* m) // return true if line continues //--------------------------------------------------------- -bool Score::layoutSystem(qreal& minWidth, qreal w, bool isFirstSystem, bool longName) +bool Score::layoutSystem(qreal& minWidth, qreal systemWidth, bool isFirstSystem, bool longName) { if (undoRedo()) // no change possible in this state return layoutSystem1(minWidth, isFirstSystem, longName); @@ -2024,7 +2035,6 @@ bool Score::layoutSystem(qreal& minWidth, qreal w, bool isFirstSystem, bool long qreal minMeasureWidth = point(styleS(StyleIdx::minMeasureWidth)); minWidth = system->leftMargin(); - qreal systemWidth = w; bool continueFlag = false; bool isFirstMeasure = true; Measure* firstMeasure = 0; @@ -2043,9 +2053,10 @@ bool Score::layoutSystem(qreal& minWidth, qreal w, bool isFirstSystem, bool long System* oldSystem = curMeasure->system(); curMeasure->setSystem(system); - qreal ww = 0.0; + bool hasCourtesy; qreal cautionaryW = 0.0; + qreal ww = 0.0; if (curMeasure->type() == Element::Type::HBOX) { ww = point(static_cast(curMeasure)->boxWidth()); @@ -2094,8 +2105,10 @@ bool Score::layoutSystem(qreal& minWidth, qreal w, bool isFirstSystem, bool long } } qreal stretch = m->userStretch() * measureSpacing; - cautionaryW = 0.0; // TODO: cautionaryWidth(m) * stretch; - ww *= stretch; + cautionaryW = cautionaryWidth(m, hasCourtesy); // * stretch; + ww *= stretch; + if (!hasCourtesy) + ww += cautionaryW; if (ww < minMeasureWidth) ww = minMeasureWidth; @@ -2104,7 +2117,7 @@ bool Score::layoutSystem(qreal& minWidth, qreal w, bool isFirstSystem, bool long // collect at least one measure bool empty = system->measures().isEmpty(); - if (!empty && (minWidth + ww + cautionaryW > systemWidth)) { + if (!empty && (minWidth + ww > systemWidth)) { curMeasure->setSystem(oldSystem); break; } @@ -2118,6 +2131,7 @@ bool Score::layoutSystem(qreal& minWidth, qreal w, bool isFirstSystem, bool long nt = curMeasure->nextMM() ? curMeasure->nextMM()->type() : Element::Type::INVALID; else nt = curMeasure->nextMeasureMM() ? curMeasure->nextMeasureMM()->type() : Element::Type::INVALID; + int n = styleI(StyleIdx::FixMeasureNumbers); bool pbreak; switch (_layoutMode) { @@ -2141,10 +2155,11 @@ bool Score::layoutSystem(qreal& minWidth, qreal w, bool isFirstSystem, bool long break; } curMeasure = nextMeasure; - if (minWidth + minMeasureWidth > systemWidth) + if (minWidth + minMeasureWidth > systemWidth) // small optimization break; // next measure will not fit minWidth += ww; + minWidth -= cautionaryW; } // @@ -2157,7 +2172,7 @@ bool Score::layoutSystem(qreal& minWidth, qreal w, bool isFirstSystem, bool long undoChangeProperty(system->measures().last(), P_ID::BREAK_HINT, true); } - if (!undoRedo() && firstMeasure && lastMeasure && firstMeasure != lastMeasure) + if (firstMeasure && lastMeasure && firstMeasure != lastMeasure) removeGeneratedElements(firstMeasure, lastMeasure); hideEmptyStaves(system, isFirstSystem); diff --git a/libmscore/measure.h b/libmscore/measure.h index d1fc5c23e0b5..a139c280001d 100644 --- a/libmscore/measure.h +++ b/libmscore/measure.h @@ -132,8 +132,8 @@ class Measure : public MeasureBase { qreal _userStretch; - mutable qreal _minWidth1; ///< minimal measure width without system header - mutable qreal _minWidth2; ///< minimal measure width with system header + mutable qreal _minWidth1; ///< minimal measure width, cached value + mutable qreal _minWidth2; ///< minimal measure width, cached value bool _irregular; ///< Irregular measure, do not count bool _breakMultiMeasureRest; ///< set by user @@ -196,8 +196,7 @@ class Measure : public MeasureBase { qreal minWidth1() const; qreal minWidth2() const; - void setMinWidth1(qreal w) { _minWidth1 = w; } - void setMinWidth2(qreal w) { _minWidth2 = w; } + bool systemHeader() const; void setDirty(); diff --git a/libmscore/score.h b/libmscore/score.h index 409b8a40cbc7..fb6c88851159 100644 --- a/libmscore/score.h +++ b/libmscore/score.h @@ -436,7 +436,7 @@ class Score : public QObject { void pasteChordRest(ChordRest* cr, int tick, const Interval&); void init(); void removeGeneratedElements(Measure* mb, Measure* end); - qreal cautionaryWidth(Measure* m); + qreal cautionaryWidth(Measure* m, bool& hasCourtesy); void createPlayEvents(); void selectSingle(Element* e, int staffIdx); diff --git a/mtest/guitarpro/keysig.gp4-ref.mscx b/mtest/guitarpro/keysig.gp4-ref.mscx index 720339cf3542..a0c347cd1863 100644 --- a/mtest/guitarpro/keysig.gp4-ref.mscx +++ b/mtest/guitarpro/keysig.gp4-ref.mscx @@ -1964,6 +1964,8 @@ + + diff --git a/mtest/guitarpro/keysig.gp5-ref.mscx b/mtest/guitarpro/keysig.gp5-ref.mscx index c1690cfb58a6..bcade8c52836 100644 --- a/mtest/guitarpro/keysig.gp5-ref.mscx +++ b/mtest/guitarpro/keysig.gp5-ref.mscx @@ -1944,6 +1944,8 @@ + +