Example #1
0
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;
}