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 :
23 : #ifndef MU_ENGRAVING_SKYLINE_H
24 : #define MU_ENGRAVING_SKYLINE_H
25 :
26 : #include <cfloat>
27 : #include <vector>
28 : #include <map>
29 :
30 : #include "draw/types/geometry.h"
31 : #include "shape.h"
32 :
33 : namespace muse::draw {
34 : class Painter;
35 : }
36 :
37 : namespace mu::engraving {
38 : class Segment;
39 :
40 : //---------------------------------------------------------
41 : // SkylineLine
42 : //---------------------------------------------------------
43 :
44 : class SkylineLine
45 : {
46 : public:
47 20794 : SkylineLine(bool n)
48 20794 : : m_isNorth(n) {}
49 :
50 : void add(const ShapeElement& r);
51 360 : void add(const RectF& r, EngravingItem* item) { add(ShapeElement(r, item)); }
52 : void add(const Shape& s);
53 :
54 : template<typename Predicate>
55 0 : inline bool remove_if(Predicate p) { return m_shape.remove_if(p); }
56 : SkylineLine getFilteredCopy(std::function<bool(const ShapeElement&)> filterOut) const;
57 :
58 : void clear();
59 : // TODO: avoid passing down minHorizontalClearance (in future it must be done
60 : // item-by-item similar to what we do for horizontal spacing)
61 : double minDistance(const SkylineLine&, double minHorizontalClearance = 0.0) const;
62 : double minDistanceToShapeAbove(const Shape&, double minHorizontalClearance = 0.0) const;
63 : double minDistanceToShapeBelow(const Shape&, double minHorizontalClearance = 0.0) const;
64 : double verticalClearanceAbove(const Shape& shapeAbove) const;
65 : double verticalClearanceBelow(const Shape& shapeBelow) const;
66 : double max() const;
67 : bool valid() const;
68 :
69 : SkylineLine& translateY(double y);
70 :
71 : double top(double startX = -DBL_MAX, double endX = DBL_MAX);
72 : double bottom(double startX = -DBL_MAX, double endX = DBL_MAX);
73 :
74 2255 : bool isNorth() const { return m_isNorth; }
75 :
76 17755 : const std::vector<ShapeElement>& elements() const { return m_shape.elements(); }
77 4647 : std::vector<ShapeElement>& elements() { return m_shape.elements(); }
78 :
79 : private:
80 : double staffLinesTopAtX(double x) const;
81 : double staffLinesBottomAtX(double x) const;
82 :
83 : private:
84 : const bool m_isNorth;
85 : Shape m_shape;
86 :
87 : struct StaffLineEdge {
88 : double top = 0.0;
89 : double bottom = 0.0;
90 22384 : StaffLineEdge(double t, double b)
91 22384 : : top(t), bottom(b) {}
92 : };
93 :
94 : std::map<double, StaffLineEdge> m_staffLineEdges;
95 895932 : bool hasValidStaffLineEdges() const { return !m_staffLineEdges.empty(); }
96 : };
97 :
98 : //---------------------------------------------------------
99 : // Skyline
100 : //---------------------------------------------------------
101 :
102 : class Skyline
103 : {
104 : SkylineLine _north;
105 : SkylineLine _south;
106 :
107 : public:
108 9951 : Skyline()
109 9951 : : _north(true), _south(false) {}
110 :
111 : void clear();
112 : void add(const Shape& s);
113 : void add(const ShapeElement& r);
114 51057 : void add(const RectF& r, EngravingItem* item) { add(ShapeElement(r, item)); }
115 :
116 : // TODO: avoid passing down minHorizontalClearance (in future it must be done
117 : // item-by-item similar to what we do for horizontal spacing)
118 : double minDistance(const Skyline&, double minHorizontalClearance = 0.0) const;
119 :
120 35330 : SkylineLine& north() { return _north; }
121 45655 : SkylineLine& south() { return _south; }
122 11144 : const SkylineLine& north() const { return _north; }
123 10954 : const SkylineLine& south() const { return _south; }
124 :
125 : void paint(muse::draw::Painter& painter, double lineWidth) const; // DEBUG only
126 : };
127 :
128 : void dump(const SkylineLine& slylineline, std::stringstream& ss);
129 : std::string dump(const Skyline& skyline);
130 : } // namespace mu::engraving
131 :
132 : #endif
|