1 // This file is part of VSTGUI. It is subject to the license terms
2 // in the LICENSE file found in the top-level directory of this
3 // distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
4
5 #include "cgraphicspath.h"
6 #include "cdrawcontext.h"
7 #include "cgraphicstransform.h"
8
9 namespace VSTGUI {
10
11 //-----------------------------------------------------------------------------
addRoundRect(const CRect & size,CCoord radius)12 void CGraphicsPath::addRoundRect (const CRect& size, CCoord radius)
13 {
14 if (radius == 0.)
15 {
16 addRect (size);
17 return;
18 }
19 CRect rect2 (size);
20 rect2.normalize ();
21 const CCoord left = rect2.left;
22 const CCoord right = rect2.right;
23 const CCoord top = rect2.top;
24 const CCoord bottom = rect2.bottom;
25
26 beginSubpath (CPoint (right-radius, top));
27 addArc (CRect (right - 2.0 * radius, top, right, top + 2.0 * radius), 270., 360., true);
28 addArc (CRect (right - 2.0 * radius, bottom - 2.0 *radius, right, bottom), 0., 90., true);
29 addArc (CRect (left, bottom - 2.0 * radius, left + 2.0 * radius, bottom), 90., 180., true);
30 addArc (CRect (left, top, left + 2.0 * radius, top + 2.0 * radius), 180., 270., true);
31 closeSubpath ();
32 }
33
34 //-----------------------------------------------------------------------------
addPath(const CGraphicsPath & path,CGraphicsTransform * transformation)35 void CGraphicsPath::addPath (const CGraphicsPath& path, CGraphicsTransform* transformation)
36 {
37 for (auto e : path.elements)
38 {
39 if (transformation)
40 {
41 switch (e.type)
42 {
43 case Element::kArc:
44 {
45 transformation->transform (e.instruction.arc.rect.left, e.instruction.arc.rect.right, e.instruction.arc.rect.top, e.instruction.arc.rect.bottom);
46 break;
47 }
48 case Element::kEllipse:
49 case Element::kRect:
50 {
51 transformation->transform (e.instruction.rect.left, e.instruction.rect.right, e.instruction.rect.top, e.instruction.rect.bottom);
52 break;
53 }
54 case Element::kBeginSubpath:
55 case Element::kLine:
56 {
57 transformation->transform (e.instruction.point.x, e.instruction.point.y);
58 break;
59 }
60 case Element::kBezierCurve:
61 {
62 transformation->transform (e.instruction.curve.control1.x, e.instruction.curve.control1.y);
63 transformation->transform (e.instruction.curve.control2.x, e.instruction.curve.control2.y);
64 transformation->transform (e.instruction.curve.end.x, e.instruction.curve.end.y);
65 break;
66 }
67 case Element::kCloseSubpath:
68 {
69 break;
70 }
71 }
72 }
73 elements.emplace_back (e);
74 }
75 dirty ();
76 }
77
78 //-----------------------------------------------------------------------------
addArc(const CRect & rect,double startAngle,double endAngle,bool clockwise)79 void CGraphicsPath::addArc (const CRect& rect, double startAngle, double endAngle, bool clockwise)
80 {
81 Element e;
82 e.type = Element::kArc;
83 CRect2Rect (rect, e.instruction.arc.rect);
84 e.instruction.arc.startAngle = startAngle;
85 e.instruction.arc.endAngle = endAngle;
86 e.instruction.arc.clockwise = clockwise;
87 elements.emplace_back (e);
88 dirty ();
89 }
90
91 //-----------------------------------------------------------------------------
addEllipse(const CRect & rect)92 void CGraphicsPath::addEllipse (const CRect& rect)
93 {
94 Element e;
95 e.type = Element::kEllipse;
96 CRect2Rect (rect, e.instruction.rect);
97 elements.emplace_back (e);
98 dirty ();
99 }
100
101 //-----------------------------------------------------------------------------
addRect(const CRect & rect)102 void CGraphicsPath::addRect (const CRect& rect)
103 {
104 Element e;
105 e.type = Element::kRect;
106 CRect2Rect (rect, e.instruction.rect);
107 elements.emplace_back (e);
108 dirty ();
109 }
110
111 //-----------------------------------------------------------------------------
addLine(const CPoint & to)112 void CGraphicsPath::addLine (const CPoint& to)
113 {
114 Element e;
115 e.type = Element::kLine;
116 CPoint2Point (to, e.instruction.point);
117 elements.emplace_back (e);
118 dirty ();
119 }
120
121 //-----------------------------------------------------------------------------
addBezierCurve(const CPoint & control1,const CPoint & control2,const CPoint & end)122 void CGraphicsPath::addBezierCurve (const CPoint& control1, const CPoint& control2, const CPoint& end)
123 {
124 Element e;
125 e.type = Element::kBezierCurve;
126 CPoint2Point (control1, e.instruction.curve.control1);
127 CPoint2Point (control2, e.instruction.curve.control2);
128 CPoint2Point (end, e.instruction.curve.end);
129 elements.emplace_back (e);
130 dirty ();
131 }
132
133 //-----------------------------------------------------------------------------
beginSubpath(const CPoint & start)134 void CGraphicsPath::beginSubpath (const CPoint& start)
135 {
136 Element e;
137 e.type = Element::kBeginSubpath;
138 CPoint2Point (start, e.instruction.point);
139 elements.emplace_back (e);
140 dirty ();
141 }
142
143 //-----------------------------------------------------------------------------
closeSubpath()144 void CGraphicsPath::closeSubpath ()
145 {
146 Element e;
147 e.type = Element::kCloseSubpath;
148 elements.emplace_back (e);
149 dirty ();
150 }
151
152 } // namespace
153