Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions src/include/mx/api/ApiCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,11 @@ enum class MeasureNumbering
system
};

// The <measure-numbering system="..."> attribute: whether this part's measure numbers are also,
// or only, associated with the system (as opposed to just this part). unspecified means the
// attribute is absent.
// Whether an item is associated with the system rather than only with the part it appears in --
// the system attribute of <measure-numbering> (MeasureData) and of <direction> and <harmony>
// (DirectionData). only... means the item is drawn on the top or bottom part of the system instead
// of this part; also... means it is drawn on both. unspecified means the attribute is absent.
// onlyBottom and alsoBottom are measure-numbering only; MusicXML has no bottom-of-system direction.
enum class SystemRelation
{
unspecified,
Expand All @@ -83,6 +85,31 @@ enum class SystemRelation
alsoTop,
alsoBottom
};

// The shape drawn around a piece of text or a symbol -- MusicXML's enclosure attribute, carried by
// RehearsalData, WordsData, SymbolData and PercussionData. unspecified means the attribute is
// absent, which draws no enclosure; none states explicitly that there is none. A bracket is a
// rectangle with the bottom line missing, as is common in jazz notation, and an invertedBracket is
// one with the top line missing.
enum class Enclosure
{
unspecified,
rectangle,
square,
oval,
circle,
bracket,
invertedBracket,
triangle,
diamond,
pentagon,
hexagon,
heptagon,
octagon,
nonagon,
decagon,
none
};
} // namespace api
} // namespace mx

Expand Down
15 changes: 12 additions & 3 deletions src/include/mx/api/DirectionData.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ struct DirectionData
int tickTimePosition;
Placement placement;

// The system attribute of <direction> and <harmony>: content that belongs to the whole system
// rather than to this part alone, such as a tempo mark drawn once above the top staff. onlyTop
// draws it only on the top part of the system, alsoTop on both this part and the top part, and
// none states explicitly that it belongs to this part alone. One value covers the direction
// types and the chords held here; both elements are written with it. SystemRelation::onlyBottom
// and ::alsoBottom exist only for measure numbering; either one here writes no attribute.
SystemRelation systemRelation;

// The source's <offset>, in divisions, or absent when it had none. An <offset> nudges only
// where the direction is *drawn*, shifting it away from the note it is anchored to; it does not
// move that anchor. tickTimePosition holds the anchor -- the musical location the direction
Expand Down Expand Up @@ -73,9 +81,9 @@ struct DirectionData
std::vector<FiguredBassData> figuredBasses;

DirectionData()
: tickTimePosition{0}, placement{Placement::unspecified}, offset{}, voice{VALUE_UNSPECIFIED},
isStaffValueSpecified{true}, isSoundDataSpecified{false}, soundData{}, directionTypes{}, chords{},
figuredBasses{}
: tickTimePosition{0}, placement{Placement::unspecified}, systemRelation{SystemRelation::unspecified}, offset{},
voice{VALUE_UNSPECIFIED}, isStaffValueSpecified{true}, isSoundDataSpecified{false}, soundData{},
directionTypes{}, chords{}, figuredBasses{}
{
}
};
Expand All @@ -89,6 +97,7 @@ inline bool isDirectionDataEmpty(const DirectionData &directionData)
MXAPI_EQUALS_BEGIN(DirectionData)
MXAPI_EQUALS_MEMBER(tickTimePosition)
MXAPI_EQUALS_MEMBER(placement)
MXAPI_EQUALS_MEMBER(systemRelation)
MXAPI_EQUALS_MEMBER(offset)
MXAPI_EQUALS_MEMBER(voice)
MXAPI_EQUALS_MEMBER(isStaffValueSpecified)
Expand Down
29 changes: 6 additions & 23 deletions src/include/mx/api/PercussionData.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,27 +464,6 @@ class PercussionDataChoice

MXAPI_NOT_EQUALS_AND_VECTORS(PercussionDataChoice);

// How a percussion pictogram is enclosed, MusicXML's enclosure attribute on <percussion>.
enum class PercussionEnclosure
{
unspecified,
rectangle,
square,
oval,
circle,
bracket,
invertedBracket,
triangle,
diamond,
pentagon,
hexagon,
heptagon,
octagon,
nonagon,
decagon,
none
};

// A percussion pictogram, MusicXML's <percussion> element: a symbol for an unpitched instrument
// or the implement striking it, used in percussion parts and legends. Several PercussionData in
// one direction read as a group (for example a membrane pictogram followed by a beater).
Expand All @@ -495,13 +474,17 @@ class PercussionData
{
public:
PercussionDataChoice choice;
PercussionEnclosure enclosure;

// A shape drawn around the pictogram. Enclosure::unspecified draws no enclosure;
// Enclosure::none states explicitly that there is none.
Enclosure enclosure;

PositionData positionData;
FontData fontData;
std::optional<ColorData> color;
std::optional<std::string> id;

PercussionData() : choice{}, enclosure{PercussionEnclosure::unspecified}, positionData{}, fontData{}, color{}, id{}
PercussionData() : choice{}, enclosure{Enclosure::unspecified}, positionData{}, fontData{}, color{}, id{}
{
}
};
Expand Down
30 changes: 14 additions & 16 deletions src/include/mx/api/RehearsalData.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,13 @@

#include "mx/api/ApiCommon.h"
#include "mx/api/ColorData.h"
#include "mx/api/FontData.h"
#include "mx/api/PositionData.h"

namespace mx
{
namespace api
{
enum class RehearsalEnclosure
{
unspecified,
rectangle,
square,
oval,
circle,
bracket,
triangle,
diamond,
none
};

class RehearsalData
{
public:
Expand All @@ -33,11 +21,20 @@ class RehearsalData
bool isColorSpecified;
ColorData colorData;
FontData fontData;
RehearsalEnclosure enclosure;

// A shape drawn around the text. Enclosure::unspecified draws no enclosure; Enclosure::none
// states explicitly that there is none.
Enclosure enclosure;

// The `justify` attribute of `<rehearsal>`: how the mark's lines sit relative to each other
// when its text runs to more than one line. `unspecified` means the attribute is absent.
// Distinct from the `halign` attribute, which is carried in `positionData.horizontalAlignment`
// and says which edge of the text the position refers to; MusicXML defines both.
HorizontalAlignment justify;

RehearsalData()
: text{}, positionData{}, isColorSpecified{false}, colorData{}, fontData{},
enclosure{RehearsalEnclosure::unspecified}
: text{}, positionData{}, isColorSpecified{false}, colorData{}, fontData{}, enclosure{Enclosure::unspecified},
justify{HorizontalAlignment::unspecified}
{
}
};
Expand All @@ -49,6 +46,7 @@ MXAPI_EQUALS_MEMBER(isColorSpecified)
MXAPI_EQUALS_MEMBER(colorData)
MXAPI_EQUALS_MEMBER(fontData)
MXAPI_EQUALS_MEMBER(enclosure)
MXAPI_EQUALS_MEMBER(justify)
MXAPI_EQUALS_END;
MXAPI_NOT_EQUALS_AND_VECTORS(RehearsalData);
} // namespace api
Expand Down
18 changes: 13 additions & 5 deletions src/include/mx/api/SymbolData.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include "mx/api/ColorData.h"
#include "mx/api/FontData.h"
#include "mx/api/PositionData.h"
#include "mx/api/RehearsalData.h"

#include <optional>
#include <string>
Expand All @@ -32,11 +31,19 @@ class SymbolData
FontData fontData;
std::optional<ColorData> color;

// A shape drawn around the symbol. RehearsalEnclosure::unspecified draws no enclosure;
// RehearsalEnclosure::none states explicitly that there is none.
RehearsalEnclosure enclosure;
// A shape drawn around the symbol. Enclosure::unspecified draws no enclosure; Enclosure::none
// states explicitly that there is none.
Enclosure enclosure;

SymbolData() : smufl{}, positionData{}, fontData{}, color{}, enclosure{RehearsalEnclosure::unspecified}
// The `justify` attribute of `<symbol>`. `unspecified` means the attribute is absent. Distinct
// from the `halign` attribute, which is carried in `positionData.horizontalAlignment` and says
// which edge of the glyph the position refers to; MusicXML defines both on `<symbol>`, whose
// symbol-formatting attributes mirror the text-formatting ones on `<words>`.
HorizontalAlignment justify;

SymbolData()
: smufl{}, positionData{}, fontData{}, color{}, enclosure{Enclosure::unspecified},
justify{HorizontalAlignment::unspecified}
{
}
};
Expand All @@ -47,6 +54,7 @@ MXAPI_EQUALS_MEMBER(positionData)
MXAPI_EQUALS_MEMBER(fontData)
MXAPI_EQUALS_MEMBER(color)
MXAPI_EQUALS_MEMBER(enclosure)
MXAPI_EQUALS_MEMBER(justify)
MXAPI_EQUALS_END;
MXAPI_NOT_EQUALS_AND_VECTORS(SymbolData);
} // namespace api
Expand Down
18 changes: 12 additions & 6 deletions src/include/mx/api/WordsData.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include "mx/api/ColorData.h"
#include "mx/api/FontData.h"
#include "mx/api/PositionData.h"
#include "mx/api/RehearsalData.h"

namespace mx
{
Expand All @@ -26,13 +25,19 @@ class WordsData
bool isColorSpecified;
ColorData colorData;

// A shape drawn around the text. RehearsalEnclosure::unspecified draws no enclosure;
// RehearsalEnclosure::none states explicitly that there is none.
RehearsalEnclosure enclosure;
// A shape drawn around the text. Enclosure::unspecified draws no enclosure; Enclosure::none
// states explicitly that there is none.
Enclosure enclosure;

// The `justify` attribute of `<words>`: how the text lines up within itself when it spans
// more than one line. `unspecified` means the attribute is absent. Distinct from the `halign`
// attribute, which is carried in `positionData.horizontalAlignment` and aligns the whole text
// block against its anchor point; MusicXML defines both attributes on `<words>`.
HorizontalAlignment justify;

WordsData()
: text{}, positionData{}, fontData{}, isColorSpecified{false}, colorData{},
enclosure{RehearsalEnclosure::unspecified}
: text{}, positionData{}, fontData{}, isColorSpecified{false}, colorData{}, enclosure{Enclosure::unspecified},
justify{HorizontalAlignment::unspecified}
{
}
};
Expand All @@ -44,6 +49,7 @@ MXAPI_EQUALS_MEMBER(fontData)
MXAPI_EQUALS_MEMBER(isColorSpecified)
MXAPI_EQUALS_MEMBER(colorData)
MXAPI_EQUALS_MEMBER(enclosure)
MXAPI_EQUALS_MEMBER(justify)
MXAPI_EQUALS_END;
MXAPI_NOT_EQUALS_AND_VECTORS(WordsData);
} // namespace api
Expand Down
64 changes: 44 additions & 20 deletions src/private/mx/impl/Converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,12 @@ const Converter::EnumMap<core::SystemRelationNumber, api::SystemRelation> Conver
{core::SystemRelationNumber::alsoBottom(), api::SystemRelation::alsoBottom},
};

const Converter::EnumMap<core::SystemRelation, api::SystemRelation> Converter::directionSystemRelationMap = {
{core::SystemRelation::none(), api::SystemRelation::none},
{core::SystemRelation::onlyTop(), api::SystemRelation::onlyTop},
{core::SystemRelation::alsoTop(), api::SystemRelation::alsoTop},
};

const Converter::EnumMap<core::TechnicalChoice::Kind, api::MarkType> Converter::technicalMarkMap = {
// { core::TechnicalChoice::Kind::technical,
// api::MarkType::unspecified },
Expand Down Expand Up @@ -1581,22 +1587,22 @@ const Converter::EnumMap<core::TipDirection, api::TipDirection> Converter::tipDi
{core::TipDirection::southwest(), api::TipDirection::southwest},
};

const Converter::EnumMap<core::EnclosureShape, api::PercussionEnclosure> Converter::percussionEnclosureMap = {
{core::EnclosureShape::rectangle(), api::PercussionEnclosure::rectangle},
{core::EnclosureShape::square(), api::PercussionEnclosure::square},
{core::EnclosureShape::oval(), api::PercussionEnclosure::oval},
{core::EnclosureShape::circle(), api::PercussionEnclosure::circle},
{core::EnclosureShape::bracket(), api::PercussionEnclosure::bracket},
{core::EnclosureShape::invertedBracket(), api::PercussionEnclosure::invertedBracket},
{core::EnclosureShape::triangle(), api::PercussionEnclosure::triangle},
{core::EnclosureShape::diamond(), api::PercussionEnclosure::diamond},
{core::EnclosureShape::pentagon(), api::PercussionEnclosure::pentagon},
{core::EnclosureShape::hexagon(), api::PercussionEnclosure::hexagon},
{core::EnclosureShape::heptagon(), api::PercussionEnclosure::heptagon},
{core::EnclosureShape::octagon(), api::PercussionEnclosure::octagon},
{core::EnclosureShape::nonagon(), api::PercussionEnclosure::nonagon},
{core::EnclosureShape::decagon(), api::PercussionEnclosure::decagon},
{core::EnclosureShape::none(), api::PercussionEnclosure::none},
const Converter::EnumMap<core::EnclosureShape, api::Enclosure> Converter::enclosureMap = {
{core::EnclosureShape::rectangle(), api::Enclosure::rectangle},
{core::EnclosureShape::square(), api::Enclosure::square},
{core::EnclosureShape::oval(), api::Enclosure::oval},
{core::EnclosureShape::circle(), api::Enclosure::circle},
{core::EnclosureShape::bracket(), api::Enclosure::bracket},
{core::EnclosureShape::invertedBracket(), api::Enclosure::invertedBracket},
{core::EnclosureShape::triangle(), api::Enclosure::triangle},
{core::EnclosureShape::diamond(), api::Enclosure::diamond},
{core::EnclosureShape::pentagon(), api::Enclosure::pentagon},
{core::EnclosureShape::hexagon(), api::Enclosure::hexagon},
{core::EnclosureShape::heptagon(), api::Enclosure::heptagon},
{core::EnclosureShape::octagon(), api::Enclosure::octagon},
{core::EnclosureShape::nonagon(), api::Enclosure::nonagon},
{core::EnclosureShape::decagon(), api::Enclosure::decagon},
{core::EnclosureShape::none(), api::Enclosure::none},
};

api::Step Converter::convert(core::Step inStep) const
Expand Down Expand Up @@ -1805,6 +1811,24 @@ api::SystemRelation Converter::convertSystemRelation(core::SystemRelationNumber
return findApiItem(systemRelationMap, api::SystemRelation::unspecified, value);
}

std::optional<core::SystemRelation> Converter::convertDirectionSystemRelation(api::SystemRelation value) const
{
const auto compare = [&value](const std::pair<core::SystemRelation, api::SystemRelation> &v) {
return v.second == value;
};
const auto it = std::find_if(directionSystemRelationMap.cbegin(), directionSystemRelationMap.cend(), compare);
if (it == directionSystemRelationMap.cend())
{
return std::nullopt;
}
return it->first;
}

api::SystemRelation Converter::convertDirectionSystemRelation(core::SystemRelation value) const
{
return findApiItem(directionSystemRelationMap, api::SystemRelation::unspecified, value);
}

core::StemValue Converter::convert(api::Stem value) const
{
return findCoreItem(stemMap, core::StemValue::up(), value);
Expand Down Expand Up @@ -2095,14 +2119,14 @@ core::TipDirection Converter::convert(api::TipDirection value) const
return findCoreItem(tipDirectionMap, core::TipDirection::up(), value);
}

api::PercussionEnclosure Converter::convert(core::EnclosureShape value) const
api::Enclosure Converter::convert(core::EnclosureShape value) const
{
return findApiItem(percussionEnclosureMap, api::PercussionEnclosure::unspecified, value);
return findApiItem(enclosureMap, api::Enclosure::unspecified, value);
}

core::EnclosureShape Converter::convert(api::PercussionEnclosure value) const
core::EnclosureShape Converter::convert(api::Enclosure value) const
{
return findCoreItem(percussionEnclosureMap, core::EnclosureShape::none(), value);
return findCoreItem(enclosureMap, core::EnclosureShape::none(), value);
}

double Converter::convertToAlter(int semitones, double cents)
Expand Down
Loading
Loading