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