LCOV - code coverage report
Current view: top level - src/engraving/rendering/score - systemlayout.h Coverage Total Hit
Test: filtered_coverage.info Lines: 100.0 % 2 2
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2023 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : #pragma once
      23              : 
      24              : #include <vector>
      25              : 
      26              : #include "layoutcontext.h"
      27              : 
      28              : #include "../../dom/measure.h"
      29              : #include "../../dom/segment.h"
      30              : #include "../../dom/sharedpart.h"
      31              : #include "../../types/types.h"
      32              : 
      33              : namespace mu::engraving {
      34              : class BarLine;
      35              : class Bracket;
      36              : class BracketItem;
      37              : class Chord;
      38              : class Dynamic;
      39              : class Expression;
      40              : class FiguredBass;
      41              : class FretDiagram;
      42              : class Harmony;
      43              : class HarpPedalDiagram;
      44              : class Image;
      45              : class InstrumentChange;
      46              : class Measure;
      47              : class MeasureNumber;
      48              : class MMRest;
      49              : class MMRestRange;
      50              : class Parenthesis;
      51              : class RehearsalMark;
      52              : class Score;
      53              : class Segment;
      54              : class SkylineLine;
      55              : class Spanner;
      56              : class StaffText;
      57              : class Sticking;
      58              : class System;
      59              : class SystemText;
      60              : class TempoText;
      61              : class TimeSig;
      62              : }
      63              : 
      64              : namespace mu::engraving::rendering::score {
      65              : class SystemLayout
      66              : {
      67              : public:
      68              :     static System* collectSystem(LayoutContext& ctx);
      69              :     static void layoutSystemElements(System* system, LayoutContext& ctx);
      70              : 
      71              :     static void layoutSystem(System* system, LayoutContext& ctx, double xo1);
      72              : 
      73              :     static void hideEmptyStaves(System* system, LayoutContext& ctx, bool isFirstSystem);
      74              :     static bool canChangeSysStaffVisibility(const System* system, const staff_idx_t staffIdx);
      75              : 
      76              :     static void layout2(System* system, LayoutContext& ctx);
      77              :     static void restoreLayout2(System* system, LayoutContext& ctx);
      78              :     static void setMeasureHeight(System* system, double height, const LayoutContext& ctx);
      79              : 
      80              :     static double minDistance(const System* top, const System* bottom, const LayoutContext& ctx);
      81              : 
      82              :     static void centerElementsBetweenStaves(const System* system);
      83              :     /* Centers the systems which were laid out during this layout but whose page was not
      84              :      * collected (e.g. the first system of the next page, re-laid out by a partial layout),
      85              :      * so centerElementsBetweenStaves has not been called for them yet. Call it after the
      86              :      * system/page collection loop, before any leftover systems are deleted. */
      87              :     static void centerPendingSystems(LayoutContext& ctx);
      88              :     static void centerBigTimeSigsAcrossStaves(const System* system);
      89              : 
      90              :     static void updateSkylineForElement(EngravingItem* element, const System* system, double yMove);
      91              :     static void removeElementFromSkyline(EngravingItem* element, const System* system);
      92              : 
      93              :     static void layoutSystemLockIndicators(System* system, LayoutContext& ctx);
      94              :     static void layoutPageLockIndicators(System* system);
      95              : 
      96              : private:
      97              :     struct MeasureState
      98              :     {
      99              :         Measure* measure = nullptr;
     100              :         double measureWidth = 0.0;
     101              :         double measurePos = 0.0;
     102              :         std::map<EngravingItem*, PointF> elementPositions;
     103              :         std::map<EngravingItem*, double> elementWidths;
     104              :         std::map<SharedPart*, SharedTrackMap> sharedTrackMaps;
     105              :         bool curHeader = false;
     106              :         bool curTrailer = false;
     107              : 
     108              :         void clear();
     109              : 
     110              :         void restoreMeasure(LayoutContext& ctx);
     111              :     };
     112              : 
     113              :     struct ElementsToLayout
     114              :     {
     115              :         System* system;
     116              :         std::vector<Measure*> measures;
     117              :         std::vector<Segment*> segments;
     118              : 
     119              :         std::vector<ChordRest*> chordRests;
     120              :         std::vector<Chord*> chords;
     121              :         std::vector<BarLine*> barlines;
     122              :         std::vector<TimeSig*> timeSigAboveStaves;
     123              : 
     124              :         std::vector<MeasureNumber*> measureNumbers;
     125              :         std::vector<MMRestRange*> mmrRanges;
     126              :         std::vector<EngravingItem*> markersAndJumps;
     127              : 
     128              :         std::vector<Sticking*> stickings;
     129              :         std::vector<EngravingItem*> fermatasAndTremoloBars;
     130              :         std::vector<FiguredBass*> figuredBass;
     131              :         std::vector<Dynamic*> dynamics;
     132              :         std::vector<Expression*> expressions;
     133              :         std::vector<HarpPedalDiagram*> harpDiagrams;
     134              :         std::vector<FretDiagram*> fretDiagrams;
     135              :         std::vector<StaffTextBase*> staffText;
     136              :         std::vector<InstrumentChange*> instrChanges;
     137              :         std::vector<SystemText*> systemText;
     138              :         std::vector<EngravingItem*> playTechCapoStringTunTripletFeel;
     139              :         std::vector<RehearsalMark*> rehMarks;
     140              :         std::vector<TempoText*> tempoText;
     141              :         std::vector<Image*> images;
     142              :         std::vector<Parenthesis*> parenthesis;
     143              :         std::vector<Harmony*> harmonies;
     144              :         std::vector<PlayCountText*> playCountText;
     145              : 
     146              :         std::vector<Spanner*> slurs;
     147              :         std::vector<Spanner*> trills;
     148              :         std::vector<Spanner*> hairpins;
     149              :         std::vector<Spanner*> ottavas;
     150              :         std::vector<Spanner*> pedal;
     151              :         std::vector<Spanner*> voltas;
     152              :         std::vector<Spanner*> tempoChangeLines;
     153              :         std::vector<Spanner*> partialLyricsLines;
     154              :         std::vector<Spanner*> allOtherSpanners;
     155              : 
     156              :         std::vector<GuitarBend*> guitarBends;
     157              : 
     158         7396 :         ElementsToLayout(System* s)
     159         7396 :             : system(s) {}
     160              :     };
     161              : 
     162              :     static void collectElementsToLayout(Measure* measure, ElementsToLayout& elements, const LayoutContext& ctx);
     163              :     static void collectSpannersToLayout(ElementsToLayout& elements, const LayoutContext& ctx);
     164              : 
     165              :     static System* getNextSystem(LayoutContext& lc);
     166              :     static void createSkylines(const ElementsToLayout& elementsToLayout, LayoutContext& ctx);
     167              :     static void processLines(System* system, LayoutContext& ctx, const std::vector<Spanner*>& lines, bool align = false);
     168              :     static void layoutTies(Chord* ch, System* system, const Fraction& stick, LayoutContext& ctx);
     169              :     static void doLayoutTies(System* system, const std::vector<Segment*>& sl, const Fraction& stick, const Fraction& etick,
     170              :                              LayoutContext& ctx);
     171              :     static void doLayoutNoteSpannersLinear(System* system, LayoutContext& ctx);
     172              :     static void layoutNoteAnchoredSpanners(System* system, Chord* chord);
     173              :     static void updateCrossBeams(System* system, LayoutContext& ctx);
     174              :     static bool measureHasCrossStuffOrModifiedBeams(const Measure* measure);
     175              :     static void restoreOldSystemLayout(System* system, LayoutContext& ctx);
     176              :     static void layoutTuplets(const std::vector<ChordRest*>& chordRests, LayoutContext& ctx);
     177              : 
     178              :     static void layoutTiesAndBends(const ElementsToLayout& elementsToLayout, LayoutContext& ctx);
     179              : 
     180              :     static double minVertSpaceForCrossStaffBeams(System* system, staff_idx_t staffIdx1, staff_idx_t staffIdx2, LayoutContext& ctx);
     181              : 
     182              :     struct CenterableItem {
     183              :         EngravingItem* item = nullptr;
     184              :         Shape shape; // x relative to the system, y relative to the upper staff of the item's gap
     185              :         bool isLyrics = false;
     186              :         bool onUpperGapStaff = false; // whether the item hangs below the upper staff of its gap or sits above the lower one
     187              :     };
     188              : 
     189              :     // The space between two vertically adjacent visible staves
     190              :     struct Gap {
     191              :         staff_idx_t upperStaffIdx = muse::nidx;
     192              :         staff_idx_t lowerStaffIdx = muse::nidx;
     193              :         double yStaffDiff = 0.0; // Inside a gap, everything is expressed relative to its upper staff, so we need the y diff between staves
     194              :         std::vector<CenterableItem> items;
     195              :     };
     196              : 
     197              :     static bool snapChainShouldBeCenteredBetweenStaves(EngravingItem* item, const System* system);
     198              :     static bool elementShouldBeCenteredBetweenStaves(const EngravingItem* item, const System* system, bool placeAbove);
     199              :     static bool mmRestShouldBeCenteredBetweenStaves(const MMRest* mmRest, const System* system);
     200              :     static bool whammyBarShouldBeCenteredBetweenStaves(const WhammyBarSegment* wbar, const System* system);
     201              :     static bool elementHasAnotherStackedOutside(const EngravingItem* element, const Shape& elementShape, const SkylineLine& skylineLine);
     202              :     static bool shapesStackVertically(const Shape& shape1, const Shape& shape2, double minHorizontalClearance);
     203              :     static void collectCenterableItems(const System* system, std::vector<Gap>& gaps, std::vector<MMRest*>& mmRestsToCenter);
     204              :     static std::vector<std::vector<const CenterableItem*> > groupItemsToCenterTogether(const std::vector<const CenterableItem*>& items,
     205              :                                                                                        double minHorizontalClearance);
     206              :     static void centerItemsInGap(const Gap& gap, const System* system, double minHorizontalClearance);
     207              :     static double gapConvergeDistance(const std::vector<const CenterableItem*>& group, double yStaffDiff, double minHorizontalClearance);
     208              :     static double convergenceMoveFor(const CenterableItem* centerableItem, double convergeDistance);
     209              :     static void centerItemGroup(const std::vector<const CenterableItem*>& group, const System* system, const SkylineLine& upperSkyline,
     210              :                                 const SkylineLine& lowerSkyline, double yStaffDiff, double minHorizontalClearance);
     211              :     static void centerMMRestBetweenStaves(MMRest* mmRest, const System* system);
     212              : 
     213              :     static bool shouldBeJustified(System* system, double curSysWidth, double targetSystemWidth, LayoutContext& ctx);
     214              : 
     215              :     static void updateTimeSigAboveStavesXPos(System* system, LayoutContext& ctx);
     216              :     static void clearBigTimeSigNotShown(System* system, LayoutContext& ctx);
     217              : 
     218              :     static void layoutSticking(const std::vector<Sticking*> stickings, System* system, LayoutContext& ctx);
     219              : 
     220              :     static void layoutLyrics(const ElementsToLayout& elements, LayoutContext& ctx);
     221              : 
     222              :     static void layoutVoltas(const ElementsToLayout& elementsToLayout, LayoutContext& ctx);
     223              : 
     224              :     static void layoutDynamicExpressionAndHairpins(const ElementsToLayout& elementsToLayout, LayoutContext& ctx);
     225              : 
     226              :     static void layoutParenthesisAndBigTimeSigs(const ElementsToLayout& elementsToLayout);
     227              : 
     228              :     static void layoutHarmonies(const std::vector<Harmony*> harmonies, System* system, LayoutContext& ctx);
     229              :     static void layoutFretDiagrams(const ElementsToLayout& elements, System* system, LayoutContext& ctx);
     230              : 
     231              :     static void alignRests(const ElementsToLayout& elementsToLayout, LayoutContext& ctx);
     232              :     static void checkFullMeasureRestCollisions(const ElementsToLayout& elementsToLayout, LayoutContext& ctx);
     233              : };
     234              : }
        

Generated by: LCOV version 2.0-1