Skip to content

Commit

Permalink
fix #279464 Error opening file created in 2.3.2
Browse files Browse the repository at this point in the history
Tuplets can be layouted only if beams on the tuplet chord/rests are layouted.
Cross beams complicate this a lot as a cross beam can only be layouted after staff
distances are fixed.
  • Loading branch information
wschweer committed Dec 9, 2018
1 parent a9203cb commit d5298f5
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 51 deletions.
2 changes: 1 addition & 1 deletion libmscore/beam.h
Expand Up @@ -96,7 +96,7 @@ class Beam final : public Element {

virtual void reset() override;

System* system() const { return (System*)parent(); }
System* system() const { return toSystem(parent()); }

void layout1();
void layoutGraceNotes();
Expand Down
74 changes: 31 additions & 43 deletions libmscore/layout.cpp
Expand Up @@ -2610,17 +2610,12 @@ void Score::getNextMeasure(LayoutContext& lc)

bool isTopBeam(ChordRest* cr)
{
if (cr->beam() && cr->beam()->elements().front() == cr) {
Beam* b = cr->beam();
bool movedUp = true;
Beam* b = cr->beam();
if (b && !b->cross() && b->elements().front() == cr) {
for (ChordRest* cr1 : b->elements()) {
if (cr1->staffMove() >= 0) {
movedUp = false;
break;
}
if (cr1->staffMove() >= 0)
return true;
}
if (!b->cross() && !movedUp)
return true;
}
return false;
}
Expand All @@ -2631,20 +2626,9 @@ bool isTopBeam(ChordRest* cr)

bool notTopBeam(ChordRest* cr)
{
if (cr->beam() && cr->beam()->elements().front() == cr) {
Beam* b = cr->beam();
if (b->cross())
return true;
bool movedUp = true;
for (ChordRest* cr1 : b->elements()) {
if (cr1->staffMove() >= 0) {
movedUp = false;
break;
}
}
if (movedUp)
return true;
}
Beam* b = cr->beam();
if (b)
return !isTopBeam(cr);
return false;
}

Expand Down Expand Up @@ -3304,26 +3288,24 @@ System* Score::collectSystem(LayoutContext& lc)

for (Segment* s : sl) {
for (Element* e : s->elist()) {
if (!e || !score()->staff(e->staffIdx())->show())
if (!e || !e->isChordRest() || !score()->staff(e->staffIdx())->show())
continue;
if (e->isChordRest()) {
ChordRest* cr = toChordRest(e);
if (isTopBeam(cr)) {
cr->beam()->layout();
cr->beam()->addSkyline(system->staff(cr->beam()->staffIdx())->skyline());

// layout fingering a second time (first layout called in note->layout2())
// to finally place fingerings above or below a beam

if (e->isChord()) {
for (Note* note : toChord(e)->notes()) {
for (Element* e : note->el()) {
if (e->isFingering())
e->layout();
}
ChordRest* cr = toChordRest(e);
if (isTopBeam(cr)) {
cr->beam()->layout();
cr->beam()->addSkyline(system->staff(cr->beam()->staffIdx())->skyline());

// layout fingering a second time (first layout called in note->layout2())
// to finally place fingerings above or below a beam

if (e->isChord()) {
for (Note* note : toChord(e)->notes()) {
for (Element* e : note->el()) {
if (e->isFingering())
e->layout();
}
}
}
}
}
}
}
Expand All @@ -3336,14 +3318,18 @@ System* Score::collectSystem(LayoutContext& lc)
for (Element* e : s->elist()) {
if (!e || !e->isChordRest() || !score()->staff(e->staffIdx())->show())
continue;
if (notTopBeam(toChordRest(e)))
ChordRest* cr = toChordRest(e);
// sanity check
if (cr->beam() && !isTopBeam(cr))
continue;
if (notTopBeam(cr))
continue;
DurationElement* de = toChordRest(e);
DurationElement* de = cr;
while (de->tuplet() && de->tuplet()->elements().front() == de) {
Tuplet* t = de->tuplet();
t->layout();
system->staff(t->staffIdx())->skyline().add(t->shape().translated(t->pos() + t->measure()->pos()));
de = de->tuplet();
de = t;
}
}
}
Expand Down Expand Up @@ -3788,6 +3774,8 @@ void Score::doLayoutRange(int stick, int etick)
pages().clear();
return;
}
// if (!_systems.isEmpty())
// return;
// qDebug("%p %d-%d %s systems %d", this, stick, etick, isMaster() ? "Master" : "Part", int(_systems.size()));
bool layoutAll = stick <= 0 && (etick < 0 || etick >= last()->endTick());
if (stick < 0)
Expand Down
2 changes: 2 additions & 0 deletions libmscore/layout.h
Expand Up @@ -69,6 +69,8 @@ enum class VerticalAlignRange {
SEGMENT, MEASURE, SYSTEM
};

extern bool isTopBeam(ChordRest* cr);
extern bool notTopBeam(ChordRest* cr);

} // namespace Ms
#endif
Expand Down
2 changes: 0 additions & 2 deletions libmscore/layoutlinear.cpp
Expand Up @@ -40,8 +40,6 @@

namespace Ms {

extern bool isTopBeam(ChordRest* cr);
extern bool notTopBeam(ChordRest* cr);
extern void layoutTies(Chord* ch, System* system, int stick);
extern void layoutDrumsetChord(Chord* c, const Drumset* drumset, const StaffType* st, qreal spatium);

Expand Down
5 changes: 4 additions & 1 deletion libmscore/textlinebase.cpp
Expand Up @@ -232,8 +232,11 @@ void TextLineBaseSegment::layout()
qreal l = 0.0;
if (!_text->empty()) {
qreal textlineTextDistance = _spatium * .5;
if (((isSingleType() || isBeginType()) && (tl->beginTextPlace() == PlaceText::LEFT || tl->beginTextPlace() == PlaceText::AUTO)) || ((isMiddleType() || isEndType()) && (tl->continueTextPlace() == PlaceText::LEFT)))
if (((isSingleType() || isBeginType())
&& (tl->beginTextPlace() == PlaceText::LEFT || tl->beginTextPlace() == PlaceText::AUTO))
|| ((isMiddleType() || isEndType()) && (tl->continueTextPlace() == PlaceText::LEFT))) {
l = _text->pos().x() + _text->bbox().width() + textlineTextDistance;
}
qreal h = _text->height();
if (textLineBase()->beginTextPlace() == PlaceText::ABOVE)
y1 = qMin(y1, -h);
Expand Down
4 changes: 3 additions & 1 deletion libmscore/tuplet.cpp
Expand Up @@ -1133,7 +1133,9 @@ void Tuplet::sanitizeTuplet()
if (TDuration::isValid(fbl)) {
setDuration(testDuration);
setBaseLen(fbl);
qDebug("Tuplet %p sanitized",this);
qDebug("Tuplet %p sanitized duration %d/%d baseLen %d/%d",this,
testDuration.numerator(), testDuration.denominator(),
1, fbl.denominator());
}
else {
qDebug("Impossible to sanitize the tuplet");
Expand Down
5 changes: 2 additions & 3 deletions libmscore/tuplet.h
Expand Up @@ -58,6 +58,8 @@ class Tuplet final : public DurationElement {
QPointF bracketL[4];
QPointF bracketR[3];

Fraction addMissingElement(int startTick, int endTick);

public:
Tuplet(Score*);
Tuplet(const Tuplet&);
Expand Down Expand Up @@ -133,9 +135,6 @@ class Tuplet final : public DurationElement {

void sanitizeTuplet();
void addMissingElements();

private:
Fraction addMissingElement(int startTick, int endTick);
};


Expand Down

0 comments on commit d5298f5

Please sign in to comment.