diff --git a/importexport/musicxml/importmxmlpass2.cpp b/importexport/musicxml/importmxmlpass2.cpp index 299339e3a035f..2b6e2dbfc5bbf 100644 --- a/importexport/musicxml/importmxmlpass2.cpp +++ b/importexport/musicxml/importmxmlpass2.cpp @@ -41,6 +41,7 @@ #include "libmscore/interval.h" #include "libmscore/jump.h" #include "libmscore/keysig.h" +#include "libmscore/line.h" #include "libmscore/lyrics.h" #include "libmscore/marker.h" #include "libmscore/measure.h" @@ -3123,6 +3124,7 @@ void MusicXMLParserDirection::handleRepeats(Measure* measure, const int track, c /** Parse the /score-partwise/part/measure/direction/direction-type/bracket node. + This creates a TextLine for all line-types except "wavy", for which it creates a Trill */ void MusicXMLParserDirection::bracket(const QString& type, const int number, @@ -3130,38 +3132,63 @@ void MusicXMLParserDirection::bracket(const QString& type, const int number, { QStringRef lineEnd = _e.attributes().value("line-end"); QStringRef lineType = _e.attributes().value("line-type"); - const auto& spdesc = _pass2.getSpanner({ ElementType::TEXTLINE, number }); + const bool isWavy = lineType == "wavy"; + const ElementType elementType = isWavy ? ElementType::TRILL : ElementType::TEXTLINE; + const auto& spdesc = _pass2.getSpanner({ elementType, number }); if (type == "start") { - auto b = spdesc._isStopped ? toTextLine(spdesc._sp) : new TextLine(_score); - // if (placement == "") placement = "above"; // TODO ? set default + SLine* sline = spdesc._isStopped ? spdesc._sp : 0; + if ((sline && sline->isTrill()) || (!sline && isWavy)) { + if (!sline) sline = new Trill(_score); + auto trill = toTrill(sline); + trill->setTrillType(Trill::Type::PRALLPRALL_LINE); + + if (!lineEnd.isEmpty() && lineEnd != "none") + _logger->logError(QString("line-end not supported for line-type \"wavy\"")); + } + else if ((sline && sline->isTextLine()) || (!sline && !isWavy)) { + if (!sline) sline = new TextLine(_score); + auto textLine = toTextLine(sline); + // if (placement == "") placement = "above"; // TODO ? set default - b->setBeginHookType(lineEnd != "none" ? HookType::HOOK_90 : HookType::NONE); - if (lineEnd == "up") - b->setBeginHookHeight(-1 * b->beginHookHeight()); + textLine->setBeginHookType(lineEnd != "none" ? HookType::HOOK_90 : HookType::NONE); + if (lineEnd == "up") + textLine->setBeginHookHeight(-1 * textLine->beginHookHeight()); - // hack: combine with a previous words element - if (!_wordsText.isEmpty()) { - // TextLine supports only limited formatting, remove all (compatible with 1.3) - b->setBeginText(MScoreTextToMXML::toPlainText(_wordsText)); - _wordsText = ""; + // hack: combine with a previous words element + if (!_wordsText.isEmpty()) { + // TextLine supports only limited formatting, remove all (compatible with 1.3) + textLine->setBeginText(MScoreTextToMXML::toPlainText(_wordsText)); + _wordsText = ""; + } + + if (lineType == "solid") + textLine->setLineStyle(Qt::SolidLine); + else if (lineType == "dashed") + textLine->setLineStyle(Qt::DashLine); + else if (lineType == "dotted") + textLine->setLineStyle(Qt::DotLine); + else if (lineType != "wavy") + _logger->logError(QString("unsupported line-type: %1").arg(lineType.toString()), &_e); } - if (lineType == "solid") - b->setLineStyle(Qt::SolidLine); - else if (lineType == "dashed") - b->setLineStyle(Qt::DashLine); - else if (lineType == "dotted") - b->setLineStyle(Qt::DotLine); - else - _logger->logError(QString("unsupported line-type: %1").arg(lineType.toString()), &_e); - starts.append(MusicXmlSpannerDesc(b, ElementType::TEXTLINE, number)); + starts.append(MusicXmlSpannerDesc(sline, elementType, number)); } else if (type == "stop") { - auto b = spdesc._isStarted ? toTextLine(spdesc._sp) : new TextLine(_score); - b->setEndHookType(lineEnd != "none" ? HookType::HOOK_90 : HookType::NONE); - if (lineEnd == "up") - b->setEndHookHeight(-1 * b->endHookHeight()); - stops.append(MusicXmlSpannerDesc(b, ElementType::TEXTLINE, number)); + SLine* sline = spdesc._isStarted ? spdesc._sp : 0; + if ((sline && sline->isTrill()) || (!sline && isWavy)) { + if (!sline) sline = new Trill(_score); + if (!lineEnd.isEmpty() && lineEnd != "none") + _logger->logError(QString("line-end not supported for line-type \"wavy\"")); + } + else if ((sline && sline->isTextLine()) || (!sline && !isWavy)) { + if (!sline) sline = new TextLine(_score); + auto textLine = toTextLine(sline); + textLine->setEndHookType(lineEnd != "none" ? HookType::HOOK_90 : HookType::NONE); + if (lineEnd == "up") + textLine->setEndHookHeight(-1 * textLine->endHookHeight()); + } + + stops.append(MusicXmlSpannerDesc(sline, elementType, number)); } _e.skipCurrentElement(); } @@ -3393,7 +3420,8 @@ MusicXmlExtendedSpannerDesc& MusicXMLParserPass2::getSpanner(const MusicXmlSpann return _ottavas[d._nr]; else if (d._tp == ElementType::PEDAL && 0 == d._nr) return _pedal; - else if (d._tp == ElementType::TEXTLINE && 0 <= d._nr && d._nr < MAX_NUMBER_LEVEL) + else if ((d._tp == ElementType::TEXTLINE || d._tp == ElementType::TRILL) + && 0 <= d._nr && d._nr < MAX_NUMBER_LEVEL) return _brackets[d._nr]; _logger->logError(QString("invalid number %1").arg(d._nr + 1), &_e); return _dummyNewMusicXmlSpannerDesc; diff --git a/mtest/musicxml/io/testBracketTypes.pdf b/mtest/musicxml/io/testBracketTypes.pdf new file mode 100644 index 0000000000000..9cd16e1903fa5 Binary files /dev/null and b/mtest/musicxml/io/testBracketTypes.pdf differ diff --git a/mtest/musicxml/io/testBracketTypes.xml b/mtest/musicxml/io/testBracketTypes.xml new file mode 100644 index 0000000000000..085c157208806 --- /dev/null +++ b/mtest/musicxml/io/testBracketTypes.xml @@ -0,0 +1,186 @@ + + + + + Bracket Types + + + Henry Ives + + MuseScore 0.7.0 + 2007-09-10 + + + + + + + + + + 7 + 40 + + + 1697.14 + 1200 + + 85.7143 + 85.7143 + 85.7143 + 85.7143 + + + 85.7143 + 85.7143 + 85.7143 + 85.7143 + + + + + + + title + Bracket Types + + + subtitle + MuseScore Testcase + + + composer + Henry Ives + + + + brace + + + Piano + Pno. + + Piano + + + + 1 + 1 + 78.7402 + 0 + + + + + + + + + 50.00 + 0.00 + + 170.00 + + + + 1 + + 0 + + + + G + 2 + + + + + + + + + + E + 5 + + 4 + 1 + whole + + + + + + + + + + + + + + + + C + 5 + + 4 + 1 + whole + + + + + + + + + + + + + + + + A + 4 + + 4 + 1 + whole + + + + + + + + + + + + + + + + F + 4 + + 4 + 1 + whole + + + + + + + + light-heavy + + + + diff --git a/mtest/musicxml/io/testBracketTypes_ref.mscx b/mtest/musicxml/io/testBracketTypes_ref.mscx new file mode 100644 index 0000000000000..94c2255ebdaf4 --- /dev/null +++ b/mtest/musicxml/io/testBracketTypes_ref.mscx @@ -0,0 +1,262 @@ + + + + + 0 + 480 + + 1 + 1 + 1 + 0 + + Henry Ives + + + + + + + + + Bracket Types + + + + stdNormal + + 3 + + Piano + + Piano + Pno. + Piano + 21 + 108 + 21 + 108 + keyboard.piano + F + + 100 + 95 + + + 100 + 33 + + + 100 + 50 + + + 100 + 67 + + + 100 + 100 + + + 120 + 67 + + + 150 + 100 + + + 150 + 50 + + + 120 + 50 + + + 120 + 100 + + + + + + + + + + 12.5 + + + + Bracket Types + + + + + MuseScore Testcase + + + + right,top + + Henry Ives + + + + + + G + G + + + 4 + 4 + + + + + + + 1 + + + + + whole + + 76 + 18 + + + + + + + + + + -1 + + + + + + 2 + + + + 1 + + + + + whole + + 72 + 14 + + + + + + + + + + -1 + + + + + + 3 + + + + 1 + + + + + whole + + 69 + 17 + + + + + + + + + + -1 + + + + + + prallprall + + + + 1/1 + + + + + whole + + 65 + 13 + + + + end + + + + + -1/1 + + + + + + + + diff --git a/mtest/musicxml/io/tst_mxml_io.cpp b/mtest/musicxml/io/tst_mxml_io.cpp index df5d9c6607175..177bad1fb015b 100644 --- a/mtest/musicxml/io/tst_mxml_io.cpp +++ b/mtest/musicxml/io/tst_mxml_io.cpp @@ -66,6 +66,7 @@ private slots: void barStyles() { mxmlIoTest("testBarStyles"); } void barStyles2() { mxmlIoTest("testBarStyles2"); } void barStyles3() { mxmlIoTest("testBarStyles3"); } + void bracketTypes() { mxmlImportTestRef("testBracketTypes"); } void beamEnd() { mxmlIoTest("testBeamEnd"); } void beams1() { mxmlIoTest("testBeams1"); } void beams2() { mxmlIoTest("testBeams2"); }