Skip to content

Commit

Permalink
Fix #30631 - TAB: tie layout.
Browse files Browse the repository at this point in the history
Fixes two aspects of tie layout in TAB described in the issue:

- ties might be too short; fixed by borrowing  into `Chord::layoutTablature()` and adapting the code in `Chord::layoutPitched()`
- ties did not adapt to fret font size and position; fixed by parameterizing `Tie::slurPos()`
  • Loading branch information
mgavioli committed Mar 4, 2015
1 parent 64cfc85 commit 0e5cd00
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 9 deletions.
54 changes: 51 additions & 3 deletions libmscore/chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2041,9 +2041,10 @@ void Chord::layoutPitched()

void Chord::layoutTablature()
{
qreal _spatium = spatium();
qreal dotNoteDistance = score()->styleS(StyleIdx::dotNoteDistance).val() * _spatium;
qreal minNoteDistance = score()->styleS(StyleIdx::minNoteDistance).val() * _spatium;
qreal _spatium = spatium();
qreal dotNoteDistance = score()->styleS(StyleIdx::dotNoteDistance).val() * _spatium;
qreal minNoteDistance = score()->styleS(StyleIdx::minNoteDistance).val() * _spatium;
qreal minTieLength = score()->styleS(StyleIdx::MinTieLength).val() * _spatium;

for (Chord* c : _graceNotes)
c->layoutTablature();
Expand Down Expand Up @@ -2076,6 +2077,53 @@ void Chord::layoutTablature()
note->setPos(x, note->line() * lineDist / 2);
else
note->setPos(x, tab->physStringToVisual(note->string()) * lineDist);

// allow extra space for shortened ties
// this code must be kept synchronized
// with the tie positioning code in Tie::slurPos()
// but the allocation of space needs to be performed here
Tie* tie;
tie = note->tieBack();
if (tie) {
tie->calculateDirection();
qreal overlap = 0.0; // how much tie can overlap start and end notes
bool shortStart = false; // whether tie should clear start note or not
Note* startNote = tie->startNote();
Chord* startChord = startNote->chord();
if (startChord && startChord->measure() == measure() && startChord == prevChordRest(this)) {
qreal startNoteWidth = startNote->width();
// overlap into start chord?
// if in start chord, there are several notes or stem and tie in same direction
if (startChord->notes().size() > 1 || (startChord->stem() && startChord->up() == tie->up())) {
// clear start note (1/8 of fret mark width)
shortStart = true;
overlap -= startNoteWidth * 0.125;
}
else // overlap start note (by ca. 1/3 of fret mark width)
overlap += startNoteWidth * 0.35;
// overlap into end chord (this)?
// if several notes or neither stem or tie are up
if (notes().size() > 1 || (stem() && !up() && !tie->up())) {
// for positive offset:
// use available space
// for negative x offset:
// space is allocated elsewhere, so don't re-allocate here
if (note->ipos().x() != 0.0) // this probably does not work for TAB, as
overlap += qAbs(note->ipos().x()); // _pos is used to centre the fret on the stem
else
overlap -= fretWidth * 0.125;
}
else {
if (shortStart)
overlap += fretWidth * 0.15;
else
overlap += fretWidth * 0.35;
}
qreal d = qMax(minTieLength - overlap, 0.0);
lll = qMax(lll, d);
}
}

}
// horiz. spacing: leave half width at each side of the (potential) stem
qreal halfHeadWidth = headWidth * 0.5;
Expand Down
4 changes: 3 additions & 1 deletion libmscore/stafftype.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ class StaffType {
bool _useNumbers = true; // true: use numbers ('0' - ...) for frets | false: use letters ('a' - ...)

// TAB: internally managed variables
// Note: values in RASTER UNITS are independent from score scaling and
// must be multiplied by magS() to be used in contexts using sp units
qreal _durationBoxH = 0.0;
qreal _durationBoxY = 0.0; // the height and the y rect.coord. (relative to staff top line)
// of a box bounding all duration symbols (raster units) internally computed:
Expand All @@ -193,7 +195,7 @@ class StaffType {
// (raster units); internally computed: depends upon _onString, _useNumbers
// and the metrics of the fret font
bool _fretMetricsValid = false; // whether fret font metrics are valid or not
qreal _refDPI = 0.0; // reference value used to last compute metrics and to see if they are still valid
qreal _refDPI = 0.0; // reference value used to last computed metrics and to see if they are still valid

// the array of configured fonts
static QList<TablatureFretFont> _fretFonts;
Expand Down
20 changes: 15 additions & 5 deletions libmscore/tie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,19 @@ void Tie::slurPos(SlurPos* sp)
StaffType* stt = nullptr;
if (useTablature)
stt = staff()->staffType();
qreal hw = startNote()->tabHeadWidth(stt); // if stt == 0, defaults to headWidth()
qreal __up = _up ? -1.0 : 1.0;
qreal _spatium = spatium();
qreal _spatium = spatium();
qreal hw = startNote()->tabHeadWidth(stt); // if stt == 0, defaults to headWidth()
qreal __up = _up ? -1.0 : 1.0;
// y offset for ties inside chord margins (typically multi-note chords): lined up with note top or bottom margin
// or outside (typically single-note chord): overlaps note and is above/below it
// Outside: Tab: uses font size and may be asymmetric placed above/below line (frets ON or ABOVE line)
// Std: assumes note head is 1 sp high, 1/2 sp above and 1/2 below line; add 1/4 sp to it
// Inside: Tab: 1/2 of Outside offset
// Std: use a fixed pecentage of note width
qreal yOffOutside = useTablature
? (_up ? stt->fretBoxY() : stt->fretBoxY() + stt->fretBoxH()) * magS()
: 0.75 * _spatium * __up;
qreal yOffInside = useTablature ? yOffOutside * 0.5 : hw * .3 * __up;

Chord* sc = startNote()->chord();
Q_ASSERT(sc);
Expand All @@ -184,12 +194,12 @@ void Tie::slurPos(SlurPos* sp)
//------p1
if ((sc->notes().size() > 1) || (sc->stem() && (sc->up() == _up))) {
xo = startNote()->x() + hw * 1.12;
yo = startNote()->pos().y() + hw * .3 * __up;
yo = startNote()->pos().y() + yOffInside;
shortStart = true;
}
else {
xo = startNote()->x() + hw * 0.65;
yo = startNote()->pos().y() + _spatium * .75 * __up;
yo = startNote()->pos().y() + yOffOutside;
}
sp->p1 = sc->pagePos() - sp->system1->pagePos() + QPointF(xo, yo);

Expand Down

0 comments on commit 0e5cd00

Please sign in to comment.