Verovio
Source code documentation
boundingbox.h
1 // Name: boundingbox.h
3 // Author: Laurent Pugin
4 // Created: 2016
5 // Copyright (c) Authors and others. All rights reserved.
7 
8 #ifndef __VRV_BOUNDING_BOX_H__
9 #define __VRV_BOUNDING_BOX_H__
10 
11 //----------------------------------------------------------------------------
12 
13 #include "vrvdef.h"
14 
15 namespace vrv {
16 
17 #define BEZIER_APPROXIMATION 50.0
18 
19 class BeamDrawingInterface;
20 class Doc;
21 class FloatingCurvePositioner;
22 class Glyph;
23 class Resources;
24 
25 //----------------------------------------------------------------------------
26 // BoundingBox
27 //----------------------------------------------------------------------------
28 
32 class BoundingBox {
33 public:
39  BoundingBox();
40  virtual ~BoundingBox() {}
41  virtual ClassId GetClassId() const = 0;
42  bool Is(ClassId classId) const { return (this->GetClassId() == classId); }
43  template <typename Range> bool IsAnyOf(const Range &classIds) const
44  {
45  return std::find(std::begin(classIds), std::end(classIds), GetClassId()) != std::end(classIds);
46  }
48 
53  virtual void UpdateContentBBoxX(int x1, int x2);
54  virtual void UpdateContentBBoxY(int y1, int y2);
55  virtual void UpdateSelfBBoxX(int x1, int x2);
56  virtual void UpdateSelfBBoxY(int y1, int y2);
57  void SetEmptyBB();
58  //
59  bool HasSelfBB() const;
60  bool HasSelfHorizontalBB() const;
61  bool HasSelfVerticalBB() const;
62  bool HasContentBB() const;
63  bool HasContentHorizontalBB() const;
64  bool HasContentVerticalBB() const;
65  bool HasEmptyBB() const;
67 
72  void SetBoundingBoxGlyph(char32_t smuflGlyph, int fontSize);
73  char32_t GetBoundingBoxGlyph() const { return m_smuflGlyph; }
74  int GetBoundingBoxGlyphFontSize() const { return m_smuflGlyphFontSize; }
76 
80  virtual void ResetBoundingBox();
81 
87  virtual int GetDrawingX() const = 0;
88  virtual int GetDrawingY() const = 0;
90 
96  virtual void ResetCachedDrawingX() const = 0;
97  virtual void ResetCachedDrawingY() const = 0;
99 
104  int GetSelfBottom() const { return (this->GetDrawingY() + m_selfBB_y1); }
105  int GetSelfTop() const { return (this->GetDrawingY() + m_selfBB_y2); }
106  int GetSelfLeft() const { return (this->GetDrawingX() + m_selfBB_x1); }
107  int GetSelfRight() const { return (this->GetDrawingX() + m_selfBB_x2); }
108  int GetContentBottom() const { return (this->GetDrawingY() + m_contentBB_y1); }
109  int GetContentTop() const { return (this->GetDrawingY() + m_contentBB_y2); }
110  int GetContentLeft() const { return (this->GetDrawingX() + m_contentBB_x1); }
111  int GetContentRight() const { return (this->GetDrawingX() + m_contentBB_x2); }
112  //
113  int GetSelfX1() const { return m_selfBB_x1; }
114  int GetSelfX2() const { return m_selfBB_x2; }
115  int GetSelfY1() const { return m_selfBB_y1; }
116  int GetSelfY2() const { return m_selfBB_y2; }
117  int GetContentX1() const { return m_contentBB_x1; }
118  int GetContentX2() const { return m_contentBB_x2; }
119  int GetContentY1() const { return m_contentBB_y1; }
120  int GetContentY2() const { return m_contentBB_y2; }
122 
127  int GetBottomBy(Accessor type) const { return ((type == SELF) ? GetSelfBottom() : GetContentBottom()); }
128  int GetTopBy(Accessor type) const { return ((type == SELF) ? GetSelfTop() : GetContentTop()); }
129  int GetLeftBy(Accessor type) const { return ((type == SELF) ? GetSelfLeft() : GetContentLeft()); }
130  int GetRightBy(Accessor type) const { return ((type == SELF) ? GetSelfRight() : GetContentRight()); }
131  int GetX1By(Accessor type) const { return ((type == SELF) ? GetSelfX1() : GetContentX1()); }
132  int GetX2By(Accessor type) const { return ((type == SELF) ? GetSelfX2() : GetContentX2()); }
133  int GetY1By(Accessor type) const { return ((type == SELF) ? GetSelfY1() : GetContentY1()); }
134  int GetY2By(Accessor type) const { return ((type == SELF) ? GetSelfY2() : GetContentY2()); }
136 
142  bool HorizontalContentOverlap(const BoundingBox *other, int margin = 0) const;
143  bool VerticalContentOverlap(const BoundingBox *other, int margin = 0) const;
144  bool HorizontalSelfOverlap(const BoundingBox *other, int margin = 0) const;
145  bool VerticalSelfOverlap(const BoundingBox *other, int margin = 0) const;
147 
152  int HorizontalLeftOverlap(const BoundingBox *other, const Doc *doc, int margin = 0, int vMargin = 0) const;
153  int HorizontalRightOverlap(const BoundingBox *other, const Doc *doc, int margin = 0, int vMargin = 0) const;
154  int VerticalTopOverlap(const BoundingBox *other, const Doc *doc, int margin = 0, int hMargin = 0) const;
155  int VerticalBottomOverlap(const BoundingBox *other, const Doc *doc, int margin = 0, int hMargin = 0) const;
157 
163  int GetCutOutTop(const Resources &resources) const;
164  int GetCutOutBottom(const Resources &resources) const;
165  int GetCutOutLeft(const Resources &resources) const;
166  int GetCutOutRight(const Resources &resources) const;
167  // Restricted version which only considers the cutout rectangles from the top or bottom
168  int GetCutOutLeft(const Resources &resources, bool fromTop) const;
169  int GetCutOutRight(const Resources &resources, bool fromTop) const;
171 
175  bool Encloses(const Point point) const;
176 
181  int Intersects(const FloatingCurvePositioner *curve, Accessor type, int margin = 0) const;
182 
188  int Intersects(const BeamDrawingInterface *beamInterface, Accessor type, int margin = 0,
189  bool fromBeamContentSide = false) const;
190 
191  //----------------//
192  // Static methods //
193  //----------------//
194 
195  static std::pair<double, int> ApproximateBezierExtrema(
196  const Point bezier[4], bool isMaxExtrema, int approximationSteps = BEZIER_APPROXIMATION);
197 
201  static double CalcDistance(const Point &p1, const Point &p2);
202 
206  static bool ArePointsClose(const Point &p1, const Point &p2, int margin);
207 
211  static double CalcSlope(const Point &p1, const Point &p2);
212 
216  static Point CalcPositionAfterRotation(Point point, float alpha, Point center);
217 
221  static double CalcBezierParamAtPosition(const Point bezier[4], int x);
222 
226  static int CalcBezierAtPosition(const Point bezier[4], int x);
227 
231  static void CalcLinearInterpolation(Point &dest, const Point &a, const Point &b, double t);
232 
236  static Point CalcPointAtBezier(const Point bezier[4], double t);
237 
241  static double GetBezierThicknessCoefficient(const Point bezier[4], int currentThickness, int penWidth);
242 
246  static Point CalcDeCasteljau(const Point bezier[4], double t);
247 
251  static void CalcThickBezier(const Point bezier[4], int thickness, Point topBezier[4], Point bottomBezier[4]);
252 
257  const Point bezier[4], Point &pos, int &width, int &height, int &minYPos, int &maxYPos);
258 
263  static int RectLeftOverlap(const Point rect1[2], const Point rect2[2], int margin, int vMargin);
264  static int RectRightOverlap(const Point rect1[2], const Point rect2[2], int margin, int vMargin);
265  static int RectTopOverlap(const Point rect1[2], const Point rect2[2], int margin, int hMargin);
266  static int RectBottomOverlap(const Point rect1[2], const Point rect2[2], int margin, int hMargin);
268 
273  static std::set<double> SolveCubicPolynomial(double a, double b, double c, double d);
274 
275 private:
283  int GetRectangles(const SMuFLGlyphAnchor &anchor, Point rect[2][2], const Resources &resources) const;
284  int GetRectangles(const SMuFLGlyphAnchor &anchor1, const SMuFLGlyphAnchor &anchor2, Point rect[3][2],
285  const Resources &resources) const;
287 
292  bool GetGlyph2PointRectangles(
293  const SMuFLGlyphAnchor &anchor1, const SMuFLGlyphAnchor &anchor2, const Glyph *glyph1, Point rect[3][2]) const;
294 
299  bool GetGlyph1PointRectangles(const SMuFLGlyphAnchor &anchor, const Glyph *glyph, Point rect[2][2]) const;
300 
301 public:
302  //
303 protected:
310  mutable int m_cachedDrawingX;
311  mutable int m_cachedDrawingY;
313 private:
318  int m_contentBB_x1, m_contentBB_y1, m_contentBB_x2, m_contentBB_y2;
319  int m_selfBB_x1, m_selfBB_y1, m_selfBB_x2, m_selfBB_y2;
321 
326  char32_t m_smuflGlyph;
327 
331  int m_smuflGlyphFontSize;
332 };
333 
334 //----------------------------------------------------------------------------
335 // SegmentedLine
336 //----------------------------------------------------------------------------
337 
341 public:
347  SegmentedLine(int start, int end);
348  virtual ~SegmentedLine() {}
350 
354  bool IsEmpty() const { return (m_segments.empty()); }
355 
359  bool IsUnsegmented() const { return (m_segments.size() == 1); }
360 
364  int GetSegmentCount() const { return (int)m_segments.size(); }
365 
369  std::pair<int, int> GetStartEnd(int idx) const;
370 
374  void AddGap(int start, int end);
375 
376 protected:
377  //
378 private:
379  //
380 public:
381  //
382 protected:
383  //
384 private:
389  ArrayOfIntPairs m_segments;
390 
394  bool m_increasing;
395 };
396 
397 } // namespace vrv
398 
399 #endif
This class is an interface for MEI beam elements (beam, beamSpan).
Definition: drawinginterface.h:98
This class represents a basic object in the layout domain.
Definition: boundingbox.h:32
int Intersects(const FloatingCurvePositioner *curve, Accessor type, int margin=0) const
Return intersection between the bounding box and the curve represented by the FloatingPositioner.
int Intersects(const BeamDrawingInterface *beamInterface, Accessor type, int margin=0, bool fromBeamContentSide=false) const
Return intersection between the bounding box and the beam represented by the BeamDrawingInterface.
static double GetBezierThicknessCoefficient(const Point bezier[4], int currentThickness, int penWidth)
Calculate thickness coefficient to be applient for bezier curve to fit MEI units thickness.
static int RectLeftOverlap(const Point rect1[2], const Point rect2[2], int margin, int vMargin)
Calculate the left / right / top / bottom overlap of two rectangle taking into account the margin / v...
int m_cachedDrawingX
The cached version of the drawingX and drawingY values.
Definition: boundingbox.h:310
bool Encloses(const Point point) const
Return true if the bounding box encloses the point.
void SetBoundingBoxGlyph(char32_t smuflGlyph, int fontSize)
Set and get the smuflGlyph / fontsize for a bounding box that is the one of a single SMuFL glyph.
static double CalcDistance(const Point &p1, const Point &p2)
Calculate the euclidean distance between two points.
static Point CalcPositionAfterRotation(Point point, float alpha, Point center)
Calculate the position of a point after a rotation of alpha (in radian) around the center.
static void CalcThickBezier(const Point bezier[4], int thickness, Point topBezier[4], Point bottomBezier[4])
Calculate the position of the bezier above and below for a thick bezier.
static int CalcBezierAtPosition(const Point bezier[4], int x)
Calculate the y position of a bezier at position x.
static double CalcSlope(const Point &p1, const Point &p2)
Calculate the slope represented by two points.
static bool ArePointsClose(const Point &p1, const Point &p2, int margin)
static std::set< double > SolveCubicPolynomial(double a, double b, double c, double d)
Solve the cubic equation ax^3 + bx^2 + cx + d = 0 Returns up to three real roots.
static Point CalcDeCasteljau(const Point bezier[4], double t)
Calculate the point bezier point position for a t between 0.0 and 1.0.
static Point CalcPointAtBezier(const Point bezier[4], double t)
Calculate point (X,Y) coordinaties on the bezier curve.
virtual void ResetBoundingBox()
Reset the bounding box values.
static void ApproximateBezierBoundingBox(const Point bezier[4], Point &pos, int &width, int &height, int &minYPos, int &maxYPos)
Approximate the bounding box of a bezier taking into accound the height and the width.
static double CalcBezierParamAtPosition(const Point bezier[4], int x)
Calculate the t parameter of a bezier at position x.
static void CalcLinearInterpolation(Point &dest, const Point &a, const Point &b, double t)
Calculate linear interpolation between two points at time t.
This class represents a basic object for a curve (slur, tie) in the layout domain.
Definition: floatingobject.h:329
This class is used for storing a music font glyph.
Definition: glyph.h:31
Simple class for representing points.
Definition: devicecontextbase.h:203
This class provides resource values.
Definition: resources.h:30
Definition: boundingbox.h:340
bool IsEmpty() const
Check if the segmented line is empty.
Definition: boundingbox.h:354
std::pair< int, int > GetStartEnd(int idx) const
Get the start and end of a segment.
int GetSegmentCount() const
The number of segments.
Definition: boundingbox.h:364
bool IsUnsegmented() const
Check if the line is one single segment.
Definition: boundingbox.h:359
void AddGap(int start, int end)
Add a gap in the line.