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