Example #1
0
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;
            }
Example #2
0
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;
            }
Example #3
0
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;
    }
Example #4
0
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();
      }
Example #5
0
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());
            }
      }
Example #6
0
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));
            }
      }
Example #7
0
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());
            }
      }
Example #8
0
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()));
                  }
            }
      }
Example #9
0
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));
      }
Example #10
0
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());
            }
      }
Example #11
0
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);
            }
      }