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 "types/types.h"
25 :
26 : namespace mu::engraving {
27 : class Chord;
28 : class ChordBracket;
29 : class EngravingItem;
30 : class Fraction;
31 : class Lyrics;
32 : class Note;
33 : class Rest;
34 : class Shape;
35 : class StemSlash;
36 : class Segment;
37 : class Measure;
38 : class System;
39 : enum class ElementType : unsigned char;
40 : enum class KerningType : unsigned char;
41 : }
42 :
43 : namespace mu::engraving::rendering::score {
44 : class HorizontalSpacing
45 : {
46 : public:
47 :
48 : static double computeSpacingForFullSystem(System* system, double stretchReduction = 1.0, double squeezeFactor = 1.0,
49 : bool overrideMinMeasureWidth = false);
50 : static double updateSpacingForLastAddedMeasure(System* system, bool startOfContinuousLayoutRegion = false);
51 : static void squeezeSystemToFit(System* system, double& curSysWidth, double targetSysWidth);
52 : static void justifySystem(System* system, double curSysWidth, double targetSystemWidth);
53 :
54 : static double minHorizontalDistance(const Shape& f, const Shape& s, double spatium, double squeezeFactor = 1.0);
55 : //! NOTE Temporary solution
56 : static double shapeSpatium(const Shape& s);
57 :
58 : static double minHorizontalDistance(const Segment* f, const Segment* ns, double squeezeFactor);
59 : static double minLeft(const Segment* seg, const Shape& ls);
60 :
61 : static double computePadding(const EngravingItem* item1, const EngravingItem* item2);
62 : static KerningType computeKerning(const EngravingItem* item1, const EngravingItem* item2);
63 : static double computeVerticalClearance(const EngravingItem* item1, const EngravingItem* item2, double spatium);
64 :
65 : private:
66 : struct HorizontalSpacingContext {
67 : System* system = nullptr;
68 : double spatium = 0.0;
69 : double xCur = 0.0;
70 : double xLeftBarrier = 0.0;
71 : bool systemIsFull = false;
72 : Measure* startMeas = nullptr;
73 : double stretchReduction = 1.0;
74 : double squeezeFactor = 1.0;
75 : double spacingDensity = 1.0;
76 : bool overrideMinMeasureWidth = false;
77 : };
78 :
79 : struct SegmentPosition {
80 : Segment* segment;
81 : double xPosInSystemCoords;
82 : bool ignoreForSpacing;
83 1073355 : SegmentPosition(Segment* s, double x, bool ignoreForSpacing = false)
84 1073355 : : segment(s), xPosInSystemCoords(x), ignoreForSpacing(ignoreForSpacing) {}
85 : };
86 :
87 : struct Spring
88 : {
89 : double springConst = 0.0;
90 : double width = 0.0;
91 : double preTension = 0.0;
92 : Segment* segment = nullptr;
93 64021 : Spring(double sc, double w, double pt, Segment* s)
94 64021 : : springConst(sc), width(w), preTension(pt), segment(s) {}
95 : };
96 :
97 : struct CrossBeamSpacing
98 : {
99 : bool upDown = false;
100 : bool downUp = false;
101 : bool canBeAdjusted = true;
102 : bool hasOpposingBeamlets = false;
103 : bool preventCrossStaffKerning = false;
104 : bool ensureMinStemDistance = false;
105 : };
106 :
107 : static void spaceMeasureGroup(const std::vector<Measure*>& measureGroup, HorizontalSpacingContext& ctx);
108 : static double getFirstSegmentXPos(Segment* segment, HorizontalSpacingContext& ctx);
109 : static std::vector<SegmentPosition> spaceSegments(const std::vector<Segment*>& segList, int startSegIdx, HorizontalSpacingContext& ctx);
110 : static bool ignoreSegmentForSpacing(const Segment* segment);
111 : static bool ignoreAllSegmentsForSpacing(const std::vector<SegmentPosition>& segmentPositions);
112 : static void spaceAgainstPreviousSegments(Segment* segment, std::vector<SegmentPosition>& prevSegPositions,
113 : HorizontalSpacingContext& ctx);
114 : static bool stopCheckingPreviousSegments(const SegmentPosition& prev, const SegmentPosition& curSegPos);
115 : static void checkLyricsAgainstLeftMargin(Segment* segment, double& x, HorizontalSpacingContext& ctx);
116 : static void checkLyricsAgainstRightMargin(std::vector<SegmentPosition>& segPositions, const HorizontalSpacingContext& ctx);
117 : static double spaceLyricsAgainstBarlines(Segment* firstSeg, Segment* secondSeg, const HorizontalSpacingContext& ctx);
118 : static void checkLargeTimeSigAgainstRightMargin(std::vector<SegmentPosition>& segPositions);
119 : static void moveRightAlignedSegments(std::vector<SegmentPosition>& placedSegments, const HorizontalSpacingContext& ctx);
120 : static void checkCollisionsWithCrossStaffStems(const Segment* thisSeg, const Segment* nextSeg, staff_idx_t staffIdx,
121 : double& curMinDist);
122 :
123 : static double chordRestSegmentNaturalWidth(Segment* segment, HorizontalSpacingContext& ctx);
124 : static double computeSegmentDurationStretch(const Segment* curSeg, const Segment* prevSeg);
125 : static double durationStretchForMMRests(const Segment* segment);
126 : static double durationStretchForTicks(double slope, const Fraction& ticks);
127 : static bool needsCueSizeSpacing(const Segment* segment);
128 : static bool needsHeaderSpacingExceptions(const Segment* seg, const Segment* nextSeg);
129 :
130 : static void applyCrossBeamSpacingCorrection(Segment* thisSeg, Segment* nextSeg, double& width);
131 : static CrossBeamSpacing computeCrossBeamSpacing(Segment* thisSeg, Segment* nextSeg);
132 : static double minStemDistOnNonAdjacentCross(const Segment* thisSeg, const Segment* nextSeg);
133 :
134 : static void enforceMinimumMeasureWidths(const std::vector<Measure*> measureGroup);
135 : static double computeMinMeasureWidth(Measure* m);
136 : static void stretchMeasureToTargetWidth(Measure* m, double targetWidth);
137 :
138 : static void stretchSegmentsToWidth(std::vector<Spring>& springs, double width);
139 :
140 : static void setPositionsAndWidths(const std::vector<SegmentPosition>& segmentPositions);
141 :
142 : static bool isSpecialNotePaddingType(ElementType type);
143 : static void computeNotePadding(const Note* note, const EngravingItem* item2, double& padding, double scaling);
144 : static void computeLedgerRestPadding(const Rest* rest2, double& padding);
145 : static bool isSpecialLyricsPaddingType(ElementType type);
146 : static void computeLyricsPadding(const Lyrics* lyrics1, const EngravingItem* item2, double& padding);
147 : static void computeChordBracketPadding(const EngravingItem* item1, const ChordBracket* chordBracket, double& padding);
148 :
149 : static bool isSameVoiceKerningLimited(const EngravingItem* item);
150 : static bool isNeverKernable(const EngravingItem* item);
151 : static bool isAlwaysKernable(const EngravingItem* item);
152 : static bool ignoreItems(const EngravingItem* item1, const EngravingItem* item2);
153 :
154 : static KerningType doComputeKerningType(const EngravingItem* item1, const EngravingItem* item2);
155 : static KerningType computeNoteKerningType(const Note* note, const EngravingItem* item2);
156 : static KerningType computeStemSlashKerningType(const StemSlash* stemSlash, const EngravingItem* item2);
157 : static KerningType computeLyricsKerningType(const Lyrics* lyrics1, const EngravingItem* item2);
158 : static KerningType computeArticulationAndFermataKerning(const EngravingItem* item1, const EngravingItem* item2);
159 :
160 : static void computeHangingLineWidth(const Segment* firstSeg, const Segment* nextSeg, double& width, bool systemHeaderGap,
161 : bool systemEnd);
162 : };
163 : }
|