Skip to content

Commit

Permalink
Extend MusicXML color support
Browse files Browse the repository at this point in the history
Backport of musescore#19132 (plus another small change for articulations placement above/below)

* add color for textlines
* add color to ornaments
* add color to slurs and ties
* add color to fermata
* add color to hairpins
* add color to accidentals
* add color to articulations
* export accidental brackets
* fix color for glissandos
  • Loading branch information
rettinghaus authored and Jojo-Schmitz committed Aug 30, 2023
1 parent e10795c commit 83954ac
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
29 changes: 25 additions & 4 deletions importexport/musicxml/exportxml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,10 +579,12 @@ void Technical::etag(XmlWriter& xml)

static QString color2xml(const Element* el)
{
QString color;
if (el->color() != MScore::defaultColor)
return QString(" color=\"%1\"").arg(el->color().name().toUpper());
else
return "";
color = QString(" color=\"%1\"").arg(el->color().name().toUpper());
else if (el->isSLine() && ((SLine*)el)->lineColor() != MScore::defaultColor)
color = QString(" color=\"%1\"").arg(((SLine*)el)->lineColor().name().toUpper());
return color;
}

//---------------------------------------------------------
Expand Down Expand Up @@ -2473,8 +2475,11 @@ static void writeAccidental(XmlWriter& xml, const QString& tagName, const Accide
QString tag = tagName;
if (s == "other")
tag += " smufl=\"" + accidentalType2SmuflMxmlString(acc->accidentalType()) + "\"";
if (acc->bracket() != AccidentalBracket::NONE)
if (acc->bracket() == AccidentalBracket::BRACKET)
tag += " bracket=\"yes\"";
else if (acc->bracket() == AccidentalBracket::PARENTHESIS)
tag += " parentheses=\"yes\"";
tag += color2xml(acc);
xml.tag(tag, s);
}
}
Expand Down Expand Up @@ -2952,6 +2957,14 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
else
mxmlArtic += " type=\"down\"";
}
else if (a->anchor() != ArticulationAnchor::CHORD) {
if (a->anchor() == ArticulationAnchor::TOP_CHORD
|| a->anchor() == ArticulationAnchor::TOP_STAFF)
mxmlArtic += " placement=\"above\"";
else
mxmlArtic += " placement=\"below\"";
}
mxmlArtic += color2xml(a);

notations.tag(_xml);
articulations.tag(_xml);
Expand All @@ -2971,6 +2984,8 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
auto mxmlOrnam = symIdToOrnam(sid);

if (mxmlOrnam != "") {
mxmlOrnam += color2xml(a);

notations.tag(_xml);
ornaments.tag(_xml);
_xml.tagE(mxmlOrnam);
Expand Down Expand Up @@ -3007,6 +3022,7 @@ void ExportMusicXml::chordAttributes(Chord* chord, Notations& notations, Technic
if (mxmlTechn != "") {
notations.tag(_xml);
technical.tag(_xml);
mxmlTechn += color2xml(a);
if (sid == SymId::stringsHarmonic) {
if (placement != "")
attr += QString(" placement=\"%1\"").arg(placement);
Expand Down Expand Up @@ -3093,6 +3109,7 @@ static void arpeggiate(Arpeggio* arp, bool front, bool back, XmlWriter& xml, Not
}

if (tagName != "") {
tagName += color2xml(arp);
tagName += positioningAttributes(arp);
xml.tagE(tagName);
}
Expand Down Expand Up @@ -3676,6 +3693,7 @@ void ExportMusicXml::chord(Chord* chord, int staff, const std::vector<Lyrics*>*
if (tieFor) {
notations.tag(_xml);
QString rest = slurTieLineStyle(tieFor);
rest += color2xml(tieFor);
_xml.tagE(QString("tied type=\"start\"%1").arg(rest));
}
if (hasLaissezVibrer(chord)) {
Expand Down Expand Up @@ -4491,6 +4509,7 @@ void ExportMusicXml::hairpin(Hairpin const* const hp, int staff, const Fraction&
else {
tag += "\"diminuendo\"";
}
tag += color2xml(hp);
}
else {
tag += "\"stop\"";
Expand Down Expand Up @@ -4740,6 +4759,7 @@ void ExportMusicXml::textLine(TextLineBase const* const tl, int staff, const Fra
}

rest += positioningAttributes(tl, tl->tick() == tick);
rest += color2xml(tl);

directionTag(_xml, _attr, tl);

Expand Down Expand Up @@ -4793,6 +4813,7 @@ void ExportMusicXml::dynamic(Dynamic const* const dyn, int staff)
_xml.stag("direction-type");

QString tagName = "dynamics";
tagName += color2xml(dyn);
tagName += positioningAttributes(dyn);
_xml.stag(tagName);
const QString dynTypeName = dyn->dynamicTypeName();
Expand Down
21 changes: 20 additions & 1 deletion importexport/musicxml/importmxmlpass2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1101,8 +1101,11 @@ static void addFermataToChord(const Notation& notation, ChordRest* cr)
{
const SymId articSym = notation.symId();
const QString direction = notation.attribute("type");
const QColor fermataColor { notation.attribute("color") };
Fermata* na = new Fermata(articSym, cr->score());
na->setTrack(cr->track());
if (fermataColor.isValid())
na->setColor(fermataColor);
if (!direction.isNull()) // Only for case where XML attribute is present (isEmpty wouldn't work)
na->setPlacement(direction == "inverted" ? Placement::BELOW : Placement::ABOVE);
setElementPropertyFlags(na, Pid::PLACEMENT, direction);
Expand Down Expand Up @@ -1174,8 +1177,11 @@ static void addMordentToChord(const Notation& notation, ChordRest* cr)
articSym = SymId::ornamentDownMordent;
}
if (articSym != SymId::noSym) {
const QColor color { notation.attribute("color") };
Articulation* na = new Articulation(cr->score());
na->setSymId(articSym);
if (color.isValid())
na->setColor(color);
cr->add(na);
}
else
Expand Down Expand Up @@ -4163,6 +4169,12 @@ void MusicXMLParserDirection::wedge(const QString& type, const int number,
? HairpinType::CRESC_HAIRPIN : HairpinType::DECRESC_HAIRPIN);
if (niente == "yes")
h->setHairpinCircledTip(true);

QColor color = QColor::Invalid;
color.setNamedColor(_e.attributes().value("color").toString());
if (color.isValid())
h->setLineColor(color);

starts.append(MusicXmlSpannerDesc(h, ElementType::HAIRPIN, number));
}
else if (type == "stop") {
Expand Down Expand Up @@ -6688,6 +6700,9 @@ static void addSlur(const Notation& notation, SlurStack& slurs, ChordRest* cr, c
newSlur->setLineType(2);
newSlur->setTick(Fraction::fromTicks(tick));
newSlur->setStartElement(cr);
const QColor color { notation.attribute("color") };
if (color.isValid())
newSlur->setColor(color);
const auto pl = notation.attribute("placement");
if (pl == "above")
newSlur->setSlurDirection(Direction::UP);
Expand Down Expand Up @@ -7065,7 +7080,7 @@ static void addGlissandoSlide(const Notation& notation, Note* note,
gliss->setTrack(track);
gliss->setParent(note);
if (glissandoColor.isValid())
gliss->setColor(glissandoColor);
gliss->setLineColor(glissandoColor);
gliss->setText(glissandoText);
gliss->setGlissandoType(glissandoTag == 0 ? GlissandoType::STRAIGHT : GlissandoType::WAVY);
spanners[gliss] = QPair<int, int>(tick.ticks(), -1);
Expand Down Expand Up @@ -7148,6 +7163,10 @@ static void addTie(const Notation& notation, Score* score, Note* note, const int
currTie->setStartNote(note);
currTie->setTrack(track);

const QColor color { notation.attribute("color") };
if (color.isValid())
currTie->setColor(color);

if (orientation == "over")
currTie->setSlurDirection(Direction::UP);
else if (orientation == "under")
Expand Down

0 comments on commit 83954ac

Please sign in to comment.