layout optimizations
This commit is contained in:
parent
2aec0b81b4
commit
32c3100f80
17 changed files with 194 additions and 237 deletions
|
@ -189,7 +189,7 @@ void BarLine::getY(qreal* y1, qreal* y2) const
|
||||||
staffIdx2 = score()->nstaves() - 1;
|
staffIdx2 = score()->nstaves() - 1;
|
||||||
}
|
}
|
||||||
Measure* measure = 0;
|
Measure* measure = 0;
|
||||||
System* system;
|
System* system = 0;
|
||||||
SysStaff* sysStaff0 = 0; // top staff for barline in system
|
SysStaff* sysStaff0 = 0; // top staff for barline in system
|
||||||
bool systemBarLine;
|
bool systemBarLine;
|
||||||
if (parent()->type() == Element::Type::SEGMENT) {
|
if (parent()->type() == Element::Type::SEGMENT) {
|
||||||
|
|
|
@ -3156,7 +3156,6 @@ Element* Chord::prevElement()
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ChordRest::prevElement();
|
return ChordRest::prevElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -767,7 +767,7 @@ Element* ChordRest::drop(const DropData& data)
|
||||||
switch (e->type()) {
|
switch (e->type()) {
|
||||||
case Element::Type::BREATH:
|
case Element::Type::BREATH:
|
||||||
{
|
{
|
||||||
Breath* b = static_cast<Breath*>(e);
|
Breath* b = toBreath(e);
|
||||||
int track = staffIdx() * VOICES;
|
int track = staffIdx() * VOICES;
|
||||||
b->setTrack(track);
|
b->setTrack(track);
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ class SlurSegment;
|
||||||
class Beam;
|
class Beam;
|
||||||
class Hook;
|
class Hook;
|
||||||
class StemSlash;
|
class StemSlash;
|
||||||
|
class Spacer;
|
||||||
|
|
||||||
enum class SymId;
|
enum class SymId;
|
||||||
|
|
||||||
|
@ -664,6 +665,7 @@ class Element : public QObject, public ScoreElement {
|
||||||
CONVERT(Hook, HOOK);
|
CONVERT(Hook, HOOK);
|
||||||
CONVERT(StemSlash, STEM_SLASH);
|
CONVERT(StemSlash, STEM_SLASH);
|
||||||
CONVERT(SlurSegment, SLUR_SEGMENT);
|
CONVERT(SlurSegment, SLUR_SEGMENT);
|
||||||
|
CONVERT(Spacer, SPACER);
|
||||||
#undef CONVERT
|
#undef CONVERT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -726,6 +728,7 @@ static inline const a* to##a(const Element* e) { Q_ASSERT(e == 0 || e->type() ==
|
||||||
CONVERT(Hook, HOOK);
|
CONVERT(Hook, HOOK);
|
||||||
CONVERT(StemSlash, STEM_SLASH);
|
CONVERT(StemSlash, STEM_SLASH);
|
||||||
CONVERT(SlurSegment, SLUR_SEGMENT);
|
CONVERT(SlurSegment, SLUR_SEGMENT);
|
||||||
|
CONVERT(Spacer, SPACER);
|
||||||
#undef CONVERT
|
#undef CONVERT
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
|
@ -1369,7 +1369,7 @@ void Score::addSystemHeader(Measure* m, bool isFirstSystem)
|
||||||
|
|
||||||
BarLine* bl = 0;
|
BarLine* bl = 0;
|
||||||
Segment* s = m->findSegment(Segment::Type::BeginBarLine, tick);
|
Segment* s = m->findSegment(Segment::Type::BeginBarLine, tick);
|
||||||
if (s && s->isBeginBarLineType())
|
if (s)
|
||||||
bl = toBarLine(s->element(0));
|
bl = toBarLine(s->element(0));
|
||||||
|
|
||||||
if ((nVisible > 1 && score()->styleB(StyleIdx::startBarlineMultiple)) || (nVisible <= 1 && score()->styleB(StyleIdx::startBarlineSingle))) {
|
if ((nVisible > 1 && score()->styleB(StyleIdx::startBarlineMultiple)) || (nVisible <= 1 && score()->styleB(StyleIdx::startBarlineSingle))) {
|
||||||
|
@ -1836,51 +1836,26 @@ static void layoutPage(Page* page, qreal restHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// sff
|
// Spring
|
||||||
// compute 1/Force for a given Extend
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
qreal sff(qreal x, qreal xMin, const SpringMap& springs)
|
struct Spring {
|
||||||
{
|
|
||||||
if (x <= xMin)
|
|
||||||
return 0.0;
|
|
||||||
auto i = springs.begin();
|
|
||||||
qreal c = i->second.stretch;
|
|
||||||
if (c == 0.0) //DEBUG
|
|
||||||
c = 1.1;
|
|
||||||
qreal f = 0.0;
|
|
||||||
for (; i != springs.end();) {
|
|
||||||
xMin -= i->second.fix;
|
|
||||||
f = (x - xMin) / c;
|
|
||||||
++i;
|
|
||||||
if (i == springs.end() || f <= i->first)
|
|
||||||
break;
|
|
||||||
c += i->second.stretch;
|
|
||||||
}
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Spring2
|
|
||||||
//---------------------------------------------------------
|
|
||||||
|
|
||||||
struct Spring2 {
|
|
||||||
int seg;
|
int seg;
|
||||||
qreal stretch;
|
qreal stretch;
|
||||||
qreal fix;
|
qreal fix;
|
||||||
Spring2(int i, qreal s, qreal f) : seg(i), stretch(s), fix(f) {}
|
Spring(int i, qreal s, qreal f) : seg(i), stretch(s), fix(f) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::multimap<qreal, Spring2, std::less<qreal> > SpringMap2;
|
typedef std::multimap<qreal, Spring, std::less<qreal> > SpringMap;
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// sff2
|
// sff2
|
||||||
// compute 1/Force for a given Extend
|
// compute 1/Force for a given Extend
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
qreal sff2(qreal x, qreal xMin, const SpringMap2& springs)
|
static qreal sff2(qreal width, qreal xMin, const SpringMap& springs)
|
||||||
{
|
{
|
||||||
if (x <= xMin)
|
if (width <= xMin)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
auto i = springs.begin();
|
auto i = springs.begin();
|
||||||
qreal c = i->second.stretch;
|
qreal c = i->second.stretch;
|
||||||
|
@ -1889,7 +1864,7 @@ qreal sff2(qreal x, qreal xMin, const SpringMap2& springs)
|
||||||
qreal f = 0.0;
|
qreal f = 0.0;
|
||||||
for (; i != springs.end();) {
|
for (; i != springs.end();) {
|
||||||
xMin -= i->second.fix;
|
xMin -= i->second.fix;
|
||||||
f = (x - xMin) / c;
|
f = (width - xMin) / c;
|
||||||
++i;
|
++i;
|
||||||
if (i == springs.end() || f <= i->first)
|
if (i == springs.end() || f <= i->first)
|
||||||
break;
|
break;
|
||||||
|
@ -1898,7 +1873,6 @@ qreal sff2(qreal x, qreal xMin, const SpringMap2& springs)
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// respace
|
// respace
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -1927,7 +1901,7 @@ void Score::respace(std::vector<ChordRest*>* elements)
|
||||||
// compute stretches
|
// compute stretches
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
|
|
||||||
SpringMap2 springs;
|
SpringMap springs;
|
||||||
qreal minimum = 0.0;
|
qreal minimum = 0.0;
|
||||||
for (int i = 0; i < n-1; ++i) {
|
for (int i = 0; i < n-1; ++i) {
|
||||||
qreal w = width[i];
|
qreal w = width[i];
|
||||||
|
@ -1935,7 +1909,7 @@ void Score::respace(std::vector<ChordRest*>* elements)
|
||||||
qreal str = 1.0 + 0.865617 * log(qreal(t) / qreal(minTick));
|
qreal str = 1.0 + 0.865617 * log(qreal(t) / qreal(minTick));
|
||||||
qreal d = w / str;
|
qreal d = w / str;
|
||||||
|
|
||||||
springs.insert(std::pair<qreal, Spring2>(d, Spring2(i, str, w)));
|
springs.insert(std::pair<qreal, Spring>(d, Spring(i, str, w)));
|
||||||
minimum += w;
|
minimum += w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2680,11 +2654,8 @@ void Score::getNextMeasure(LayoutContext& lc)
|
||||||
}
|
}
|
||||||
else if (isMaster() && s->isChordRestType()) {
|
else if (isMaster() && s->isChordRestType()) {
|
||||||
for (Element* e : s->annotations()) {
|
for (Element* e : s->annotations()) {
|
||||||
if (e->isTempoText()) {
|
if (!e->isTempoText()) // layout tempotext after stretchMeasure
|
||||||
TempoText* tt = toTempoText(e);
|
e->layout();
|
||||||
setTempo(tt->segment(), tt->tempo());
|
|
||||||
}
|
|
||||||
e->layout();
|
|
||||||
}
|
}
|
||||||
qreal stretch = 0.0;
|
qreal stretch = 0.0;
|
||||||
for (Element* e : s->elist()) {
|
for (Element* e : s->elist()) {
|
||||||
|
@ -3250,6 +3221,14 @@ System* Score::collectSystem(LayoutContext& lc)
|
||||||
cr->beam()->layout();
|
cr->beam()->layout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Element* e : s->annotations()) {
|
||||||
|
if (e->isTempoText()) {
|
||||||
|
TempoText* tt = toTempoText(e);
|
||||||
|
setTempo(tt->segment(), tt->tempo());
|
||||||
|
tt->layout();
|
||||||
|
s->staffShape(tt->staffIdx()).add(tt->shape());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
system->layout2();
|
system->layout2();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// MuseScore
|
// MuseScore
|
||||||
// Music Composition & Notation
|
// Music Composition & Notation
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002-2011 Werner Schweer
|
// Copyright (C) 2002-2016 Werner Schweer
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License version 2
|
// it under the terms of the GNU General Public License version 2
|
||||||
|
@ -17,17 +17,6 @@ namespace Ms {
|
||||||
|
|
||||||
class Segment;
|
class Segment;
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// Spring
|
|
||||||
//---------------------------------------------------------
|
|
||||||
|
|
||||||
struct Spring {
|
|
||||||
Segment* seg;
|
|
||||||
qreal stretch;
|
|
||||||
qreal fix;
|
|
||||||
Spring(Segment* s, qreal str) : seg(s), stretch(str), fix(s->width()) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// LayoutContext
|
// LayoutContext
|
||||||
// temp values used during layout
|
// temp values used during layout
|
||||||
|
@ -58,10 +47,6 @@ struct LayoutContext {
|
||||||
int adjustMeasureNo(MeasureBase*);
|
int adjustMeasureNo(MeasureBase*);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::multimap<qreal, Spring, std::less<qreal> > SpringMap;
|
|
||||||
|
|
||||||
extern qreal sff(qreal x, qreal xMin, const SpringMap& springs);
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Ms
|
} // namespace Ms
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -620,8 +620,8 @@ void Measure::add(Element* e)
|
||||||
break;
|
break;
|
||||||
case Element::Type::SEGMENT:
|
case Element::Type::SEGMENT:
|
||||||
{
|
{
|
||||||
Segment* seg = static_cast<Segment*>(e);
|
Segment* seg = toSegment(e);
|
||||||
int t = seg->tick();
|
int t = seg->tick();
|
||||||
Segment::Type st = seg->segmentType();
|
Segment::Type st = seg->segmentType();
|
||||||
Segment* s;
|
Segment* s;
|
||||||
for (s = first(); s && s->tick() < t; s = s->next())
|
for (s = first(); s && s->tick() < t; s = s->next())
|
||||||
|
@ -675,7 +675,6 @@ void Measure::add(Element* e)
|
||||||
MeasureBase::add(e);
|
MeasureBase::add(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -694,9 +693,9 @@ void Measure::remove(Element* e)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Element::Type::SPACER:
|
case Element::Type::SPACER:
|
||||||
if (static_cast<Spacer*>(e)->spacerType() == SpacerType::DOWN)
|
if (toSpacer(e)->spacerType() == SpacerType::DOWN)
|
||||||
_mstaves[e->staffIdx()]->_vspacerDown = 0;
|
_mstaves[e->staffIdx()]->_vspacerDown = 0;
|
||||||
else if (static_cast<Spacer*>(e)->spacerType() == SpacerType::UP)
|
else if (toSpacer(e)->spacerType() == SpacerType::UP)
|
||||||
_mstaves[e->staffIdx()]->_vspacerUp = 0;
|
_mstaves[e->staffIdx()]->_vspacerUp = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3199,6 +3198,10 @@ qreal Measure::userStretch() const
|
||||||
return (score()->layoutMode() == LayoutMode::FLOAT ? 1.0 : _userStretch);
|
return (score()->layoutMode() == LayoutMode::FLOAT ? 1.0 : _userStretch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// nextElementStaff
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
Element* Measure::nextElementStaff(int staff)
|
Element* Measure::nextElementStaff(int staff)
|
||||||
{
|
{
|
||||||
Segment* firstSeg = segments().first();
|
Segment* firstSeg = segments().first();
|
||||||
|
@ -3207,6 +3210,10 @@ Element* Measure::nextElementStaff(int staff)
|
||||||
return score()->firstElement();
|
return score()->firstElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// prevElementStaff
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
Element* Measure::prevElementStaff(int staff)
|
Element* Measure::prevElementStaff(int staff)
|
||||||
{
|
{
|
||||||
Measure* prevM = prevMeasureMM();
|
Measure* prevM = prevMeasureMM();
|
||||||
|
@ -3229,108 +3236,116 @@ QString Measure::accessibleInfo() const
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// stretchMeasure
|
// stretchMeasure
|
||||||
// resize width of measure to stretch
|
// resize width of measure to targetWidth
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void Measure::stretchMeasure(qreal stretch)
|
void Measure::stretchMeasure(qreal targetWidth)
|
||||||
{
|
{
|
||||||
bbox().setWidth(stretch);
|
bbox().setWidth(targetWidth);
|
||||||
|
|
||||||
int nstaves = score()->nstaves();
|
//---------------------------------------------------
|
||||||
int minTick = 100000;
|
// compute minTick and set ticks for all segments
|
||||||
|
//---------------------------------------------------
|
||||||
|
|
||||||
for (auto& s : _segments) {
|
int minTick = ticks();
|
||||||
int nticks;
|
Segment* ns = first();
|
||||||
if (s.isChordRestType()) {
|
while (ns) {
|
||||||
const Segment* nseg = s.next(Segment::Type::ChordRest);
|
Segment* s = ns;
|
||||||
nticks = (nseg ? nseg->rtick() : ticks()) - s.rtick();
|
ns = s->next();
|
||||||
if (nticks) {
|
int nticks = (ns ? ns->rtick() : ticks()) - s->rtick();
|
||||||
if (nticks < minTick)
|
if (nticks) {
|
||||||
minTick = nticks;
|
if (nticks < minTick)
|
||||||
}
|
minTick = nticks;
|
||||||
}
|
}
|
||||||
else
|
s->setTicks(nticks);
|
||||||
nticks = 0;
|
|
||||||
s.setTicks(nticks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
// computeStretch
|
// compute stretch
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
|
|
||||||
SpringMap springs;
|
// typedef std::multimap<qreal, Segment*, std::less<qreal>> SpringMap;
|
||||||
qreal minimum = first()->pos().x();
|
std::multimap<qreal, Segment*> springs;
|
||||||
|
|
||||||
for (auto& s : _segments) {
|
Q_ASSERT(minTick > 0);
|
||||||
qreal str = 1.0;
|
|
||||||
qreal d;
|
|
||||||
|
|
||||||
|
qreal minimumWidth = first()->pos().x();
|
||||||
|
for (Segment& s : _segments) {
|
||||||
int t = s.ticks();
|
int t = s.ticks();
|
||||||
if (t) {
|
if (t) {
|
||||||
if (minTick > 0)
|
qreal str = 1.0 + 0.865617 * log(qreal(t) / qreal(minTick)); // .6 * log(t / minTick) / log(2);
|
||||||
// str += .6 * log(qreal(t) / qreal(minTick)) / log(2.0);
|
qreal d = s.width() / str;
|
||||||
str = 1.0 + 0.865617 * log(qreal(t) / qreal(minTick));
|
s.setStretch(str);
|
||||||
d = s.width() / str;
|
springs.insert(std::pair<qreal, Segment*>(d, &s));
|
||||||
}
|
}
|
||||||
else {
|
minimumWidth += s.width();
|
||||||
str = 0.0; // dont stretch timeSig and key
|
|
||||||
d = 100000000.0; // CHECK
|
|
||||||
}
|
|
||||||
springs.insert(std::pair<qreal, Spring>(d, Spring(&s, str)));
|
|
||||||
minimum += s.width();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
// distribute stretch to segments
|
// compute 1/Force for a given Extend
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
|
|
||||||
qreal force = sff(stretch, minimum, springs);
|
if (targetWidth > minimumWidth) {
|
||||||
|
qreal force = 0;
|
||||||
|
qreal c = 0.0;
|
||||||
|
for (auto i = springs.begin();;) {
|
||||||
|
c += i->second->stretch();
|
||||||
|
minimumWidth -= i->second->width();
|
||||||
|
qreal f = (targetWidth - minimumWidth) / c;
|
||||||
|
++i;
|
||||||
|
if (i == springs.end() || f <= i->first) {
|
||||||
|
force = f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//---------------------------------------------------
|
||||||
|
// distribute stretch to segments
|
||||||
|
//---------------------------------------------------
|
||||||
|
|
||||||
for (auto& i : springs) {
|
for (auto& i : springs) {
|
||||||
qreal stretch = force * i.second.stretch;
|
qreal width = force * i.second->stretch();
|
||||||
if (stretch < i.second.fix)
|
if (width > i.second->width())
|
||||||
stretch = i.second.fix;
|
i.second->setWidth(width);
|
||||||
i.second.seg->setWidth(stretch);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
qreal x = first()->pos().x();
|
//---------------------------------------------------
|
||||||
for (Segment* s = first(); s; s = s->next()) {
|
// move segments to final position
|
||||||
s->rxpos() = x;
|
//---------------------------------------------------
|
||||||
x += s->width();
|
|
||||||
|
qreal x = first()->pos().x();
|
||||||
|
for (Segment& s : _segments) {
|
||||||
|
s.rxpos() = x;
|
||||||
|
x += s.width();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
// layout individual elements
|
// layout individual elements
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
|
|
||||||
int tracks = nstaves * VOICES;
|
for (Segment& s : _segments) {
|
||||||
for (Segment* s = first(); s; s = s->next()) {
|
for (Element* e : s.elist()) {
|
||||||
for (int track = 0; track < tracks; ++track) {
|
if (!e)
|
||||||
if (!score()->staff(track/VOICES)->show()) {
|
|
||||||
track += VOICES-1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Element* e = s->element(track);
|
|
||||||
if (e == 0)
|
|
||||||
continue;
|
continue;
|
||||||
Element::Type t = e->type();
|
Element::Type t = e->type();
|
||||||
Rest* rest = static_cast<Rest*>(e);
|
int staffIdx = e->staffIdx();
|
||||||
if (t == Element::Type::REPEAT_MEASURE || (t == Element::Type::REST && (isMMRest() || rest->isFullMeasureRest()))) {
|
if (t == Element::Type::REPEAT_MEASURE || (t == Element::Type::REST && (isMMRest() || toRest(e)->isFullMeasureRest()))) {
|
||||||
//
|
//
|
||||||
// element has to be centered in free space
|
// element has to be centered in free space
|
||||||
// x1 - left measure position of free space
|
// x1 - left measure position of free space
|
||||||
// x2 - right measure position of free space
|
// x2 - right measure position of free space
|
||||||
|
|
||||||
Segment* s1 = s->prev() ? s->prev() : 0;
|
Segment* s1 = s.prev() ? s.prev() : 0;
|
||||||
Segment* s2;
|
Segment* s2;
|
||||||
for (s2 = s->next(); s2; s2 = s2->next()) {
|
for (s2 = s.next(); s2; s2 = s2->next()) {
|
||||||
if (!s2->isChordRestType())
|
if (!s2->isChordRestType())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
qreal x1 = s1 ? s1->x() + s1->minRight() : 0;
|
qreal x1 = s1 ? s1->x() + s1->minRight() : 0;
|
||||||
qreal x2 = s2 ? s2->x() - s2->minLeft() : width();
|
qreal x2 = s2 ? s2->x() - s2->minLeft() : targetWidth;
|
||||||
|
|
||||||
if (isMMRest()) {
|
if (isMMRest()) {
|
||||||
|
Rest* rest = toRest(e);
|
||||||
//
|
//
|
||||||
// center multi measure rest
|
// center multi measure rest
|
||||||
//
|
//
|
||||||
|
@ -3338,19 +3353,19 @@ void Measure::stretchMeasure(qreal stretch)
|
||||||
qreal w = x2 - x1 - 2 * d;
|
qreal w = x2 - x1 - 2 * d;
|
||||||
|
|
||||||
rest->setMMWidth(w);
|
rest->setMMWidth(w);
|
||||||
StaffLines* sl = _mstaves[track/VOICES]->lines;
|
StaffLines* sl = _mstaves[staffIdx]->lines;
|
||||||
qreal x = x1 - s->x() + d;
|
qreal x = x1 - s.x() + d;
|
||||||
e->setPos(x, sl->staffHeight() * .5); // center vertically in measure
|
e->setPos(x, sl->staffHeight() * .5); // center vertically in measure
|
||||||
rest->layout();
|
rest->layout();
|
||||||
s->createShape(track/VOICES);
|
s.createShape(staffIdx);
|
||||||
}
|
}
|
||||||
else { // if (rest->isFullMeasureRest()) {
|
else { // if (rest->isFullMeasureRest()) {
|
||||||
//
|
//
|
||||||
// center full measure rest
|
// center full measure rest
|
||||||
//
|
//
|
||||||
rest->rxpos() = (x2 - x1 - e->width()) * .5 + x1 - s->x() - e->bbox().x();
|
e->rxpos() = (x2 - x1 - e->width()) * .5 + x1 - s.x() - e->bbox().x();
|
||||||
rest->adjustReadPos();
|
e->adjustReadPos();
|
||||||
s->createShape(track/VOICES); // DEBUG
|
s.createShape(staffIdx); // DEBUG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (t == Element::Type::REST)
|
else if (t == Element::Type::REST)
|
||||||
|
|
|
@ -263,8 +263,8 @@ class CmdState {
|
||||||
public:
|
public:
|
||||||
LayoutFlags layoutFlags;
|
LayoutFlags layoutFlags;
|
||||||
|
|
||||||
bool _excerptsChanged;
|
bool _excerptsChanged { false };
|
||||||
bool _instrumentsChanged;
|
bool _instrumentsChanged { false };
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
UpdateMode updateMode() const { return _updateMode; }
|
UpdateMode updateMode() const { return _updateMode; }
|
||||||
|
|
|
@ -767,10 +767,12 @@ void Segment::checkEmpty() const
|
||||||
// tick
|
// tick
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
#if 0
|
||||||
int Segment::tick() const
|
int Segment::tick() const
|
||||||
{
|
{
|
||||||
return _tick + measure()->tick();
|
return _tick + measure()->tick();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// setTick
|
// setTick
|
||||||
|
@ -1332,7 +1334,7 @@ void Segment::createShape(int staffIdx)
|
||||||
s.add(e->shape());
|
s.add(e->shape());
|
||||||
}
|
}
|
||||||
for (Element* e : _annotations) {
|
for (Element* e : _annotations) {
|
||||||
if (e->staffIdx() == staffIdx && e->visible())
|
if (e->staffIdx() == staffIdx && e->visible() && !e->isTempoText())
|
||||||
s.add(e->shape());
|
s.add(e->shape());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1359,18 +1361,22 @@ qreal Segment::minRight() const
|
||||||
qreal Segment::minLeft(const Shape& sl) const
|
qreal Segment::minLeft(const Shape& sl) const
|
||||||
{
|
{
|
||||||
qreal distance = 0.0;
|
qreal distance = 0.0;
|
||||||
for (const Shape& sh : shapes())
|
for (const Shape& sh : shapes()) {
|
||||||
distance = qMax(distance, sl.minHorizontalDistance(sh));
|
qreal d = sl.minHorizontalDistance(sh);
|
||||||
|
if (d > distance)
|
||||||
|
distance = d;
|
||||||
|
}
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal Segment::minLeft() const
|
qreal Segment::minLeft() const
|
||||||
{
|
{
|
||||||
qreal distance = 0.0;
|
qreal distance = 0.0;
|
||||||
for (const Shape& sh : shapes())
|
for (const Shape& sh : shapes()) {
|
||||||
distance = qMax(distance, sh.left());
|
qreal l = sh.left();
|
||||||
|
if (l > distance)
|
||||||
|
distance = l;
|
||||||
|
}
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1410,8 +1416,8 @@ qreal Segment::minHorizontalDistance(Segment* ns, bool systemHeaderGap) const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
d = score()->styleP(StyleIdx::barNoteDistance);
|
d = score()->styleP(StyleIdx::barNoteDistance);
|
||||||
qreal dd = minRight() + ns->minLeft();
|
qreal dd = minRight() + ns->minLeft() + spatium();
|
||||||
w = qMax(d, dd + spatium());
|
w = qMax(d, dd);
|
||||||
// d -= ns->minLeft() * .7; // hack
|
// d -= ns->minLeft() * .7; // hack
|
||||||
// d = qMax(d, ns->minLeft());
|
// d = qMax(d, ns->minLeft());
|
||||||
// d = qMax(d, spatium()); // minimum distance is one spatium
|
// d = qMax(d, spatium()); // minimum distance is one spatium
|
||||||
|
|
|
@ -66,40 +66,42 @@ class Segment : public Element {
|
||||||
Q_PROPERTY(int tick READ tick)
|
Q_PROPERTY(int tick READ tick)
|
||||||
Q_ENUMS(Type)
|
Q_ENUMS(Type)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Type {
|
// Type need to be in the order in which they appear in a measure
|
||||||
Invalid = 0x0,
|
enum class Type {
|
||||||
BeginBarLine = 0x1,
|
Invalid = 0x0,
|
||||||
Clef = 0x2, // type from Clef to TimeSig
|
BeginBarLine = 0x1,
|
||||||
KeySig = 0x4, // need to be in the order in which they
|
Clef = 0x2,
|
||||||
Ambitus = 0x8, // appear in a measure
|
KeySig = 0x4,
|
||||||
TimeSig = 0x10,
|
Ambitus = 0x8,
|
||||||
StartRepeatBarLine = 0x20,
|
TimeSig = 0x10,
|
||||||
BarLine = 0x40,
|
StartRepeatBarLine = 0x20,
|
||||||
Breath = 0x80,
|
BarLine = 0x40,
|
||||||
ChordRest = 0x100,
|
Breath = 0x80,
|
||||||
EndBarLine = 0x200,
|
ChordRest = 0x100,
|
||||||
KeySigAnnounce = 0x400,
|
EndBarLine = 0x200,
|
||||||
TimeSigAnnounce = 0x800,
|
KeySigAnnounce = 0x400,
|
||||||
All = -1
|
TimeSigAnnounce = 0x800,
|
||||||
};
|
All = -1
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Segment* _next; // linked list of segments inside a measure
|
Segment* _next; // linked list of segments inside a measure
|
||||||
Segment* _prev;
|
Segment* _prev;
|
||||||
|
|
||||||
mutable bool _empty; // cached value
|
std::vector<Element*> _annotations;
|
||||||
mutable bool _written { false }; // used for write()
|
std::vector<Element*> _elist; // Element storage, size = staves * VOICES.
|
||||||
|
std::vector<Shape> _shapes; // size = staves
|
||||||
|
std::vector<qreal> _dotPosX; // size = staves
|
||||||
|
|
||||||
Type _segmentType { Type::Invalid };
|
Spatium _extraLeadingSpace;
|
||||||
|
qreal _stretch;
|
||||||
int _tick;
|
int _tick;
|
||||||
int _ticks;
|
int _ticks;
|
||||||
Spatium _extraLeadingSpace;
|
Type _segmentType { Type::Invalid };
|
||||||
|
|
||||||
std::vector<Element*> _annotations;
|
mutable bool _empty; // cached value
|
||||||
std::vector<Element*> _elist; ///< Element storage, size = staves * VOICES.
|
mutable bool _written { false }; // used for write()
|
||||||
std::vector<Shape> _shapes; // size = staves
|
|
||||||
std::vector<qreal> _dotPosX; ///< size = staves
|
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void checkEmpty() const;
|
void checkEmpty() const;
|
||||||
|
@ -176,8 +178,11 @@ public:
|
||||||
void removeGeneratedElements();
|
void removeGeneratedElements();
|
||||||
bool empty() const { return _empty; }
|
bool empty() const { return _empty; }
|
||||||
void fixStaffIdx();
|
void fixStaffIdx();
|
||||||
|
|
||||||
|
qreal stretch() const { return _stretch; }
|
||||||
|
void setStretch(qreal v) { _stretch = v; }
|
||||||
void setTick(int);
|
void setTick(int);
|
||||||
virtual int tick() const override;
|
virtual int tick() const override { return _tick + parent()->tick(); }
|
||||||
virtual int rtick() const override { return _tick; } // tickposition relative to measure start
|
virtual int rtick() const override { return _tick; } // tickposition relative to measure start
|
||||||
void setRtick(int val) { _tick = val; }
|
void setRtick(int val) { _tick = val; }
|
||||||
int ticks() const { return _ticks; }
|
int ticks() const { return _ticks; }
|
||||||
|
|
|
@ -83,6 +83,10 @@ void SegmentList::check()
|
||||||
if (l != _last) {
|
if (l != _last) {
|
||||||
qFatal("SegmentList::check: bad last");
|
qFatal("SegmentList::check: bad last");
|
||||||
}
|
}
|
||||||
|
if (f->prev())
|
||||||
|
qFatal("SegmentList::check: first has prev");
|
||||||
|
if (l->next())
|
||||||
|
qFatal("SegmentList::check: last has next");
|
||||||
if (n != _size) {
|
if (n != _size) {
|
||||||
qFatal("SegmentList::check: counted %d but _size is %d", n, _size);
|
qFatal("SegmentList::check: counted %d but _size is %d", n, _size);
|
||||||
_size = n;
|
_size = n;
|
||||||
|
@ -107,34 +111,46 @@ void SegmentList::insert(Segment* e, Segment* el)
|
||||||
e->setPrev(el->prev());
|
e->setPrev(el->prev());
|
||||||
el->prev()->setNext(e);
|
el->prev()->setNext(e);
|
||||||
el->setPrev(e);
|
el->setPrev(e);
|
||||||
check();
|
|
||||||
}
|
}
|
||||||
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// remove
|
// remove
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
void SegmentList::remove(Segment* el)
|
void SegmentList::remove(Segment* e)
|
||||||
{
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
check();
|
||||||
|
bool found = false;
|
||||||
|
for (Segment* s = _first; s; s = s->next()) {
|
||||||
|
if (e == s) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
qFatal("segment %p %s not in list", e, e->subTypeName());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
--_size;
|
--_size;
|
||||||
if (el == _first) {
|
if (e == _first) {
|
||||||
_first = _first->next();
|
_first = _first->next();
|
||||||
if (_first)
|
if (_first)
|
||||||
_first->setPrev(0);
|
_first->setPrev(0);
|
||||||
if (el == _last)
|
if (e == _last)
|
||||||
_last = 0;
|
_last = 0;
|
||||||
}
|
}
|
||||||
else if (el == _last) {
|
else if (e == _last) {
|
||||||
_last = _last->prev();
|
_last = _last->prev();
|
||||||
if (_last)
|
if (_last)
|
||||||
_last->setNext(0);
|
_last->setNext(0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
el->prev()->setNext(el->next());
|
e->prev()->setNext(e->next());
|
||||||
el->next()->setPrev(el->prev());
|
e->next()->setPrev(e->prev());
|
||||||
}
|
}
|
||||||
check();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
@ -171,54 +187,6 @@ void SegmentList::push_front(Segment* e)
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
// insert
|
|
||||||
//---------------------------------------------------------
|
|
||||||
|
|
||||||
void SegmentList::insert(Segment* seg)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug("insertSeg <%s> %p %p %p", seg->subTypeName(), seg->prev(), seg, seg->next());
|
|
||||||
check();
|
|
||||||
for (Segment* s = _first; s; s = s->next()) {
|
|
||||||
if (s == seg) {
|
|
||||||
qFatal("SegmentList::insert: already in list");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (seg->prev()) {
|
|
||||||
Segment* s;
|
|
||||||
for (s = _first; s; s = s->next()) {
|
|
||||||
if (s == seg->prev())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (s != seg->prev()) {
|
|
||||||
qFatal("SegmentList::insert: seg->prev() not in list");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seg->next()) {
|
|
||||||
Segment* s;
|
|
||||||
for (s = _first; s; s = s->next()) {
|
|
||||||
if (s == seg->next())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (s != seg->next()) {
|
|
||||||
qFatal("SegmentList::insert: seg->next() not in list");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (seg->prev())
|
|
||||||
seg->prev()->setNext(seg);
|
|
||||||
else
|
|
||||||
_first = seg;
|
|
||||||
if (seg->next())
|
|
||||||
seg->next()->setPrev(seg);
|
|
||||||
else
|
|
||||||
_last = seg;
|
|
||||||
++_size;
|
|
||||||
check();
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// firstCRSegment
|
// firstCRSegment
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
|
@ -45,8 +45,7 @@ class SegmentList {
|
||||||
void remove(Segment*);
|
void remove(Segment*);
|
||||||
void push_back(Segment*);
|
void push_back(Segment*);
|
||||||
void push_front(Segment*);
|
void push_front(Segment*);
|
||||||
void insert(Segment*);
|
void insert(Segment* e, Segment* el); // insert e before el
|
||||||
void insert(Segment* e, Segment* el);
|
|
||||||
|
|
||||||
class iterator {
|
class iterator {
|
||||||
Segment* p;
|
Segment* p;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
namespace Ms {
|
namespace Ms {
|
||||||
|
|
||||||
// #define DEBUG_SHAPES
|
#define DEBUG_SHAPES
|
||||||
|
|
||||||
class Segment;
|
class Segment;
|
||||||
|
|
||||||
|
|
|
@ -279,31 +279,29 @@ QVariant TempoText::propertyDefault(P_ID id) const
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// layout
|
// layout
|
||||||
|
// called after Measure->stretchMeasure()
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
void TempoText::layout()
|
void TempoText::layout()
|
||||||
{
|
{
|
||||||
setPos(textStyle().offset(spatium()));
|
setPos(textStyle().offset(spatium()));
|
||||||
Text::layout1();
|
Text::layout1();
|
||||||
|
|
||||||
|
// tempo text on first chordrest of measure should align over time sig if present
|
||||||
|
//
|
||||||
Segment* s = segment();
|
Segment* s = segment();
|
||||||
if (s && !s->rtick()) {
|
if (s && !s->rtick()) {
|
||||||
// tempo text on first chordrest of measure should align over time sig if present
|
|
||||||
Segment* p = segment()->prev(Segment::Type::TimeSig);
|
Segment* p = segment()->prev(Segment::Type::TimeSig);
|
||||||
if (p) {
|
if (p) {
|
||||||
rxpos() -= s->x() - p->x();
|
rxpos() -= s->x() - p->x();
|
||||||
Element* e = p->element(staffIdx() * VOICES);
|
Element* e = p->element(staffIdx() * VOICES);
|
||||||
if (e)
|
if (e)
|
||||||
rxpos() += e->x();
|
rxpos() += e->x();
|
||||||
// correct user offset in older scores
|
|
||||||
if (score()->mscVersion() <= 114 && !userOff().isNull())
|
|
||||||
rUserXoffset() += s->x() - p->x();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (placement() == Element::Placement::BELOW) {
|
|
||||||
|
if (placement() == Element::Placement::BELOW)
|
||||||
rypos() = -rypos() + 4 * spatium();
|
rypos() = -rypos() + 4 * spatium();
|
||||||
// rUserYoffset() *= -1;
|
|
||||||
// text height ?
|
|
||||||
}
|
|
||||||
adjustReadPos();
|
adjustReadPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@
|
||||||
<Segment>
|
<Segment>
|
||||||
<subtype>0</subtype>
|
<subtype>0</subtype>
|
||||||
<off2 x="0" y="0"/>
|
<off2 x="0" y="0"/>
|
||||||
<pos x="33.8175" y="6.60645"/>
|
<pos x="34.0159" y="6.60645"/>
|
||||||
</Segment>
|
</Segment>
|
||||||
<beginText>
|
<beginText>
|
||||||
<text>cresc.</text>
|
<text>cresc.</text>
|
||||||
|
|
|
@ -194,7 +194,7 @@
|
||||||
<Segment>
|
<Segment>
|
||||||
<subtype>0</subtype>
|
<subtype>0</subtype>
|
||||||
<off2 x="0" y="0"/>
|
<off2 x="0" y="0"/>
|
||||||
<pos x="33.8175" y="6.60645"/>
|
<pos x="34.0159" y="6.60645"/>
|
||||||
</Segment>
|
</Segment>
|
||||||
<beginText>
|
<beginText>
|
||||||
<text>cresc.</text>
|
<text>cresc.</text>
|
||||||
|
|
|
@ -337,7 +337,7 @@ MasterScore* TestParts::doAddBreath()
|
||||||
|
|
||||||
Measure* m = score->firstMeasure();
|
Measure* m = score->firstMeasure();
|
||||||
Segment* s = m->tick2segment(MScore::division);
|
Segment* s = m->tick2segment(MScore::division);
|
||||||
Ms::Chord* chord = static_cast<Ms::Chord*>(s->element(0));
|
Ms::Chord* chord = toChord(s->element(0));
|
||||||
Note* note = chord->upNote();
|
Note* note = chord->upNote();
|
||||||
DropData dd;
|
DropData dd;
|
||||||
dd.view = 0;
|
dd.view = 0;
|
||||||
|
|
Loading…
Reference in a new issue