Skip to content

Commit

Permalink
change implementation of articulations
Browse files Browse the repository at this point in the history
  • Loading branch information
wschweer committed Oct 6, 2016
1 parent 89fd34f commit 2b25520
Show file tree
Hide file tree
Showing 81 changed files with 1,180 additions and 1,319 deletions.
393 changes: 164 additions & 229 deletions libmscore/articulation.cpp

Large diffs are not rendered by default.

49 changes: 17 additions & 32 deletions libmscore/articulation.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ constexpr bool operator& (ArticulationShowIn a1, ArticulationShowIn a2) {
return static_cast<unsigned char>(a1) & static_cast<unsigned char>(a2);
}

struct ArticulationInfo {
SymId upSym;
SymId downSym;
const char* name; // as stored in score files
qreal timeStretch; // for fermata
ArticulationShowIn flags;
};

//---------------------------------------------------------
// @@ Articulation
/// articulation marks
Expand All @@ -66,39 +58,40 @@ struct ArticulationInfo {
class Articulation : public Element {
Q_OBJECT

ArticulationType _articulationType;
SymId _symId;
Direction _direction;
QString _channelName;

ArticulationAnchor _anchor;
PropertyStyle anchorStyle;

bool _up;
qreal _timeStretch; // for fermata
MScore::OrnamentStyle _ornamentStyle; // for use in ornaments such as trill
qreal _timeStretch; // for fermata
MScore::OrnamentStyle _ornamentStyle; // for use in ornaments such as trill
bool _playArticulation;

virtual void draw(QPainter*) const;

public:
Articulation(Score*);
Articulation(SymId, Score*);
Articulation &operator=(const Articulation&) = delete;

virtual Articulation* clone() const override { return new Articulation(*this); }
virtual Element::Type type() const override { return Element::Type::ARTICULATION; }

virtual qreal mag() const override;

void setArticulationType(ArticulationType);
ArticulationType articulationType() const { return _articulationType; }

virtual int subtype() const override { return int(_articulationType); }
void setSubtype(const QString& s);
QString subtypeName() const;
SymId symId() const { return _symId; }
void setSymId(SymId id);
virtual int subtype() const override { return int(_symId); }
QString userName() const;

virtual void layout() override;

virtual void read(XmlReader&) override;
virtual void write(Xml& xml) const override;
virtual bool readProperties(XmlReader&) override;

virtual void reset() override;
virtual QLineF dragAnchor() const override;
Expand All @@ -108,13 +101,10 @@ class Articulation : public Element {
virtual QVariant propertyDefault(P_ID) const override;
virtual PropertyStyle propertyStyle(P_ID) const override;
virtual void resetProperty(P_ID id) override;
virtual void styleChanged() override;
StyleIdx getPropertyStyle(P_ID id) const override;

QString userName() const;

bool up() const { return _up; }
void setUp(bool val) { _up = val; }
void setUp(bool val);
void setDirection(Direction d);
Direction direction() const { return _direction; }

Expand All @@ -123,9 +113,6 @@ class Articulation : public Element {
Measure* measure() const;
System* system() const;
Page* page() const;
SymId symId() const;

static ArticulationInfo articulationList[];

ArticulationAnchor anchor() const { return _anchor; }
void setAnchor(ArticulationAnchor v) { _anchor = v; }
Expand All @@ -142,15 +129,13 @@ class Articulation : public Element {
QString channelName() const { return _channelName; }
void setChannelName(const QString& s) { _channelName = s; }

const ArticulationInfo* articulationInfo() const { return &articulationList[int(articulationType())]; }

static QString idx2name(int idx);
bool isFermata() { return _articulationType == ArticulationType::Fermata ||
_articulationType == ArticulationType::Shortfermata ||
_articulationType == ArticulationType::Longfermata ||
_articulationType == ArticulationType::Verylongfermata; }

QString accessibleInfo() const override;

bool isFermata() const;
bool isTenuto() const;
bool isStaccato() const;
bool isAccent() const;
bool isLuteFingering() const;
};

} // namespace Ms
Expand Down
32 changes: 13 additions & 19 deletions libmscore/chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2650,7 +2650,7 @@ bool Chord::setProperty(P_ID propertyId, const QVariant& v)

//---------------------------------------------------------
// layoutArticulation
// called from chord()->layoutArticulations()
// called from ChordRest()->layoutArticulations()
//---------------------------------------------------------

QPointF Chord::layoutArticulation(Articulation* a)
Expand All @@ -2668,10 +2668,9 @@ QPointF Chord::layoutArticulation(Articulation* a)
qreal x = centerX();
qreal y = 0.0;

ArticulationType st = a->articulationType();

// TENUTO and STACCATO: always near the notehead (or stem end if beyond a stem)
if ((st == ArticulationType::Tenuto || st == ArticulationType::Staccato || st == ArticulationType::Sforzatoaccent) && (aa != ArticulationAnchor::TOP_STAFF && aa != ArticulationAnchor::BOTTOM_STAFF)) {
if ((a->isTenuto() || a->isStaccato() || a->isAccent())
&& (aa != ArticulationAnchor::TOP_STAFF && aa != ArticulationAnchor::BOTTOM_STAFF)) {
bool bottom; // true: artic. is below chord | false: artic. is above chord
bool alignToStem = false;
// if there area voices, articulation is on stem side
Expand Down Expand Up @@ -2704,15 +2703,15 @@ QPointF Chord::layoutArticulation(Articulation* a)
qreal dy = (score()->styleS(StyleIdx::beamWidth).val() + 1) * _spatium2;
pos.ry() += bottom ? dy : - dy;
}
alignToStem = (st == ArticulationType::Staccato && articulations().size() == 1);
alignToStem = a->isStaccato() && articulations().size() == 1;
}
else { // if articulation is not beyond a stem
int lline; // logical line of note
int line; // physical line of note
int staffOff; // offset that should account for line spacing
int extraOff = 0; // offset that should not acocunt for line spacing
int lines = (staff()->lines() - 1) * 2; // num. of staff positions within staff
int add = (st == ArticulationType::Sforzatoaccent ? 1 : 0); // sforzato accent needs more offset
int add = a->isAccent() ? 1 : 0; // sforzato accent needs more offset
if (bottom) { // if below chord
lline = downLine(); // logical line of chord lowest note
line = scale ? lline : lline * (lld / pld); // corresponding physical line
Expand Down Expand Up @@ -2766,8 +2765,7 @@ QPointF Chord::layoutArticulation(Articulation* a)
}

// Lute fingering are always in the middle of the space right below the fret mark,
else if (staff() && staff()->staffGroup() == StaffGroup::TAB
&& st >= ArticulationType::LuteFingThumb && st <= ArticulationType::LuteFingThird) {
else if (staff() && staff()->staffGroup() == StaffGroup::TAB && a->isLuteFingering()) {
// lute fing. glyphs are vertically registered in the middle of bottom space;
// move down of half a space to have the glyph on the line
y = chordBotY + _spatium * 0.5;
Expand Down Expand Up @@ -2867,17 +2865,13 @@ QPointF Chord::layoutArticulation(Articulation* a)
}
}

qreal dist; // distance between occupied area and articulation
switch(st) {
case ArticulationType::Marcato:
dist = 1.0 * _spatium;
break;
case ArticulationType::Sforzatoaccent:
dist = 1.5 * _spatium;
break;
default:
dist = score()->styleP(StyleIdx::propertyDistance);
}
qreal dist; // distance between occupied area and articulation
if (a->symId() == SymId::articMarcatoAbove || a->symId() == SymId::articMarcatoBelow)
dist = 1.0 * _spatium;
else if (a->isAccent())
dist = 1.5 * _spatium;
else
dist = score()->styleP(StyleIdx::propertyDistance);

if (aa == ArticulationAnchor::CHORD || aa == ArticulationAnchor::TOP_CHORD || aa == ArticulationAnchor::BOTTOM_CHORD) {
bool bottom;
Expand Down
82 changes: 14 additions & 68 deletions libmscore/chordrest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ namespace Ms {

Articulation* ChordRest::hasArticulation(const Articulation* aa)
{
ArticulationType idx = aa->articulationType();
foreach(Articulation* a, _articulations) {
if (idx == a->articulationType())
SymId id = aa->symId();
for (Articulation* a : _articulations) {
if (id == a->symId())
return a;
}
return 0;
Expand Down Expand Up @@ -289,7 +289,7 @@ bool ChordRest::readProperties(XmlReader& e)
bm = Beam::Mode(val.toInt());
_beamMode = Beam::Mode(bm);
}
else if (tag == "Attribute" || tag == "Articulation") { // obsolete: "Attribute"
else if (tag == "Articulation") {
Articulation* atr = new Articulation(score());
atr->setTrack(track());
atr->read(e);
Expand Down Expand Up @@ -487,7 +487,6 @@ void ChordRest::layout0(AccidentalState* as)

//---------------------------------------------------------
// layoutArticulations
// called from chord()->layout()
//---------------------------------------------------------

void ChordRest::layoutArticulations()
Expand All @@ -499,60 +498,10 @@ void ChordRest::layoutArticulations()
qreal pld = staff()->lineDistance();
qreal lld = staff()->logicalLineDistance();
qreal _spStaff = _spatium * pld; // scaled to staff line distance for vert. pos. within a staff
qreal _spDist = _spatium; // scaling for distance between articulations

if (isChord()) {
if (_articulations.size() == 1) {
toChord(this)->layoutArticulation(_articulations[0]);
return;
}
if (_articulations.size() == 2) {
//
// staccato | tenuto + marcato
//
Articulation* a1 = _articulations[0];
Articulation* a2 = _articulations[1];
ArticulationType st1 = a1->articulationType();
ArticulationType st2 = a2->articulationType();

if ((st2 == ArticulationType::Tenuto || st2 == ArticulationType::Staccato)
&& (st1 == ArticulationType::Marcato)) {
qSwap(a1, a2);
qSwap(st1, st2);
}
if ((st1 == ArticulationType::Tenuto || st1 == ArticulationType::Staccato)
&& (st2 == ArticulationType::Marcato)) {
QPointF pt = static_cast<Chord*>(this)->layoutArticulation(a1);
//if (pt.y() < 0 || pt.y() > staff()->height())
// _spDist = _spatium;
pt.ry() += a1->up() ? -_spDist * .5 : _spDist * .5;
a2->layout();
a2->setUp(a1->up());
a2->setPos(pt);
a2->adjustReadPos();
return;
}
//
// staccato | tenuto + sforzato
//
if ((st2 == ArticulationType::Tenuto || st2 == ArticulationType::Staccato)
&& (st1 == ArticulationType::Sforzatoaccent)) {
qSwap(a1, a2);
qSwap(st1, st2);
}
if ((st1 == ArticulationType::Tenuto || st1 == ArticulationType::Staccato)
&& (st2 == ArticulationType::Sforzatoaccent)) {
QPointF pt = static_cast<Chord*>(this)->layoutArticulation(a1);
//if (pt.y() < 0 || pt.y() > staff()->height())
// _spDist = _spatium;
pt.ry() += a1->up() ? -_spDist * .7 : _spDist * .7;
a2->layout();
a2->setUp(a1->up());
a2->setPos(pt);
a2->adjustReadPos();
return;
}
}
if (isChord() && _articulations.size() == 1) {
toChord(this)->layoutArticulation(_articulations[0]);
return;
}

qreal x = centerX();
Expand All @@ -569,8 +518,8 @@ void ChordRest::layoutArticulations()
// avoid collisions of staff articulations with chord notes:
// gap between note and staff articulation is distance0 + 0.5 spatium

if (type() == Element::Type::CHORD) {
Chord* chord = static_cast<Chord*>(this);
if (isChord()) {
Chord* chord = toChord(this);
Stem* stem = chord->stem();
if (stem) {
qreal y = stem->pos().y() + pos().y();
Expand Down Expand Up @@ -621,8 +570,7 @@ void ChordRest::layoutArticulations()
a->layout();
ArticulationAnchor aa = a->anchor();

if ((a->articulationType() != ArticulationType::Tenuto)
&& (a->articulationType() != ArticulationType::Staccato))
if (!(a->isTenuto() || a->isStaccato()))
continue;

if (aa != ArticulationAnchor::CHORD && aa != ArticulationAnchor::TOP_CHORD && aa != ArticulationAnchor::BOTTOM_CHORD)
Expand All @@ -637,13 +585,13 @@ void ChordRest::layoutArticulations()

dy += distance1;
qreal y;
Chord* chord = static_cast<Chord*>(this);
Chord* chord = toChord(this);
if (bottom) {
int line = downLine();
if (!scale)
line = ceil((line * lld) / pld);
y = chordBotY + dy;
if (!headSide && type() == Element::Type::CHORD && chord->stem()) {
if (!headSide && isChord() && chord->stem()) {
Stem* stem = chord->stem();
y = chordTopY + stem->stemLen();
if (chord->beam())
Expand Down Expand Up @@ -715,16 +663,14 @@ void ChordRest::layoutArticulations()
Articulation* a = _articulations.at(i);
a->layout();
ArticulationAnchor aa = a->anchor();
if ((a->articulationType() == ArticulationType::Tenuto)
|| (a->articulationType() == ArticulationType::Staccato))
if (a->isTenuto() || a->isStaccato())
continue;

if (aa != ArticulationAnchor::CHORD && aa != ArticulationAnchor::TOP_CHORD && aa != ArticulationAnchor::BOTTOM_CHORD)
continue;

// for tenuto and staccate check for staff line collision
bool staffLineCT = a->articulationType() == ArticulationType::Tenuto
|| a->articulationType() == ArticulationType::Staccato;
bool staffLineCT = a->isTenuto() || a->isStaccato();

bool bottom = (aa == ArticulationAnchor::BOTTOM_CHORD) || (aa == ArticulationAnchor::CHORD && up());

Expand Down
Loading

0 comments on commit 2b25520

Please sign in to comment.