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; }