Skip to content

Commit

Permalink
Implement support for @oct.default. Closes #3513
Browse files Browse the repository at this point in the history
  • Loading branch information
lpugin committed Oct 31, 2023
1 parent 0719e75 commit 2929379
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 6 deletions.
14 changes: 13 additions & 1 deletion include/vrv/pitchinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ class PitchInterface : public Interface, public AttNoteGes, public AttOctave, pu
InterfaceId IsInterface() const override { return INTERFACE_PITCH; }
///@}

/**
* @name Set and get the default octave
*/
///@{
void SetOctDefault(data_OCTAVE oct) { m_octDefault = oct; }
data_OCTAVE GetOctDefault() const { return m_octDefault; }
bool HasOctDefault() const { return (m_octDefault != MEI_UNSET_OCT); }
///@}

/**
* Interface comparison operator.
* Checks if the LayerElement has a PitchInterface and compares attributes
Expand Down Expand Up @@ -90,7 +99,10 @@ class PitchInterface : public Interface, public AttNoteGes, public AttOctave, pu
public:
//
private:
//
/**
* The default octave: extracted from scoreDef/staffDef and used when no octave attribute is given
*/
data_OCTAVE m_octDefault;
};

} // namespace vrv
Expand Down
17 changes: 14 additions & 3 deletions src/calcalignmentpitchposfunctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ namespace vrv {
// CalcAlignmentPitchPosFunctor
//----------------------------------------------------------------------------

CalcAlignmentPitchPosFunctor::CalcAlignmentPitchPosFunctor(Doc *doc) : DocFunctor(doc) {}
CalcAlignmentPitchPosFunctor::CalcAlignmentPitchPosFunctor(Doc *doc) : DocFunctor(doc)
{
m_octDefault = MEI_UNSET_OCT;
}

FunctorCode CalcAlignmentPitchPosFunctor::VisitLayerElement(LayerElement *layerElement)
{
Expand All @@ -38,6 +41,15 @@ FunctorCode CalcAlignmentPitchPosFunctor::VisitLayerElement(LayerElement *layerE
Layer *layerY = vrv_cast<Layer *>(layerElement->GetFirstAncestor(LAYER));
assert(layerY);

PitchInterface *pitchInterface = layerElement->GetPitchInterface();
if (pitchInterface) {
pitchInterface->SetOctDefault(m_octDefault);
// Check if there is a octave default for the staff - ignore cross-staff for this and use staffY
if (m_octDefaultForStaffN.count(staffY->GetN()) > 0) {
pitchInterface->SetOctDefault(m_octDefaultForStaffN.at(staffY->GetN()));
}
}

if (layerElement->m_crossStaff && layerElement->m_crossLayer) {
layerElementY = layerElement->m_crossLayer->GetAtPos(layerElement->GetDrawingX());
staffY = layerElement->m_crossStaff;
Expand Down Expand Up @@ -95,7 +107,7 @@ FunctorCode CalcAlignmentPitchPosFunctor::VisitLayerElement(LayerElement *layerE
loc = staffY->m_drawingTuning->CalcPitchPos(
note->GetTabCourse(), staffY->m_drawingNotationType, staffY->m_drawingLines);
}
else if ((note->HasPname() && note->HasOct()) || note->HasLoc()) {
else if ((note->HasPname() && (note->HasOct() || note->HasOctDefault())) || note->HasLoc()) {
loc = PitchInterface::CalcLoc(note, layerY, layerElementY);
}
int yRel = staffY->CalcPitchPosYRel(m_doc, loc);
Expand Down Expand Up @@ -314,7 +326,6 @@ FunctorCode CalcAlignmentPitchPosFunctor::VisitLayerElement(LayerElement *layerE
return FUNCTOR_CONTINUE;
}


FunctorCode CalcAlignmentPitchPosFunctor::VisitScore(Score *score)
{
ScoreDef *scoreDef = score->GetScoreDef();
Expand Down
7 changes: 5 additions & 2 deletions src/pitchinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ void PitchInterface::Reset()
this->ResetOctave();
this->ResetPitch();
this->ResetPitchGes();

m_octDefault = MEI_UNSET_OCT;
}

bool PitchInterface::HasIdenticalPitchInterface(const PitchInterface *otherPitchInterface) const
Expand Down Expand Up @@ -155,13 +157,14 @@ int PitchInterface::CalcLoc(
if (note->HasLoc()) {
return note->GetLoc();
}
else if (note->HasPname() && note->HasOct()) {
else if (note->HasPname() && (note->HasOct() || note->HasOctDefault())) {
int offset = layer->GetClefLocOffset(crossStaffElement);
const Layer *parentLayer = vrv_cast<const Layer *>(layerElement->GetFirstAncestor(LAYER));
if (parentLayer != layer) {
offset = parentLayer->GetCrossStaffClefLocOffset(layerElement, offset);
}
return PitchInterface::CalcLoc(note->GetPname(), note->GetOct(), offset);
const data_OCTAVE oct = (note->HasOct()) ? note->GetOct() : note->GetOctDefault();
return PitchInterface::CalcLoc(note->GetPname(), oct, offset);
}
else {
return 0;
Expand Down

0 comments on commit 2929379

Please sign in to comment.