bool LineSegment::readProperties(XmlReader& e) { const QStringRef& tag(e.name()); if (tag == "subtype") setSubtype(SpannerSegmentType(e.readInt())); else if (tag == "off1") // obsolete setUserOff(e.readPoint() * spatium()); else if (tag == "off2") setUserOff2(e.readPoint() * spatium()); else if (tag == "pos") { if (score()->mscVersion() > 114) { qreal _spatium = spatium(); setUserOff(QPointF()); setReadPos(e.readPoint() * _spatium); } else e.readNext(); } #if 0 else if (tag == "pos") { QPointF rp = e.readPoint() * spatium(); if ((score()->mscVersion() <= 114) && (type() == VOLTA_SEGMENT)) { rp.ry() -= spatium(); } setReadPos(rp); } #endif else if (!Element::readProperties(e)) { e.unknown(); return false; } return true; }
QRectF Dynamic::drag(EditData* ed) { QRectF f = Element::drag(ed); // // move anchor // Qt::KeyboardModifiers km = qApp->keyboardModifiers(); if (km != (Qt::ShiftModifier | Qt::ControlModifier)) { int si; Segment* seg = 0; if (score()->pos2measure(ed->pos, &si, 0, &seg, 0) == nullptr) return f; if (seg && (seg != segment() || staffIdx() != si)) { QPointF pos1(canvasPos()); score()->undo(new ChangeParent(this, seg, si)); setUserOff(QPointF()); layout(); QPointF pos2(canvasPos()); setUserOff(pos1 - pos2); ed->startMove = pos2; } } return f; }
void RehearsalMark::layout() { if (autoplace()) setUserOff(QPointF()); setPos(textStyle().offset(spatium())); Text::layout1(); Segment* s = segment(); if (s) { if (!s->rtick()) { // first CR of measure, decide whether to align to barline if (!s->prev() && align() & AlignmentFlags::CENTER) { // measure with no clef / keysig / timesig rxpos() -= s->x(); } else if (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(); } } if (autoplace()) { Shape s1 = s->staffShape(staffIdx()).translated(s->pos()); Shape s2 = shape().translated(s->pos()); qreal d = s2.minVerticalDistance(s1); if (d > 0) setUserOff(QPointF(0.0, -d)); } } }
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(); } }
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(); } }
void Jump::layout() { setPos(QPointF(0.0, score()->styleP(Sid::jumpPosAbove))); TextBase::layout1(); if (parent() && autoplace()) { setUserOff(QPointF()); #if 0 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); #endif } }
void OttavaSegment::layout() { TextLineBaseSegment::layout(); if (parent()) { qreal y; if (placeAbove()) { y = score()->styleP(Sid::ottavaPosAbove); } else { qreal sh = ottava()->staff() ? ottava()->staff()->height() : 0; y = score()->styleP(Sid::ottavaPosBelow) + sh; } rypos() = y; if (autoplace()) { setUserOff(QPointF()); qreal minDistance = spatium() * .7; Shape s1 = shape().translated(pos()); if (ottava()->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; } } } }
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(); } }
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(); }
QRectF BSymbol::drag(EditData& ed) { QRectF r(canvasBoundingRect()); foreach(const Element* e, _leafs) r |= e->canvasBoundingRect(); qreal x = ed.delta.x(); qreal y = ed.delta.y(); qreal _spatium = spatium(); if (ed.hRaster) { qreal hRaster = _spatium / MScore::hRaster(); int n = lrint(x / hRaster); x = hRaster * n; } if (ed.vRaster) { qreal vRaster = _spatium / MScore::vRaster(); int n = lrint(y / vRaster); y = vRaster * n; } setUserOff(QPointF(x, y)); r |= canvasBoundingRect(); foreach(const Element* e, _leafs) r |= e->canvasBoundingRect(); return r; }
void Fingering::reset() { QPointF o(userOff()); score()->layoutFingering(this); QPointF no(userOff()); setUserOff(o); score()->undoChangeProperty(this, P_ID::USER_OFF, no); }
void LineSegment::editDrag(const EditData& ed) { // Only for resizing according to the diagonal properties QPointF deltaResize(ed.delta.x(), line()->diagonal() ? ed.delta.y() : 0.0); // Only for moving, no y limitaion QPointF deltaMove(ed.delta.x(), ed.delta.y()); switch(ed.curGrip) { case GRIP_LINE_START: // Resize the begin of element (left grip) setUserOff(userOff() + deltaResize); _userOff2 -= deltaResize; break; case GRIP_LINE_END: // Resize the end of element (rigth grip) _userOff2 += deltaResize; break; case GRIP_LINE_MIDDLE: // Move the element (middle grip) setUserOff(userOff() + deltaMove); break; } if ((line()->anchor() == Spanner::ANCHOR_NOTE) && (ed.curGrip == GRIP_LINE_START || ed.curGrip == GRIP_LINE_END)) { // // if we touch a different note, change anchor // Element* e = ed.view->elementNear(ed.pos); if (e && e->type() == NOTE) { SLine* l = line(); if (ed.curGrip == GRIP_LINE_END && e != line()->endElement()) { qDebug("LineSegment: move end anchor"); Note* noteOld = static_cast<Note*>(l->endElement()); Note* noteNew = static_cast<Note*>(e); noteOld->removeSpannerBack(l); noteNew->addSpannerBack(l); l->setEndElement(noteNew); _userOff2 += noteOld->canvasPos() - noteNew->canvasPos(); } else if (ed.curGrip == GRIP_LINE_START && e != l->startElement()) { qDebug("LineSegment: move start anchor (not impl.)"); } } } line()->layout(); }
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)); } }
void TrillSegment::layout() { if (autoplace()) setUserOff(QPointF()); if (staff()) setMag(staff()->mag(tick())); if (isSingleType() || isBeginType()) { 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->setParent(this); } 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: symbolLine(SymId::ornamentBottomLeftConcaveStroke, SymId::ornamentZigZagLineNoRightEnd, SymId::ornamentZigZagLineWithRightEnd); break; case Trill::Type::DOWNPRALL_LINE: symbolLine(SymId::ornamentLeftVerticalStroke, SymId::ornamentZigZagLineNoRightEnd, SymId::ornamentZigZagLineWithRightEnd); break; } } else symbolLine(SymId::wiggleTrill, SymId::wiggleTrill); if (parent()) { qreal yo = score()->styleP(trill()->placeBelow() ? Sid::trillPosBelow : Sid::trillPosAbove); rypos() = yo; if (autoplace()) { qreal minDistance = spatium(); Shape s1 = shape().translated(pos()); if (trill()->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; } } } }
void Fingering::reset() { QPointF o(userOff()); score()->layoutFingering(this); QPointF no; TextStyleType tst = textStyleType(); if (tst == TextStyleType::FINGERING || tst == TextStyleType::RH_GUITAR_FINGERING || tst == TextStyleType::STRING_NUMBER) no = userOff(); setUserOff(o); score()->undoChangeProperty(this, P_ID::USER_OFF, no); }
void LineSegment::editDrag(const EditData& ed) { // Only for resizing according to the diagonal properties QPointF deltaResize(ed.delta.x(), line()->diagonal() ? ed.delta.y() : 0.0); // Only for moving, no y limitaion QPointF deltaMove(ed.delta.x(), ed.delta.y()); switch(ed.curGrip) { case GRIP_LINE_START: // Resize the begin of element (left grip) setUserOff(userOff() + deltaResize); _userOff2 -= deltaResize; break; case GRIP_LINE_END: // Resize the end of element (rigth grip) _userOff2 += deltaResize; break; case GRIP_LINE_MIDDLE: // Move the element (middle grip) setUserOff(userOff() + deltaMove); break; } layout(); }
bool LineSegment::readProperties(const QDomElement& e) { const QString& tag(e.tagName()); if (tag == "subtype") setSubtype(SpannerSegmentType(e.text().toInt())); else if (tag == "off1") // obsolete setUserOff(readPoint(e) * spatium()); else if (tag == "off2") setUserOff2(readPoint(e) * spatium()); else if (tag == "pos") { if (score()->mscVersion() > 114) { qreal _spatium = spatium(); setUserOff(QPointF()); setReadPos(readPoint(e) * _spatium); } } else if (!Element::readProperties(e)) { domError(e); return false; } return true; }
void LineSegment::setGrip(int grip, const QPointF& p) { QPointF pt(p * spatium()); if (grip == GRIP_LINE_START) { QPointF delta = pt - (pagePos() - gripAnchor(grip)); setUserOff(userOff() + delta); _userOff2 -= delta; } else { setUserOff2(pt - pagePos() - _p2 + gripAnchor(grip)); } layout(); }
QRectF Rest::drag(EditData* data) { QPointF s(data->delta); QRectF r(abbox()); // Limit horizontal drag range static const qreal xDragRange = spatium() * 5; if (fabs(s.x()) > xDragRange) s.rx() = xDragRange * (s.x() < 0 ? -1.0 : 1.0); setUserOff(QPointF(s.x(), s.y())); layout(); score()->rebuildBspTree(); return abbox() | r; }
void Lyrics::layout() { // setPos(_textStyle.offset(spatium())); layout1(); QPointF rp(readPos()); if (!rp.isNull()) { if (score()->mscVersion() <= 114) { rp.ry() += lineSpacing() + 2; rp.rx() += bbox().width() * .5; } setUserOff(rp - ipos()); setReadPos(QPointF()); } }
void RehearsalMark::layout() { if (autoplace()) setUserOff(QPointF()); qreal y; if (placeAbove()) y = score()->styleP(StyleIdx::rehearsalMarkPosAbove); else { qreal sh = staff() ? staff()->height() : 0; y = score()->styleP(StyleIdx::rehearsalMarkPosBelow) + sh + lineSpacing(); } setPos(QPointF(0.0, y)); Text::layout1(); Segment* s = segment(); if (s) { if (!s->rtick()) { // first CR of measure, decide whether to align to barline if (!s->prev() && align() & Align::CENTER) { // measure with no clef / keysig / timesig rxpos() -= s->x(); } else if (align() & Align::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(); } } if (autoplace()) { int firstStaffIdx = s->measure()->system()->firstVisibleStaff(); qreal minDistance = score()->styleP(StyleIdx::rehearsalMarkMinDistance); Shape s1 = s->measure()->staffShape(firstStaffIdx); Shape s2 = shape().translated(s->pos() + pos()); if (placeAbove()) { qreal d = s2.minVerticalDistance(s1); if (d > -minDistance) rUserYoffset() = -d - minDistance; } else { qreal d = s1.minVerticalDistance(s2); if (d > -minDistance) rUserYoffset() = d + minDistance; } } } }
void Rest::setUserOffset(qreal x, qreal y) { qreal _spatium = spatium(); int line = lrint(y/_spatium); if (_sym == wholerestSym && (line <= -2 || line >= 3)) _sym = outsidewholerestSym; else if (_sym == outsidewholerestSym && (line > -2 && line < 4)) _sym = wholerestSym; else if (_sym == halfrestSym && (line <= -3 || line >= 3)) _sym = outsidehalfrestSym; else if (_sym == outsidehalfrestSym && (line > -3 && line < 3)) _sym = halfrestSym; setUserOff(QPointF(x, qreal(line) * _spatium)); }
QRectF HBox::drag(const EditData& data) { QRectF r(canvasBoundingRect()); qreal diff = data.delta.x(); qreal x1 = userOff().x() + diff; if (parent()->type() == VBOX) { VBox* vb = static_cast<VBox*>(parent()); qreal x2 = parent()->width() - width() - (vb->leftMargin() + vb->rightMargin()) * MScore::DPMM; if (x1 < 0.0) x1 = 0.0; else if (x1 > x2) x1 = x2; } setUserOff(QPointF(x1, 0.0)); setStartDragPosition(data.pos); return canvasBoundingRect() | r; }
void Marker::adjustReadPos() { if (!readPos().isNull()) { QPointF uo; if (score()->mscVersion() <= 114) { // rebase from Measure to Segment uo = userOff(); uo.rx() -= segment()->pos().x(); // 1.2 is always HCENTER aligned if ((align() & ALIGN_HMASK) == 0) // ALIGN_LEFT uo.rx() -= bbox().width() * .5; } else uo = readPos() - ipos(); setUserOff(uo); setReadPos(QPointF()); } }
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(); }
bool Articulation::setProperty(P_ID propertyId, const QVariant& v) { score()->addRefresh(canvasBoundingRect()); switch (propertyId) { case P_ID::DIRECTION: setDirection(MScore::Direction(v.toInt())); break; case P_ID::ARTICULATION_ANCHOR: anchorStyle = PropertyStyle::UNSTYLED; setAnchor(ArticulationAnchor(v.toInt())); break; case P_ID::PLAY: setPlayArticulation(v.toBool()); break; case P_ID::ORNAMENT_STYLE: setOrnamentStyle(MScore::OrnamentStyle(v.toInt())); break; case P_ID::TIME_STRETCH: setTimeStretch(v.toDouble()); score()->fixTicks(); break; case P_ID::USER_OFF: setUserOff(v.toPointF()); if (_articulationType == ArticulationType::Tenuto) { // moving a tenuto may move slurs: score()->setLayoutAll(true); } return true; default: return Element::setProperty(propertyId, v); } // layout: if (chordRest()) chordRest()->layoutArticulations(); else if (parent() && parent()->type() == Element::Type::BAR_LINE) static_cast<BarLine*>(parent())->layout(); score()->addRefresh(canvasBoundingRect()); score()->setLayoutAll(false); // DEBUG canvasBoundingRectChanged(); // rebuild bsp tree return true; }
void Clef::read(XmlReader& e) { while (e.readNextStartElement()) { const QStringRef& tag(e.name()); if (tag == "subtype") setClefType(clefType(e.readElementText())); else if (tag == "concertClefType") _clefTypes._concertClef = Clef::clefType(e.readElementText()); else if (tag == "transposingClefType") _clefTypes._transposingClef = Clef::clefType(e.readElementText()); else if (tag == "showCourtesyClef") _showCourtesy = e.readInt(); else if (!Element::readProperties(e)) e.unknown(); } if (score()->mscVersion() < 113) setUserOff(QPointF()); if (clefType() == ClefType::INVALID) setClefType(ClefType::G); }
void SlurSegment::editDrag(const EditData& ed) { qreal _spatium = spatium(); ups[ed.curGrip].off += (ed.delta / _spatium); if (ed.curGrip == GRIP_START || ed.curGrip == GRIP_END) { slurTie()->computeBezier(this); // // move anchor for slurs // Slur* slur = static_cast<Slur*>(slurTie()); Element* e = ed.view->elementNear(ed.pos); if ((slur->type() == SLUR) && ( (ed.curGrip == GRIP_START && (subtype() == SEGMENT_SINGLE || subtype() == SEGMENT_BEGIN)) || (ed.curGrip == GRIP_END && (subtype() == SEGMENT_SINGLE || subtype() == SEGMENT_END)) ) ) { if (e && e->type() == NOTE) { Chord* chord = static_cast<Note*>(e)->chord(); if ((ed.curGrip == GRIP_END && chord != slur->endElement()) || (ed.curGrip == GRIP_START && chord != slur->startElement())) { changeAnchor(ed.view, ed.curGrip, chord); QPointF p1 = ed.pos - ups[ed.curGrip].p - pagePos(); ups[ed.curGrip].off = p1 / _spatium; return; } } } } else if (ed.curGrip == GRIP_BEZIER1 || ed.curGrip == GRIP_BEZIER2) slurTie()->computeBezier(this); else if (ed.curGrip == GRIP_SHOULDER) { ups[ed.curGrip].off = QPointF(); slurTie()->computeBezier(this, ed.delta); } else if (ed.curGrip == GRIP_DRAG) { ups[GRIP_DRAG].off = QPointF(); setUserOff(userOff() + ed.delta); } }
bool ChordRest::readProperties(XmlReader& e) { const QStringRef& tag(e.name()); if (tag == "durationType") { setDurationType(e.readElementText()); if (actualDurationType().type() != TDuration::DurationType::V_MEASURE) { if ((type() == Element::Type::REST) && // for backward compatibility, convert V_WHOLE rests to V_MEASURE // if long enough to fill a measure. // OTOH, freshly created (un-initialized) rests have numerator == 0 (< 4/4) // (see Fraction() constructor in fraction.h; this happens for instance // when pasting selection from clipboard): they should not be converted duration().numerator() != 0 && // rest durations are initialized to full measure duration when // created upon reading the <Rest> tag (see Measure::read() ) // so a V_WHOLE rest in a measure of 4/4 or less => V_MEASURE (actualDurationType()==TDuration::DurationType::V_WHOLE && duration() <= Fraction(4, 4)) ) { // old pre 2.0 scores: convert setDurationType(TDuration::DurationType::V_MEASURE); } else // not from old score: set duration fraction from duration type setDuration(actualDurationType().fraction()); } else { if (score()->mscVersion() < 115) { SigEvent event = score()->sigmap()->timesig(e.tick()); setDuration(event.timesig()); } } } else if (tag == "BeamMode") { QString val(e.readElementText()); Beam::Mode bm = Beam::Mode::AUTO; if (val == "auto") bm = Beam::Mode::AUTO; else if (val == "begin") bm = Beam::Mode::BEGIN; else if (val == "mid") bm = Beam::Mode::MID; else if (val == "end") bm = Beam::Mode::END; else if (val == "no") bm = Beam::Mode::NONE; else if (val == "begin32") bm = Beam::Mode::BEGIN32; else if (val == "begin64") bm = Beam::Mode::BEGIN64; else bm = Beam::Mode(val.toInt()); _beamMode = Beam::Mode(bm); } else if (tag == "Attribute" || tag == "Articulation") { // obsolete: "Attribute" Articulation* atr = new Articulation(score()); atr->read(e); add(atr); } else if (tag == "leadingSpace") { qDebug("ChordRest: leadingSpace obsolete"); // _extraLeadingSpace = Spatium(val.toDouble()); e.skipCurrentElement(); } else if (tag == "trailingSpace") { qDebug("ChordRest: trailingSpace obsolete"); // _extraTrailingSpace = Spatium(val.toDouble()); e.skipCurrentElement(); } else if (tag == "Beam") { int id = e.readInt(); Beam* beam = e.findBeam(id); if (beam) beam->add(this); // also calls this->setBeam(beam) else qDebug("Beam id %d not found", id); } else if (tag == "small") _small = e.readInt(); else if (tag == "duration") setDuration(e.readFraction()); else if (tag == "ticklen") { // obsolete (version < 1.12) int mticks = score()->sigmap()->timesig(e.tick()).timesig().ticks(); int i = e.readInt(); if (i == 0) i = mticks; if ((type() == Element::Type::REST) && (mticks == i)) { setDurationType(TDuration::DurationType::V_MEASURE); setDuration(Fraction::fromTicks(i)); } else { Fraction f = Fraction::fromTicks(i); setDuration(f); setDurationType(TDuration(f)); } } else if (tag == "dots") setDots(e.readInt()); else if (tag == "move") _staffMove = e.readInt(); else if (tag == "Slur") { int id = e.intAttribute("id"); if (id == 0) id = e.intAttribute("number"); // obsolete Spanner* spanner = e.findSpanner(id); if (!spanner) qDebug("ChordRest::read(): Slur id %d not found", id); else { QString atype(e.attribute("type")); if (atype == "start") { spanner->setTick(e.tick()); if (spanner->ticks() > 0) // stop has been read first, ticks is tick2 - (-1) spanner->setTick2(spanner->ticks() - 1); spanner->setTrack(track()); if (spanner->type() == Element::Type::SLUR) spanner->setStartElement(this); if (e.pasteMode()) { for (Element* e : spanner->linkList()) { if (e == spanner) continue; Spanner* ls = static_cast<Spanner*>(e); ls->setTick(spanner->tick()); for (Element* ee : linkList()) { ChordRest* cr = static_cast<ChordRest*>(ee); if (cr->score() == ee->score() && cr->staffIdx() == ls->staffIdx()) { ls->setTrack(cr->track()); if (ls->type() == Element::Type::SLUR) ls->setStartElement(cr); break; } } } } } else if (atype == "stop") { spanner->setTick2(e.tick()); spanner->setTrack2(track()); if (spanner->type() == Element::Type::SLUR) spanner->setEndElement(this); Chord* start = static_cast<Chord*>(spanner->startElement()); if (start) spanner->setTrack(start->track()); if (e.pasteMode()) { for (Element* e : spanner->linkList()) { if (e == spanner) continue; Spanner* ls = static_cast<Spanner*>(e); ls->setTick2(spanner->tick2()); for (Element* ee : linkList()) { ChordRest* cr = static_cast<ChordRest*>(ee); if (cr->score() == ee->score() && cr->staffIdx() == ls->staffIdx()) { ls->setTrack2(cr->track()); if (ls->type() == Element::Type::SLUR) ls->setEndElement(cr); break; } } } } } else qDebug("ChordRest::read(): unknown Slur type <%s>", qPrintable(atype)); } e.readNext(); } else if (tag == "Lyrics" /*|| tag == "FiguredBass"*/) { Element* element = Element::name2Element(tag, score()); element->setTrack(e.track()); element->read(e); add(element); } else if (tag == "pos") { QPointF pt = e.readPoint(); if (score()->mscVersion() > 114) setUserOff(pt * spatium()); } else if (tag == "offset") { if (score()->mscVersion() > 114) // || voice() >= 2) { DurationElement::readProperties(e); else if (type() == Element::Type::REST) { DurationElement::readProperties(e); setUserXoffset(0.0); // honor Y offset but not X for rests in older scores } else e.skipCurrentElement(); // ignore manual layout otherwise } else if (DurationElement::readProperties(e)) return true; else return false; return true; }
void HairpinSegment::layout() { Dynamic* sd = 0; Dynamic* ed = 0; qreal _spatium = spatium(); if (autoplace()) { setUserOff(QPointF()); setUserOff2(QPointF()); } if (isSingleType() || isBeginType()) { sd = lookupDynamic(hairpin()->startElement()); if (sd) { if (autoplace()) { qreal dx = sd->bbox().right() + sd->pos().x() + sd->segment()->pos().x() + sd->measure()->pos().x(); // hardcoded distance between Dynamic and Hairpin: 0.5sp qreal dist = dx - pos().x() + score()->styleP(StyleIdx::autoplaceHairpinDynamicsDistance); rUserXoffset() = dist; rUserXoffset2() = -dist; } else sd->doAutoplace(); } } if (isSingleType() || isEndType()) { ed = lookupDynamic(hairpin()->endElement()); if (ed) { if (autoplace()) { rUserXoffset2() -= ed->bbox().width(); qreal dx = ed->bbox().left() + ed->pos().x() + ed->segment()->pos().x() + ed->measure()->pos().x(); // hardcoded distance between Hairpin and Dynamic: 0.5sp ed->rUserXoffset() = pos2().x() + pos().x() - dx + score()->styleP(StyleIdx::autoplaceHairpinDynamicsDistance); } else ed->doAutoplace(); } } Hairpin::Type type = hairpin()->hairpinType(); if (type == Hairpin::Type::DECRESC_LINE || type == Hairpin::Type::CRESC_LINE) { twoLines = false; TextLineSegment::layout(); drawCircledTip = false; if (parent()) rypos() += score()->styleP(StyleIdx::hairpinY); } else { delete _text; delete _endText; _text = 0; _endText = 0; QTransform t; 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 = drawCircledTip ? 0.6 * _spatium * .5 : 0.0; QLine l1, l2; twoLines = true; switch (type) { case Hairpin::Type::CRESC_HAIRPIN: { switch (spannerSegmentType()) { case SpannerSegmentType::SINGLE: case SpannerSegmentType::BEGIN: l1.setLine(circledTipRadius * 2.0, 0.0, len, h1); l2.setLine(circledTipRadius * 2.0, 0.0, len, -h1); circledTip.setX(circledTipRadius ); circledTip.setY(0.0); break; case SpannerSegmentType::MIDDLE: case SpannerSegmentType::END: drawCircledTip = false; l1.setLine(.0, h2, len, h1); l2.setLine(.0, -h2, len, -h1); break; } } break; case Hairpin::Type::DECRESC_HAIRPIN: { switch(spannerSegmentType()) { case SpannerSegmentType::SINGLE: case SpannerSegmentType::END: l1.setLine(0.0, h1, len - circledTipRadius * 2, 0.0); l2.setLine(0.0, -h1, len - circledTipRadius * 2, 0.0); circledTip.setX(len - circledTipRadius); circledTip.setY(0.0); break; case SpannerSegmentType::BEGIN: case SpannerSegmentType::MIDDLE: drawCircledTip = false; l1.setLine(.0, h1, len, + h2); l2.setLine(.0, -h1, len, - h2); break; } } break; default: break; } // Do Coord rotation l1 = t.map(l1); l2 = t.map(l2); if (drawCircledTip ) circledTip = t.map(circledTip); points[0] = l1.p1(); points[1] = l1.p2(); points[2] = l2.p1(); points[3] = l2.p2(); npoints = 4; QRectF r = QRectF(l1.p1(), l1.p2()).normalized() | QRectF(l2.p1(), l2.p2()).normalized(); qreal w = score()->styleP(StyleIdx::hairpinLineWidth); setbbox(r.adjusted(-w*.5, -w*.5, w, w)); if (parent()) rypos() += score()->styleP(StyleIdx::hairpinY); } if (autoplace() && parent()) { qreal minDistance = spatium() * .7; Shape s1 = shape().translated(pos()); qreal d = system()->bottomDistance(staffIdx(), s1); qreal ymax = pos().y(); if (d > -minDistance) ymax += d + minDistance; qreal sdy; if (sd) { sdy = -sd->bbox().top() * .4; sd->doAutoplace(); if (sd->pos().y() - sdy > ymax) ymax = sd->pos().y() - sdy; } qreal edy; if (ed) { edy = -ed->bbox().top() * .4; ed->doAutoplace(); if (ed->pos().y() - edy > ymax) ymax = ed->pos().y() - edy; } rUserYoffset() = ymax - pos().y(); if (sd) moveDynamic(sd, ymax - sd->ipos().y() + sdy); if (ed) moveDynamic(ed, ymax - ed->ipos().y() + edy); } else adjustReadPos(); }