Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #304353: melisma line overlaps next syllable | collect_artifacts #6081

Merged
merged 1 commit into from
Jun 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions libmscore/chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,18 @@ QPointF Chord::stemPosBeam() const
return p;
}

//---------------------------------------------------------
// rightEdge
//---------------------------------------------------------

qreal Chord::rightEdge() const
{
qreal right = 0.0;
for (Note* n : notes())
right = qMax(right, x() + n->x() + n->bboxRightPos());
return right;
}

//---------------------------------------------------------
// setTremolo
//---------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions libmscore/chord.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ class Chord final : public ChordRest {
QPointF stemPos() const override; ///< page coordinates
QPointF stemPosBeam() const override; ///< page coordinates
qreal stemPosX() const override;
qreal rightEdge() const override;

bool underBeam() const;
Hook* hook() const { return _hook; }
Expand Down
30 changes: 30 additions & 0 deletions libmscore/chordrest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ ChordRest::ChordRest(Score* s)
_up = true;
_beamMode = Beam::Mode::AUTO;
_small = false;
_melismaEnd = false;
_crossMeasure = CrossMeasure::UNKNOWN;
}

Expand All @@ -79,6 +80,7 @@ ChordRest::ChordRest(const ChordRest& cr, bool link)
_beamMode = cr._beamMode;
_up = cr._up;
_small = cr._small;
_melismaEnd = cr._melismaEnd;
_crossMeasure = cr._crossMeasure;

for (Lyrics* l : cr._lyrics) { // make deep copy
Expand Down Expand Up @@ -1218,6 +1220,29 @@ QString ChordRest::accessibleExtraInfo() const
return rez;
}

//---------------------------------------------------------
// isMelismaEnd
// returns true if chordrest represents the end of a melisma
//---------------------------------------------------------

bool ChordRest::isMelismaEnd() const
{
return _melismaEnd;
}

//---------------------------------------------------------
// setMelismaEnd
//---------------------------------------------------------

void ChordRest::setMelismaEnd(bool v)
{
_melismaEnd = v;
// TODO: don't take "false" at face value
// check to see if some other melisma ends here,
// in which case we can leave this set to true
// for now, rely on the fact that we'll generate the value correctly on layout
}

//---------------------------------------------------------
// shape
//---------------------------------------------------------
Expand Down Expand Up @@ -1269,6 +1294,11 @@ Shape ChordRest::shape() const
shape.addHorizontalSpacing(Shape::SPACING_HARMONY, x1, x2);
}

if (isMelismaEnd()) {
qreal right = rightEdge();
shape.addHorizontalSpacing(Shape::SPACING_LYRICS, right, right);
}

return shape;
}

Expand Down
4 changes: 4 additions & 0 deletions libmscore/chordrest.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class ChordRest : public DurationElement {
Beam::Mode _beamMode;
bool _up; // actual stem direction
bool _small;
bool _melismaEnd;

// CrossMeasure: combine 2 tied notes if across a bar line and can be combined in a single duration
CrossMeasure _crossMeasure; ///< 0: no cross-measure modification; 1: 1st note of a mod.; -1: 2nd note
Expand Down Expand Up @@ -102,6 +103,7 @@ class ChordRest : public DurationElement {
virtual QPointF stemPos() const = 0;
virtual qreal stemPosX() const = 0;
virtual QPointF stemPosBeam() const = 0;
virtual qreal rightEdge() const = 0;

bool up() const { return _up; }
void setUp(bool val) { _up = val; }
Expand Down Expand Up @@ -136,6 +138,8 @@ class ChordRest : public DurationElement {
std::vector<Lyrics*>& lyrics() { return _lyrics; }
Lyrics* lyrics(int verse, Placement) const;
int lastVerse(Placement) const;
bool isMelismaEnd() const;
void setMelismaEnd(bool v);

virtual void add(Element*);
virtual void remove(Element*);
Expand Down
34 changes: 5 additions & 29 deletions libmscore/line.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -837,35 +837,11 @@ QPointF SLine::linePos(Grip grip, System** sys) const
}

// layout to right edge of CR
bool extendToEnd = true; // extend to end or start element?
if (cr == toChordRest(startElement()))
extendToEnd = false;
else if (cr) {
// if next segment is a chord with lyrics which spans to the left
// then do not extend to the right edge of end element.
Segment* seg = cr->segment();
seg = seg->next(SegmentType::ChordRest);
if (seg) {
ChordRest* cr2 = seg->cr(cr->track());
if (cr2 && !cr2->lyrics().empty())
extendToEnd = false;
}
}
ChordRest* right = extendToEnd ? cr : toChordRest(startElement());
if (right) {
qreal maxRight = 0.0;
if (right->isChord()) {
// chord bbox() is unreliable, look at notes
// this also allows us to more easily ignore ledger lines
for (Note* n : toChord(right)->notes())
maxRight = qMax(maxRight, right->x() + n->x() + n->bboxRightPos());
}
else {
// rest - won't normally happen
maxRight = right->x() + right->width();
}
x = maxRight;
}
// except if CR is start element, in which case use a nominal length
if (cr && cr != toChordRest(startElement()))
x = cr->rightEdge();
else
x = spatium() - score()->styleP(Sid::minNoteDistance);
}
else if (isHairpin() || isTrill() || isVibrato() || isTextLine() || isLyricsLine()) {
// (for LYRICSLINE, this is hyphen; melisma line is handled above)
Expand Down
44 changes: 42 additions & 2 deletions libmscore/lyrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,18 @@ void Lyrics::remove(Element* el)
if (el->isLyricsLine()) {
// only if separator still exists and is the right one
if (_separator && el == _separator) {
#if 0
// clear melismaEnd flag from end cr
// find end cr from melisma itself, as ticks for lyrics may not be accurate at this point
// note this clearing this might be premature, as there may be other lyrics that still end there
// also, at this point we can't be sure if this is a melisma or a dash
// but the flag will be regenerated on next layout
Element* e = _separator->endElement();
if (!e)
e = score()->findCRinStaff(_separator->tick2(), track());
if (e && e->isChordRest())
toChordRest(e)->setMelismaEnd(false);
#endif
// Lyrics::remove() and LyricsLine::removeUnmanaged() call each other;
// be sure each finds a clean context
LyricsLine* separ = _separator;
Expand Down Expand Up @@ -274,10 +286,16 @@ void Lyrics::layout()
if (styleDidChange)
styleChanged();

if (isMelisma() || hasNumber)
if (isStyled(Pid::ALIGN)) {
if (isMelisma() || hasNumber) {
// use the melisma style alignment setting
if (isStyled(Pid::ALIGN))
setAlign(score()->styleV(Sid::lyricsMelismaAlign).value<Align>());
}
else {
// use the text style alignment setting
if (isStyled(Pid::ALIGN))
setAlign(propertyDefault(Pid::ALIGN).value<Align>());
}
QPointF o(propertyDefault(Pid::OFFSET).toPointF());
rxpos() = o.x();
qreal x = pos().x();
Expand Down Expand Up @@ -345,6 +363,14 @@ void Lyrics::layout()
_separator = 0;
}
}

if (_ticks.isNotZero()) {
// set melisma end
ChordRest* ecr = score()->findCR(endTick(), track());
if (ecr)
ecr->setMelismaEnd(true);
}

}

//---------------------------------------------------------
Expand Down Expand Up @@ -495,6 +521,12 @@ void Lyrics::endEdit(EditData& ed)

void Lyrics::removeFromScore()
{
if (_ticks.isNotZero()) {
// clear melismaEnd flag from end cr
ChordRest* ecr = score()->findCR(endTick(), track());
if (ecr)
ecr->setMelismaEnd(false);
}
if (_separator) {
_separator->removeUnmanaged();
delete _separator;
Expand Down Expand Up @@ -534,6 +566,14 @@ bool Lyrics::setProperty(Pid propertyId, const QVariant& v)
_syllabic = Syllabic(v.toInt());
break;
case Pid::LYRIC_TICKS:
if (_ticks.isNotZero()) {
// clear melismaEnd flag from previous end cr
// this might be premature, as there may be other melismas ending there
// but flag will be generated correctly on layout
ChordRest* ecr = score()->findCR(endTick(), track());
if (ecr)
ecr->setMelismaEnd(false);
}
_ticks = v.value<Fraction>();
break;
case Pid::VERSE:
Expand Down
6 changes: 3 additions & 3 deletions libmscore/lyricsline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,9 +408,9 @@ void LyricsLineSegment::layout()
if (isEndMelisma) { // melisma
_numOfDashes = 1;
rypos() -= lyricsLine()->lineWidth() * .5; // let the line 'sit on' the base line
qreal offsetX = score()->styleP(Sid::minNoteDistance) * mag();
// if final segment, extend slightly after the chord, otherwise shorten it
rxpos2() += (isBeginType() || isEndType()) ? -offsetX : +offsetX;
// if not final segment, shorten it
if (isBeginType() || isMiddleType())
rxpos2() -= score()->styleP(Sid::minNoteDistance) * mag();
}
else { // dash(es)
// set conventional dash Y pos
Expand Down
9 changes: 9 additions & 0 deletions libmscore/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,15 @@ qreal Rest::stemPosX() const
return bbox().left();
}

//---------------------------------------------------------
// rightEdge
//---------------------------------------------------------

qreal Rest::rightEdge() const
{
return x() + width();
}

//---------------------------------------------------------
// accent
//---------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions libmscore/rest.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class Rest : public ChordRest {
virtual QPointF stemPos() const;
virtual qreal stemPosX() const;
virtual QPointF stemPosBeam() const;
virtual qreal rightEdge() const override;

void localSpatiumChanged(qreal oldValue, qreal newValue) override;
QVariant propertyDefault(Pid) const override;
Expand Down
3 changes: 2 additions & 1 deletion vtest/gen
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ else
beams-1 beams-2 beams-3 beams-4 beams-5 beams-6 beams-7 beams-8 beams-9 beams-10\
beams-11 beams-12 beams-13 beams-14 beams-15 beams-16 beams-17\
user-offset-1 user-offset-2 chord-space-1 chord-space-2 tablature-1 image-1\
lyrics-1 lyrics-2 lyrics-3 lyrics-4 lyrics-5 lyrics-6 lyrics-7 lyrics-8 voice-1 voice-2 slash-1 slash-2\
lyrics-1 lyrics-2 lyrics-3 lyrics-4 lyrics-5 lyrics-6 lyrics-7 lyrics-8 lyrics-9\
voice-1 voice-2 slash-1 slash-2\
system-1 system-2 system-3 system-4 system-5 system-6 system-7 system-8 system-9 hide-1 small-1 tremolo-1\
staff-1 staff-2 staff-3 staff-4 layout-1 layout-2 layout-3 layout-4 layout-5 layout-6 layout-7 layout-8 layout-9 layout-10\
articulation-1\
Expand Down
3 changes: 2 additions & 1 deletion vtest/gen.bat
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ set SRC=mmrest-1,bravura-mmrest,gonville-mmrest,mmrest-2,mmrest-4,mmrest-5,mmres
beams-1,beams-2,beams-3,beams-4,beams-5,beams-6,beams-7,beams-8,beams-9,beams-10, ^
beams-11,beams-12,beams-13,beams-14,beams-15,beams-16,beams-17, ^
user-offset-1,user-offset-2,chord-space-1,chord-space-2,tablature-1,image-1, ^
lyrics-1,lyrics-2,lyrics-3,lyrics-4,lyrics-5,lyrics-6,lyrics-7,lyrics-8,voice-1,voice-2,slash-1,slash-2, ^
lyrics-1,lyrics-2,lyrics-3,lyrics-4,lyrics-5,lyrics-6,lyrics-7,lyrics-8,lyrics-9, ^
voice-1,voice-2,slash-1,slash-2, ^
system-1,system-2,system-3,system-4,system-5,system-6,system-7,system-8,system-9,hide-1,small-1,tremolo-1, ^
staff-1,staff-2,staff-3,staff-4,layout-1,layout-2,layout-3,layout-4,layout-5,layout-6,layout-7,layout-8,layout-9,layout-10, ^
articulation-1, ^
Expand Down
Binary file modified vtest/lyrics-2-ref.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified vtest/lyrics-3-ref.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified vtest/lyrics-4-ref.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added vtest/lyrics-8-ref.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added vtest/lyrics-9-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added vtest/lyrics-9-ref.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading