From 53cc666faee12d58f39d82574c19e3a4d0ff8e3b Mon Sep 17 00:00:00 2001 From: Leon Vinken Date: Mon, 6 May 2013 22:10:49 +0200 Subject: [PATCH] fix #20912 --- mscore/capella.cpp | 96 +++++++++--- mscore/capella.h | 6 +- mscore/capxml.cpp | 35 ++++- mtest/capella/io/testVolta1.capx | Bin 0 -> 836 bytes mtest/capella/io/testVolta1.capx-ref.mscx | 169 ++++++++++++++++++++++ mtest/capella/io/tst_capella_io.cpp | 1 + 6 files changed, 280 insertions(+), 27 deletions(-) create mode 100644 mtest/capella/io/testVolta1.capx create mode 100644 mtest/capella/io/testVolta1.capx-ref.mscx diff --git a/mscore/capella.cpp b/mscore/capella.cpp index 08ff683747ca..496c6768af96 100644 --- a/mscore/capella.cpp +++ b/mscore/capella.cpp @@ -45,6 +45,7 @@ #include "libmscore/layoutbreak.h" #include "libmscore/dynamic.h" #include "libmscore/barline.h" +#include "libmscore/volta.h" //--------------------------------------------------------- // errmsg @@ -237,6 +238,44 @@ static void processBasicDrawObj(QList objects, Segment* s, int tr } } +//--------------------------------------------------------- +// findChordRests -- find begin and end ChordRest for BasicDrawObj o +// return true on success (both begin and end found) +//--------------------------------------------------------- + +static bool findChordRests(BasicDrawObj const* const o, Score const* const score, const int track, const int tick, + ChordRest*& cr1, ChordRest*& cr2) + { + cr1 = 0; // ChordRest where BasicDrawObj o begins + cr2 = 0; // ChordRest where BasicDrawObj o ends + + // find the ChordRests where o begins and ends + int n = o->nNotes + 1; // # notes in BasicDrawObj (nNotes is # notes following the first note) + for (Segment* seg = score->tick2segment(tick); seg; seg = seg->next1()) { + if (seg->segmentType() != Segment::SegChordRest) + continue; + ChordRest* cr = static_cast(seg->element(track)); + if (cr) { + --n; // found a ChordRest, count down + if (!cr1) cr1 = cr; // found first ChordRest + } + else + qDebug(" %d empty seg", n); + if (n == 0) { + cr2 = cr; // cr should be the second ChordRest + break; + } + } + qDebug("findChordRests o %p nNotes %d score %p track %d tick %d cr1 %p cr2 %p", o, o->nNotes, score, track, tick, cr1, cr2); + + if (!(cr1 && cr2)) { + qDebug("first or second anchor for BasicDrawObj not found (tick %d type %d track %d first %p second %p)", + tick, o->type, track, cr1, cr2); + return false; + } + return true; + } + //--------------------------------------------------------- // readCapVoice //--------------------------------------------------------- @@ -646,34 +685,17 @@ static int readCapVoice(Score* score, CapVoice* cvoice, int staffIdx, int tick, break; case CAP_SLUR: { - SlurObj* so = static_cast(o); + // SlurObj* so = static_cast(o); // qDebug("slur tick %d %d-%d-%d-%d %d-%d", tick, so->nEnd, so->nMid, // so->nDotDist, so->nDotWidth, so->nRefNote, so->nNotes); ChordRest* cr1 = 0; // ChordRest where slur begins ChordRest* cr2 = 0; // ChordRest where slur ends + bool res = findChordRests(o, score, track, tick, cr1, cr2); - // find the ChordRests where the slur begins and ends - int n = so->nNotes + 1; // # notes in slur (nNotes is # notes following the first note) - for (Segment* seg = score->tick2segment(tick); seg; seg = seg->next1()) { - if (seg->segmentType() != Segment::SegChordRest) - continue; - ChordRest* cr = static_cast(seg->element(track)); - if (cr) { - --n; // found a ChordRest, count down - if (!cr1) cr1 = cr; // found first ChordRest - } - else - qDebug(" %d empty seg", n); - if (n == 0) { - cr2 = cr; // cr should be the second ChordRest - break; - } - } - // qDebug("cr1 %p cr2 %p", cr1, cr2); - - if (cr1 && cr2) { + if (res) { if (cr1 == cr2) - qDebug("first and second anchor for slur identical (tick %d track %d first %p second %p)", tick, track, cr1, cr2); + qDebug("first and second anchor for slur identical (tick %d track %d first %p second %p)", + tick, track, cr1, cr2); else { Slur* slur = new Slur(score); qDebug("tick %d track %d cr1 %p cr2 %p -> slur %p", tick, track, cr1, cr2, slur); @@ -683,8 +705,6 @@ static int readCapVoice(Score* score, CapVoice* cvoice, int staffIdx, int tick, slur->setEndElement(cr2); } } - else - qDebug("first or second anchor for slur not found (tick %d track %d first %p second %p)", tick, track, cr1, cr2); } break; case CAP_TEXT: { @@ -707,6 +727,30 @@ static int readCapVoice(Score* score, CapVoice* cvoice, int staffIdx, int tick, measure->add(s); } break; + case CAP_VOLTA: + { + VoltaObj* vo = static_cast(o); + ChordRest* cr1 = 0; // ChordRest where volta begins + ChordRest* cr2 = 0; // ChordRest where volta ends + bool res = findChordRests(o, score, track, tick, cr1, cr2); + + if (res) { + Volta* volta = new Volta(score); + volta->setTrack(track); + // TODO also support endings such as "1 - 3" + volta->setText(QString("%1.").arg(vo->to)); + volta->endings().append(vo->to); + if (vo->bRight) + volta->setVoltaType(VoltaType::CLOSED); + else + volta->setVoltaType(VoltaType::OPEN); + volta->setStartElement(cr1->measure()); + cr1->measure()->add(volta); + volta->setEndElement(cr2->measure()); + cr2->measure()->addSpannerBack(volta); + } + } + break; default: break; } @@ -1200,6 +1244,8 @@ void VoltaObj::read() unsigned char numbers = cap->readByte(); from = numbers & 0x0F; to = (numbers >> 4) & 0x0F; + qDebug("VoltaObj::read x0 %d x1 %d y %d bLeft %d bRight %d bDotted %d allNumbers %d from %d to %d", + x0, x1, y, bLeft, bRight, bDotted, allNumbers, from, to); } //--------------------------------------------------------- @@ -1364,6 +1410,8 @@ void BasicDrawObj::read() nNotes = range & 0x0fff; background = range & 0x1000; pageRange = (range >> 13) & 0x7; + qDebug("BasicDrawObj::read modeX %d modeY %d distY %d flags %d nRefNote %d nNotes %d background %d pageRange %d", + modeX, modeY, distY, flags, nRefNote, nNotes, background, pageRange); } //--------------------------------------------------------- diff --git a/mscore/capella.h b/mscore/capella.h index 24797417fed3..dd20d6f540cd 100644 --- a/mscore/capella.h +++ b/mscore/capella.h @@ -383,8 +383,12 @@ class NotelinesObj : public BasicDrawObj { class VoltaObj : public BasicDrawObj { public: - VoltaObj(Capella* c) : BasicDrawObj(CAP_VOLTA, c) {} + VoltaObj(Capella* c) + : BasicDrawObj(CAP_VOLTA, c), x0(0), x1(0), y(0), + bLeft(false), bRight(false), bDotted(false), + allNumbers(false), from(0), to(0) {} void read(); + void readCapx(XmlReader& e); int x0, x1, y; QColor color; diff --git a/mscore/capxml.cpp b/mscore/capxml.cpp index b9dcfa176a23..b27c110e968c 100644 --- a/mscore/capxml.cpp +++ b/mscore/capxml.cpp @@ -463,6 +463,34 @@ void SlurObj::readCapx(XmlReader& e) e.skipCurrentElement(); } +//--------------------------------------------------------- +// VoltaObj::readCapx -- capx equivalent of VoltaObj::read +//--------------------------------------------------------- + +void VoltaObj::readCapx(XmlReader& e) + { + bLeft = e.attribute("leftBent", "true") == "true"; + bRight = e.attribute("rightBent", "true") == "true"; + bDotted = e.attribute("dotted", "false") == "true"; + allNumbers = e.attribute("allNumbers", "false") == "true"; + int firstNumber = e.intAttribute("firstNumber", 0); + int lastNumber = e.intAttribute("lastNumber", 0); + if (firstNumber == 0) { + // don't know what this means (spec: no number) + // cap status equivalent to no first or last number + from = 1; + to = 0; + } + else { + from = firstNumber; + to = (lastNumber == 0) ? firstNumber : lastNumber; + } + qDebug("VoltaObj::read firstNumber %d lastNumber %d", firstNumber, lastNumber); + qDebug("VoltaObj::read x0 %d x1 %d y %d bLeft %d bRight %d bDotted %d allNumbers %d from %d to %d", + x0, x1, y, bLeft, bRight, bDotted, allNumbers, from, to); + e.readNext(); + } + //--------------------------------------------------------- // readCapxDrawObjectArray -- capx equivalent of readDrawObjectArray() //--------------------------------------------------------- @@ -476,6 +504,7 @@ QList Capella::readCapxDrawObjectArray(XmlReader& e) while (e.readNextStartElement()) { const QStringRef& tag(e.name()); if (tag == "basic") { + // note: the element always follows the DrawObject it applies to if (bdo) bdo->readCapx(e); else @@ -538,8 +567,10 @@ QList Capella::readCapxDrawObjectArray(XmlReader& e) e.skipCurrentElement(); } else if (tag == "volta") { - qDebug("readCapxDrawObjectArray: found volta (skipping)"); - e.skipCurrentElement(); + VoltaObj* o = new VoltaObj(this); + bdo = o; // save o to handle the "basic" tag (which sometimes follows) + o->readCapx(e); + ol.append(o); } else if (tag == "trill") { qDebug("readCapxDrawObjectArray: found trill (skipping)"); diff --git a/mtest/capella/io/testVolta1.capx b/mtest/capella/io/testVolta1.capx new file mode 100644 index 0000000000000000000000000000000000000000..76813ba13fef968a09c72ccb31feb908dcd6f88c GIT binary patch literal 836 zcmWIWW@Zs#U|`^2Xk4|-$ui>pu{lf(44Xt57&sYZ7>bkgi&FI}a&tmMI2o9em^uPM zxU_9}_?Dtzb*_s4Sv201t{WWvr!-5FjO0J+!SuAg6F5e#) zbw+V9+e!O{I!imf~wyG;AO{+1S_u=Lu1X&U$3 z&+kt?ROHL~zQly*!_8M(sk0S)Cavsv;=s7pTtiaDs5l_*Z(8rN^Y?ZoClxWTC+N)O6Y6_dk_|gFU2*BtHAxntv#F=|QR489EAVogC&;k#(~zrtjxS z(evIOJ>znCXY2KI`5bT8sXf2q%vl&+B3j68^SmncvEllo8$AO0lGA;r9^$O-?DNtP zdlk5BXLtFfhsTb}efHXE=z6&(V&3i00QN&731V*3dJN9an$p7@_3^`O?-ct5iq8yQ z{7uT}-fD4hlfY+zpEXySyuGRvcG+5ceooxDZ{=0K1y!v#1%?l2|gbwsyCXk^q0xyb%l0`(%czmmNvE?SsgE& zFPSo{!asd_#r2Y#j5$>sbI(nBlC*xS?t#NK!ms#Oysj;?J#|t0c=6{uTE}Znx9$DC z_53$^g`Ya|QMvP5Hm+T~A&F&2oy`uLb6l?jBZ!5R+*u*X9WAK`c(byB6fy##Kajo;%qt8G0Dr}9LjV8( literal 0 HcmV?d00001 diff --git a/mtest/capella/io/testVolta1.capx-ref.mscx b/mtest/capella/io/testVolta1.capx-ref.mscx new file mode 100644 index 000000000000..37fc5ff98fd8 --- /dev/null +++ b/mtest/capella/io/testVolta1.capx-ref.mscx @@ -0,0 +1,169 @@ + + + + + 0 + 480 + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + 0 + + + + + +

Guitar

+
+ + +

Gtr.

+
+ + + + +
+
+ + + 14 + + + + G8vb + G8vb + + + 4 + 4 + 1 + + + + + Volta 1 + + + + + MuseScore testfile + + + whole + + 55 + 15 + + + + + 2 + + 1 + 0.1 + 1 + + + 1. + + 1 + + + + whole + + 57 + 17 + + + + + + 0 + 0.1 + 1 + + + 2. + + 2 + + + + whole + + 59 + 19 + + + + + + line + 3 + + + + + Leon Vinken + + + whole + + 60 + 14 + + + + end + 1 + + + +
+
diff --git a/mtest/capella/io/tst_capella_io.cpp b/mtest/capella/io/tst_capella_io.cpp index 321f3e8d4e8c..4e01fc4c5010 100644 --- a/mtest/capella/io/tst_capella_io.cpp +++ b/mtest/capella/io/tst_capella_io.cpp @@ -58,6 +58,7 @@ private slots: void capxTestSlurTie() { capxReadTest("testSlurTie"); } void capxTestText1() { capxReadTest("testText1"); } // void capxTestTuplet1() { capxReadTest("testTuplet1"); } // generates different (incorrect ?) l1 and l2 values in beams + void capxTestVolta1() { capxReadTest("testVolta1"); } }; //---------------------------------------------------------