Verovio
Source code documentation
beam.h
1 // Name: beam.h
3 // Author: Rodolfo Zitellini
4 // Created: 26/06/2012
5 // Copyright (c) Authors and others. All rights reserved.
7 
8 #ifndef __VRV_BEAM_H__
9 #define __VRV_BEAM_H__
10 
11 #include "atts_cmn.h"
12 #include "atts_shared.h"
13 #include "drawinginterface.h"
14 #include "layerelement.h"
15 
16 namespace vrv {
17 
18 class BeamElementCoord;
19 class TabDurSym;
20 class StaffAlignment;
21 
22 // the maximum allowed number of partials
23 #define MAX_DURATION_PARTIALS 16
24 
25 enum { PARTIAL_NONE = 0, PARTIAL_THROUGH, PARTIAL_RIGHT, PARTIAL_LEFT };
26 
27 //----------------------------------------------------------------------------
28 // BeamSegment
29 //----------------------------------------------------------------------------
30 
36 class BeamSegment {
37 public:
42  BeamSegment();
43  virtual ~BeamSegment();
44 
45  void Reset();
46 
47  void CalcBeam(const Layer *layer, Staff *staff, const Doc *doc, BeamDrawingInterface *beamInterface,
48  data_BEAMPLACE place = BEAMPLACE_NONE, bool init = true);
49 
53  const ArrayOfBeamElementCoords *GetElementCoordRefs();
54 
59  void InitCoordRefs(const ArrayOfBeamElementCoords *beamElementCoords);
60 
65 
69  int GetAdjacentElementsDuration(int elementX) const;
70 
75  int GetStartingX() const;
76  int GetStartingY() const;
78 
83  bool StemSameas() const { return (m_stemSameasRole != SAMEAS_NONE); }
84  bool StemSameasIsUnset() const { return (m_stemSameasRole == SAMEAS_UNSET); }
85  bool StemSameasIsPrimary() const { return (m_stemSameasRole == SAMEAS_PRIMARY); }
86  bool StemSameasIsSecondary() const { return (m_stemSameasRole == SAMEAS_SECONDARY); }
88 
95  void InitSameasRoles(Beam *sameasBeam, data_BEAMPLACE &drawingPlace);
96  void UpdateSameasRoles(data_BEAMPLACE place);
97  void CalcNoteHeadShiftForStemSameas(Beam *sameasBeam, data_BEAMPLACE place);
99 
103  void RequestStaffSpace(const Doc *doc, const BeamDrawingInterface *beamInterface);
104 
105 private:
106  // Helper to adjust stem length to extend only towards outmost subbeam (if option "--beam-french-style" is set)
107  void AdjustBeamToFrenchStyle(const BeamDrawingInterface *beamInterface);
108 
109  // Helper to adjust beam positioning with regards to ledger lines (top and bottom of the staff)
110  void AdjustBeamToLedgerLines(
111  const Doc *doc, const Staff *staff, const BeamDrawingInterface *beamInterface, bool isHorizontal);
112 
117  void AdjustBeamToTremolos(const Doc *doc, const Staff *staff, const BeamDrawingInterface *beamInterface);
118 
119  void CalcBeamInit(const Staff *staff, const Doc *doc, BeamDrawingInterface *beamInterface, data_BEAMPLACE place);
120 
121  void CalcBeamInitForNotePair(const Note *note1, const Note *note2, const Staff *staff, int &yMax, int &yMin);
122 
123  bool CalcBeamSlope(const Staff *staff, const Doc *doc, BeamDrawingInterface *beamInterface, int &step);
124 
125  int CalcBeamSlopeStep(
126  const Doc *doc, const Staff *staff, BeamDrawingInterface *beamInterface, int noteStep, bool &shortStep);
127 
128  void CalcMixedBeamPosition(const BeamDrawingInterface *beamInterface, int step, int unit);
129 
130  void CalcBeamPosition(const Doc *doc, const Staff *staff, BeamDrawingInterface *beamInterface, bool isHorizontal);
131 
132  void CalcAdjustSlope(const Staff *staff, const Doc *doc, BeamDrawingInterface *beamInterface, int &step);
133 
134  // Helper to adjust position of starting point to make sure that beam start-/endpoints touch the staff lines
135  void CalcAdjustPosition(const Staff *staff, const Doc *doc, const BeamDrawingInterface *beamInterface);
136 
137  void CalcBeamPlace(const Layer *layer, BeamDrawingInterface *beamInterface, data_BEAMPLACE place);
138 
143  void CalcBeamPlaceTab(const Layer *layer, const Staff *staff, const Doc *doc, BeamDrawingInterface *beamInterface,
144  data_BEAMPLACE place);
145 
146  // Helper to calculate the longest stem length of the beam (which will be used uniformely)
147  void CalcBeamStemLength(const Staff *staff, data_BEAMPLACE place, bool isHorizontal);
148 
149  // Helper to set the stem values
150  void CalcSetStemValues(const Staff *staff, const Doc *doc, const BeamDrawingInterface *beamInterface);
151 
152  // Helper to set the stem values for tablature
153  void CalcSetStemValuesTab(const Staff *staff, const Doc *doc, const BeamDrawingInterface *beamInterface);
154 
155  // Helper to calculate the vertical center of mixed beams
156  int CalcMixedBeamCenterY(int step, int unit) const;
157 
158  // Helper to calculate location and duration of the note that would be setting highest/lowest point for the beam
159  std::tuple<int, int, data_DURATION> CalcStemDefiningNote(const Staff *staff, data_BEAMPLACE place) const;
160 
161  // Calculate positioning for the horizontal beams
162  void CalcHorizontalBeam(const Doc *doc, const Staff *staff, const BeamDrawingInterface *beamInterface);
163 
164  // Helper to calculate relative position of the beam to for each of the coordinates
165  void CalcMixedBeamPlace(const Staff *staff);
166 
167  // Helper to calculate proper positioning of the additional beamlines for notes
168  void CalcPartialFlagPlace();
169 
170  // Helper to simply set the values of each BeamElementCoord according the the first position and the slope
171  void CalcSetValues();
172 
173  // Helper to check whether beam fits within certain bounds
174  bool DoesBeamOverlap(
175  const BeamDrawingInterface *beamInterface, int topBorder, int bottomBorder, int minStemLength) const;
176 
177  // Helper to calculate the vertical offset of the beam top/bottom w.r.t. the beam center
178  std::pair<int, int> GetVerticalOffset(const BeamDrawingInterface *beamInterface) const;
179 
180  // Helper to calculate the minimal stem length of above/below notes
181  std::pair<int, int> GetMinimalStemLength(const BeamDrawingInterface *beamInterface) const;
182 
183  // Helper to check mixed beam positioning compared to other elements (ledger lines, staff) and adjust it accordingly
184  bool NeedToResetPosition(Staff *staff, const Doc *doc, BeamDrawingInterface *beamInterface);
185 
186 public:
187  // values set by CalcBeam
188  int m_nbNotesOrChords;
189  double m_beamSlope; // the slope of the beam
190  int m_verticalCenter;
191  int m_ledgerLinesAbove;
192  int m_ledgerLinesBelow;
193  int m_uniformStemLength;
194  data_BEAMPLACE m_weightedPlace;
195 
196  BeamElementCoord *m_firstNoteOrChord;
197  BeamElementCoord *m_lastNoteOrChord;
198 
202  ArrayOfBeamElementCoords m_beamElementCoordRefs;
203 
214  StemSameasDrawingRole m_stemSameasRole;
215  StemSameasDrawingRole *m_stemSameasReverseRole;
217 };
218 
219 //----------------------------------------------------------------------------
220 // BeamSpanSegment
221 //----------------------------------------------------------------------------
222 
223 // Class for storing additional information regarding beamSegment placement (in case of beamSpan spanning over
224 // the systems)
225 class BeamSpanSegment : public BeamSegment {
226 public:
227  BeamSpanSegment();
228  virtual ~BeamSpanSegment() {}
229 
234  Measure *GetMeasure() { return m_measure; }
235  const Measure *GetMeasure() const { return m_measure; }
236  void SetMeasure(Measure *measure) { m_measure = measure; }
237  Staff *GetStaff() { return m_staff; }
238  const Staff *GetStaff() const { return m_staff; }
239  void SetStaff(Staff *staff) { m_staff = staff; }
240  Layer *GetLayer() { return m_layer; }
241  const Layer *GetLayer() const { return m_layer; }
242  void SetLayer(Layer *layer) { m_layer = layer; }
243  BeamElementCoord *GetBeginCoord() { return m_begin; }
244  const BeamElementCoord *GetBeginCoord() const { return m_begin; }
245  void SetBeginCoord(BeamElementCoord *begin) { m_begin = begin; }
246  BeamElementCoord *GetEndCoord() { return m_end; }
247  const BeamElementCoord *GetEndCoord() const { return m_end; }
248  void SetEndCoord(BeamElementCoord *end) { m_end = end; }
250 
256  void SetSpanningType(int systemIndex, int systemCount);
257  int GetSpanningType() const { return m_spanningType; }
259 
260  // Helper to append coordinates for the beamSpans that are drawn over systems
261  void AppendSpanningCoordinates(const Measure *measure);
262 
263 private:
264  // main values to track positioning of the segment
265  Measure *m_measure;
266  Staff *m_staff;
267  Layer *m_layer;
268  BeamElementCoord *m_begin;
269  BeamElementCoord *m_end;
270 
271  // spanning type for purposes of adding additional coordinates to segment
272  int m_spanningType = SPANNING_START_END;
273 };
274 
275 //----------------------------------------------------------------------------
276 // Beam
277 //----------------------------------------------------------------------------
278 
279 class Beam : public LayerElement,
280  public BeamDrawingInterface,
281  public AttBeamedWith,
282  public AttBeamRend,
283  public AttColor,
284  public AttCue {
285 public:
291  Beam();
292  virtual ~Beam();
293  Object *Clone() const override { return new Beam(*this); }
294  void Reset() override;
295  std::string GetClassName() const override { return "beam"; }
297 
301  void CloneReset() override;
302 
307  BeamDrawingInterface *GetBeamDrawingInterface() override { return vrv_cast<BeamDrawingInterface *>(this); }
308  const BeamDrawingInterface *GetBeamDrawingInterface() const override
309  {
310  return vrv_cast<const BeamDrawingInterface *>(this);
311  }
313 
314  int GetNoteCount() const { return this->GetChildCount(NOTE); }
315 
320  bool IsSupportedChild(ClassId classId) override;
321 
325  const ArrayOfBeamElementCoords *GetElementCoords();
326 
332  bool IsTabBeam() const;
333 
338  bool HasStemSameasBeam() const { return (m_stemSameas); }
339  Beam *GetStemSameasBeam() { return m_stemSameas; }
340  const Beam *GetStemSameasBeam() const { return m_stemSameas; }
341  void SetStemSameasBeam(Beam *stemSameas) { m_stemSameas = stemSameas; }
343 
347  std::pair<int, int> GetAdditionalBeamCount() const override;
348 
353  int GetBeamPartDuration(int x, bool includeRests = true) const;
354  int GetBeamPartDuration(const Object *object, bool includeRests = true) const;
356 
357  //----------//
358  // Functors //
359  //----------//
360 
365  FunctorCode Accept(Functor &functor) override;
366  FunctorCode Accept(ConstFunctor &functor) const override;
367  FunctorCode AcceptEnd(Functor &functor) override;
368  FunctorCode AcceptEnd(ConstFunctor &functor) const override;
370 
371 protected:
376  void FilterList(ListOfConstObjects &childList) const override;
377 
378 private:
384  Beam *m_stemSameas;
385 
386 public:
388  BeamSegment m_beamSegment;
389 };
390 
391 //----------------------------------------------------------------------------
392 // BeamElementCoord
393 //----------------------------------------------------------------------------
394 
396 public:
402  {
403  m_element = NULL;
404  m_closestNote = NULL;
405  m_tabDurSym = NULL;
406  m_stem = NULL;
407  m_overlapMargin = 0;
408  m_beamRelativePlace = BEAMPLACE_NONE;
409  m_partialFlagPlace = BEAMPLACE_NONE;
410  }
411  virtual ~BeamElementCoord();
412 
417  data_STEMDIRECTION GetStemDir() const;
418 
419  void SetDrawingStemDir(data_STEMDIRECTION stemDir, const Staff *staff, const Doc *doc, const BeamSegment *segment,
420  const BeamDrawingInterface *interface);
421 
423  void SetClosestNoteOrTabDurSym(data_STEMDIRECTION stemDir, bool outsideStaff);
424 
427  const Staff *staff, data_STEMDIRECTION stemDir, bool isHorizontal, data_DURATION preferredDur) const;
428 
430  int CalculateStemLengthTab(const Staff *staff, data_STEMDIRECTION stemDir) const;
431 
435  int CalculateStemModAdjustment(int stemLength, int directionBias) const;
436 
444 
448  void UpdateStemLength(StemmedDrawingInterface *stemmedInterface, int y1, int y2, int stemAdjust, bool inMixedBeam);
449 
450  int m_x;
451  int m_yBeam; // y value of stem top position
452  data_DURATION m_dur; // drawing duration
453  int m_breaksec;
454  int m_overlapMargin;
455  bool m_centered; // beam is centered on the line
456  data_BEAMPLACE m_beamRelativePlace;
457  char m_partialFlags[MAX_DURATION_PARTIALS];
458  data_BEAMPLACE m_partialFlagPlace;
459  LayerElement *m_element;
460  Note *m_closestNote;
461  TabDurSym *m_tabDurSym;
462  Stem *m_stem; // a pointer to the stem in order to avoid to have to re-cast it
463 };
464 
465 } // namespace vrv
466 
467 #endif
This class is an interface for MEI beam elements (beam, beamSpan).
Definition: drawinginterface.h:97
Definition: beam.h:395
int CalculateStemLengthTab(const Staff *staff, data_STEMDIRECTION stemDir) const
Helper for calculating the stem length for tablature beam placed outside the staff.
void UpdateStemLength(StemmedDrawingInterface *stemmedInterface, int y1, int y2, int stemAdjust, bool inMixedBeam)
Update stem length based on the calculated coordinates and stemAdjust value.
StemmedDrawingInterface * GetStemHolderInterface()
Helper to get the StemmedDrawingInterface associated with the m_element (if any) Return the Chord or ...
int CalculateStemLength(const Staff *staff, data_STEMDIRECTION stemDir, bool isHorizontal, data_DURATION preferredDur) const
Helper for calculating the stem length for staff notation and tablature beams within the staff.
data_STEMDIRECTION GetStemDir() const
Return the encoded stem direction.
void SetClosestNoteOrTabDurSym(data_STEMDIRECTION stemDir, bool outsideStaff)
Set the note or closest note for chord or tabdursym for tablature beams placed outside the staff.
int CalculateStemModAdjustment(int stemLength, int directionBias) const
Return stem length adjustment in half units, depending on the @stem.mode attribute.
Definition: beam.h:284
std::pair< int, int > GetAdditionalBeamCount() const override
See DrawingInterface::GetAdditionalBeamCount.
bool IsTabBeam() const
Return true if the beam has a tabGrp child.
void FilterList(ListOfConstObjects &childList) const override
Filter the flat list and keep only Note and Chords elements.
void CloneReset() override
Overriding CloneReset() method to be called after copy / assignment calls.
FunctorCode Accept(Functor &functor) override
Interface for class functor visitation.
Object * Clone() const override
Method call for copying child classes.
Definition: beam.h:293
int GetBeamPartDuration(int x, bool includeRests=true) const
Return duration of the beam part that is closest to the specified object X position.
bool IsSupportedChild(ClassId classId) override
Add an element (a note or a rest) to a beam.
Class for storing drawing parameters when calculating beams.
Definition: beam.h:36
void RequestStaffSpace(const Doc *doc, const BeamDrawingInterface *beamInterface)
Request staff space for mixed beams if minimal stem length is too short.
void ClearCoordRefs()
Clear the m_beamElementCoords vector and delete all the objects.
ArrayOfBeamElementCoords m_beamElementCoordRefs
An array of coordinates for each element.
Definition: beam.h:202
void InitCoordRefs(const ArrayOfBeamElementCoords *beamElementCoords)
Initializes the m_beamElementCoords vector objects.
int GetAdjacentElementsDuration(int elementX) const
Get longest duration of the elements that are adjacent to the X coordinate passed.
Definition: beam.h:225
Measure * GetMeasure()
Set/get methods for member variables.
Definition: beam.h:234
void SetSpanningType(int systemIndex, int systemCount)
Set/get methods for spanning type of segment.
This abstract class is the base class for all const functors.
Definition: functor.h:126
This class is a hold the data and corresponds to the model of a MVC design pattern.
Definition: doc.h:41
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 represents a layer in a laid-out score (Doc).
Definition: layer.h:39
This class represents a measure in a page-based score (Doc).
Definition: measure.h:46
This class models the MEI <note> element.
Definition: note.h:67
This class represents a basic object.
Definition: object.h:61
This class represents a staff in a laid-out score (Doc).
Definition: staff.h:107
This class models a stem as a layer element part and as MEI <stem> element.
Definition: stem.h:27
This class is an interface for MEI stemmed element.
Definition: drawinginterface.h:353
This class models the MEI <tabDurSym> element.
Definition: tabdursym.h:29