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()); }
int Object::SetBoundingBoxXShift( ArrayPtrVoid params ) { // param 0: the minimu position (i.e., the width of the previous element) // param 1: the maximum width in the current measure // param 2: the Doc int *min_pos = static_cast<int*>(params[0]); int *measure_width = static_cast<int*>(params[1]); Doc *doc = static_cast<Doc*>(params[2]); // starting a new measure Measure *current_measure = dynamic_cast<Measure*>(this); if ( current_measure ) { // we reset the measure width and the minimum position (*measure_width) = 0; (*min_pos) = 0; if (current_measure->GetLeftBarlineType() != BARRENDITION_NONE) { current_measure->GetLeftBarline()->SetBoundingBoxXShift( params ); } return FUNCTOR_CONTINUE; } // starting an new layer Layer *current_layer = dynamic_cast<Layer*>(this); if ( current_layer ) { // reset it as the minimum position to the step (HARDCODED) (*min_pos) = 30 * doc->m_drawingUnit[0] / 10; // set scoreDef attr if (current_layer->GetDrawingClef()) { current_layer->GetDrawingClef()->SetBoundingBoxXShift( params ); } if (current_layer->GetDrawingKeySig()) { current_layer->GetDrawingKeySig()->SetBoundingBoxXShift( params ); } if (current_layer->GetDrawingMensur()) { current_layer->GetDrawingMensur()->SetBoundingBoxXShift( params ); } if (current_layer->GetDrawingMeterSig()) { current_layer->GetDrawingMeterSig()->SetBoundingBoxXShift( params ); } return FUNCTOR_CONTINUE; } LayerElement *current = dynamic_cast<LayerElement*>(this); if ( !current ) { return FUNCTOR_CONTINUE; } // we should have processed aligned before assert( current->GetAlignment() ); if ( !current->HasUpdatedBB() ) { // if nothing was drawn, do not take it into account return FUNCTOR_CONTINUE; } if ( current->IsBeam() ) { return FUNCTOR_CONTINUE; } if ( current->IsNote() ) { Chord* chordParent = dynamic_cast<Chord*>(current->GetFirstParent( &typeid( Chord ), MAX_CHORD_DEPTH)); if( chordParent ) { return FUNCTOR_CONTINUE; } } if ( current->IsTie() ) { return FUNCTOR_CONTINUE; } if ( current->IsTuplet() ) { return FUNCTOR_CONTINUE; } if ( current->IsVerse() || current->IsSyl() ) { return FUNCTOR_CONTINUE; } // the negative offset it the part of the bounding box that overflows on the left // |____x_____| // ---- = negative offset //int negative_offset = current->GetAlignment()->GetXRel() - current->m_contentBB_x1; int negative_offset = - (current->m_contentBB_x1) + (doc->GetLeftMargin(&typeid(*current)) * doc->m_drawingUnit[0] / PARAM_DENOMINATOR); // this should never happen (but can with glyphs not exactly registered at position x=0 in the SMuFL font used if ( negative_offset < 0 ) { //LogDebug("%s negative offset %d;", current->GetClassName().c_str(), negative_offset ); negative_offset = 0; } if ( current->IsMRest() ) { // With MRest, the only thing we want to do it keep their with as possible measure with (if only MRest in all staves/layers) int width = current->m_contentBB_x2 + doc->GetRightMargin(&typeid(*current)) * doc->m_drawingUnit[0] / PARAM_DENOMINATOR + negative_offset ; // Keep it if more than the current measure width (*measure_width) = std::max( (*measure_width), width ); (*min_pos) = 0; return FUNCTOR_CONTINUE; } // check if the element overlaps with the preceeding one given by (*min_pos) int overlap = 0; overlap = (*min_pos) - current->GetAlignment()->GetXRel() + negative_offset; if ( (current->GetAlignment()->GetXRel() - negative_offset) < (*min_pos) ) { overlap = (*min_pos) - current->GetAlignment()->GetXRel() + negative_offset; // shift the current element current->GetAlignment()->SetXShift( overlap ); } //LogDebug("%s min_pos %d; negative offset %d; drawXRel %d; overlap %d; m_drawingX %d", current->GetClassName().c_str(), (*min_pos), negative_offset, current->GetAlignment()->GetXRel(), overlap, current->GetDrawingX() ); // the next minimal position if given by the right side of the bounding box + the spacing of the element (*min_pos) = current->GetAlignment()->GetXRel() + current->m_contentBB_x2 + doc->GetRightMargin(&typeid(*current)) * doc->m_drawingUnit[0] / PARAM_DENOMINATOR; current->GetAlignment()->SetMaxWidth( current->m_contentBB_x2 + doc->GetRightMargin(&typeid(*current)) * doc->m_drawingUnit[0] / PARAM_DENOMINATOR ); return FUNCTOR_CONTINUE; }