예제 #1
0
void Tie::slurPos(SlurPos* sp)
      {
      qreal hw   = startNote()->headWidth();
      qreal __up = _up ? -1.0 : 1.0;
      qreal _spatium = spatium();

      Chord* sc   = startNote()->chord();
      Q_ASSERT(sc);
      sp->system1 = sc->measure()->system();
      if (!sp->system1) {
            Measure* m = sc->measure();
            qDebug("No system: measure is %d has %d count %d", m->isMMRest(), m->hasMMRest(), m->mmRestCount());
            }
      Q_ASSERT(sp->system1);

      qreal xo;
      qreal yo;
      bool shortStart = false;

      // determine attachment points
      // similar code is used in Chord::layoutPitched()
      // to allocate extra space to enforce minTieLength
      // so keep these in sync

      //------p1
      if ((sc->notes().size() > 1) || (sc->stem() && (sc->up() == _up))) {
            xo = startNote()->x() + hw * 1.12;
            yo = startNote()->pos().y() + hw * .3 * __up;
            shortStart = true;
            }
      else {
            xo = startNote()->x() + hw * 0.65;
            yo = startNote()->pos().y() + _spatium * .75 * __up;
            }
      sp->p1 = sc->pagePos() - sp->system1->pagePos() + QPointF(xo, yo);

      //------p2
      if (endNote() == 0) {
            sp->p2 = sp->p1 + QPointF(_spatium * 3, 0.0);
            sp->system2 = sp->system1;
            return;
            }
      Chord* ec   = endNote()->chord();
      sp->system2 = ec->measure()->system();
      if ((ec->notes().size() > 1) || (ec->stem() && !ec->up() && !_up))
            xo = endNote()->x() - hw * 0.12;
      else if (shortStart)
            xo = endNote()->x() + hw * 0.15;
      else
            xo = endNote()->x() + hw * 0.35;
      sp->p2 = ec->pagePos() - sp->system2->pagePos() + QPointF(xo, yo);
      }
예제 #2
0
void Fingering::layout()
      {
      TextBase::layout();

      if (autoplace() && note()) {
            Chord* chord = note()->chord();
            Staff* staff = chord->staff();
            Part* part   = staff->part();
            int n        = part->nstaves();
            bool voices  = chord->measure()->hasVoices(staff->idx());
            bool below   = voices ? !chord->up() : (n > 1) && (staff->rstaff() == n-1);
            bool tight   = voices && !chord->beam();

            qreal x = 0.0;
            qreal y = 0.0;
            qreal headWidth = note()->bboxRightPos();
            qreal headHeight = note()->headHeight();
            qreal fh = headHeight;        // TODO: fingering number height

            if (chord->notes().size() == 1) {
                  x = headWidth * .5;
                  if (below) {
                        // place fingering below note
                        y = fh + spatium() * .4;
                        if (tight) {
                              y += 0.5 * spatium();
                              if (chord->stem())
                                    x += 0.5 * spatium();
                              }
                        else if (chord->stem() && !chord->up()) {
                              // on stem side
                              y += chord->stem()->height();
                              x -= spatium() * .4;
                              }
                        }
                  else {
                        // place fingering above note
                        y = -headHeight - spatium() * .4;
                        if (tight) {
                              y -= 0.5 * spatium();
                              if (chord->stem())
                                    x -= 0.5 * spatium();
                              }
                        else if (chord->stem() && chord->up()) {
                              // on stem side
                              y -= chord->stem()->height();
                              x += spatium() * .4;
                              }
                        }
                  }
            else {
                  x -= spatium();
                  }
            setUserOff(QPointF(x, y));
            }
      }
예제 #3
0
파일: slur.cpp 프로젝트: kuribas/MuseScore
void Tie::slurPos(SlurPos* sp)
      {
      Note* note1 = static_cast<Note*>(startElement());
      qreal hw   = note1->headWidth();
      qreal __up = _up ? -1.0 : 1.0;
      qreal _spatium = spatium();

      Chord* sc   = note1->chord();
      sp->system1 = sc->measure()->system();

      qreal xo;
      qreal yo;

      //------p1
      if ((sc->notes().size() > 1) || (sc->stem() && (sc->up() == _up))) {
            xo = note1->x() + hw * 1.12;
            yo = note1->pos().y() + hw * .3 * __up;
            }
      else {
            xo = note1->x() + hw * 0.85;
            yo = note1->pos().y() + _spatium * .75 * __up;
            }
      sp->p1 = sc->pagePos() - sp->system1->pagePos() + QPointF(xo, yo);

      //------p2
      Note* note2 = static_cast<Note*>(endElement());
      if (note2 == 0) {
            sp->p2 = sp->p1 + QPointF(_spatium * 3, 0.0);
            sp->system2 = sp->system1;
            return;
            }
      Chord* ec   = note2->chord();
      sp->system2 = ec->measure()->system();
      if ((ec->notes().size() > 1) || (ec->stem() && !ec->up() && !_up))
            xo = note2->x() - hw * 0.12;
      else
            xo = note2->x() + hw * 0.15;
      sp->p2 = ec->pagePos() - sp->system2->pagePos() + QPointF(xo, yo);
      }
예제 #4
0
Placement Fingering::calculatePlacement() const
      {
      Note* n = note();
      if (!n)
            return Placement::ABOVE;
      Chord* chord = n->chord();
      Staff* staff = chord->staff();
      Part* part   = staff->part();
      int nstaves  = part->nstaves();
      bool voices  = chord->measure()->hasVoices(staff->idx());
      bool below   = voices ? !chord->up() : (nstaves > 1) && (staff->rstaff() == nstaves - 1);
      return below ? Placement::BELOW : Placement::ABOVE;
      }
예제 #5
0
파일: stem.cpp 프로젝트: akinsgre/MuseScore
Element* Stem::drop(const DropData& data)
      {
      Element* e = data.element;
      Chord* ch = chord();
      switch(e->type()) {
            case TREMOLO:
                  e->setParent(ch);
                  score()->setLayout(ch->measure());
                  score()->undoAddElement(e);
                  return e;
            default:
                  delete e;
                  break;
            }
      return 0;
      }
예제 #6
0
파일: slur.cpp 프로젝트: kuribas/MuseScore
void Slur::slurPos(SlurPos* sp)
      {
      qreal _spatium = spatium();
      Element* e1 = startElement();
      Element* e2 = endElement();

      if (e2 == 0) {
            sp->p1 = e1->pagePos();
            sp->p1.rx() += e1->width();
            sp->p2 = sp->p1;
            sp->p2.rx() += 5 * _spatium;
            sp->system1 = static_cast<ChordRest*>(e1)->measure()->system();
            sp->system2 = sp->system1;
            return;
            }

      if ((e1->type() != CHORD) || (e2->type() != CHORD)) {
            sp->p1 = e1->pagePos();
            sp->p2 = e2->pagePos();
            sp->p1.rx() += e1->width();
            sp->p2.rx() += e2->width();
            sp->system1 = static_cast<ChordRest*>(e1)->measure()->system();
            sp->system2 = static_cast<ChordRest*>(e2)->measure()->system();
            return;
            }
      Chord* sc   = static_cast<Chord*>(e1);
      Chord* ec   = static_cast<Chord*>(e2);
      Note* note1 = _up ? sc->upNote() : sc->downNote();
      Note* note2 = _up ? ec->upNote() : ec->downNote();

      sp->system1 = sc->measure()->system();
      sp->system2 = ec->measure()->system();
      sp->p1      = sc->pagePos() - sp->system1->pagePos();
      sp->p2      = ec->pagePos() - sp->system2->pagePos();

      qreal xo, yo;

      Stem* stem1 = sc->stem();
      Stem* stem2 = ec->stem();

      enum SlurAnchor {
            SA_NONE, SA_STEM
            };
      SlurAnchor sa1 = SA_NONE;
      SlurAnchor sa2 = SA_NONE;
      if ((sc->up() == ec->up()) && !sc->beam() && !ec->beam() && (_up == sc->up())) {
            if (stem1)
                  sa1 = SA_STEM;
            if (stem2)
                  sa2 = SA_STEM;
            }

      qreal __up = _up ? -1.0 : 1.0;
      qreal hw   = note1->headWidth();
      switch (sa1) {
            case SA_STEM:
                  sp->p1 += sc->stemPosBeam() - sc->pagePos() + sc->stem()->p2();
                  sp->p1 += QPointF(0.35 * _spatium, 0.25 * _spatium);
                  break;
            case SA_NONE:
                  break;
            }
      switch(sa2) {
            case SA_STEM:
                  sp->p2 += ec->stemPosBeam() - ec->pagePos() + ec->stem()->p2();
                  sp->p2 += QPointF(-0.35 * _spatium, 0.25 * _spatium);
                  break;
            case SA_NONE:
                  break;
            }

      //
      // default position:
      //    horizontal: middle of note head
      //    vertical:   _spatium * .4 above/below note head
      //
      //------p1
      bool stemPos = false;   // p1 starts at chord stem side
      yo = note1->pos().y() + _spatium * .9 * __up;
      xo = hw * .5;

      if (stem1) {
            Beam* beam1 = sc->beam();
            if (beam1 && (beam1->elements().back() != sc) && (sc->up() == _up)) {
                  qreal sh = stem1->height() + _spatium;
                  yo       = sc->downNote()->pos().y() + sh * __up;
                  xo       = stem1->pos().x();
                  stemPos  = true;
                  }
            else {
                  if (sc->up() && _up)
                        xo = hw + _spatium * .3;
                  //
                  // handle case: stem up   - stem down
                  //              stem down - stem up
                  //
                  if ((sc->up() != ec->up()) && (sc->up() == _up)) {
                        Note* n1  = sc->up() ? sc->downNote() : sc->upNote();
                        Note* n2  = ec->up() ? ec->downNote() : ec->upNote();
                        qreal yd  = n2->pos().y() - n1->pos().y();

                        yd *= .5;

                        qreal sh = stem1->height();    // limit y move
                        if (yd > 0.0) {
                              if (yd > sh)
                                    yd = sh;
                              }
                        else {
                              if (yd < - sh)
                                    yd = -sh;
                              }
                        stemPos = true;
                        if ((_up && (yd < -_spatium)) || (!_up && (yd > _spatium)))
                              yo += yd;
                        }
                  else if (sc->up() != _up)
                        yo = fixArticulations(yo, sc, __up);
                  }
            }

      if (sa1 == SA_NONE)
            sp->p1 += QPointF(xo, yo);

      //------p2
      xo = hw * .5;
      yo = note2->pos().y() + _spatium * .9 * __up;

      if (stem2) {
            Beam* beam2 = ec->beam();
            if ((stemPos && (sc->up() == ec->up()))
               || (beam2
                 && (!beam2->elements().isEmpty())
                 && (beam2->elements().front() != ec)
                 && (ec->up() == _up)
                 && (sc->noteType() == NOTE_NORMAL)
                 )
                  ) {
                  qreal sh = stem2->height() + _spatium;
                  if (_up)
                        yo = ec->downNote()->pos().y() - sh;
                  else
                        yo = ec->upNote()->pos().y() + sh;
                  xo = stem2->pos().x();
                  }
            else if (!ec->up() && !_up)
                  xo = -_spatium * .3 + note2->x();
            //
            // handle case: stem up   - stem down
            //              stem down - stem up
            //
            if ((sc->up() != ec->up()) && (ec->up() == _up)) {
                  Note* n1 = sc->up() ? sc->downNote() : sc->upNote();
                  Note* n2 = ec->up() ? ec->downNote() : ec->upNote();
                  qreal yd = n2->pos().y() - n1->pos().y();

                  yd *= .5;

                  qreal mh = stem2->height();    // limit y move
                  if (yd > 0.0) {
                        if (yd > mh)
                              yd = mh;
                        }
                  else {
                        if (yd < - mh)
                              yd = -mh;
                        }

                  if ((_up && (yd > _spatium)) || (!_up && (yd < -_spatium)))
                        yo -= yd;
                  }
            else if (ec->up() != _up)
                  yo = fixArticulations(yo, ec, __up);
            }

      if (sa2 == SA_NONE)
            sp->p2 += QPointF(xo, yo);
      }
예제 #7
0
void Fingering::layout()
      {
      if (parent()) {
            Fraction tick = parent()->tick();
            const Staff* st = staff();
            if (st && st->isTabStaff(tick) && !st->staffType(tick)->showTabFingering()) {
                  setbbox(QRectF());
                  return;
                  }
            }

      TextBase::layout();
      rypos() = 0.0;    // handle placement below

      if (autoplace() && note()) {
            Note* n      = note();
            Chord* chord = n->chord();
            bool voices  = chord->measure()->hasVoices(chord->staffIdx());
            bool tight   = voices && chord->notes().size() == 1 && !chord->beam() && tid() != Tid::STRING_NUMBER;

            qreal headWidth = n->bboxRightPos();

            // update offset after drag
            qreal rebase = 0.0;
            if (offsetChanged() != OffsetChange::NONE)
                  rebase = rebaseOffset();

            // temporarily exclude self from chord shape
            setAutoplace(false);

            if (layoutType() == ElementType::CHORD) {
                  Stem* stem = chord->stem();
                  Segment* s = chord->segment();
                  Measure* m = s->measure();
                  qreal sp = spatium();
                  qreal md = minDistance().val() * sp;
                  SysStaff* ss = m->system()->staff(chord->vStaffIdx());
                  Staff* vStaff = chord->staff();     // TODO: use current height at tick

                  if (n->mirror())
                        rxpos() -= n->ipos().x();
                  rxpos() += headWidth * .5;
                  if (placeAbove()) {
                        if (tight) {
                              if (chord->stem())
                                    rxpos() -= 0.8 * sp;
                              rypos() -= 1.5 * sp;
                              }
                        else {
                              QRectF r = bbox().translated(m->pos() + s->pos() + chord->pos() + n->pos() + pos());
                              SkylineLine sk(false);
                              sk.add(r.x(), r.bottom(), r.width());
                              qreal d = sk.minDistance(ss->skyline().north());
                              qreal yd = 0.0;
                              if (d > 0.0 && isStyled(Pid::MIN_DISTANCE))
                                    yd -= d + height() * .25;
                              // force extra space above staff & chord (but not other fingerings)
                              qreal top;
                              if (chord->up() && chord->beam() && stem) {
                                    top = stem->y() + stem->bbox().top();
                                    }
                              else {
                                    Note* un = chord->upNote();
                                    top = qMin(0.0, un->y() + un->bbox().top());
                                    }
                              top -= md;
                              qreal diff = (bbox().bottom() + ipos().y() + yd + n->y()) - top;
                              if (diff > 0.0)
                                    yd -= diff;
                              if (offsetChanged() != OffsetChange::NONE) {
                                    // user moved element within the skyline
                                    // we may need to adjust minDistance, yd, and/or offset
                                    bool inStaff = placeAbove() ? r.bottom() + rebase > 0.0 : r.top() + rebase < staff()->height();
                                    rebaseMinDistance(md, yd, sp, rebase, inStaff);
                                    }
                              rypos() += yd;
                              }
                        }
                  else {
                        if (tight) {
                              if (chord->stem())
                                    rxpos() += 0.8 * sp;
                              rypos() += 1.5 * sp;
                              }
                        else {
                              QRectF r = bbox().translated(m->pos() + s->pos() + chord->pos() + n->pos() + pos());
                              SkylineLine sk(true);
                              sk.add(r.x(), r.top(), r.width());
                              qreal d = ss->skyline().south().minDistance(sk);
                              qreal yd = 0.0;
                              if (d > 0.0 && isStyled(Pid::MIN_DISTANCE))
                                    yd += d + height() * .25;
                              // force extra space below staff & chord (but not other fingerings)
                              qreal bottom;
                              if (!chord->up() && chord->beam() && stem) {
                                    bottom = stem->y() + stem->bbox().bottom();
                                    }
                              else {
                                    Note* dn = chord->downNote();
                                    bottom = qMax(vStaff->height(), dn->y() + dn->bbox().bottom());
                                    }
                              bottom += md;
                              qreal diff = bottom - (bbox().top() + ipos().y() + yd + n->y());
                              if (diff > 0.0)
                                    yd += diff;
                              if (offsetChanged() != OffsetChange::NONE) {
                                    // user moved element within the skyline
                                    // we may need to adjust minDistance, yd, and/or offset
                                    bool inStaff = placeAbove() ? r.bottom() + rebase > 0.0 : r.top() + rebase < staff()->height();
                                    rebaseMinDistance(md, yd, sp, rebase, inStaff);
                                    }
                              rypos() += yd;
                              }
                        }
                  }
            else if (tid() == Tid::LH_GUITAR_FINGERING) {
                  // place to left of note
                  qreal left = n->shape().left();
                  if (left - n->x() > 0.0)
                        rxpos() -= left;
                  else
                        rxpos() -= n->x();
                  }
            // for other fingering styles, do not autoplace

            // restore autoplace
            setAutoplace(true);
            }
      else if (offsetChanged() != OffsetChange::NONE) {
            // rebase horizontally too, as autoplace may have adjusted it
            rebaseOffset(false);
            }
      setOffsetChanged(false);
      }
예제 #8
0
파일: tie.cpp 프로젝트: Angeldude/MuseScore
void Tie::slurPos(SlurPos* sp)
      {
      bool useTablature = staff() != nullptr && staff()->isTabStaff();
      StaffType* stt = nullptr;
      if (useTablature)
            stt = staff()->staffType();
      qreal _spatium    = spatium();
      qreal hw          = startNote()->tabHeadWidth(stt);   // if stt == 0, defaults to headWidth()
      qreal __up        = _up ? -1.0 : 1.0;
      // y offset for ties inside chord margins (typically multi-note chords): lined up with note top or bottom margin
      //    or outside (typically single-note chord): overlaps note and is above/below it
      // Outside: Tab: uses font size and may be asymmetric placed above/below line (frets ON or ABOVE line)
      //          Std: assumes notehead is 1 sp high, 1/2 sp above and 1/2 below line; add 1/4 sp to it
      // Inside:  Tab: 1/2 of Outside offset
      //          Std: use a fixed pecentage of note width
      qreal yOffOutside = useTablature
            ? (_up ? stt->fretBoxY() : stt->fretBoxY() + stt->fretBoxH()) * magS()
            : 0.75 * _spatium * __up;
      qreal yOffInside  = useTablature ? yOffOutside * 0.5 : hw * .3 * __up;

      Chord* sc   = startNote()->chord();
      Q_ASSERT(sc);
      sp->system1 = sc->measure()->system();
      if (!sp->system1) {
            Measure* m = sc->measure();
            qDebug("No system: measure is %d has %d count %d", m->isMMRest(), m->hasMMRest(), m->mmRestCount());
            }
      Q_ASSERT(sp->system1);

      qreal xo;
      qreal yo;
      bool shortStart = false;

      // determine attachment points
      // similar code is used in Chord::layoutPitched()
      // to allocate extra space to enforce minTieLength
      // so keep these in sync

      //------p1
      if ((sc->notes().size() > 1) || (sc->stem() && (sc->up() == _up))) {
            xo = startNote()->x() + hw * 1.12;
            yo = startNote()->pos().y() + yOffInside;
            shortStart = true;
            }
      else {
            xo = startNote()->x() + hw * 0.65;
            yo = startNote()->pos().y() + yOffOutside;
            }
      sp->p1 = sc->pagePos() - sp->system1->pagePos() + QPointF(xo, yo);

      //------p2
      if (endNote() == 0) {
            sp->p2 = sp->p1 + QPointF(_spatium * 3, 0.0);
            sp->system2 = sp->system1;
            return;
            }
      Chord* ec   = endNote()->chord();
      sp->system2 = ec->measure()->system();
      if (!sp->system2) {
            qDebug("Tie::slurPos no system2");
            sp->system2 = sp->system1;
            }
      hw = endNote()->tabHeadWidth(stt);
      if ((ec->notes().size() > 1) || (ec->stem() && !ec->up() && !_up))
            xo = endNote()->x() - hw * 0.12;
      else if (shortStart)
            xo = endNote()->x() + hw * 0.15;
      else
            xo = endNote()->x() + hw * 0.35;
      sp->p2 = ec->pagePos() - sp->system2->pagePos() + QPointF(xo, yo);
      }