Skip to content

Commit

Permalink
Fix #6107 : bar lines and brackets disappearing when some of the staf…
Browse files Browse the repository at this point in the history
…f they span is hidden

Fixed by analyzing brackets and bar line spans rather than only relying on start and stop staff Y offset (which is not set if the staff is not shown).

Note: there are still issues with measure numbers, but these belong more to system items than to bar lining.
  • Loading branch information
mgavioli committed Dec 28, 2013
1 parent b83bb62 commit f978323
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 17 deletions.
42 changes: 36 additions & 6 deletions libmscore/barline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,16 +133,43 @@ void BarLine::getY(qreal* y1, qreal* y2) const
measure = system->firstMeasure();
}
if (measure) {
// test start and end staff visibility
int span = _span;
Staff* staff1 = score()->staff(staffIdx1);
Staff* staff2 = score()->staff(staffIdx2);
SysStaff* sysStaff1 = system->staff(staffIdx1);
SysStaff* sysStaff2 = system->staff(staffIdx2);
while (span > 0) {
// if start staff not shown, reduce span and move one staff down
if ( !(sysStaff1->show() && staff1->show()) ) {
span--;
sysStaff1 = system->staff(++staffIdx1);
staff1 = score()->staff(staffIdx1);
}
// if end staff not shown, reduce span and move one staff up
else if ( !(sysStaff2->show() && staff2->show()) ) {
span--;
sysStaff2 = system->staff(--staffIdx2);
staff2 = score()->staff(staffIdx2);
}
// if both staves shown, exit loop
else
break;
}
// if no longer any span, set 0 length and exit
if (span <= 0) {
*y1 = *y2 = 0;
return;
}
// both staffIdx1 and staffIdx2 are shown: compute corresponding line length
StaffLines* l1 = measure->staffLines(staffIdx1);
StaffLines* l2 = measure->staffLines(staffIdx2);

if (system)
yp += system->staff(staffIdx1)->y();
yp += sysStaff1->y();
*y1 = l1->y1() - yp;
Staff* staff1 = score()->staff(staffIdx1);
*y1 += (_spanFrom * staff1->lineDistance() * staff1->spatium()) / 2;
*y2 = l2->y1() - yp;
Staff* staff2 = score()->staff(staffIdx2);
*y2 += (_spanTo * staff2->lineDistance() * staff2->spatium()) / 2;
}
}
Expand Down Expand Up @@ -201,11 +228,14 @@ void BarLine::drawDots(QPainter* painter, qreal x) const

void BarLine::draw(QPainter* painter) const
{
qreal _spatium = score()->spatium();

qreal lw = score()->styleS(ST_barWidth).val() * _spatium;
// get line length and do nothing if 0 (or near enough)
qreal y1, y2;
getY(&y1, &y2);
if (y2-y1 < 0.1)
return;

qreal _spatium = score()->spatium();
qreal lw = score()->styleS(ST_barWidth).val() * _spatium;

QPen pen(curColor(), lw, Qt::SolidLine, Qt::FlatCap);
painter->setPen(pen);
Expand Down
39 changes: 30 additions & 9 deletions libmscore/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2273,17 +2273,38 @@ void Measure::scanElements(void* data, void (*func)(void*, Element*), bool all)

int tracks = nstaves * VOICES;
for (Segment* s = first(); s; s = s->next()) {
for (int track = 0; track < tracks; ++track) {
int staffIdx = track/VOICES;
if (!all && !(visible(staffIdx) && score()->staff(staffIdx)->show())) {
track += VOICES - 1;
continue;
// bar line visibility depends on spanned staves,
// not simply on visibility of first staff
if (s->segmentType() == Segment::SegBarLine || s->segmentType() == Segment::SegEndBarLine
|| Segment::SegStartRepeatBarLine) {
for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
Element* e = s->element(staffIdx*VOICES);
if (e == 0) // if no element, skip
continue;
// if staff not visible
if (!all && !(visible(staffIdx) && score()->staff(staffIdx)->show())) {
// if bar line spans just this staff...
if (static_cast<BarLine*>(e)->span() <= 1
// ...or span another staff but without entering INTO it...
|| (static_cast<BarLine*>(e)->span() < 2 &&
static_cast<BarLine*>(e)->spanTo() < 1) )
continue; // ...skip
}
e->scanElements(data, func, all);
}
Element* e = s->element(track);
if (e == 0)
continue;
e->scanElements(data, func, all);
}
else
for (int track = 0; track < tracks; ++track) {
int staffIdx = track/VOICES;
if (!all && !(visible(staffIdx) && score()->staff(staffIdx)->show())) {
track += VOICES - 1;
continue;
}
Element* e = s->element(track);
if (e == 0)
continue;
e->scanElements(data, func, all);
}
foreach(Element* e, s->annotations()) {
if (all || e->systemFlag() || visible(e->staffIdx()))
e->scanElements(data, func, all);
Expand Down
16 changes: 14 additions & 2 deletions libmscore/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,20 @@ void System::layout2()
n = _brackets.size();
for (int i = 0; i < n; ++i) {
Bracket* b = _brackets.at(i);
qreal sy = _staves[b->firstStaff()]->bbox().top();
qreal ey = _staves[b->lastStaff()]->bbox().bottom();
int staffIdx1 = b->firstStaff();
int staffIdx2 = b->lastStaff();
qreal sy = 0; // assume bracket not visible
qreal ey = 0;
// if start staff not visible, try next staff
while (!_staves[staffIdx1]->show() && staffIdx1 < staffIdx2)
++staffIdx1;
// if end staff not visible, try prev staff
while (!_staves[staffIdx2]->show() && staffIdx1 < staffIdx2)
--staffIdx2;
if (staffIdx1 < staffIdx2) { // if at least two staves visible for this bracket
sy = _staves[staffIdx1]->bbox().top();
ey = _staves[staffIdx2]->bbox().bottom();
}
b->rypos() = sy;
b->setHeight(ey - sy);
b->layout();
Expand Down

0 comments on commit f978323

Please sign in to comment.