Verovio
Source code documentation
slur.h
1 // Name: slur.h
3 // Author: Rodolfo Zitellini
4 // Created: 26/06/2012
5 // Copyright (c) Authors and others. All rights reserved.
7 
8 #ifndef __VRV_SLUR_H__
9 #define __VRV_SLUR_H__
10 
11 #include "controlelement.h"
12 #include "offsetinterface.h"
13 #include "timeinterface.h"
14 
15 namespace vrv {
16 
17 class Chord;
18 class Doc;
19 class Layer;
20 class Note;
21 class Staff;
22 
23 //----------------------------------------------------------------------------
24 // SpannedElements
25 //----------------------------------------------------------------------------
30  std::vector<const LayerElement *> elements;
31  std::set<int> layersN;
32 };
33 
34 //----------------------------------------------------------------------------
35 // NearEndCollision
36 //----------------------------------------------------------------------------
41  double metricAtStart;
42  double metricAtEnd;
43  bool endPointsAdjusted;
44 };
45 
46 // Helper enum classes
47 enum class SlurCurveDirection { None, Above, Below, AboveBelow, BelowAbove };
48 enum class PortatoSlurType { None, StemSide, Centered };
49 
50 //----------------------------------------------------------------------------
51 // Slur
52 //----------------------------------------------------------------------------
53 
54 class Slur : public ControlElement,
56  public TimeSpanningInterface,
57  public AttCurvature,
58  public AttLayerIdent,
59  public AttLineRendBase {
60 public:
66  Slur();
67  Slur(ClassId classId);
68  virtual ~Slur();
69  Object *Clone() const override { return new Slur(*this); }
70  void Reset() override;
71  std::string GetClassName() const override { return "slur"; }
73 
78  OffsetSpanningInterface *GetOffsetSpanningInterface() override { return vrv_cast<OffsetSpanningInterface *>(this); }
79  const OffsetSpanningInterface *GetOffsetSpanningInterface() const override
80  {
81  return vrv_cast<const OffsetSpanningInterface *>(this);
82  }
83  TimePointInterface *GetTimePointInterface() override { return vrv_cast<TimePointInterface *>(this); }
84  const TimePointInterface *GetTimePointInterface() const override
85  {
86  return vrv_cast<const TimePointInterface *>(this);
87  }
88  TimeSpanningInterface *GetTimeSpanningInterface() override { return vrv_cast<TimeSpanningInterface *>(this); }
89  const TimeSpanningInterface *GetTimeSpanningInterface() const override
90  {
91  return vrv_cast<const TimeSpanningInterface *>(this);
92  }
94 
99  SlurCurveDirection GetDrawingCurveDir() const { return m_drawingCurveDir; }
100  void SetDrawingCurveDir(SlurCurveDirection curveDir) { m_drawingCurveDir = curveDir; }
101  bool HasDrawingCurveDir() const { return (m_drawingCurveDir != SlurCurveDirection::None); }
102  curvature_CURVEDIR CalcDrawingCurveDir(char spanningType) const;
104 
109  bool HasMixedCurveDir() const
110  {
111  return (m_drawingCurveDir == SlurCurveDirection::AboveBelow)
112  || (m_drawingCurveDir == SlurCurveDirection::BelowAbove);
113  }
114  bool HasEndpointAboveStart() const
115  {
116  return (m_drawingCurveDir == SlurCurveDirection::Above)
117  || (m_drawingCurveDir == SlurCurveDirection::AboveBelow);
118  }
119  bool HasEndpointBelowStart() const
120  {
121  return (m_drawingCurveDir == SlurCurveDirection::Below)
122  || (m_drawingCurveDir == SlurCurveDirection::BelowAbove);
123  }
124  bool HasEndpointAboveEnd() const
125  {
126  return (m_drawingCurveDir == SlurCurveDirection::Above)
127  || (m_drawingCurveDir == SlurCurveDirection::BelowAbove);
128  }
129  bool HasEndpointBelowEnd() const
130  {
131  return (m_drawingCurveDir == SlurCurveDirection::Below)
132  || (m_drawingCurveDir == SlurCurveDirection::AboveBelow);
133  }
135 
139  bool HasInnerSlur(const Slur *innerSlur) const;
140 
144  void CalcInitialCurve(const Doc *doc, FloatingCurvePositioner *curve, NearEndCollision *nearEndCollision = NULL);
145 
150 
155 
160  Staff *CalculatePrincipalStaff(const Staff *staff, int xMin, int xMax);
161  const Staff *CalculatePrincipalStaff(const Staff *staff, int xMin, int xMax) const;
163 
168  std::pair<const Layer *, const LayerElement *> GetBoundaryLayer() const;
169  const Staff *GetBoundaryCrossStaff() const;
171 
175  void InitBezierControlSides(BezierCurve &bezier, curvature_CURVEDIR curveDir) const;
176 
177  //----------//
178  // Functors //
179  //----------//
180 
185  FunctorCode Accept(Functor &functor) override;
186  FunctorCode Accept(ConstFunctor &functor) const override;
187  FunctorCode AcceptEnd(Functor &functor) override;
188  FunctorCode AcceptEnd(ConstFunctor &functor) const override;
190 
191 private:
196  // Determine layer elements spanned by the slur
197  SpannedElements CollectSpannedElements(const Staff *staff, int xMin, int xMax) const;
198  // Filter and add layer elements spanned by the slur to the positioner
199  void AddSpannedElements(
200  FloatingCurvePositioner *curve, const SpannedElements &elements, Staff *staff, int xMin, int xMax);
201  // Determine whether a layer element should lie above or below the slur
202  bool IsElementBelow(const LayerElement *element, const Staff *startStaff, const Staff *endStaff) const;
203  bool IsElementBelow(const FloatingPositioner *positioner, const Staff *startStaff, const Staff *endStaff) const;
204  // Discard tuplets that don't have to be considered for slur adjustment
205  void DiscardTupletElements(FloatingCurvePositioner *curve, int xMin, int xMax);
207 
212  // Calculate the endpoint coordinates depending on the curve direction and spanning type of the slur
213  std::pair<Point, Point> CalcEndPoints(const Doc *doc, const Staff *staff, NearEndCollision *nearEndCollision,
214  int x1, int x2, curvature_CURVEDIR drawingCurveDir, char spanningType) const;
215  // Consider the melodic direction for the break location?
216  bool ConsiderMelodicDirection() const;
217  // Retrieve the start and end note locations of the slur
218  std::pair<int, int> GetStartEndLocs(
219  const Note *startNote, const Chord *startChord, const Note *endNote, const Chord *endChord) const;
220  // Calculate the pitch difference used to adjust for melodic direction
221  int CalcPitchDifference(const Staff *staff, int startLoc, int endLoc) const;
222  // Check if the slur resembles portato
223  PortatoSlurType IsPortatoSlur(const Doc *doc, const Note *startNote, const Chord *startChord) const;
224  // Check if the slur starts or ends on a beam
225  bool StartsOnBeam() const { return this->HasBoundaryOnBeam(true); }
226  bool EndsOnBeam() const { return this->HasBoundaryOnBeam(false); }
227  bool HasBoundaryOnBeam(bool isStart) const;
228  // Angle adjustment
229  float GetAdjustedSlurAngle(const Doc *doc, Point &p1, Point &p2, curvature_CURVEDIR curveDir) const;
231 
232 public:
233  //
234 private:
240  SlurCurveDirection m_drawingCurveDir;
241 };
242 
243 } // namespace vrv
244 
245 #endif
Simple class for representing bezier cCurve.
Definition: devicecontextbase.h:258
This class represents a collection of notes in the same layer with the same onset time.
Definition: chord.h:44
This abstract class is the base class for all const functors.
Definition: functor.h:126
This class represents elements appearing within a measure.
Definition: controlelement.h:35
This class is a hold the data and corresponds to the model of a MVC design pattern.
Definition: doc.h:41
This class represents a basic object for a curve (slur, tie) in the layout domain.
Definition: floatingobject.h:329
This class represents a basic object in the layout domain.
Definition: floatingobject.h:165
This abstract class is the base class for all mutable functors.
Definition: functor.h:101
This class is a base class for the Layer (<layer>) content.
Definition: layerelement.h:51
This class models the MEI <note> element.
Definition: note.h:69
This class represents a basic object.
Definition: object.h:64
This class is an interface for elements having spanning visual offsets, such as slur,...
Definition: offsetinterface.h:72
Definition: slur.h:59
void Reset() override
Virtual reset method.
void AddPositionerToArticulations(FloatingCurvePositioner *curve)
Add curve positioner to articulations.
void InitBezierControlSides(BezierCurve &bezier, curvature_CURVEDIR curveDir) const
Set the bezier control sides depending on the curve direction.
FunctorCode Accept(Functor &functor) override
Interface for class functor visitation.
void CalcInitialCurve(const Doc *doc, FloatingCurvePositioner *curve, NearEndCollision *nearEndCollision=NULL)
Calculate the initial slur bezier curve and store it in the curve positioner.
Object * Clone() const override
Method call for copying child classes.
Definition: slur.h:69
void CalcSpannedElements(FloatingCurvePositioner *curve)
Recalculate the spanned elements of the curve positioner.
std::pair< const Layer *, const LayerElement * > GetBoundaryLayer() const
Determine the slur's layer/cross staff by only considering the boundary.
Staff * CalculatePrincipalStaff(const Staff *staff, int xMin, int xMax)
Calculate the staff where the slur's floating curve positioner lives.
This class represents a staff in a laid-out score (Doc).
Definition: staff.h:107
This class is an interface for spanning elements, such as slur, hairpin, etc.
Definition: timeinterface.h:145
Measure collisions near the end points.
Definition: slur.h:40
Contains the layer elements used for collision detection.
Definition: slur.h:29