void Page::LayOutVertically() { Doc *doc = dynamic_cast<Doc *>(GetParent()); assert(doc); // Doc::SetDrawingPage should have been called before // Make sure we have the correct page assert(this == doc->GetDrawingPage()); // Reset the vertical alignment Functor resetVerticalAlignment(&Object::ResetVerticalAlignment); this->Process(&resetVerticalAlignment, NULL); FunctorDocParams calcLegerLinesParams(doc); Functor calcLedgerLines(&Object::CalcLedgerLines); this->Process(&calcLedgerLines, &calcLegerLinesParams); // Align the content of the page using system aligners // After this: // - each Staff object will then have its StaffAlignment pointer initialized Functor alignVertically(&Object::AlignVertically); Functor alignVerticallyEnd(&Object::AlignVerticallyEnd); AlignVerticallyParams alignVerticallyParams(doc, &alignVerticallyEnd); this->Process(&alignVertically, &alignVerticallyParams, &alignVerticallyEnd); // Adjust the position of outside articulations FunctorDocParams calcArticParams(doc); Functor calcArtic(&Object::CalcArtic); this->Process(&calcArtic, &calcArticParams); // Render it for filling the bounding box View view; BBoxDeviceContext bBoxDC(&view, 0, 0); view.SetDoc(doc); // Do not do the layout in this view - otherwise we will loop... view.SetPage(this->GetIdx(), false); view.DrawCurrentPage(&bBoxDC, false); // Adjust the position of outside articulations with slurs end and start positions FunctorDocParams adjustArticWithSlursParams(doc); Functor adjustArticWithSlurs(&Object::AdjustArticWithSlurs); this->Process(&adjustArticWithSlurs, &adjustArticWithSlursParams); // Fill the arrays of bounding boxes (above and below) for each staff alignment for which the box overflows. SetOverflowBBoxesParams setOverflowBBoxesParams(doc); Functor setOverflowBBoxes(&Object::SetOverflowBBoxes); Functor setOverflowBBoxesEnd(&Object::SetOverflowBBoxesEnd); this->Process(&setOverflowBBoxes, &setOverflowBBoxesParams, &setOverflowBBoxesEnd); // Adjust the positioners of floationg elements (slurs, hairpin, dynam, etc) Functor adjustFloatingPostioners(&Object::AdjustFloatingPostioners); AdjustFloatingPostionersParams adjustFloatingPostionersParams(doc, &adjustFloatingPostioners); this->Process(&adjustFloatingPostioners, &adjustFloatingPostionersParams); // Adjust the overlap of the staff aligmnents by looking at the overflow bounding boxes params.clear(); Functor adjustStaffOverlap(&Object::AdjustStaffOverlap); AdjustStaffOverlapParams adjustStaffOverlapParams(&adjustStaffOverlap); this->Process(&adjustStaffOverlap, &adjustStaffOverlapParams); // Set the Y position of each StaffAlignment // Adjust the Y shift to make sure there is a minimal space (staffMargin) between each staff Functor adjustYPos(&Object::AdjustYPos); AdjustYPosParams adjustYPosParams(doc, &adjustYPos); this->Process(&adjustYPos, &adjustYPosParams); // Adjust system Y position AlignSystemsParams alignSystemsParams; alignSystemsParams.m_shift = doc->m_drawingPageHeight - doc->m_drawingPageTopMar; alignSystemsParams.m_systemMargin = (doc->GetSpacingSystem()) * doc->GetDrawingUnit(100); Functor alignSystems(&Object::AlignSystems); this->Process(&alignSystems, &alignSystemsParams); }
void Page::LayOutTranscription(bool force) { if (m_layoutDone && !force) { return; } Doc *doc = dynamic_cast<Doc *>(GetParent()); assert(doc); // Doc::SetDrawingPage should have been called before // Make sure we have the correct page assert(this == doc->GetDrawingPage()); // Reset the horizontal alignment Functor resetHorizontalAlignment(&Object::ResetHorizontalAlignment); this->Process(&resetHorizontalAlignment, NULL); // Reset the vertical alignment Functor resetVerticalAlignment(&Object::ResetVerticalAlignment); this->Process(&resetVerticalAlignment, NULL); // Align the content of the page using measure aligners // After this: // - each LayerElement object will have its Alignment pointer initialized Functor alignHorizontally(&Object::AlignHorizontally); Functor alignHorizontallyEnd(&Object::AlignHorizontallyEnd); AlignHorizontallyParams alignHorizontallyParams(&alignHorizontally); this->Process(&alignHorizontally, &alignHorizontallyParams, &alignHorizontallyEnd); // Align the content of the page using system aligners // After this: // - each Staff object will then have its StaffAlignment pointer initialized Functor alignVertically(&Object::AlignVertically); Functor alignVerticallyEnd(&Object::AlignVerticallyEnd); AlignVerticallyParams alignVerticallyParams(doc, &alignVerticallyEnd); this->Process(&alignVertically, &alignVerticallyParams, &alignVerticallyEnd); // Set the pitch / pos alignement SetAlignmentPitchPosParams setAlignmentPitchPosParams(doc); Functor setAlignmentPitchPos(&Object::SetAlignmentPitchPos); this->Process(&setAlignmentPitchPos, &setAlignmentPitchPosParams); CalcStemParams calcStemParams(doc); Functor calcStem(&Object::CalcStem); this->Process(&calcStem, &calcStemParams); FunctorDocParams calcChordNoteHeadsParams(doc); Functor calcChordNoteHeads(&Object::CalcChordNoteHeads); this->Process(&calcChordNoteHeads, &calcChordNoteHeadsParams); CalcDotsParams calcDotsParams(doc); Functor calcDots(&Object::CalcDots); this->Process(&calcDots, &calcDotsParams); // Render it for filling the bounding box View view; view.SetDoc(doc); BBoxDeviceContext bBoxDC(&view, 0, 0, BBOX_HORIZONTAL_ONLY); // Do not do the layout in this view - otherwise we will loop... view.SetPage(this->GetIdx(), false); view.DrawCurrentPage(&bBoxDC, false); Functor adjustXRelForTranscription(&Object::AdjustXRelForTranscription); this->Process(&adjustXRelForTranscription, NULL); FunctorDocParams calcLegerLinesParams(doc); Functor calcLedgerLines(&Object::CalcLedgerLines); this->Process(&calcLedgerLines, &calcLegerLinesParams); m_layoutDone = true; }
void Page::LayOutHorizontally() { Doc *doc = dynamic_cast<Doc *>(GetParent()); assert(doc); // Doc::SetDrawingPage should have been called before // Make sure we have the correct page assert(this == doc->GetDrawingPage()); // Reset the horizontal alignment Functor resetHorizontalAlignment(&Object::ResetHorizontalAlignment); this->Process(&resetHorizontalAlignment, NULL); // Reset the vertical alignment Functor resetVerticalAlignment(&Object::ResetVerticalAlignment); this->Process(&resetVerticalAlignment, NULL); // Align the content of the page using measure aligners // After this: // - each LayerElement object will have its Alignment pointer initialized Functor alignHorizontally(&Object::AlignHorizontally); Functor alignHorizontallyEnd(&Object::AlignHorizontallyEnd); AlignHorizontallyParams alignHorizontallyParams(&alignHorizontally); this->Process(&alignHorizontally, &alignHorizontallyParams, &alignHorizontallyEnd); // Align the content of the page using system aligners // After this: // - each Staff object will then have its StaffAlignment pointer initialized Functor alignVertically(&Object::AlignVertically); Functor alignVerticallyEnd(&Object::AlignVerticallyEnd); AlignVerticallyParams alignVerticallyParams(doc, &alignVerticallyEnd); this->Process(&alignVertically, &alignVerticallyParams, &alignVerticallyEnd); // Unless duration-based spacing is disabled, set the X position of each Alignment. // Does non-linear spacing based on the duration space between two Alignment objects. if (!doc->GetEvenSpacing()) { int longestActualDur = DUR_4; // Get the longest duration in the piece AttDurExtreme durExtremeComparison(LONGEST); Object *longestDur = this->FindChildExtremeByAttComparison(&durExtremeComparison); if (longestDur) { DurationInterface *interface = longestDur->GetDurationInterface(); assert(interface); longestActualDur = interface->GetActualDur(); // LogDebug("Longest duration is DUR_* code %d", longestActualDur); } Functor setAlignmentX(&Object::SetAlignmentXPos); SetAlignmentXPosParams setAlignmentXPosParams(doc, &setAlignmentX); setAlignmentXPosParams.m_longestActualDur = longestActualDur; this->Process(&setAlignmentX, &setAlignmentXPosParams); } // Set the pitch / pos alignement SetAlignmentPitchPosParams setAlignmentPitchPosParams(doc); Functor setAlignmentPitchPos(&Object::SetAlignmentPitchPos); this->Process(&setAlignmentPitchPos, &setAlignmentPitchPosParams); CalcStemParams calcStemParams(doc); Functor calcStem(&Object::CalcStem); this->Process(&calcStem, &calcStemParams); FunctorDocParams calcChordNoteHeadsParams(doc); Functor calcChordNoteHeads(&Object::CalcChordNoteHeads); this->Process(&calcChordNoteHeads, &calcChordNoteHeadsParams); CalcDotsParams calcDotsParams(doc); Functor calcDots(&Object::CalcDots); this->Process(&calcDots, &calcDotsParams); // Render it for filling the bounding box View view; view.SetDoc(doc); BBoxDeviceContext bBoxDC(&view, 0, 0, BBOX_HORIZONTAL_ONLY); // Do not do the layout in this view - otherwise we will loop... view.SetPage(this->GetIdx(), false); view.DrawCurrentPage(&bBoxDC, false); // Adjust the x position of the LayerElement where multiple layer collide // Look at each LayerElement and change the m_xShift if the bounding box is overlapping Functor adjustLayers(&Object::AdjustLayers); AdjustLayersParams adjustLayersParams(doc, &adjustLayers, doc->m_scoreDef.GetStaffNs()); this->Process(&adjustLayers, &adjustLayersParams); // Adjust the X position of the accidentals, including in chords Functor adjustAccidX(&Object::AdjustAccidX); AdjustAccidXParams adjustAccidXParams(doc, &adjustAccidX); this->Process(&adjustAccidX, &adjustAccidXParams); // Adjust the X shift of the Alignment looking at the bounding boxes // Look at each LayerElement and change the m_xShift if the bounding box is overlapping Functor adjustXPos(&Object::AdjustXPos); Functor adjustXPosEnd(&Object::AdjustXPosEnd); AdjustXPosParams adjustXPosParams(doc, &adjustXPos, &adjustXPosEnd, doc->m_scoreDef.GetStaffNs()); this->Process(&adjustXPos, &adjustXPosParams, &adjustXPosEnd); // Adjust the X shift of the Alignment looking at the bounding boxes // Look at each LayerElement and change the m_xShift if the bounding box is overlapping Functor adjustGraceXPos(&Object::AdjustGraceXPos); Functor adjustGraceXPosEnd(&Object::AdjustGraceXPosEnd); AdjustGraceXPosParams adjustGraceXPosParams( doc, &adjustGraceXPos, &adjustGraceXPosEnd, doc->m_scoreDef.GetStaffNs()); this->Process(&adjustGraceXPos, &adjustGraceXPosParams, &adjustGraceXPosEnd); // We need to populate processing lists for processing the document by Layer (for matching @tie) and // by Verse (for matching syllable connectors) PrepareProcessingListsParams prepareProcessingListsParams; Functor prepareProcessingLists(&Object::PrepareProcessingLists); this->Process(&prepareProcessingLists, &prepareProcessingListsParams); this->AdjustSylSpacingByVerse(prepareProcessingListsParams, doc); // Adjust measure X position AlignMeasuresParams alignMeasuresParams; Functor alignMeasures(&Object::AlignMeasures); Functor alignMeasuresEnd(&Object::AlignMeasuresEnd); this->Process(&alignMeasures, &alignMeasuresParams, &alignMeasuresEnd); }