Skip to content

Commit

Permalink
fix #36256
Browse files Browse the repository at this point in the history
  • Loading branch information
wschweer committed Oct 21, 2014
1 parent dc48ff5 commit c51599b
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 60 deletions.
125 changes: 70 additions & 55 deletions libmscore/layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<TimeSig*>(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<TimeSig*>(s->element(0))->space().width();
qreal w;
if (showCourtesy && ns) {
TimeSig* ts = static_cast<TimeSig*>(ns->element(0));
if (ts && ts->showCourtesySig()) {
Segment* s = m->findSegment(Segment::Type::TimeSigAnnounce, tick);
if (s && s->element(0)) {
w = static_cast<TimeSig*>(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<KeySig*>(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<KeySig*>(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<KeySig*>(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;
}

Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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<Box*>(curMeasure)->boxWidth());
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand All @@ -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) {
Expand All @@ -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;
}

//
Expand All @@ -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);
Expand Down
7 changes: 3 additions & 4 deletions libmscore/measure.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();

Expand Down
2 changes: 1 addition & 1 deletion libmscore/score.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions mtest/guitarpro/keysig.gp4-ref.mscx
Original file line number Diff line number Diff line change
Expand Up @@ -1964,6 +1964,8 @@
</System>
<System>
</System>
<System>
</System>
</Page>
</PageList>
<Part>
Expand Down
2 changes: 2 additions & 0 deletions mtest/guitarpro/keysig.gp5-ref.mscx
Original file line number Diff line number Diff line change
Expand Up @@ -1944,6 +1944,8 @@
</System>
<System>
</System>
<System>
</System>
</Page>
</PageList>
<Part>
Expand Down

0 comments on commit c51599b

Please sign in to comment.