Ejemplo n.º 1
0
void NoteDot::layout()
      {
      setbbox(symBbox(SymId::augmentationDot));
      }
Ejemplo n.º 2
0
void Arpeggio::draw(QPainter* p) const
      {
      qreal _spatium = spatium();

      p->setPen(curColor());

      qreal y1 = -_userLen1;
      qreal y2 = _height + _userLen2;

      p->setPen(QPen(curColor(),
         score()->styleS(ST_ArpeggioLineWidth).val() * _spatium,
         Qt::SolidLine, Qt::RoundCap));

      switch (arpeggioType()) {
            case ArpeggioType::NORMAL:
            case ArpeggioType::UP:
                  {
                  QRectF r(symBbox(symbols));
                  p->rotate(-90.0);
                  drawSymbols(symbols, p, QPointF(-r.right() - y1, -r.bottom() + r.height()));
                  p->rotate(90.0);
                  }
                  break;

            case ArpeggioType::DOWN:
                  {
                  QRectF r(symBbox(symbols));
                  p->rotate(90.0);
                  drawSymbols(symbols, p, QPointF(-r.left() + y1, -r.top() - r.height()));
                  p->rotate(-90.0);
                  }
                  break;

            case ArpeggioType::UP_STRAIGHT:
                  {
                  QRectF r(symBbox(SymId::arrowheadBlackUp));
                  qreal x1 = _spatium * .5;
                  drawSymbol(SymId::arrowheadBlackUp, p, QPointF(x1 - r.width() * .5, y1 - r.top()));
                  y1 -= r.top() * .5;
                  p->drawLine(QLineF(x1, y1, x1, y2));
                  }
                  break;

            case ArpeggioType::DOWN_STRAIGHT:
                  {
                  QRectF r(symBbox(SymId::arrowheadBlackDown));
                  qreal x1 = _spatium * .5;

                  drawSymbol(SymId::arrowheadBlackDown, p, QPointF(x1 - r.width() * .5, y2 - r.bottom()));
                  y2 += r.top() * .5;
                  p->drawLine(QLineF(x1, y1, x1, y2));
                  }
                  break;

            case ArpeggioType::BRACKET:
                  {
                  qreal w = score()->styleS(ST_ArpeggioHookLen).val() * _spatium;
                  p->drawLine(QLineF(0.0, y1, 0.0, y2));
                  p->drawLine(QLineF(0.0, y1, w, y1));
                  p->drawLine(QLineF(0.0, y2, w, y2));
                  }
                  break;
            }
      }
Ejemplo n.º 3
0
void Articulation::layout()
      {
      SymId sym = _up ? articulationList[int(articulationType())].upSym : articulationList[int(articulationType())].downSym;
      QRectF b(symBbox(sym));
      setbbox(b.translated(-0.5 * b.width(), 0.0));
      }
Ejemplo n.º 4
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()));
                  }
            }
      }
Ejemplo n.º 5
0
qreal Rest::downPos() const
      {
      return symBbox(_sym).y() + symHeight(_sym);
      }
Ejemplo n.º 6
0
void TrillSegment::draw(QPainter* painter) const
      {
      QRectF b2(symBbox(SymId::wiggleTrill));
      qreal w2   = symWidth(SymId::wiggleTrill);

      qreal x2   = pos2().x();

      QColor color;
      if (flag(ELEMENT_DROP_TARGET))
            color = MScore::dropColor;
      else if (selected() && !(score() && score()->printing()))
            color = MScore::selectColor[0];
      else if (!visible())
            color = Qt::gray;
      else {
            color = trill()->curColor();
            }

      painter->setPen(color);
      if (spannerSegmentType() == SEGMENT_SINGLE || spannerSegmentType() == SEGMENT_BEGIN) {
            SymId sym = SymId::noSym;
            qreal x0 = 0.0, x1 = 0.0, y = 0.0;
            int n = 0;
            QRectF b1;

            switch(trill()->trillType()) {
                  case Trill::TRILL_LINE:
                        sym  = SymId::ornamentTrill;
                        b1   = symBbox(sym);
                        x0   = -b1.x();
                        x1   = x0 + b1.width();
                        n    = int(floor((x2-x1) / w2));
                        y    = 0.0;
                        break;
#if 0 // TODO-smufl
                  case Trill::UPPRALL_LINE:
                        sym  = SymId(upprallSym);
                        b1   = score()->sym(sym).bbox(mag);
                        x0   = -b1.x();
                        x1   = b1.width();
                        n    = int(floor((x2-x1) / w2));
                        y    = -b1.height();
                        break;
                  case Trill::DOWNPRALL_LINE:
                        sym  = SymId(downprallSym);
                        b1   = score()->sym(sym).bbox(mag);
                        x0   = -b1.x();
                        x1   = b1.width();
                        n    = int(floor((x2-x1) / w2));
                        y    = -b1.height();
                        break;
                  case Trill::PRALLPRALL_LINE:
                        sym  = SymId(prallprallSym);
                        b1   = score()->sym(sym).bbox(mag);
                        x0   = -b1.x();
                        x1   = b1.width();
                        n    = int(floor((x2-x1) / w2));
                        y    = -b1.height();
                        break;
#endif
                  case Trill::PURE_LINE:
                        sym = SymId::noSym;
                        x0 = 0;
                        x1 = 0;
                        n    = int(floor((x2-x1) / w2));
                        y = 0.0;
                  }
            if (n <= 0)
                  n = 1;
            if (sym != SymId::noSym)
                  drawSymbol(sym, painter, QPointF(x0, y));
            drawSymbol(SymId::wiggleTrill, painter, QPointF(x1, b2.y() * .9), n);
            }
      else {
            qreal x1 = 0.0;
            int n = int(floor((x2-x1) / w2));
            drawSymbol(SymId::wiggleTrill, painter, QPointF(x1, b2.y() * .9), n);
            }
      }
Ejemplo n.º 7
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));
      }
Ejemplo n.º 8
0
qreal Rest::upPos() const
      {
      return symBbox(_sym).y();
      }
Ejemplo n.º 9
0
void Clef::layout()
      {
      // determine current number of lines and line distance
      int   lines;
      qreal lineDist;
      Segment* clefSeg  = segment();
      int stepOffset;

      // check clef visibility and type compatibility
      if (clefSeg && staff()) {
            int tick             = clefSeg->tick();
            StaffType* staffType = staff()->staffType(tick);
            bool show            = staffType->genClef();        // check staff type allows clef display

            // check clef is compatible with staff type group:
            if (ClefInfo::staffGroup(clefType()) != staffType->group()) {
                  if (tick > 0 && !generated()) // if clef is not generated, hide it
                        show = false;
                  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 = staff()->clefType(0);
                  }

            Measure* meas = clefSeg->measure();
            if (meas && meas->system()) {
                  auto ml = meas->system()->measures();
                  bool found = (std::find(ml.begin(), ml.end(), meas) != ml.end());
                  bool courtesy = (tick == meas->endTick() && (meas == meas->system()->lastMeasure() || !found));
                  if (courtesy && (!showCourtesy() || !score()->styleB(Sid::genCourtesyClef) || meas->isFinalMeasureOfSection()))
                        show = false;
                  }
            // if clef not to show or not compatible with staff group
            if (!show) {
                  setbbox(QRectF());
                  qDebug("Clef::layout(): invisible clef at tick %d(%d) staff %d",
                     segment()->tick(), segment()->tick()/1920, staffIdx());
                  return;
                  }
            lines      = staffType->lines();         // init values from staff type
            lineDist   = staffType->lineDistance().val();
            stepOffset = staffType->stepOffset();
            }
      else {
            lines      = 5;
            lineDist   = 1.0;
            stepOffset = 0;
            }

      qreal _spatium = spatium();
      qreal yoff     = 0.0;
      if (clefType() !=  ClefType::INVALID && clefType() !=  ClefType::MAX) {
            symId = ClefInfo::symId(clefType());
            yoff = lineDist * (lines - ClefInfo::line(clefType()));
            }

      switch (clefType()) {
            case ClefType::C_19C:                            // 19th C clef is like a G clef
                  yoff = lineDist * 1.5;
                  break;
            case ClefType::TAB:                            // TAB clef
                  // on tablature, position clef at half the number of spaces * line distance
                  yoff = lineDist * (lines - 1) * .5;
                  break;
            case ClefType::TAB4:                            // TAB clef 4 strings
                  // on tablature, position clef at half the number of spaces * line distance
                  yoff = lineDist * (lines - 1) * .5;
                  break;
            case ClefType::TAB_SERIF:                           // TAB clef alternate style
                  // on tablature, position clef at half the number of spaces * line distance
                  yoff = lineDist * (lines - 1) * .5;
                  break;
            case ClefType::TAB4_SERIF:                           // TAB clef alternate style
                  // on tablature, position clef at half the number of spaces * line distance
                  yoff = lineDist * (lines - 1) * .5;
                  break;
            case ClefType::PERC:                           // percussion clefs
                  yoff = lineDist * (lines - 1) * 0.5;
                  break;
            case ClefType::PERC2:
                  yoff = lineDist * (lines - 1) * 0.5;
                  break;
            case ClefType::INVALID:
            case ClefType::MAX:
                  qDebug("Clef::layout: invalid type");
                  return;
            default:
                  break;
            }
      // clefs are right aligned to Segment
      QRectF r(symBbox(symId));
      setPos(0.0, yoff * _spatium + (stepOffset * -_spatium));

      setbbox(r);
      }
Ejemplo n.º 10
0
void Hook::layout()
      {
      ElementLayout::layout(this);
      setbbox(symBbox(_sym));
      }
Ejemplo n.º 11
0
void Breath::layout()
      {
      setbbox(symBbox(symList[breathType()]));
      }
Ejemplo n.º 12
0
void Hook::layout()
      {
      setbbox(symBbox(_sym));
      }
Ejemplo n.º 13
0
void KeySig::layout()
      {
      qreal _spatium = spatium();
      setbbox(QRectF());

      if (isCustom() && !isAtonal()) {
            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* prevMeasure = measure() ? measure()->prevMeasure() : 0;

      // If we're not force hiding naturals (Continuous panel), use score style settings
      if (!_hideNaturals)
            naturalsOn = (prevMeasure && !prevMeasure->sectionBreak()
               && (score()->styleI(StyleIdx::keySigNaturals) != int(KeySigNatural::NONE))) || (t1 == 0);


      // Don't repeat naturals if shown in courtesy
      if (prevMeasure && prevMeasure->findSegment(Segment::Type::KeySigAnnounce, segment()->tick())
          && !segment()->isKeySigAnnounceType())
            naturalsOn = false;
      if (track() == -1)
            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", int(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 signed 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));
            }
      }