Skip to content

Commit

Permalink
Improve layout related to two-note cross-staff tremolos (+ collect_ar…
Browse files Browse the repository at this point in the history
…tifacts)
  • Loading branch information
Harmoniker1 committed Jan 29, 2020
1 parent 6018579 commit b1c8e59
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 8 deletions.
34 changes: 27 additions & 7 deletions libmscore/chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1466,23 +1466,43 @@ qreal Chord::minAbsStemLength() const
std::array<double, 2> extendedStemLenWithTwoNoteTremolo(Tremolo* _tremolo, qreal _spatium,
qreal stemLen1, qreal stemLen2)
{
const qreal sw = _tremolo->score()->styleS(Sid::tremoloStrokeWidth).val();
const qreal td = _tremolo->score()->styleS(Sid::tremoloDistance).val();
Chord* c1 = _tremolo->chord1();
Chord* c2 = _tremolo->chord2();
const qreal sgn1 = c1->up() ? -1.0 : 1.0;
const qreal sgn2 = c2->up() ? -1.0 : 1.0;
if (c1->up() == c2->up()) {
const qreal stemTipDistance =
(c2->stemPos().y() + stemLen2) - (c1->stemPos().y() + stemLen1);
const qreal stemTipDistance =
(c2->stemPos().y() + stemLen2) - (c1->stemPos().y() + stemLen1);

// same staff & same direction: extend one of the stems
if (c1->staffMove() == c2->staffMove() && c1->up() == c2->up()) {
const bool stem1Higher = stemTipDistance > 0.0;
if (std::abs(stemTipDistance) > 1.0 * _spatium) {
if ( ( c1->up() && !stem1Higher)
|| (!c1->up() && stem1Higher))
if ((c1->up() && !stem1Higher) || (!c1->up() && stem1Higher))
return { stemLen1 + sgn1 * (std::abs(stemTipDistance) - 1.0 * _spatium), stemLen2 };
else /* if (( c1->up() && stem1Higher)
|| (!c1->up() && !stem1Higher)) */
else /* if ((c1->up() && stem1Higher) || (!c1->up() && !stem1Higher)) */
return { stemLen1, stemLen2 + sgn2 * (std::abs(stemTipDistance) - 1.0 * _spatium) };
}
}

// cross-staff & beam between staves: extend both stems by the same length
else if (_tremolo->crossStaffBeamBetween()) {
const qreal tremoloMinHeight = ((_tremolo->lines() - 1) * td + sw) * _spatium;
const bool needExtend = std::abs(stemTipDistance) + tremoloMinHeight > 1.0 * _spatium;
const qreal idealDistance = 1.0 * _spatium - tremoloMinHeight;
const bool tooShort = ( c1->up() && stemTipDistance - tremoloMinHeight < 0)
|| (!c1->up() && stemTipDistance + tremoloMinHeight > 0);
if (needExtend) {
if (tooShort)
return { stemLen1 + sgn1 * (std::abs(stemTipDistance) - idealDistance) / 2,
stemLen2 + sgn2 * (std::abs(stemTipDistance) - idealDistance) / 2 };
else
return { stemLen1 - sgn1 * (std::abs(stemTipDistance) + idealDistance) / 2,
stemLen2 - sgn2 * (std::abs(stemTipDistance) + idealDistance) / 2 };
}
}

return { stemLen1, stemLen2 };
}

Expand Down
18 changes: 17 additions & 1 deletion libmscore/tremolo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,9 @@ void Tremolo::layoutTwoNotesTremolo(qreal x, qreal y, qreal h, qreal _spatium)
}

// improve the case when one stem is up and another is down
if (_chord1->beams() == 0 && _chord2->beams() == 0 && _chord1->up() != _chord2->up()) {
if (_chord1->beams() == 0 && _chord2->beams() == 0
&& _chord1->up() != _chord2->up()
&& !crossStaffBeamBetween()) {
qreal meanNote1Y = .5 * (_chord1->upNote()->pagePos().y() - firstChordStaffY + _chord1->downNote()->pagePos().y() - firstChordStaffY);
qreal meanNote2Y = .5 * (_chord2->upNote()->pagePos().y() - firstChordStaffY + _chord2->downNote()->pagePos().y() - firstChordStaffY);
y1 = .5 * (y1 + meanNote1Y);
Expand Down Expand Up @@ -476,6 +478,20 @@ void Tremolo::layoutTwoNotesTremolo(qreal x, qreal y, qreal h, qreal _spatium)
setPos(x, y + beamYOffset);
}

//---------------------------------------------------------
// crossStaffBeamBetween
// Return true if tremolo is two-note cross-staff and beams between staves
//---------------------------------------------------------

bool Tremolo::crossStaffBeamBetween() const
{
if (!twoNotes())
return false;

return ((_chord1->staffMove() > _chord2->staffMove()) && _chord1->up() && !_chord2->up())
|| ((_chord1->staffMove() < _chord2->staffMove()) && !_chord1->up() && _chord2->up());
}

//---------------------------------------------------------
// write
//---------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions libmscore/tremolo.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ class Tremolo final : public Element {

bool placeMidStem() const;

bool crossStaffBeamBetween() const;

virtual void spatiumChanged(qreal oldValue, qreal newValue) override;
virtual void localSpatiumChanged(qreal oldValue, qreal newValue) override;
virtual void styleChanged() override;
Expand Down

0 comments on commit b1c8e59

Please sign in to comment.