void KeySig::layout() { qreal _spatium = spatium(); setbbox(QRectF()); if (isCustom()) { foreach(KeySym* ks, keySymbols) { ks->pos = ks->spos * _spatium; addbbox(symbols[score()->symIdx()][ks->sym].bbox(magS()).translated(ks->pos)); } return; }
void KeySig::layout() { qreal _spatium = spatium(); setbbox(QRectF()); if (staff() && !staff()->genKeySig()) { // no key sigs on TAB staves qDeleteAll(keySymbols); return; } if (isCustom()) { foreach(KeySym* ks, keySymbols) { ks->pos = ks->spos * _spatium; addbbox(symBbox(ks->sym).translated(ks->pos)); } return; }
void KeySig::layout() { qreal _spatium = spatium(); setbbox(QRectF()); if (staff() && !staff()->genKeySig()) { // no key sigs on TAB staves foreach(KeySym* ks, keySymbols) delete ks; keySymbols.clear(); return; } if (isCustom()) { foreach(KeySym* ks, keySymbols) { ks->pos = ks->spos * _spatium; addbbox(symbols[score()->symIdx()][ks->sym].bbox(magS()).translated(ks->pos)); } return; }
void Tremolo::layout() { qreal _spatium = spatium() * mag(); qreal w2 = _spatium * score()->styleS(StyleIdx::tremoloWidth).val() * .5; qreal lw = _spatium * score()->styleS(StyleIdx::tremoloStrokeWidth).val(); qreal td = _spatium * score()->styleS(StyleIdx::tremoloDistance).val(); path = QPainterPath(); qreal ty = 0.0; for (int i = 0; i < _lines; i++) { path.addRect(-w2, ty, 2.0 * w2, lw); ty += td; } // QRectF rect = path.boundingRect(); // if ((parent() == 0) && !twoNotes()) // rect.setHeight(rect.height() + _spatium); _chord1 = static_cast<Chord*>(parent()); if (_chord1 == 0) { // just for the palette QTransform shearTransform; shearTransform.shear(0.0, -(lw / 2.0) / w2); path = shearTransform.map(path); setbbox(path.boundingRect()); addbbox(QRectF(bbox().x(), bbox().bottom(), bbox().width(), _spatium)); return; } Note* anchor1 = _chord1->upNote(); Stem* stem = _chord1->stem(); qreal x, y, h; if (stem) { x = stem->pos().x(); y = stem->pos().y(); h = stem->stemLen(); } else { // center tremolo above note x = anchor1->x() + anchor1->headWidth() * .5; y = anchor1->y(); h = 2.0 * _spatium + bbox().height(); if (anchor1->line() > 4) h *= -1; } if (!twoNotes()) { // // single note tremolos // bool up = _chord1->up(); int line = up ? _chord1->upLine() : _chord1->downLine(); static const qreal t[3][2][4][2] = { // normal stem { // DOWN { // even line odd line { 6, 5 }, // line 1 { 6 - 2 * .8, 5 - 2 * .8 }, // line 2 { 6 - 4 * .8, 3 }, // line 3 { 2 , 3 } // line 4 }, // UP { // even line odd line { -6, -5 }, // line 1 { -6, -5 }, // line 2 { -6, -3 - 4 * .8 }, // line 3 { -2 - 6 * .8, -3 - 6 * .8 } // line 4 } }, // stem with hook { // DOWN { // even line odd line { 3, 3 }, // line 1 { 2, 2 }, // line 2 { 2, 2 }, // line 3 { 2, 2 } // line 4 }, // UP { // even line odd line { -3, -3 }, // line 1 { -2 - 2 * .8, -2 - 2 * .8 }, // line 2 { -2 - 4 * .8, -2 - 4 * .8 }, // line 3 { -2 - 6 * .8, -2 - 6 * .8 } // line 4 } }, // stem with beam { // DOWN { // even line odd line { 3, 3 }, // line 1 { 2, 2 }, // line 2 { 2, 2 }, // line 3 { 2, 2 } // line 4 }, // UP { // even line odd line { -3, -3 }, // line 1 { -2 - 2 * .8, -2 - 2 * .8 }, // line 2 { -2 - 4 * .8, -2 - 4 * .8 }, // line 3 { -2 - 6 * .8, -2 - 6 * .8 } // line 4 } }, }; int idx = _chord1->hook() ? 1 : (_chord1->beam() ? 2 : 0); y = (line + t[idx][up][_lines-1][line & 1]) * spatium() * .5; QTransform shearTransform; shearTransform.shear(0.0, -(lw / 2.0) / w2); path = shearTransform.map(path); setbbox(path.boundingRect()); setPos(x, y); adjustReadPos(); return; } y += (h - bbox().height()) * .5; // // two chord tremolo // Segment* s = _chord1->segment()->next(); while (s) { if (s->element(track()) && (s->element(track())->type() == Element::Type::CHORD)) break; s = s->next(); } if (s == 0) { qDebug("no second note of tremolo found"); return; } _chord2 = static_cast<Chord*>(s->element(track())); _chord2->setTremolo(this); Stem* stem1 = _chord1->stem(); Stem* stem2 = _chord2->stem(); // compute the y coordinates of the tips of the stems qreal y1, y2; qreal firstChordStaffY; if (stem2 && stem1) { // stemPageYOffset variable is used for the case when the first // chord is cross-staff firstChordStaffY = stem1->pagePos().y() - stem1->y(); // y coordinate of the staff of the first chord y1 = stem1->y() + stem1->p2().y(); y2 = stem2->pagePos().y() - firstChordStaffY + stem2->p2().y(); // ->p2().y() is better than ->stemLen() } else { firstChordStaffY = _chord1->pagePos().y() - _chord1->y(); // y coordinate of the staff of the first chord y1 = _chord1->stemPosBeam().y() - firstChordStaffY + _chord1->defaultStemLength(); y2 = _chord2->stemPosBeam().y() - firstChordStaffY + _chord2->defaultStemLength(); } // improve the case when one stem is up and another is down if (_chord1->beams() == 0 && _chord2->beams() == 0 && _chord1->up() != _chord2->up()) { qreal meanNote1Y = .5 * (_chord1->upNote()->pagePos().y() - firstChordStaffY + _chord1->downNote()->pagePos().y() - firstChordStaffY); qreal meanNote2Y = .5 * (_chord2->upNote()->pagePos().y() - firstChordStaffY + _chord2->downNote()->pagePos().y() - firstChordStaffY); y1 = .5 * (y1 + meanNote1Y); y2 = .5 * (y2 + meanNote2Y); } y = (y1 + y2) * .5; if (!_chord1->up()) { y -= path.boundingRect().height() * .5; } if (!_chord2->up()) { y -= path.boundingRect().height() * .5; } // compute the x coordinates of the inner edge of the stems qreal x2 = _chord2->stemPosBeam().x(); if (_chord2->up() && stem2) x2 -= stem2->lineWidth(); qreal x1 = _chord1->stemPosBeam().x(); if (!_chord1->up() && stem1) x1 += stem1->lineWidth(); x = (x1 + x2) * .5 - _chord1->pagePos().x(); QTransform xScaleTransform; // TODO const qreal H_MULTIPLIER = score()->styleS(StyleIdx::tremoloBeamLengthMultiplier).val(); const qreal H_MULTIPLIER = 0.62; // TODO const qreal MAX_H_LENGTH = _spatium * score()->styleS(StyleIdx::tremoloBeamLengthMultiplier).val(); const qreal MAX_H_LENGTH = _spatium * 12.0; qreal xScaleFactor = qMin(H_MULTIPLIER * (x2 - x1), MAX_H_LENGTH); xScaleFactor /= (2.0 * w2); xScaleTransform.scale(xScaleFactor, 1.0); path = xScaleTransform.map(path); qreal beamYOffset = 0.0; if (_chord1->beams() == _chord2->beams() && _chord1->beam()) { int beams = _chord1->beams(); qreal beamHalfLineWidth = point(score()->styleS(StyleIdx::beamWidth)) * .5 * mag(); beamYOffset = beams * _chord1->beam()->beamDist() - beamHalfLineWidth; if (_chord1->up() != _chord2->up()) { // cross-staff beamYOffset += beamYOffset + beamHalfLineWidth; } else if (!_chord1->up() && !_chord2->up()) { beamYOffset = -beamYOffset; } } QTransform shearTransform; if (_chord1->beams() == 0 && _chord2->beams() == 0) { if (_chord1->up() && !_chord2->up()) shearTransform.shear(0.0, (y2 - y1 - path.boundingRect().height()) / (x2 - x1)); else if (!_chord1->up() && _chord2->up()) shearTransform.shear(0.0, (y2 - y1 + path.boundingRect().height()) / (x2 - x1)); else shearTransform.shear(0.0, (y2 - y1) / (x2 - x1)); } else { shearTransform.shear(0.0, (y2 - y1) / (x2 - x1)); } path = shearTransform.map(path); setbbox(path.boundingRect()); setPos(x, y + beamYOffset); adjustReadPos(); }
void Clef::layout1() { qreal smag = _small ? score()->style(ST_smallClefMag).toDouble() : 1.0; qreal _spatium = spatium(); qreal msp = _spatium * smag; qreal yoff = 0.0; qDeleteAll(elements); elements.clear(); Symbol* symbol = new Symbol(score()); switch (curClefType) { case CLEF_G: // G clef on 2nd line symbol->setSym(trebleclefSym); yoff = 3.0 * curLineDist; break; case CLEF_G1: // G clef 8va on 2nd line { symbol->setSym(trebleclefSym); yoff = 3.0 * curLineDist; Symbol* number = new Symbol(score()); number->setMag(smag); number->setSym(clefEightSym); addElement(number, 1.0 * msp, -5.0 * msp + yoff * _spatium); } break; case CLEF_G2: // G clef 15ma on 2nd line { symbol->setSym(trebleclefSym); yoff = 3.0 * curLineDist; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefOneSym); addElement(number, .6 * msp, -5.0 * msp + yoff * _spatium); number = new Symbol(score()); number->setSym(clefFiveSym); addElement(number, 1.4 * msp, -5.0 * msp + yoff * _spatium); } break; case CLEF_G3: // G clef 8va bassa on 2nd line { symbol->setSym(trebleclefSym); yoff = 3.0 * curLineDist; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefEightSym); addElement(number, 1.0 * msp, 4.0 * msp + yoff * _spatium); } break; case CLEF_F: // F clef on penultimate line symbol->setSym(bassclefSym); yoff = 1.0 * curLineDist; break; case CLEF_F8: // F clef 8va bassa on penultimate line { symbol->setSym(bassclefSym); yoff = 1.0 * curLineDist; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefEightSym); addElement(number, .0, 4.5 * msp + yoff * _spatium); } break; case CLEF_F15: // F clef 15ma bassa on penultimate line { symbol->setSym(bassclefSym); yoff = 1.0 * curLineDist; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefOneSym); addElement(number, .0, 4.5 * msp + yoff * _spatium); number = new Symbol(score()); number->setSym(clefFiveSym); addElement(number, .8 * msp, 4.5 * msp + yoff * _spatium); } break; case CLEF_F_B: // baritone clef symbol->setSym(bassclefSym); yoff = 2.0 * curLineDist; break; case CLEF_F_C: // subbass clef symbol->setSym(bassclefSym); yoff = 0.0; break; case CLEF_C1: // C clef in 1st line symbol->setSym(altoclefSym); yoff = 4.0 * curLineDist; break; case CLEF_C2: // C clef on 2nd line symbol->setSym(altoclefSym); yoff = 3.0 * curLineDist; break; case CLEF_C3: // C clef in 3rd line symbol->setSym(altoclefSym); yoff = 2.0 * curLineDist; break; case CLEF_C4: // C clef on 4th line symbol->setSym(altoclefSym); yoff = 1.0 * curLineDist; break; case CLEF_C5: // C clef on 5th line symbol->setSym(altoclefSym); yoff = 0.0; break; case CLEF_TAB: // TAB clef symbol->setSym(tabclefSym); // on tablature, position clef at half the number of spaces * line distance yoff = curLineDist * (curLines - 1) * .5; break; // TAB clef alternate style case CLEF_TAB2: symbol->setSym(tabclef2Sym); // on tablature, position clef at half the number of spaces * line distance yoff = curLineDist * (curLines - 1) * .5; break; case CLEF_PERC: // percussion clefs case CLEF_PERC2: symbol->setSym(percussionclefSym); yoff = curLineDist * (curLines - 1) * 0.5; break; case CLEF_G4: // G clef in 1st line symbol->setSym(trebleclefSym); yoff = 4.0 * curLineDist; break; case CLEF_F_8VA: // F clef 8va on penultimate line { symbol->setSym(bassclefSym); yoff = 1.0 * curLineDist; Symbol* number = new Symbol(score()); number->setMag(smag); number->setSym(clefEightSym); addElement(number, .5 * msp, -1.5 * msp + yoff * _spatium); } break; case CLEF_F_15MA: // F clef 15ma on penultimate line { symbol->setSym(bassclefSym); yoff = 1.0 * curLineDist; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefOneSym); addElement(number, .0 * msp, -1.5 * msp + yoff * _spatium); number = new Symbol(score()); number->setSym(clefFiveSym); addElement(number, .8 * msp, -1.5 * msp + yoff * _spatium); } break; case CLEF_INVALID: case CLEF_MAX: return; } symbol->setMag(smag * mag()); symbol->layout(); addElement(symbol, .0, yoff * _spatium); setbbox(QRectF()); for (auto i = elements.begin(); i != elements.end(); ++i) { Element* e = *i; e->setColor(curColor()); addbbox(e->bbox().translated(e->pos())); e->setSelected(selected()); } }
void KeySig::layout() { qreal _spatium = spatium(); setbbox(QRectF()); if (isCustom()) { for (KeySym& ks: _sig.keySymbols()) { ks.pos = ks.spos * _spatium; addbbox(symBbox(ks.sym).translated(ks.pos)); } return; } _sig.keySymbols().clear(); if (staff() && !staff()->genKeySig()) // no key sigs on TAB staves return; // determine current clef for this staff ClefType clef = ClefType::G; if (staff()) clef = staff()->clef(segment()->tick()); int accidentals = 0, naturals = 0; int t1 = int(_sig.key()); switch (qAbs(t1)) { case 7: accidentals = 0x7f; break; case 6: accidentals = 0x3f; break; case 5: accidentals = 0x1f; break; case 4: accidentals = 0xf; break; case 3: accidentals = 0x7; break; case 2: accidentals = 0x3; break; case 1: accidentals = 0x1; break; case 0: accidentals = 0; break; default: qDebug("illegal t1 key %d", t1); break; } // manage display of naturals: // naturals are shown if there is some natural AND prev. measure has no section break // AND style says they are not off // OR key sig is CMaj/Amin (in which case they are always shown) bool naturalsOn = false; Measure* prevMeas = measure() ? measure()->prevMeasure() : nullptr; // If we're not force hiding naturals (Continuous panel), use score style settings if (!_hideNaturals) naturalsOn = (prevMeas && prevMeas->sectionBreak() == nullptr && (score()->styleI(StyleIdx::keySigNaturals) != int(KeySigNatural::NONE) || t1 == 0) ); // Don't repeat naturals if shown in courtesy if (prevMeas && prevMeas->findSegment(Segment::Type::KeySigAnnounce, measure()->tick()) != 0 && segment()->segmentType() != Segment::Type::KeySigAnnounce ) naturalsOn = false; int coffset = 0; Key t2 = Key::C; if (naturalsOn) { t2 = staff()->key(segment()->tick() - 1); if (t2 == Key::C) naturalsOn = false; else { switch (qAbs(int(t2))) { case 7: naturals = 0x7f; break; case 6: naturals = 0x3f; break; case 5: naturals = 0x1f; break; case 4: naturals = 0xf; break; case 3: naturals = 0x7; break; case 2: naturals = 0x3; break; case 1: naturals = 0x1; break; case 0: naturals = 0; break; default: qDebug("illegal t2 key %d", t2); break; } // remove redundant naturals if (!((t1 > 0) ^ (t2 > 0))) naturals &= ~accidentals; if (t2 < 0) coffset = 7; } } // naturals should go BEFORE accidentals if style says so // OR going from sharps to flats or vice versa (i.e. t1 & t2 have opposite signs) bool prefixNaturals = naturalsOn && (score()->styleI(StyleIdx::keySigNaturals) == int(KeySigNatural::BEFORE) || t1 * int(t2) < 0); // naturals should go AFTER accidentals if they should not go before! bool suffixNaturals = naturalsOn && !prefixNaturals; const char* lines = ClefInfo::lines(clef); // add prefixed naturals, if any qreal xo = 0.0; if (prefixNaturals) { for (int i = 0; i < 7; ++i) { if (naturals & (1 << i)) { addLayout(SymId::accidentalNatural, xo, lines[i + coffset]); xo += 1.0; } } } // add accidentals static const qreal sspread = 1.0; static const qreal fspread = 1.0; switch(t1) { case 7: addLayout(SymId::accidentalSharp, xo + 6.0 * sspread, lines[6]); case 6: addLayout(SymId::accidentalSharp, xo + 5.0 * sspread, lines[5]); case 5: addLayout(SymId::accidentalSharp, xo + 4.0 * sspread, lines[4]); case 4: addLayout(SymId::accidentalSharp, xo + 3.0 * sspread, lines[3]); case 3: addLayout(SymId::accidentalSharp, xo + 2.0 * sspread, lines[2]); case 2: addLayout(SymId::accidentalSharp, xo + 1.0 * sspread, lines[1]); case 1: addLayout(SymId::accidentalSharp, xo, lines[0]); break; case -7: addLayout(SymId::accidentalFlat, xo + 6.0 * fspread, lines[13]); case -6: addLayout(SymId::accidentalFlat, xo + 5.0 * fspread, lines[12]); case -5: addLayout(SymId::accidentalFlat, xo + 4.0 * fspread, lines[11]); case -4: addLayout(SymId::accidentalFlat, xo + 3.0 * fspread, lines[10]); case -3: addLayout(SymId::accidentalFlat, xo + 2.0 * fspread, lines[9]); case -2: addLayout(SymId::accidentalFlat, xo + 1.0 * fspread, lines[8]); case -1: addLayout(SymId::accidentalFlat, xo, lines[7]); case 0: break; default: qDebug("illegal t1 key %d", t1); break; } // add suffixed naturals, if any if (suffixNaturals) { xo += qAbs(t1); // skip accidentals if (t1 > 0) { // after sharps, add a little more space xo += 0.15; // if last sharp (t1) is above next natural (t1+1)... if (lines[t1] < lines[t1+1]) xo += 0.2; // ... add more space } for (int i = 0; i < 7; ++i) { if (naturals & (1 << i)) { addLayout(SymId::accidentalNatural, xo, lines[i + coffset]); xo += 1.0; } } } // compute bbox for (KeySym& ks : _sig.keySymbols()) { ks.pos = ks.spos * _spatium; addbbox(symBbox(ks.sym).translated(ks.pos)); } }
void Clef::layout1() { qreal smag = mag(); qreal _spatium = spatium(); qreal yoff = 0.0; qDeleteAll(elements); elements.clear(); Symbol* symbol = new Symbol(score()); switch (curClefType) { case ClefType::G: // G clef on 2nd line symbol->setSym(SymId::gClef); yoff = 3.0 * curLineDist; break; case ClefType::G1: // G clef 8va on 2nd line symbol->setSym(SymId::gClef8va); yoff = 3.0 * curLineDist; break; case ClefType::G2: // G clef 15ma on 2nd line symbol->setSym(SymId::gClef15ma); yoff = 3.0 * curLineDist; break; case ClefType::G3: // G clef 8vb on 2nd line symbol->setSym(SymId::gClef8vb); yoff = 3.0 * curLineDist; break; case ClefType::G3_O: // double G clef 8vb on 2nd line symbol->setSym(SymId::gClef8vbOld); yoff = 3.0 * curLineDist; break; case ClefType::F: // F clef on penultimate line symbol->setSym(SymId::fClef); yoff = 1.0 * curLineDist; break; case ClefType::F8: // F clef 8va bassa on penultimate line symbol->setSym(SymId::fClef8vb); yoff = 1.0 * curLineDist; break; case ClefType::F15: // F clef 15ma bassa on penultimate line symbol->setSym(SymId::fClef15mb); yoff = 1.0 * curLineDist; break; case ClefType::F_B: // baritone clef symbol->setSym(SymId::fClef); yoff = 2.0 * curLineDist; break; case ClefType::F_C: // subbass clef symbol->setSym(SymId::fClef); yoff = 0.0; break; case ClefType::C1: // C clef in 1st line symbol->setSym(SymId::cClef); yoff = 4.0 * curLineDist; break; case ClefType::C2: // C clef on 2nd line symbol->setSym(SymId::cClef); yoff = 3.0 * curLineDist; break; case ClefType::C3: // C clef in 3rd line symbol->setSym(SymId::cClef); yoff = 2.0 * curLineDist; break; case ClefType::C4: // C clef on 4th line symbol->setSym(SymId::cClef); yoff = 1.0 * curLineDist; break; case ClefType::C5: // C clef on 5th line symbol->setSym(SymId::cClef); yoff = 0.0; break; case ClefType::TAB: // TAB clef symbol->setSym(SymId::sixStringTabClef); // on tablature, position clef at half the number of spaces * line distance yoff = curLineDist * (curLines - 1) * .5; break; case ClefType::TAB2: // TAB clef alternate style symbol->setSym(SymId::sixStringTabClefSerif); // on tablature, position clef at half the number of spaces * line distance yoff = curLineDist * (curLines - 1) * .5; break; case ClefType::PERC: // percussion clefs symbol->setSym(SymId::unpitchedPercussionClef1); yoff = curLineDist * (curLines - 1) * 0.5; break; case ClefType::PERC2: symbol->setSym(SymId::unpitchedPercussionClef2); yoff = curLineDist * (curLines - 1) * 0.5; break; case ClefType::G4: // G clef in 1st line symbol->setSym(SymId::gClef); yoff = 4.0 * curLineDist; break; case ClefType::F_8VA: // F clef 8va on penultimate line symbol->setSym(SymId::fClef8va); yoff = 1.0 * curLineDist; break; case ClefType::F_15MA: // F clef 15ma on penultimate line symbol->setSym(SymId::fClef15ma); yoff = 1.0 * curLineDist; break; case ClefType::G5: // G clef on 2nd line symbol->setSym(SymId::gClef8vbParens); yoff = 3.0 * curLineDist; break; case ClefType::INVALID: case ClefType::MAX: return; } symbol->setMag(smag); symbol->layout(); addElement(symbol, .0, yoff * _spatium); setbbox(QRectF()); for (auto i = elements.begin(); i != elements.end(); ++i) { Element* e = *i; e->setColor(curColor()); addbbox(e->bbox().translated(e->pos())); e->setSelected(selected()); } }
void TimeSig::layout() { setPos(0.0, 0.0); qreal _spatium = spatium(); setbbox(QRectF()); // prepare for an empty time signature pointLargeLeftParen = QPointF(); pz = QPointF(); pn = QPointF(); pointLargeRightParen = QPointF(); qreal lineDist; int numOfLines; TimeSigType sigType = timeSigType(); Staff* _staff = staff(); if (_staff) { // if staff is without time sig, format as if no text at all if (!_staff->staffType(tick())->genTimesig() ) { // reset position and box sizes to 0 // qDebug("staff: no time sig"); pointLargeLeftParen.rx() = 0.0; pn.rx() = 0.0; pz.rx() = 0.0; pointLargeRightParen.rx() = 0.0; setbbox(QRectF()); // leave everything else as it is: // draw() will anyway skip any drawing if staff type has no time sigs return; } numOfLines = _staff->lines(tick()); lineDist = _staff->lineDistance(tick()); } else { // assume dimensions of a standard staff lineDist = 1.0; numOfLines = 5; } // if some symbol // compute vert. displacement to center in the staff height // determine middle staff position: qreal yoff = _spatium * (numOfLines-1) *.5 * lineDist; // C and Ccut are placed at the middle of the staff: use yoff directly if (sigType == TimeSigType::FOUR_FOUR) { pz = QPointF(0.0, yoff); setbbox(symBbox(SymId::timeSigCommon).translated(pz)); ns.clear(); ns.push_back(SymId::timeSigCommon); ds.clear(); } else if (sigType == TimeSigType::ALLA_BREVE) { pz = QPointF(0.0, yoff); setbbox(symBbox(SymId::timeSigCutCommon).translated(pz)); ns.clear(); ns.push_back(SymId::timeSigCutCommon); ds.clear(); } else { ns = toTimeSigString(_numeratorString.isEmpty() ? QString::number(_sig.numerator()) : _numeratorString); ds = toTimeSigString(_denominatorString.isEmpty() ? QString::number(_sig.denominator()) : _denominatorString); ScoreFont* font = score()->scoreFont(); QSizeF mag(magS() * _scale); QRectF numRect = font->bbox(ns, mag); QRectF denRect = font->bbox(ds, mag); // position numerator and denominator; vertical displacement: // number of lines is odd: 0.0 (strings are directly above and below the middle line) // number of lines even: 0.05 (strings are moved up/down to leave 1/10sp between them) qreal displ = (numOfLines & 1) ? 0.0 : (0.05 * _spatium); //align on the wider qreal pzY = yoff - (denRect.width() < 0.01 ? 0.0 : (displ + numRect.height() * .5)); qreal pnY = yoff + displ + denRect.height() * .5; if (numRect.width() >= denRect.width()) { // numerator: one space above centre line, unless denomin. is empty (if so, directly centre in the middle) pz = QPointF(0.0, pzY); // denominator: horiz: centred around centre of numerator | vert: one space below centre line pn = QPointF((numRect.width() - denRect.width())*.5, pnY); } else { // numerator: one space above centre line, unless denomin. is empty (if so, directly centre in the middle) pz = QPointF((denRect.width() - numRect.width())*.5, pzY); // denominator: horiz: centred around centre of numerator | vert: one space below centre line pn = QPointF(0.0, pnY); } // centering of parenthesis so the middle of the parenthesis is at the divisor marking level int centerY = yoff/2 + _spatium; int widestPortion = numRect.width() > denRect.width() ? numRect.width() : denRect.width(); pointLargeLeftParen = QPointF(-_spatium, centerY); pointLargeRightParen = QPointF(widestPortion + _spatium, centerY); setbbox(numRect.translated(pz)); // translate bounding boxes to actual string positions addbbox(denRect.translated(pn)); if (_largeParentheses) { addbbox(QRect(pointLargeLeftParen.x(), pointLargeLeftParen.y() - denRect.height(), _spatium / 2, numRect.height() + denRect.height())); addbbox(QRect(pointLargeRightParen.x(), pointLargeRightParen.y() - denRect.height(), _spatium / 2, numRect.height() + denRect.height())); } } }
void Rest::layout() { _space.setLw(0.0); if (parent() && measure() && measure()->isMMRest()) { _space.setRw(point(score()->styleS(StyleIdx::minMMRestWidth))); static const qreal verticalLineWidth = .2; qreal _spatium = spatium(); qreal h = _spatium * (2 + verticalLineWidth); qreal w = _mmWidth + _spatium * verticalLineWidth*.5; bbox().setRect(-_spatium * verticalLineWidth*.5, -h * .5, w, h); // text qreal y = -_spatium * 2.5 - staff()->height() *.5; addbbox(QRectF(0, y, w, _spatium * 2)); // approximation return; } rxpos() = 0.0; if (staff() && staff()->isTabStaff()) { StaffType* tab = staff()->staffType(); // if rests are shown and note values are shown as duration symbols if (tab->showRests() && tab->genDurations()) { TDuration::DurationType type = durationType().type(); int dots = durationType().dots(); // if rest is whole measure, convert into actual type and dot values if (type == TDuration::DurationType::V_MEASURE) { int ticks = measure()->ticks(); TDuration dur = TDuration(Fraction::fromTicks(ticks)).type(); type = dur.type(); dots = dur.dots(); } // symbol needed; if not exist, create, if exists, update duration if (!_tabDur) _tabDur = new TabDurationSymbol(score(), tab, type, dots); else _tabDur->setDuration(type, dots, tab); _tabDur->setParent(this); // needed? _tabDur->setTrack(track()); _tabDur->layout(); setbbox(_tabDur->bbox()); setPos(0.0, 0.0); // no rest is drawn: reset any position might be set for it _space.setLw(0.0); _space.setRw(width()); return; } // if no rests or no duration symbols, delete any dur. symbol and chain into standard staff mngmt // this is to ensure horiz space is reserved for rest, even if they are not diplayed // Rest::draw() will skip their drawing, if not needed if(_tabDur) { delete _tabDur; _tabDur = 0; } } switch(durationType().type()) { case TDuration::DurationType::V_64TH: case TDuration::DurationType::V_32ND: dotline = -3; break; case TDuration::DurationType::V_1024TH: case TDuration::DurationType::V_512TH: case TDuration::DurationType::V_256TH: case TDuration::DurationType::V_128TH: dotline = -5; break; default: dotline = -1; break; } qreal _spatium = spatium(); int stepOffset = 0; if (staff()) stepOffset = staff()->staffType()->stepOffset(); int line = lrint(userOff().y() / _spatium); // + ((staff()->lines()-1) * 2); qreal lineDist = staff() ? staff()->staffType()->lineDistance().val() : 1.0; int lines = staff() ? staff()->lines() : 5; int lineOffset = computeLineOffset(); int yo; _sym = getSymbol(durationType().type(), line + lineOffset/2, lines, &yo); layoutArticulations(); rypos() = (qreal(yo) + qreal(lineOffset + stepOffset) * .5) * lineDist * _spatium; Spatium rs; if (dots()) { rs = Spatium(score()->styleS(StyleIdx::dotNoteDistance) + dots() * score()->styleS(StyleIdx::dotDotDistance)); } if (dots()) { rs = Spatium(score()->styleS(StyleIdx::dotNoteDistance) + dots() * score()->styleS(StyleIdx::dotDotDistance)); } setbbox(symBbox(_sym)); _space.setRw(width() + point(rs)); }
void Clef::layout() { if (curClefType == clefType()) return; qreal smag = _small ? score()->style(ST_smallClefMag).toDouble() : 1.0; qreal _spatium = spatium(); qreal msp = _spatium * smag; qreal yoff = 0.0; qDeleteAll(elements); elements.clear(); curClefType = clefType(); int lines = 5; qreal lineDist = 1.0; #if 0 // TODO: does not work with caching of curClefType if (staff() && staff()->staffType()) { StaffType* staffType = staff()->staffType(); if (staffType->group() == TAB_STAFF) { if (!staffType->genClef()) return; if (clefTable[st].staffGroup != TAB_STAFF) st = ClefType(score()->styleI(ST_tabClef)); } lines = staffType->lines(); lineDist = staffType->lineDistance().val(); } #endif Symbol* symbol = new Symbol(score()); switch (curClefType) { case CLEF_G: symbol->setSym(trebleclefSym); yoff = 3.0; break; case CLEF_G1: { symbol->setSym(trebleclefSym); yoff = 3.0; Symbol* number = new Symbol(score()); number->setMag(smag); number->setSym(clefEightSym); addElement(number, 1.0 * msp, -5.0 * msp + yoff * _spatium); } break; case CLEF_G2: { symbol->setSym(trebleclefSym); yoff = 3.0; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefOneSym); addElement(number, .6 * msp, -5.0 * msp + yoff * _spatium); number = new Symbol(score()); number->setSym(clefFiveSym); addElement(number, 1.4 * msp, -5.0 * msp + yoff * _spatium); } break; case CLEF_G3: { symbol->setSym(trebleclefSym); yoff = 3.0; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefEightSym); addElement(number, 1.0 * msp, 4.0 * msp + yoff * _spatium); } break; case CLEF_F: symbol->setSym(bassclefSym); yoff = 1.0; break; case CLEF_F8: { symbol->setSym(bassclefSym); yoff = 1.0; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefEightSym); addElement(number, .0, 4.5 * msp + yoff * _spatium); } break; case CLEF_F15: { symbol->setSym(bassclefSym); yoff = 1.0; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefOneSym); addElement(number, .0, 4.5 * msp + yoff * _spatium); number = new Symbol(score()); number->setSym(clefFiveSym); addElement(number, .8 * msp, 4.5 * msp + yoff * _spatium); } break; case CLEF_F_B: // baritone clef symbol->setSym(bassclefSym); yoff = 2.0; break; case CLEF_F_C: // subbass clef symbol->setSym(bassclefSym); yoff = 0.0; break; case CLEF_C1: symbol->setSym(altoclefSym); yoff = 4.0; break; case CLEF_C2: symbol->setSym(altoclefSym); yoff = 3.0; break; case CLEF_C3: symbol->setSym(altoclefSym); yoff = 2.0; break; case CLEF_C4: symbol->setSym(altoclefSym); yoff = 1.0; break; case CLEF_C5: symbol->setSym(altoclefSym); yoff = 0.0; break; case CLEF_TAB: symbol->setSym(tabclefSym); // on tablature, position clef at half the number of spaces * line distance yoff = lineDist * (lines - 1) * .5; break; case CLEF_TAB2: symbol->setSym(tabclef2Sym); // on tablature, position clef at half the number of spaces * line distance yoff = lineDist * (lines - 1) * .5; break; case CLEF_PERC: case CLEF_PERC2: symbol->setSym(percussionclefSym); yoff = lineDist * (lines - 1) * 0.5; break; case CLEF_G4: symbol->setSym(trebleclefSym); yoff = 4.0; break; case CLEF_F_8VA: { symbol->setSym(bassclefSym); yoff = 1.0; Symbol* number = new Symbol(score()); number->setMag(smag); number->setSym(clefEightSym); addElement(number, .5 * msp, -1.5 * msp + yoff * _spatium); } break; case CLEF_F_15MA: { symbol->setSym(bassclefSym); yoff = 1.0; Symbol* number = new Symbol(score()); symbol->setMag(smag); number->setSym(clefOneSym); addElement(number, .0 * msp, -1.5 * msp + yoff * _spatium); number = new Symbol(score()); number->setSym(clefFiveSym); addElement(number, .8 * msp, -1.5 * msp + yoff * _spatium); } break; case CLEF_INVALID: case CLEF_MAX: return; } symbol->setMag(smag * mag()); symbol->layout(); addElement(symbol, .0, yoff * _spatium); setbbox(QRectF()); for (iElement i = elements.begin(); i != elements.end(); ++i) { Element* e = *i; e->setColor(curColor()); addbbox(e->bbox().translated(e->pos())); e->setSelected(selected()); } }
void Clef::layout() { // determine current number of lines and line distance int lines = 5; // assume resonable defaults qreal lineDist = 1.0; Staff* stf = staff(); StaffType* staffType = nullptr; Segment* clefSeg = static_cast<Segment*>(parent()); // check clef visibility and type compatibility if (clefSeg && stf && stf->staffType()) { bool bHide; // check staff type allows clef display staffType = staff()->staffType(); #if 0 // <<<<<<< HEAD if (!staffType->genClef()) { // if no clef, set empty bbox and do nothing qDeleteAll(elements); elements.clear(); setbbox(QRectF()); return; } // tablatures: if (staffType->group() == StaffGroup::TAB) { // if current clef type not compatible with tablature, // set tab clef according to score style if (ClefInfo::staffGroup(clefType()) != StaffGroup::TAB) setClefType( ClefType(score()->styleI(StyleIdx::tabClef)) ); #else bHide = !staffType->genClef(); // check clef is compatible with staff type group int tick = clefSeg->tick(); if (ClefInfo::staffGroup(clefType()) != staffType->group()) { if (tick > 0 && !generated()) // if clef is not generated, hide it bHide = true; else // if generated, replace with initial clef type // TODO : instead of initial staff clef (which is assumed to be compatible) // use the last compatible clef previously found in staff _clefTypes = stf->clefTypeList(0); #endif // >>>>>>> 38c666fa91f5bdaaa6d9ca0645c437c799be8c79 } // // courtesy clef // bool showClef = true; #if 0 // <<<<<<< HEAD Segment* clefSeg = static_cast<Segment*>(parent()); if (clefSeg) { int tick = clefSeg->tick(); // only if there is a clef change if (stf->clef(tick) != stf->clef(tick-1)) { // locate clef at the begining of next measure, if any Clef* clefNext = nullptr; Segment* clefSegNext = nullptr; Measure* meas = static_cast<Measure*>(clefSeg->parent()); Measure* measNext = meas->nextMeasure(); if (measNext) { clefSegNext = measNext->findSegment(SegmentType::Clef, tick); if (clefSegNext) clefNext = static_cast<Clef*>(clefSegNext->element(track())); } // show this clef if: it is not a courtesy clef (no next clef or not at the end of the measure) showClef = !clefNext || (clefSeg->tick() != meas->tick() + meas->ticks()) // if courtesy clef: show if score has courtesy clefs on || ( score()->styleB(StyleIdx::genCourtesyClef) // AND measure is not at the end of a repeat or of a section && !( (meas->repeatFlags() & Repeat::END) || meas->sectionBreak() ) // AND this clef has courtesy clef turned on && showCourtesy() ); if (!showClef) { // if no clef, set empty bbox and do nothing qDeleteAll(elements); elements.clear(); setbbox(QRectF()); return; } #else // only if there is a clef change if (!bHide && tick > 0 && stf->clef(tick) != stf->clef(tick-1)) { // locate clef at the begining of next measure, if any Clef* clefNext = nullptr; Segment* clefSegNext = nullptr; Measure* meas = static_cast<Measure*>(clefSeg->parent()); Measure* measNext = meas->nextMeasure(); if (measNext) { clefSegNext = measNext->findSegment(SegmentType::Clef, tick); if (clefSegNext) clefNext = static_cast<Clef*>(clefSegNext->element(track())); #endif // >>>>>>> 38c666fa91f5bdaaa6d9ca0645c437c799be8c79 } // show this clef if: it is not a courtesy clef (no next clef or not at the end of the measure) showClef = !clefNext || (clefSeg->tick() != meas->tick() + meas->ticks()) // if courtesy clef: show if score has courtesy clefs on || ( score()->styleB(StyleIdx::genCourtesyClef) // AND measure is not at the end of a repeat or of a section && !( (meas->repeatFlags() & Repeat::END) || meas->sectionBreak() ) // AND this clef has courtesy clef turned on && showCourtesy() ); bHide |= !showClef; } // if clef not to show or not compatible with staff group if (bHide) { qDeleteAll(elements); // set empty bbox and do nothing elements.clear(); setbbox(QRectF()); return; } lines = staffType->lines(); // init values from staff type lineDist = staffType->lineDistance().val(); } // if nothing changed since last layout, do nothing //DEBUG if (curClefType == clefType() && curLines == lines && curLineDist == lineDist) // return; // if something has changed, cache new values and re-layout curClefType = clefType(); curLines = lines; curLineDist = lineDist; layout1(); } //--------------------------------------------------------- // layout1 //--------------------------------------------------------- void Clef::layout1() { qreal smag = mag(); qreal _spatium = spatium(); // qreal msp = score()->spatium() * smag; qreal yoff = 0.0; qDeleteAll(elements); elements.clear(); Symbol* symbol = new Symbol(score()); switch (curClefType) { case ClefType::G: // G clef on 2nd line symbol->setSym(SymId::gClef); yoff = 3.0 * curLineDist; break; case ClefType::G1: // G clef 8va on 2nd line symbol->setSym(SymId::gClef8va); yoff = 3.0 * curLineDist; break; case ClefType::G2: // G clef 15ma on 2nd line symbol->setSym(SymId::gClef15ma); yoff = 3.0 * curLineDist; break; case ClefType::G3: // G clef 8vb on 2nd line symbol->setSym(SymId::gClef8vb); yoff = 3.0 * curLineDist; break; case ClefType::F: // F clef on penultimate line symbol->setSym(SymId::fClef); yoff = 1.0 * curLineDist; break; case ClefType::F8: // F clef 8va bassa on penultimate line symbol->setSym(SymId::fClef8vb); yoff = 1.0 * curLineDist; break; case ClefType::F15: // F clef 15ma bassa on penultimate line symbol->setSym(SymId::fClef15mb); yoff = 1.0 * curLineDist; break; case ClefType::F_B: // baritone clef symbol->setSym(SymId::fClef); yoff = 2.0 * curLineDist; break; case ClefType::F_C: // subbass clef symbol->setSym(SymId::fClef); yoff = 0.0; break; case ClefType::C1: // C clef in 1st line symbol->setSym(SymId::cClef); yoff = 4.0 * curLineDist; break; case ClefType::C2: // C clef on 2nd line symbol->setSym(SymId::cClef); yoff = 3.0 * curLineDist; break; case ClefType::C3: // C clef in 3rd line symbol->setSym(SymId::cClef); yoff = 2.0 * curLineDist; break; case ClefType::C4: // C clef on 4th line symbol->setSym(SymId::cClef); yoff = 1.0 * curLineDist; break; case ClefType::C5: // C clef on 5th line symbol->setSym(SymId::cClef); yoff = 0.0; break; case ClefType::TAB: // TAB clef symbol->setSym(SymId::sixStringTabClef); // on tablature, position clef at half the number of spaces * line distance yoff = curLineDist * (curLines - 1) * .5; break; case ClefType::TAB2: // TAB clef alternate style symbol->setSym(SymId::sixStringTabClefSerif); // on tablature, position clef at half the number of spaces * line distance yoff = curLineDist * (curLines - 1) * .5; break; case ClefType::PERC: // percussion clefs case ClefType::PERC2: // no longer supported: fall back to same glyph as PERC symbol->setSym(SymId::unpitchedPercussionClef1); yoff = curLineDist * (curLines - 1) * 0.5; break; case ClefType::G4: // G clef in 1st line symbol->setSym(SymId::gClef); yoff = 4.0 * curLineDist; break; case ClefType::F_8VA: // F clef 8va on penultimate line symbol->setSym(SymId::fClef8va); yoff = 1.0 * curLineDist; break; case ClefType::F_15MA: // F clef 15ma on penultimate line symbol->setSym(SymId::fClef15ma); yoff = 1.0 * curLineDist; break; case ClefType::INVALID: case ClefType::MAX: return; } symbol->setMag(smag); symbol->layout(); addElement(symbol, .0, yoff * _spatium); setbbox(QRectF()); for (auto i = elements.begin(); i != elements.end(); ++i) { Element* e = *i; e->setColor(curColor()); addbbox(e->bbox().translated(e->pos())); e->setSelected(selected()); } } //--------------------------------------------------------- // draw //--------------------------------------------------------- void Clef::draw(QPainter* painter) const { if (staff() && !staff()->staffType()->genClef()) return; QColor color(curColor()); foreach(Element* e, elements) { e->setColor(color); QPointF pt(e->pos()); painter->translate(pt); e->draw(painter); painter->translate(-pt); } }