Merge pull request #4768 from dmitrio95/skyline_opt2
Skylines construction optimization
This commit is contained in:
commit
fc515c4601
3 changed files with 72 additions and 17 deletions
|
@ -3507,6 +3507,9 @@ void Score::layoutSystemElements(System* system, LayoutContext& lc)
|
|||
if (!mb->isMeasure())
|
||||
continue;
|
||||
Measure* m = toMeasure(mb);
|
||||
if (MeasureNumber* mno = m->noText(staffIdx))
|
||||
ss->skyline().add(mno->bbox().translated(m->pos() + mno->pos()));
|
||||
ss->skyline().add(m->staffLines(staffIdx)->bbox().translated(m->pos()));
|
||||
for (Segment& s : m->segments()) {
|
||||
if (!s.enabled() || s.isTimeSigType()) // hack: ignore time signatures
|
||||
continue;
|
||||
|
@ -3534,7 +3537,6 @@ void Score::layoutSystemElements(System* system, LayoutContext& lc)
|
|||
}
|
||||
for (auto n : c->notes())
|
||||
notes.push_back(n);
|
||||
std::list<Fingering*> fingerings;
|
||||
for (Note* note : notes) {
|
||||
for (Element* e : note->el()) {
|
||||
if (e->isFingering()) {
|
||||
|
@ -3561,10 +3563,6 @@ void Score::layoutSystemElements(System* system, LayoutContext& lc)
|
|||
}
|
||||
}
|
||||
}
|
||||
ss->skyline().add(m->staffLines(staffIdx)->bbox().translated(m->pos()));
|
||||
MeasureNumber* mno = m->noText(staffIdx);
|
||||
if (mno)
|
||||
ss->skyline().add(mno->bbox().translated(m->pos() + mno->pos()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,46 @@ void Skyline::add(const QRectF& r)
|
|||
_south.add(r.x(), r.bottom(), r.width());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// insert
|
||||
//---------------------------------------------------------
|
||||
|
||||
SkylineLine::SegIter SkylineLine::insert(SegIter i, qreal x, qreal y, qreal w)
|
||||
{
|
||||
const qreal xr = x + w;
|
||||
// Only x coordinate change is handled here as width change gets handled
|
||||
// in SkylineLine::add().
|
||||
if (i != seg.end() && xr > i->x)
|
||||
i->x = xr;
|
||||
return seg.emplace(i, x, y, w);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// append
|
||||
//---------------------------------------------------------
|
||||
|
||||
void SkylineLine::append(qreal x, qreal y, qreal w)
|
||||
{
|
||||
seg.emplace_back(x, y, w);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// getApproxPosition
|
||||
//---------------------------------------------------------
|
||||
|
||||
SkylineLine::SegIter SkylineLine::find(qreal x)
|
||||
{
|
||||
auto it = std::upper_bound(seg.begin(), seg.end(), x, [](qreal x, const SkylineSegment& s) { return x < s.x; });
|
||||
if (it == seg.begin())
|
||||
return it;
|
||||
return (--it);
|
||||
}
|
||||
|
||||
SkylineLine::SegConstIter SkylineLine::find(qreal x) const
|
||||
{
|
||||
return const_cast<SkylineLine*>(this)->find(x);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// add
|
||||
//---------------------------------------------------------
|
||||
|
@ -72,8 +112,10 @@ void SkylineLine::add(qreal x, qreal y, qreal w)
|
|||
}
|
||||
|
||||
DP("===add %f %f %f\n", x, y, w);
|
||||
qreal cx = 0.0;
|
||||
for (auto i = begin(); i != end(); ++i) {
|
||||
|
||||
SegIter i = find(x);
|
||||
qreal cx = seg.empty() ? 0.0 : i->x;
|
||||
for (; i != seg.end(); ++i) {
|
||||
qreal cy = i->y;
|
||||
if ((x + w) <= cx) // A
|
||||
return; // break;
|
||||
|
@ -93,7 +135,7 @@ void SkylineLine::add(qreal x, qreal y, qreal w)
|
|||
if (w1 > 0.0000001) {
|
||||
i->w = w1;
|
||||
++i;
|
||||
i = insert(i, SkylineSegment(y, w2));
|
||||
i = insert(i, x, y, w2);
|
||||
DP(" A w1 %f w2 %f\n", w1, w2);
|
||||
}
|
||||
else {
|
||||
|
@ -104,7 +146,7 @@ void SkylineLine::add(qreal x, qreal y, qreal w)
|
|||
if (w3 > 0.0000001) {
|
||||
++i;
|
||||
DP(" C w3 %f\n", w3);
|
||||
insert(i, SkylineSegment(cy, w3));
|
||||
insert(i, x + w2, cy, w3);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -116,7 +158,7 @@ void SkylineLine::add(qreal x, qreal y, qreal w)
|
|||
qreal w1 = x + w - cx;
|
||||
i->w -= w1;
|
||||
DP(" add(C) cx %f y %f w %f w1 %f\n", cx, y, w1, i->w);
|
||||
insert(i, SkylineSegment(y, w1));
|
||||
insert(i, cx, y, w1);
|
||||
return;
|
||||
}
|
||||
else { // D
|
||||
|
@ -127,7 +169,7 @@ void SkylineLine::add(qreal x, qreal y, qreal w)
|
|||
cx += w1;
|
||||
DP(" add(D) %f %f\n", y, w2);
|
||||
++i;
|
||||
i = insert(i, SkylineSegment(y, w2));
|
||||
i = insert(i, cx, y, w2);
|
||||
}
|
||||
}
|
||||
cx += i->w;
|
||||
|
@ -136,13 +178,13 @@ void SkylineLine::add(qreal x, qreal y, qreal w)
|
|||
if (x > cx) {
|
||||
qreal cy = north ? MAXIMUM_Y : MINIMUM_Y;
|
||||
DP(" append1 %f %f\n", cy, x - cx);
|
||||
push_back(SkylineSegment(cy, x - cx));
|
||||
append(cx, cy, x - cx);
|
||||
}
|
||||
DP(" append2 %f %f\n", y, w);
|
||||
push_back(SkylineSegment(y, w));
|
||||
append(x, y, w);
|
||||
}
|
||||
else if (x + w > cx)
|
||||
push_back(SkylineSegment(y, x + w - cx));
|
||||
append(cx, y, x + w - cx);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -27,30 +27,45 @@ class Shape;
|
|||
//---------------------------------------------------------
|
||||
|
||||
struct SkylineSegment {
|
||||
qreal x;
|
||||
qreal y;
|
||||
qreal w;
|
||||
|
||||
SkylineSegment(qreal _y, qreal _w) : y(_y), w(_w) {}
|
||||
SkylineSegment(qreal _x, qreal _y, qreal _w) : x(_x), y(_y), w(_w) {}
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// SkylineLine
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct SkylineLine : public std::vector<SkylineSegment> {
|
||||
class SkylineLine {
|
||||
const bool north;
|
||||
std::vector<SkylineSegment> seg;
|
||||
typedef std::vector<SkylineSegment>::iterator SegIter;
|
||||
typedef std::vector<SkylineSegment>::const_iterator SegConstIter;
|
||||
|
||||
SegIter insert(SegIter i, qreal x, qreal y, qreal w);
|
||||
void append(qreal x, qreal y, qreal w);
|
||||
SegIter find(qreal x);
|
||||
SegConstIter find(qreal x) const;
|
||||
|
||||
public:
|
||||
SkylineLine(bool n) : north(n) {}
|
||||
void add(qreal x, qreal y, qreal w);
|
||||
void add(const Shape& s);
|
||||
void add(const QRectF& r);
|
||||
void add(qreal x, qreal y, qreal w);
|
||||
void clear() { seg.clear(); }
|
||||
void paint(QPainter&) const;
|
||||
void dump() const;
|
||||
qreal minDistance(const SkylineLine&) const;
|
||||
qreal max() const;
|
||||
bool valid(const SkylineSegment& s) const;
|
||||
bool isNorth() const { return north; }
|
||||
|
||||
SegIter begin() { return seg.begin(); }
|
||||
SegConstIter begin() const { return seg.begin(); }
|
||||
SegIter end() { return seg.end(); }
|
||||
SegConstIter end() const { return seg.end(); }
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue