data_STEMDIRECTION Layer::GetDrawingStemDir(const ArrayOfBeamElementCoords *coords) { assert(!coords->empty()); // Adjust the x position of the first and last element for taking into account the stem width LayerElement *first = dynamic_cast<LayerElement *>(coords->front()->m_element); LayerElement *last = dynamic_cast<LayerElement *>(coords->back()->m_element); if (!first || !last) { return m_drawingStemDir; } Measure *measure = dynamic_cast<Measure *>(this->GetFirstParent(MEASURE)); assert(measure); // First check if there is any <space> in the measure - if not we can return the layer stem direction if (!measure->FindChildByType(SPACE)) { return m_drawingStemDir; } Alignment *alignmentFirst = first->GetAlignment(); assert(alignmentFirst); Alignment *alignmentLast = last->GetAlignment(); assert(alignmentLast); // We are ignoring cross-staff situation here because this should not be called if we have one Staff *staff = dynamic_cast<Staff *>(first->GetFirstParent(STAFF)); assert(staff); double time = alignmentFirst->GetTime(); double duration = alignmentLast->GetTime() - time + last->GetAlignmentDuration(); duration = durRound(duration); return GetDrawingStemDir(time, duration, measure, staff->GetN()); }
data_STEMDIRECTION Layer::GetDrawingStemDir(LayerElement *element) { assert(element); Measure *measure = dynamic_cast<Measure *>(this->GetFirstParent(MEASURE)); assert(measure); // First check if there is any <space> in the measure - if not we can return the layer stem direction if (!measure->FindChildByType(SPACE)) { return m_drawingStemDir; } Alignment *alignment = element->GetAlignment(); assert(alignment); Layer *layer = NULL; Staff *staff = element->GetCrossStaff(layer); if (!staff) { staff = dynamic_cast<Staff *>(element->GetFirstParent(STAFF)); } // At this stage we have the parent or the cross-staff assert(staff); return GetDrawingStemDir(alignment->GetTime(), element->GetAlignmentDuration(), measure, staff->GetN()); }
Alignment* MeasureAligner::GetAlignmentAtTime( double time, AlignmentType type ) { int i; int idx = -1; // the index if we reach the end. Alignment *alignment = NULL; // First try to see if we already have something at the time position for (i = 0; i < GetAlignmentCount(); i++) { alignment = dynamic_cast<Alignment*>(m_children[i]); assert( alignment ); double alignment_time = alignment->GetTime(); if ( vrv::AreEqual( alignment_time, time ) ) { // we found a default alignment, but we are inserting a grace note (another layer) // we need the grace note to be inserted before so we stop here // this does not work when we have grace notes simultanously at different voices because // they will all have their own alignment. We need something more sophisticated that takes // care of the staff/layer number (or using the layer uuid?) if ( (alignment->GetType() == ALIGNMENT_DEFAULT) && (type == ALIGNMENT_GRACENOTE) ) { idx = i; break; } else if ( (alignment->GetType() == type) && (type != ALIGNMENT_GRACENOTE) ) { return alignment; } else if ( alignment->GetType() > type ) { idx = i; break; } } // nothing found, do not go any further but keep the index if (alignment->GetTime() > time) { idx = i; break; } } // nothing found if ( idx == -1 ) { // this is tricky! Because we want m_rightAlignment to always stay at the end, // we always to insert _before_ the last one - m_rightAlignment is added in Reset() idx = GetAlignmentCount() - 1; } Alignment *newAlignement = new Alignment( time, type ); AddAlignment( newAlignement, idx ); return newAlignement; }
Alignment *MeasureAligner::GetAlignmentAtTime(double time, AlignmentType type) { time = round(time * (pow(10, 10)) / pow(10, 10)); int i; int idx = -1; // the index if we reach the end. Alignment *alignment = NULL; // First try to see if we already have something at the time position for (i = 0; i < GetAlignmentCount(); i++) { alignment = dynamic_cast<Alignment *>(m_children.at(i)); assert(alignment); double alignment_time = alignment->GetTime(); if (vrv::AreEqual(alignment_time, time)) { if (alignment->GetType() == type) { return alignment; } else if (alignment->GetType() > type) { idx = i; break; } } // nothing found, do not go any further but keep the index if (alignment->GetTime() > time) { idx = i; break; } } // nothing found if (idx == -1) { if ((type != ALIGNMENT_MEASURE_END) && (this->Is() != GRACE_ALIGNER)) { // This typically occurs when a tstamp event occurs after the last note of a measure int rightBarlineIdx = m_rightBarLineAlignment->GetIdx(); assert(rightBarlineIdx != -1); idx = rightBarlineIdx - 1; this->SetMaxTime(time); } else { idx = GetAlignmentCount(); } } Alignment *newAlignment = new Alignment(time, type); AddAlignment(newAlignment, idx); return newAlignment; }
void MeasureAligner::SetMaxTime(double time) { // we have to have a m_rightBarLineAlignment assert(m_rightBarLineAlignment); // it must be found in the aligner int idx = m_rightBarLineAlignment->GetIdx(); assert(idx != -1); int i; Alignment *alignment = NULL; // Increase the time position for all alignment from the right barline for (i = idx; i < GetAlignmentCount(); i++) { alignment = dynamic_cast<Alignment *>(m_children.at(i)); assert(alignment); // Change it only if higher than before if (time > alignment->GetTime()) alignment->SetTime(time); } }