Skip to content

Commit

Permalink
ENG-20: Add support for "wavy" type brackets
Browse files Browse the repository at this point in the history
Previously, brackets with line-type "wavy" were unsupported. This commit
adds handling for them by creating a Trill line of type PRALLPRALL_LINE,
which best visually matches the examples in the MusicXML spec. This
required some fairly involved changes to the structure of
MusicXMLParserPass2::bracket().

Duplicate of musescore#8480
  • Loading branch information
iveshenry18 authored and Jojo-Schmitz committed Aug 19, 2021
1 parent f271408 commit e21d7c3
Show file tree
Hide file tree
Showing 5 changed files with 503 additions and 26 deletions.
80 changes: 54 additions & 26 deletions importexport/musicxml/importmxmlpass2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -3135,45 +3136,71 @@ 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,
QList<MusicXmlSpannerDesc>& starts, QList<MusicXmlSpannerDesc>& stops)
{
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();
}
Expand Down Expand Up @@ -3405,7 +3432,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;
Expand Down
Binary file added mtest/musicxml/io/testBracketTypes.pdf
Binary file not shown.
186 changes: 186 additions & 0 deletions mtest/musicxml/io/testBracketTypes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="3.1">
<work>
<work-title>Bracket Types</work-title>
</work>
<identification>
<creator type="composer">Henry Ives</creator>
<encoding>
<software>MuseScore 0.7.0</software>
<encoding-date>2007-09-10</encoding-date>
<supports element="accidental" type="yes"/>
<supports element="beam" type="yes"/>
<supports element="print" attribute="new-page" type="no"/>
<supports element="print" attribute="new-system" type="no"/>
<supports element="stem" type="yes"/>
</encoding>
</identification>
<defaults>
<scaling>
<millimeters>7</millimeters>
<tenths>40</tenths>
</scaling>
<page-layout>
<page-height>1697.14</page-height>
<page-width>1200</page-width>
<page-margins type="even">
<left-margin>85.7143</left-margin>
<right-margin>85.7143</right-margin>
<top-margin>85.7143</top-margin>
<bottom-margin>85.7143</bottom-margin>
</page-margins>
<page-margins type="odd">
<left-margin>85.7143</left-margin>
<right-margin>85.7143</right-margin>
<top-margin>85.7143</top-margin>
<bottom-margin>85.7143</bottom-margin>
</page-margins>
</page-layout>
<word-font font-family="Edwin" font-size="10"/>
<lyric-font font-family="Edwin" font-size="10"/>
</defaults>
<credit page="1">
<credit-type>title</credit-type>
<credit-words default-x="600" default-y="1611.43" justify="center" valign="top" font-size="22">Bracket Types</credit-words>
</credit>
<credit page="1">
<credit-type>subtitle</credit-type>
<credit-words default-x="600" default-y="1554.29" justify="center" valign="top" font-size="16">MuseScore Testcase</credit-words>
</credit>
<credit page="1">
<credit-type>composer</credit-type>
<credit-words default-x="1114.29" default-y="1511.43" justify="right" valign="bottom">Henry Ives</credit-words>
</credit>
<part-list>
<part-group type="start" number="1">
<group-symbol>brace</group-symbol>
</part-group>
<score-part id="P1">
<part-name>Piano</part-name>
<part-abbreviation>Pno.</part-abbreviation>
<score-instrument id="P1-I1">
<instrument-name>Piano</instrument-name>
</score-instrument>
<midi-device id="P1-I1" port="1"></midi-device>
<midi-instrument id="P1-I1">
<midi-channel>1</midi-channel>
<midi-program>1</midi-program>
<volume>78.7402</volume>
<pan>0</pan>
</midi-instrument>
</score-part>
</part-list>
<part id="P1">
<measure number="1" width="290.24">
<print>
<system-layout>
<system-margins>
<left-margin>50.00</left-margin>
<right-margin>0.00</right-margin>
</system-margins>
<top-system-distance>170.00</top-system-distance>
</system-layout>
</print>
<attributes>
<divisions>1</divisions>
<key>
<fifths>0</fifths>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<clef>
<sign>G</sign>
<line>2</line>
</clef>
</attributes>
<direction placement="above">
<direction-type>
<bracket type="start" number="1" line-end="none" line-type="solid" default-y="10.00"/>
</direction-type>
</direction>
<note default-x="80.72" default-y="-5.00">
<pitch>
<step>E</step>
<octave>5</octave>
</pitch>
<duration>4</duration>
<voice>1</voice>
<type>whole</type>
</note>
<direction placement="above">
<direction-type>
<bracket type="stop" number="1" line-end="none"/>
</direction-type>
</direction>
</measure>
<measure number="2" width="227.80">
<direction placement="above">
<direction-type>
<bracket type="start" number="1" line-end="none" line-type="dashed" default-y="10.00"/>
</direction-type>
</direction>
<note default-x="13.96" default-y="-15.00">
<pitch>
<step>C</step>
<octave>5</octave>
</pitch>
<duration>4</duration>
<voice>1</voice>
<type>whole</type>
</note>
<direction placement="above">
<direction-type>
<bracket type="stop" number="1" line-end="none"/>
</direction-type>
</direction>
</measure>
<measure number="3" width="228.00">
<direction placement="above">
<direction-type>
<bracket type="start" number="1" line-end="none" line-type="dotted" default-y="10.00"/>
</direction-type>
</direction>
<note default-x="13.00" default-y="-25.00">
<pitch>
<step>A</step>
<octave>4</octave>
</pitch>
<duration>4</duration>
<voice>1</voice>
<type>whole</type>
</note>
<direction placement="above">
<direction-type>
<bracket type="stop" number="1" line-end="none"/>
</direction-type>
</direction>
</measure>
<measure number="4" width="232.53">
<direction placement="above">
<direction-type>
<bracket type="start" number="1" line-end="none" line-type="wavy" default-y="10.00"/>
</direction-type>
</direction>
<note default-x="13.00" default-y="-35.00">
<pitch>
<step>F</step>
<octave>4</octave>
</pitch>
<duration>4</duration>
<voice>1</voice>
<type>whole</type>
</note>
<direction placement="above">
<direction-type>
<bracket type="stop" number="1" line-end="none"/>
</direction-type>
</direction>
<barline location="right">
<bar-style>light-heavy</bar-style>
</barline>
</measure>
</part>
</score-partwise>

0 comments on commit e21d7c3

Please sign in to comment.