示例#1
0
void Image::layout()
{
    qreal f = _sizeIsSpatium ? spatium() : MScore::DPMM;
    // if autoscale && inside a box, scale to box relevant size
    if (autoScale() && parent() && ((parent()->type() == HBOX || parent()->type() == VBOX))) {
        if (_lockAspectRatio) {
            QSizeF size(imageSize());
            qreal ratio = size.width() / size.height();
            qreal w = parent()->width();
            qreal h = parent()->height();
            if ((w / h) < ratio) {
                _size.setWidth(w / f);
                _size.setHeight((w / ratio) / f);
            }
            else {
                _size.setHeight(h / f);
                _size.setWidth(h * ratio / f);
            }
        }
        else
            _size = parent()->bbox().size() / f;
    }

    // in any case, adjust position relative to parent
    adjustReadPos();
    setbbox(QRectF(0.0, 0.0, _size.width() * f, _size.height() * f));
}
示例#2
0
void Dynamic::layout()
      {
      if (!readPos().isNull()) {
            if (score()->mscVersion() <= 114) {
                  setReadPos(QPointF());
                  // hack: 1.2 boundingBoxes are a bit wider which results
                  // in symbols moved right
                  setUserXoffset(userOff().x() - spatium() * .6);
                  }
            }
      setPos(textStyle().offset(spatium()));
      Text::layout1();

      Segment* s = segment();
      if (!s)
            return;
      for (int voice = 0; voice < VOICES; ++voice) {
            int t = (track() & ~0x3) + voice;
            Chord* c = static_cast<Chord*>(s->element(t));
            if (!c)
                  continue;
            if (c->type() == Element::Type::CHORD) {
                  qreal noteHeadWidth = score()->noteHeadWidth() * c->mag();
                  if (c->stem() && !c->up())  // stem down
                        rxpos() += noteHeadWidth * .25;  // center on stem + optical correction
                  else
                        rxpos() += noteHeadWidth * .5;   // center on notehead
                  }
            else
                  rxpos() += c->width() * .5;
            break;
            }
      adjustReadPos();
      }
示例#3
0
void Jump::layout()
      {
      setPos(QPointF(0.0, score()->styleP(Sid::jumpPosAbove)));
      TextBase::layout1();

      if (parent() && autoplace()) {
            setUserOff(QPointF());
            int si             = staffIdx();
            qreal minDistance  = 0.5 * spatium(); // score()->styleP(Sid::tempoMinDistance);
            Shape& s1          = measure()->staffShape(si);
            Shape s2           = shape().translated(pos());
            if (placeAbove()) {
                  qreal d = s2.minVerticalDistance(s1);
                  if (d > -minDistance) {
                        qreal yd       = -d - minDistance;
                        rUserYoffset() = yd;
                        s2.translate(QPointF(0.0, yd));
                        }
                  }
            else {
                  qreal d = s1.minVerticalDistance(s2);
                  if (d > -minDistance) {
                        qreal yd       = d + minDistance;
                        rUserYoffset() = yd;
                        s2.translate(QPointF(0.0, yd));
                        }
                  }
            s1.add(s2);
            }
      else {
            adjustReadPos();
            }
      }
示例#4
0
void StaffText::layout()
      {
      if (autoplace())
            setUserOff(QPointF());
      QPointF p(textStyle().offset(spatium()));
      if (placement() == Element::Placement::BELOW)
            p.ry() =  - p.ry() + lineHeight();
      setPos(p);
      Text::layout1();
      if (!parent()) // palette & clone trick
          return;

      if (autoplace() && segment()) {
            qreal minDistance = score()->styleP(StyleIdx::dynamicsMinDistance);  // TODO
            Shape s1          = segment()->staffShape(staffIdx()).translated(segment()->pos());
            Shape s2          = shape().translated(segment()->pos());

            if (placement() == Element::Placement::ABOVE) {
                  qreal d = s2.minVerticalDistance(s1);
                  if (d > -minDistance)
                        rUserYoffset() = -d - minDistance;
                  }
            else {
                  qreal d = s1.minVerticalDistance(s2);
                  if (d > -minDistance)
                        rUserYoffset() = d + minDistance;
                  }
            }
      adjustReadPos();
      }
示例#5
0
void PedalSegment::layout()
      {
      TextLineSegment::layout();
      if (parent())     // for palette
            rypos() += score()->styleS(StyleIdx::pedalY).val() * spatium();
      adjustReadPos();
      }
示例#6
0
void TextLineSegment::layout()
      {
      if (autoplace())
            setUserOff(QPointF());

      TextLineBaseSegment::layout();
      if (parent()) {
            if (textLine()->placeBelow()) {
                  qreal sh = staff() ? staff()->height() : 0.0;
                  rypos() = sh + score()->styleP(StyleIdx::textLinePosBelow) * mag();
                  }
            else
                  rypos() = score()->styleP(StyleIdx::textLinePosAbove) * mag();
            if (autoplace()) {
                  qreal minDistance = spatium() * .7;
                  Shape s1 = shape().translated(pos());
                  if (textLine()->placeAbove()) {
                        qreal d  = system()->topDistance(staffIdx(), s1);
                        if (d > -minDistance)
                              rUserYoffset() = -d - minDistance;
                        }
                  else {
                        qreal d  = system()->bottomDistance(staffIdx(), s1);
                        if (d > -minDistance)
                              rUserYoffset() = d + minDistance;
                        }
                  }
            else
                  adjustReadPos();
            }
      }
示例#7
0
void GlissandoSegment::layout()
      {
      QRectF r = QRectF(0.0, 0.0, pos2().x(), pos2().y()).normalized();
      qreal lw = spatium() * glissando()->lineWidth().val() * .5;
      setbbox(r.adjusted(-lw, -lw, lw, lw));
      adjustReadPos();
      }
示例#8
0
void OttavaSegment::layout()
      {
      if (autoplace())
            setUserOff(QPointF());

      TextLineSegment::layout();
      if (parent()) {
            qreal yo = score()->styleP(StyleIdx::ottavaY) * mag();
            if (ottava()->placement() == Element::Placement::BELOW)
                  yo = -yo + staff()->height();
            rypos() += yo;
            if (autoplace()) {
                  qreal minDistance = spatium() * .7;
                  Shape s1 = shape().translated(pos());
                  if (ottava()->placement() == Element::Placement::ABOVE) {
                        qreal d  = system()->topDistance(staffIdx(), s1);
                        if (d > -minDistance)
                              rUserYoffset() = -d - minDistance;
                        }
                  else {
                        qreal d  = system()->bottomDistance(staffIdx(), s1);
                        if (d > -minDistance)
                              rUserYoffset() = d + minDistance;
                        }
                  }
            else
                  adjustReadPos();
            }
      }
示例#9
0
void PedalSegment::layout()
      {
      if (autoplace())
            setUserOff(QPointF());
      TextLineBaseSegment::layout();
      if (parent()) {     // for palette
            rypos() += score()->styleP(pedal()->placeBelow() ? StyleIdx::pedalPosBelow : StyleIdx::pedalPosAbove);
            if (autoplace()) {
                  qreal minDistance = spatium() * .7;
                  Shape s1 = shape().translated(pos());

                  if (pedal()->placeBelow()) {
                        qreal d  = system()->bottomDistance(staffIdx(), s1);
                        if (d > -minDistance)
                              rUserYoffset() = d + minDistance;
                        }
                  else {
                        qreal d  = system()->topDistance(staffIdx(), s1);
                        if (d > -minDistance)
                              rUserYoffset() = -(d + minDistance);
                        }
                  }
            else
                  adjustReadPos();
            }
      }
示例#10
0
void OttavaSegment::layout()
      {
      TextLineSegment::layout1();
      if (parent())     // for palette
            rypos() += score()->styleS(ST_ottavaY).val() * spatium();
      adjustReadPos();
      }
示例#11
0
void SlurSegment::layout(const QPointF& p1, const QPointF& p2)
      {
      ups[GRIP_START].p = p1;
      ups[GRIP_END].p   = p2;
      slurTie()->computeBezier(this);
      setbbox(path.boundingRect());
      adjustReadPos();
      }
示例#12
0
void VoltaSegment::layout()
{
    rypos() = 0.0;
    TextLineSegment::layout1();
    if (parent())     // for palette
        rypos() += score()->styleS(ST_voltaY).val() * spatium();
    adjustReadPos();
}
示例#13
0
void Image::layout()
      {
      setPos(0.0, 0.0);
      if (imageType == ImageType::SVG && !svgDoc) {
            if (_storeItem) {
                  svgDoc = new QSvgRenderer(_storeItem->buffer());
                  if (svgDoc->isValid()) {
                        if (_size.isNull()) {
                              _size = svgDoc->defaultSize();
                              if (_sizeIsSpatium)
                                    _size /= 10.0;    // by convention
                              }
                        }
                  }
            }
      else if (imageType == ImageType::RASTER && !rasterDoc) {
            if (_storeItem) {
                  rasterDoc = new QImage;
                  rasterDoc->loadFromData(_storeItem->buffer());
                  if (!rasterDoc->isNull()) {
                        if (_size.isNull()) {
                              _size = rasterDoc->size() * 0.4;
                              if (_sizeIsSpatium)
                                    _size /= spatium();
                              else
                                    _size /= MScore::DPMM;
                              }
                        _dirty = true;
                        }
                  }
            }

      qreal f = _sizeIsSpatium ? spatium() : MScore::DPMM;
      // if autoscale && inside a box, scale to box relevant size
      if (autoScale() && parent() && ((parent()->type() == Element::Type::HBOX || parent()->type() == Element::Type::VBOX))) {
            if (_lockAspectRatio) {
                  QSizeF size(imageSize());
                  qreal ratio = size.width() / size.height();
                  qreal w = parent()->width();
                  qreal h = parent()->height();
                  if ((w / h) < ratio) {
                        _size.setWidth(w / f);
                        _size.setHeight((w / ratio) / f);
                        }
                  else {
                        _size.setHeight(h / f);
                        _size.setWidth(h * ratio / f);
                        }
                  }
            else
                  _size = parent()->bbox().size() / f;
            }

      // in any case, adjust position relative to parent
      adjustReadPos();
      bbox().setRect(0.0, 0.0, _size.width() * f, _size.height() * f);
      }
示例#14
0
文件: trill.cpp 项目: aiena/MuseScore
void TrillSegment::layout()
      {
      QRectF b1(symbols[score()->symIdx()][trillSym].bbox(magS()));
      QRectF rr(b1.translated(-b1.x(), 0.0));
      rr |= QRectF(0.0, rr.y(), pos2().x(), rr.height());
      setbbox(rr);
      rypos() += score()->styleS(ST_trillY).val() * spatium();
      adjustReadPos();
      }
示例#15
0
void HairpinSegment::layout()
      {
      QTransform t;
      qreal _spatium = spatium();
      qreal h1 = score()->styleS(ST_hairpinHeight).val() * _spatium * .5;
      qreal h2 = score()->styleS(ST_hairpinContHeight).val() * _spatium * .5;

      rypos() = 0.0;
      qreal len;
      qreal x = pos2().x();
      if (x < _spatium)             // minimum size of hairpin
            x = _spatium;
      qreal y = pos2().y();
      len     = sqrt(x * x + y * y);
      t.rotateRadians(asin(y/len));

      if (hairpin()->hairpinType() == 0) {
            // crescendo
            switch (spannerSegmentType()) {
                  case SEGMENT_SINGLE:
                  case SEGMENT_BEGIN:
                        l1.setLine(.0, .0, len, h1);
                        l2.setLine(.0, .0, len, - h1);
                        break;
                  case SEGMENT_MIDDLE:
                  case SEGMENT_END:
                        l1.setLine(.0,  h2, len, h1);
                        l2.setLine(.0, -h2, len, - h1);
                        break;
                  }
            }
      else {
            // decrescendo
            switch(spannerSegmentType()) {
                  case SEGMENT_SINGLE:
                  case SEGMENT_END:
                        l1.setLine(.0,  h1, len, 0.0);
                        l2.setLine(.0, -h1, len, 0.0);
                        break;
                  case SEGMENT_BEGIN:
                  case SEGMENT_MIDDLE:
                        l1.setLine(.0,  h1, len, + h2);
                        l2.setLine(.0, -h1, len, - h2);
                        break;
                  }
            }
      l1 = t.map(l1);
      l2 = t.map(l2);

      QRectF r = QRectF(l1.p1(), l1.p2()).normalized() | QRectF(l2.p1(), l2.p2()).normalized();
      qreal w = point(score()->styleS(ST_hairpinWidth));
      setbbox(r.adjusted(-w*.5, -w*.5, w, w));
      if (parent())
            rypos() += score()->styleS(ST_hairpinY).val() * _spatium;
      adjustReadPos();
      }
示例#16
0
void Text::layout()
      {
      if (styled() && !_editMode) {
            SimpleText::layout();
            }
      else {
            _doc->setDefaultFont(textStyle().font(spatium()));
            qreal w = -1.0;
            qreal x = 0.0;
            qreal y = 0.0;
            if (parent() && layoutToParentWidth()) {
                  w = parent()->width();
                  if (parent()->type() == HBOX || parent()->type() == VBOX || parent()->type() == TBOX) {
                        Box* box = static_cast<Box*>(parent());
                        x += box->leftMargin() * MScore::DPMM;
                        y += box->topMargin() * MScore::DPMM;
                        w = box->width()   - ((box->leftMargin() + box->rightMargin()) * MScore::DPMM);
                        }
                  }

            QTextOption to = _doc->defaultTextOption();
            to.setUseDesignMetrics(true);
            to.setWrapMode(w <= 0.0 ? QTextOption::NoWrap : QTextOption::WrapAtWordBoundaryOrAnywhere);
            _doc->setDefaultTextOption(to);

            if (w < 0.0)
                  w = _doc->idealWidth();
            _doc->setTextWidth(w);

            setbbox(QRectF(QPointF(0.0, 0.0), _doc->size()));
            if (hasFrame())
                  layoutFrame();
            _doc->setModified(false);
            textStyle().layout(this);      // process alignment

#if 0 // TODO  TEXT_STYLE_TEXTLINE
            if ((textStyle().align() & ALIGN_VCENTER) && (textStyle() == TEXT_STYLE_TEXTLINE)) {
                  // special case: vertically centered text with TextLine needs to
                  // take into account the line width
                  TextLineSegment* tls = static_cast<TextLineSegment*>(parent());
                  TextLine* tl = tls->textLine();
                  if (tl) {
                        qreal textlineLineWidth = point(tl->lineWidth());
                        rypos() -= textlineLineWidth * .5;
                        }
                  }
#endif
            rxpos() += x;
            rypos() += y;
            }
      if (parent() && parent()->type() == SEGMENT) {
            Segment* s = static_cast<Segment*>(parent());
            rypos() += s ? s->measure()->system()->staff(staffIdx())->y() : 0.0;
            }
      adjustReadPos();
      }
示例#17
0
void Marker::layout()
      {
      setPos(textStyle().offset(spatium()));
      Text::layout1();
      // although normally laid out to parent (measure) width,
      // force to center over barline if left-aligned
      if (layoutToParentWidth() && !(textStyle().align() & (AlignmentFlags::RIGHT|AlignmentFlags::HCENTER)))
            rxpos() -= width() * 0.5;
      adjustReadPos();
      }
示例#18
0
void Marker::layout()
      {
      setPos(QPointF(0.0, score()->styleP(StyleIdx::markerPosAbove)));
      Text::layout1();
      // although normally laid out to parent (measure) width,
      // force to center over barline if left-aligned
      if (layoutToParentWidth() && !(align() & (Align::RIGHT | Align::HCENTER)))
            rxpos() -= width() * 0.5;
      adjustReadPos();
      }
示例#19
0
void OttavaSegment::layout()
      {
      TextLineSegment::layout1();
      if (parent()) {     // for palette
            qreal yo(score()->styleS(StyleIdx::ottavaY).val() * spatium());
            if (ottava()->placement() == Placement::BELOW)
                  yo = -yo + staff()->height();
            rypos() += yo;
            }
      adjustReadPos();
      }
示例#20
0
void FSymbol::layout()
{
    QString s;
    if (_code & 0xffff0000) {
        s = QChar(QChar::highSurrogate(_code));
        s += QChar(QChar::lowSurrogate(_code));
    }
    else
        s = QChar(_code);
    QFontMetricsF fm(_font);
    setbbox(fm.boundingRect(s));
    adjustReadPos();
}
示例#21
0
void HBox::layout()
      {
      if (parent() && parent()->type() == VBOX) {
            VBox* vb = static_cast<VBox*>(parent());
            qreal x = vb->leftMargin() * MScore::DPMM;
            qreal y = vb->topMargin() * MScore::DPMM;
            qreal w = point(boxWidth());
            qreal h = vb->height() - (vb->topMargin() + vb->bottomMargin()) * MScore::DPMM;
            setPos(x, y);
            bbox().setRect(0.0, 0.0, w, h);
            }
      else {
            bbox().setRect(0.0, 0.0, point(boxWidth()), system()->height());
            }
      Box::layout();
      adjustReadPos();
      }
示例#22
0
void TrillSegment::layout()
{
    if (parent())
        rypos() += score()->styleS(StyleIdx::trillY).val() * spatium();
    if (staff())
        setMag(staff()->mag());
    if (spannerSegmentType() == SpannerSegmentType::SINGLE || spannerSegmentType() == SpannerSegmentType::BEGIN) {
        Accidental* a = trill()->accidental();
        if (a) {
            a->layout();
            a->setMag(a->mag() * .6);
            qreal _spatium = spatium();
            a->setPos(_spatium * 1.3, -2.2 * _spatium);
            a->adjustReadPos();
        }
        switch (trill()->trillType()) {
        case Trill::Type::TRILL_LINE:
            symbolLine(SymId::ornamentTrill, SymId::wiggleTrill);
            break;
        case Trill::Type::PRALLPRALL_LINE:
            symbolLine(SymId::wiggleTrill, SymId::wiggleTrill);
            break;
        case Trill::Type::UPPRALL_LINE:
            if (score()->scoreFont()->isValid(SymId::ornamentBottomLeftConcaveStroke))
                symbolLine(SymId::ornamentBottomLeftConcaveStroke,
                           SymId::ornamentZigZagLineNoRightEnd, SymId::ornamentZigZagLineWithRightEnd);
            else
                symbolLine(SymId::ornamentUpPrall,
                           // SymId::ornamentZigZagLineNoRightEnd, SymId::ornamentZigZagLineWithRightEnd);
                           SymId::ornamentZigZagLineNoRightEnd);
            break;
        case Trill::Type::DOWNPRALL_LINE:
            if (score()->scoreFont()->isValid(SymId::ornamentLeftVerticalStroke))
                symbolLine(SymId::ornamentLeftVerticalStroke,
                           SymId::ornamentZigZagLineNoRightEnd, SymId::ornamentZigZagLineWithRightEnd);
            else
                symbolLine(SymId::ornamentDownPrall,
                           // SymId::ornamentZigZagLineNoRightEnd, SymId::ornamentZigZagLineWithRightEnd);
                           SymId::ornamentZigZagLineNoRightEnd);
            break;
        }
    }
    else
        symbolLine(SymId::wiggleTrill, SymId::wiggleTrill);
    adjustReadPos();
}
示例#23
0
void VoltaSegment::layout()
      {
      if (autoplace())
            setUserOff(QPointF());
      TextLineBaseSegment::layout();
      if (!parent())
            return;
      rypos() = score()->styleP(StyleIdx::voltaY) * mag();
      if (autoplace()) {
            qreal minDistance = spatium() * .7;
            Shape s1 = shape().translated(pos());
            qreal d  = system()->topDistance(staffIdx(), s1);
            if (d > -minDistance)
                  rUserYoffset() = -d - minDistance;
            }
      else
            adjustReadPos();
      }
示例#24
0
文件: stem.cpp 项目: Fyrult/MuseScore
void Stem::layout()
      {
      qreal l    = _len + _userLen;
      qreal _up  = up() ? -1.0 : 1.0;
      l         *= _up;

      qreal y1 = 0.0;                           // vertical displacement to match note attach point
      Staff* stf = staff();
      if (chord()) {
            int tick = chord()->tick();
            StaffType* st = stf->staffType(tick);
            if (st->isTabStaff() ) {            // TAB staves
                  if (st->stemThrough()) {
                        // if stems through staves, gets Y pos. of stem-side note relative to chord other side
                        qreal lineDist = st->lineDistance().val() * spatium();
                        y1             = (chord()->downString() - chord()->upString()) * _up * lineDist;
                        // if fret marks above lines, raise stem beginning by 1/2 line distance
                        if (!st->onLines())
                              y1 -= lineDist * 0.5;
                        // shorten stem by 1/2 lineDist to clear the note and a little more to keep 'air' betwen stem and note
                        lineDist *= 0.7 * mag();
                        y1       += _up * lineDist;
                        }
                  // in other TAB types, no correction
                  }
            else {                              // non-TAB
                  // move stem start to note attach point
                  Note* n  = up() ? chord()->downNote() : chord()->upNote();
                  y1      += (up() ? n->stemUpSE().y() : n->stemDownNW().y());
                  rypos() = n->rypos();
                  }
            }

      qreal lw5 = _lineWidth * .5;

      line.setLine(0.0, y1, 0.0, l);

      // compute bounding rectangle
      QRectF r(line.p1(), line.p2());
      setbbox(r.normalized().adjusted(-lw5, -lw5, lw5, lw5));
      adjustReadPos();  // does not work if stem is layouted twice
      }
示例#25
0
void TrillSegment::layout()
      {
      QRectF b1(symBbox(SymId::ornamentTrill));
      QRectF rr(b1.translated(-b1.x(), 0.0));
      rr |= QRectF(0.0, rr.y(), pos2().x(), rr.height());
      setbbox(rr);
      if (parent())
            rypos() += score()->styleS(ST_trillY).val() * spatium();
      if (spannerSegmentType() == SEGMENT_SINGLE || spannerSegmentType() == SEGMENT_BEGIN) {
            Accidental* a = trill()->accidental();
            if (a) {
                  a->layout();
                  a->setMag(a->mag() * .6);
                  qreal _spatium = spatium();
                  a->setPos(_spatium*1.3, -2.2*_spatium);
                  a->adjustReadPos();
                  }
            }
      adjustReadPos();
      }
示例#26
0
void RehearsalMark::layout()
      {
      setPos(textStyle().offset(spatium()));
      Text::layout1();
      Segment* s = segment();
      if (s && !s->rtick()) {
            // first CR of measure, decide whether to align to barline
            if (!s->prev()) {
                  // measure with no clef / keysig / timesig
                  rxpos() -= s->x();
                  }
            else if (textStyle().align() & AlignmentFlags::RIGHT) {
                  // measure with clef / keysig / timesig, rehearsal mark right aligned
                  // align left edge of rehearsal to barline if that is further to left
                  qreal leftX = bbox().x();
                  qreal barlineX = -s->x();
                  rxpos() += qMin(leftX, barlineX) + width();
                  }
            }
      adjustReadPos();
      }
示例#27
0
void TempoText::layout()
      {
      setPos(textStyle().offset(spatium()));
      Text::layout1();

      // tempo text on first chordrest of measure should align over time sig if present
      //
      Segment* s = segment();
      if (s && !s->rtick()) {
            Segment* p = segment()->prev(Segment::Type::TimeSig);
            if (p) {
                  rxpos() -= s->x() - p->x();
                  Element* e = p->element(staffIdx() * VOICES);
                  if (e)
                        rxpos() += e->x();
                  }
            }

      if (placement() == Element::Placement::BELOW)
            rypos() = -rypos() + 4 * spatium();
      adjustReadPos();
      }
示例#28
0
void HairpinSegment::layout()
      {
      if (hairpin()->useTextLine()) {
            if (parent())
                  rypos() += score()->styleS(StyleIdx::hairpinY).val() * spatium();
            TextLineSegment::layout();
            return;
            }

      QTransform t;
      qreal _spatium = spatium();
      qreal h1 = hairpin()->hairpinHeight().val() * spatium() * .5;
      qreal h2 = hairpin()->hairpinContHeight().val() * spatium() * .5;

      qreal len;
      qreal x = pos2().x();
      if (x < _spatium)             // minimum size of hairpin
            x = _spatium;
      qreal y = pos2().y();
      len     = sqrt(x * x + y * y);
      t.rotateRadians(asin(y/len));

      drawCircledTip =  hairpin()->hairpinCircledTip();
      circledTipRadius = 0;
      if( drawCircledTip )
        circledTipRadius  = 0.6 * _spatium * .5;
      if (hairpin()->hairpinType() == Hairpin::Type::CRESCENDO) {
            // crescendo
            switch (spannerSegmentType()) {
                  case SpannerSegmentType::SINGLE:
                  case SpannerSegmentType::BEGIN:
                        l1.setLine(.0 + circledTipRadius*2, .0, len, h1);
                        l2.setLine(.0 + circledTipRadius*2, .0, len, -h1);
                        circledTip.setX( 0 + circledTipRadius );
                        circledTip.setY( 0 );
                        break;
                  case SpannerSegmentType::MIDDLE:
                  case SpannerSegmentType::END:
                        drawCircledTip = false;
                        l1.setLine(.0,  h2, len, h1);
                        l2.setLine(.0, -h2, len, -h1);
                        break;
                  }
            }
      else {
            // decrescendo
            switch(spannerSegmentType()) {
                  case SpannerSegmentType::SINGLE:
                  case SpannerSegmentType::END:
                        l1.setLine(.0,  h1, len - circledTipRadius*2, 0.0);
                        l2.setLine(.0, -h1, len - circledTipRadius*2, 0.0);
                        circledTip.setX( len - circledTipRadius );
                        circledTip.setY( 0 );
                        break;
                  case SpannerSegmentType::BEGIN:
                  case SpannerSegmentType::MIDDLE:
                        drawCircledTip = false;
                        l1.setLine(.0,  h1, len, + h2);
                        l2.setLine(.0, -h1, len, - h2);
                        break;
                  }
            }
// Do Coord rotation
      l1 = t.map(l1);
      l2 = t.map(l2);
      if( drawCircledTip )
        circledTip = t.map(circledTip);


      QRectF r = QRectF(l1.p1(), l1.p2()).normalized() | QRectF(l2.p1(), l2.p2()).normalized();
      qreal w = point(score()->styleS(StyleIdx::hairpinLineWidth));
      setbbox(r.adjusted(-w*.5, -w*.5, w, w));
      if (parent())
            rypos() += score()->styleS(StyleIdx::hairpinY).val() * _spatium;
      adjustReadPos();
      }
示例#29
0
文件: text.cpp 项目: aeliot/MuseScore
void Text::layout()
      {
      layout1();
      adjustReadPos();
      }
示例#30
0
void Glissando::layout()
      {
      qreal       _spatium    = spatium();

      if (score() == gscore                                                   // for use in palettes
                  || startElement() == nullptr || endElement() == nullptr) {  // or while dragging
            if (spannerSegments().isEmpty())
                  add(createLineSegment());
            LineSegment* s = frontSegment();
            s->setPos(QPointF());
            s->setPos2(QPointF(_spatium * GLISS_PALETTE_WIDTH, -_spatium * GLISS_PALETTE_HEIGHT));
            s->layout();
            return;
            }

      SLine::layout();
      setPos(0.0, 0.0);
      adjustReadPos();

      Note*       anchor1     = static_cast<Note*>(startElement());
      Note*       anchor2     = static_cast<Note*>(endElement());
      Chord*      cr1         = anchor1->chord();
      Chord*      cr2         = anchor2->chord();
      GlissandoSegment*       segm1 = static_cast<GlissandoSegment*>(frontSegment());
      GlissandoSegment*       segm2 = static_cast<GlissandoSegment*>(backSegment());

      // Note: line segments are defined by
      // initial point: ipos() (relative to system origin)
      // ending point:  pos2() (relative to initial point)

      // LINE ENDING POINTS TO NOTE HEAD CENTRES

      // assume gliss. line goes from centre of initial note centre to centre of ending note:
      // move first segment origin and last segment ending point from note head origin to note head centre
      QPointF     offs1       = QPointF(anchor1->headWidth() * 0.5, 0.0);
      QPointF     offs2       = QPointF(anchor2->headWidth() * 0.5, 0.0);

      // AVOID HORIZONTAL LINES

      int         upDown      = (0 < (anchor2->pitch() - anchor1->pitch())) - ((anchor2->pitch() - anchor1->pitch()) < 0);
      // on TAB's, glissando are by necessity on the same string, this gives an horizontal glissando line;
      // make bottom end point lower and top ending point higher
      if (cr1->staff()->isTabStaff()) {
                  qreal yOff = cr1->staff()->lineDistance() * 0.3 * _spatium;
                  offs1.ry() += yOff * upDown;
                  offs2.ry() -= yOff * upDown;
            }
      // if not TAB, angle glissando between notes on the same line
      else {
            if (anchor1->line() == anchor2->line()) {
                  offs1.ry() += _spatium * 0.25 * upDown;
                  offs2.ry() -= _spatium * 0.25 * upDown;
                  }
            }

      // move initial point of first segment and adjust its length accordingly
      segm1->setPos (segm1->ipos()  + offs1);
      segm1->setPos2(segm1->ipos2() - offs1);
      // adjust ending point of last segment
      segm2->setPos2(segm2->ipos2() + offs2);

      // FINAL SYSTEM-INITIAL NOTE
      // if the last gliss. segment attaches to a system-initial note, some extra width has to be added
      if (cr2->segment()->measure() == cr2->segment()->system()->firstMeasure() && cr2->rtick() == 0)
      {
            segm2->rxpos() -= GLISS_STARTOFSYSTEM_WIDTH * _spatium;
            segm2->rxpos2()+= GLISS_STARTOFSYSTEM_WIDTH * _spatium;
      }

      // INTERPOLATION OF INTERMEDIATE POINTS
      // This probably belongs to SLine class itself; currently it does not seem
      // to be needed for anything else than Glissando, though

      // get total x-width and total y-height of all segments
      qreal xTot = 0.0;
      for (SpannerSegment* segm : spannerSegments())
            xTot += segm->ipos2().x();
      qreal y0   = segm1->ipos().y();
      qreal yTot = segm2->ipos().y() + segm2->ipos2().y() - y0;
      qreal ratio = yTot / xTot;
      // interpolate y-coord of intermediate points across total width and height
      qreal xCurr = 0.0;
      qreal yCurr;
      for (int i = 0; i < spannerSegments().count()-1; i++)
      {
           SpannerSegment* segm = segmentAt(i);
           xCurr += segm->ipos2().x();
           yCurr = y0 + ratio * xCurr;
           segm->rypos2() = yCurr - segm->ipos().y();       // position segm. end point at yCurr
           // next segment shall start where this segment stopped
           segm = segmentAt(i+1);
           segm->rypos2() += segm->ipos().y() - yCurr;      // adjust next segm. vertical length
           segm->rypos() = yCurr;                           // position next segm. start point at yCurr
      }

      // STAY CLEAR OF NOTE APPENDAGES

      // initial note dots / ledger line / note head
      offs1 *= -1.0;          // discount changes already applied
      int dots = cr1->dots();
      LedgerLine * ledLin = cr1->ledgerLines();
      // if dots, start at right of last dot
      // if no dots, from right of ledger line, if any; from right of note head, if no ledger line
      offs1.rx() += (dots && anchor1->dot(dots-1) ? anchor1->dot(dots-1)->pos().x() + anchor1->dot(dots-1)->width()
                  : (ledLin ? ledLin->pos().x() + ledLin->width() : anchor1->headWidth()) );

      // final note arpeggio / accidental / ledger line / accidental / arpeggio (i.e. from outermost to innermost)
      offs2 *= -1.0;          // discount changes already applied
      if (Arpeggio* a = cr2->arpeggio())
            offs2.rx() += a->pos().x() + a->userOff().x();
      else if (Accidental* a = anchor2->accidental())
            offs2.rx() += a->pos().x() + a->userOff().x();
      else if ( (ledLin = cr2->ledgerLines()) != nullptr)
            offs2.rx() += ledLin->pos().x();

      // add another a quarter spatium of 'air'
      offs1.rx() += _spatium * 0.25;
      offs2.rx() -= _spatium * 0.25;

      // apply offsets: shorten first segment by x1 (and proportionally y) and adjust its length accordingly
      offs1.ry() = segm1->ipos2().y() * offs1.x() / segm1->ipos2().x();
      segm1->setPos(segm1->ipos() + offs1);
      segm1->setPos2(segm1->ipos2() - offs1);
      // adjust last segment length by x2 (and proportionally y)
      offs2.ry() = segm2->ipos2().y() * offs2.x() / segm2->ipos2().x();
      segm2->setPos2(segm2->ipos2() + offs2);

      for (SpannerSegment* segm : spannerSegments())
            static_cast<GlissandoSegment*>(segm)->layout();

      // compute glissando bbox as the bbox of the last segment, relative to the end anchor note
      QPointF anchor2PagePos = anchor2->pagePos();
      QPointF system2PagePos = cr2->segment()->system()->pagePos();
      QPointF anchor2SystPos = anchor2PagePos - system2PagePos;
      QRectF r = QRectF(anchor2SystPos - segm2->pos(), anchor2SystPos - segm2->pos() - segm2->pos2()).normalized();
      qreal lw = _spatium * lineWidth().val() * .5;
      setbbox(r.adjusted(-lw, -lw, lw, lw));
      }