The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

294 lines
9.7KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. RelativePointPath::RelativePointPath()
  19. : usesNonZeroWinding (true),
  20. containsDynamicPoints (false)
  21. {
  22. }
  23. RelativePointPath::RelativePointPath (const RelativePointPath& other)
  24. : usesNonZeroWinding (true),
  25. containsDynamicPoints (false)
  26. {
  27. for (int i = 0; i < other.elements.size(); ++i)
  28. elements.add (other.elements.getUnchecked(i)->clone());
  29. }
  30. RelativePointPath::RelativePointPath (const Path& path)
  31. : usesNonZeroWinding (path.isUsingNonZeroWinding()),
  32. containsDynamicPoints (false)
  33. {
  34. for (Path::Iterator i (path); i.next();)
  35. {
  36. switch (i.elementType)
  37. {
  38. case Path::Iterator::startNewSubPath: elements.add (new StartSubPath (RelativePoint (i.x1, i.y1))); break;
  39. case Path::Iterator::lineTo: elements.add (new LineTo (RelativePoint (i.x1, i.y1))); break;
  40. case Path::Iterator::quadraticTo: elements.add (new QuadraticTo (RelativePoint (i.x1, i.y1), RelativePoint (i.x2, i.y2))); break;
  41. case Path::Iterator::cubicTo: elements.add (new CubicTo (RelativePoint (i.x1, i.y1), RelativePoint (i.x2, i.y2), RelativePoint (i.x3, i.y3))); break;
  42. case Path::Iterator::closePath: elements.add (new CloseSubPath()); break;
  43. default: jassertfalse; break;
  44. }
  45. }
  46. }
  47. RelativePointPath::~RelativePointPath()
  48. {
  49. }
  50. bool RelativePointPath::operator== (const RelativePointPath& other) const noexcept
  51. {
  52. if (elements.size() != other.elements.size()
  53. || usesNonZeroWinding != other.usesNonZeroWinding
  54. || containsDynamicPoints != other.containsDynamicPoints)
  55. return false;
  56. for (int i = 0; i < elements.size(); ++i)
  57. {
  58. ElementBase* const e1 = elements.getUnchecked(i);
  59. ElementBase* const e2 = other.elements.getUnchecked(i);
  60. if (e1->type != e2->type)
  61. return false;
  62. int numPoints1, numPoints2;
  63. const RelativePoint* const points1 = e1->getControlPoints (numPoints1);
  64. const RelativePoint* const points2 = e2->getControlPoints (numPoints2);
  65. jassert (numPoints1 == numPoints2);
  66. for (int j = numPoints1; --j >= 0;)
  67. if (points1[j] != points2[j])
  68. return false;
  69. }
  70. return true;
  71. }
  72. bool RelativePointPath::operator!= (const RelativePointPath& other) const noexcept
  73. {
  74. return ! operator== (other);
  75. }
  76. void RelativePointPath::swapWith (RelativePointPath& other) noexcept
  77. {
  78. elements.swapWithArray (other.elements);
  79. std::swap (usesNonZeroWinding, other.usesNonZeroWinding);
  80. std::swap (containsDynamicPoints, other.containsDynamicPoints);
  81. }
  82. void RelativePointPath::createPath (Path& path, Expression::Scope* scope) const
  83. {
  84. for (int i = 0; i < elements.size(); ++i)
  85. elements.getUnchecked(i)->addToPath (path, scope);
  86. }
  87. bool RelativePointPath::containsAnyDynamicPoints() const
  88. {
  89. return containsDynamicPoints;
  90. }
  91. void RelativePointPath::addElement (ElementBase* newElement)
  92. {
  93. if (newElement != nullptr)
  94. {
  95. elements.add (newElement);
  96. containsDynamicPoints = containsDynamicPoints || newElement->isDynamic();
  97. }
  98. }
  99. //==============================================================================
  100. RelativePointPath::ElementBase::ElementBase (const ElementType type_) : type (type_)
  101. {
  102. }
  103. bool RelativePointPath::ElementBase::isDynamic()
  104. {
  105. int numPoints;
  106. const RelativePoint* const points = getControlPoints (numPoints);
  107. for (int i = numPoints; --i >= 0;)
  108. if (points[i].isDynamic())
  109. return true;
  110. return false;
  111. }
  112. //==============================================================================
  113. RelativePointPath::StartSubPath::StartSubPath (const RelativePoint& pos)
  114. : ElementBase (startSubPathElement), startPos (pos)
  115. {
  116. }
  117. ValueTree RelativePointPath::StartSubPath::createTree() const
  118. {
  119. ValueTree v (DrawablePath::ValueTreeWrapper::Element::startSubPathElement);
  120. v.setProperty (DrawablePath::ValueTreeWrapper::point1, startPos.toString(), nullptr);
  121. return v;
  122. }
  123. void RelativePointPath::StartSubPath::addToPath (Path& path, Expression::Scope* scope) const
  124. {
  125. path.startNewSubPath (startPos.resolve (scope));
  126. }
  127. RelativePoint* RelativePointPath::StartSubPath::getControlPoints (int& numPoints)
  128. {
  129. numPoints = 1;
  130. return &startPos;
  131. }
  132. RelativePointPath::ElementBase* RelativePointPath::StartSubPath::clone() const
  133. {
  134. return new StartSubPath (startPos);
  135. }
  136. //==============================================================================
  137. RelativePointPath::CloseSubPath::CloseSubPath()
  138. : ElementBase (closeSubPathElement)
  139. {
  140. }
  141. ValueTree RelativePointPath::CloseSubPath::createTree() const
  142. {
  143. return ValueTree (DrawablePath::ValueTreeWrapper::Element::closeSubPathElement);
  144. }
  145. void RelativePointPath::CloseSubPath::addToPath (Path& path, Expression::Scope*) const
  146. {
  147. path.closeSubPath();
  148. }
  149. RelativePoint* RelativePointPath::CloseSubPath::getControlPoints (int& numPoints)
  150. {
  151. numPoints = 0;
  152. return nullptr;
  153. }
  154. RelativePointPath::ElementBase* RelativePointPath::CloseSubPath::clone() const
  155. {
  156. return new CloseSubPath();
  157. }
  158. //==============================================================================
  159. RelativePointPath::LineTo::LineTo (const RelativePoint& endPoint_)
  160. : ElementBase (lineToElement), endPoint (endPoint_)
  161. {
  162. }
  163. ValueTree RelativePointPath::LineTo::createTree() const
  164. {
  165. ValueTree v (DrawablePath::ValueTreeWrapper::Element::lineToElement);
  166. v.setProperty (DrawablePath::ValueTreeWrapper::point1, endPoint.toString(), nullptr);
  167. return v;
  168. }
  169. void RelativePointPath::LineTo::addToPath (Path& path, Expression::Scope* scope) const
  170. {
  171. path.lineTo (endPoint.resolve (scope));
  172. }
  173. RelativePoint* RelativePointPath::LineTo::getControlPoints (int& numPoints)
  174. {
  175. numPoints = 1;
  176. return &endPoint;
  177. }
  178. RelativePointPath::ElementBase* RelativePointPath::LineTo::clone() const
  179. {
  180. return new LineTo (endPoint);
  181. }
  182. //==============================================================================
  183. RelativePointPath::QuadraticTo::QuadraticTo (const RelativePoint& controlPoint, const RelativePoint& endPoint)
  184. : ElementBase (quadraticToElement)
  185. {
  186. controlPoints[0] = controlPoint;
  187. controlPoints[1] = endPoint;
  188. }
  189. ValueTree RelativePointPath::QuadraticTo::createTree() const
  190. {
  191. ValueTree v (DrawablePath::ValueTreeWrapper::Element::quadraticToElement);
  192. v.setProperty (DrawablePath::ValueTreeWrapper::point1, controlPoints[0].toString(), nullptr);
  193. v.setProperty (DrawablePath::ValueTreeWrapper::point2, controlPoints[1].toString(), nullptr);
  194. return v;
  195. }
  196. void RelativePointPath::QuadraticTo::addToPath (Path& path, Expression::Scope* scope) const
  197. {
  198. path.quadraticTo (controlPoints[0].resolve (scope),
  199. controlPoints[1].resolve (scope));
  200. }
  201. RelativePoint* RelativePointPath::QuadraticTo::getControlPoints (int& numPoints)
  202. {
  203. numPoints = 2;
  204. return controlPoints;
  205. }
  206. RelativePointPath::ElementBase* RelativePointPath::QuadraticTo::clone() const
  207. {
  208. return new QuadraticTo (controlPoints[0], controlPoints[1]);
  209. }
  210. //==============================================================================
  211. RelativePointPath::CubicTo::CubicTo (const RelativePoint& controlPoint1, const RelativePoint& controlPoint2, const RelativePoint& endPoint)
  212. : ElementBase (cubicToElement)
  213. {
  214. controlPoints[0] = controlPoint1;
  215. controlPoints[1] = controlPoint2;
  216. controlPoints[2] = endPoint;
  217. }
  218. ValueTree RelativePointPath::CubicTo::createTree() const
  219. {
  220. ValueTree v (DrawablePath::ValueTreeWrapper::Element::cubicToElement);
  221. v.setProperty (DrawablePath::ValueTreeWrapper::point1, controlPoints[0].toString(), nullptr);
  222. v.setProperty (DrawablePath::ValueTreeWrapper::point2, controlPoints[1].toString(), nullptr);
  223. v.setProperty (DrawablePath::ValueTreeWrapper::point3, controlPoints[2].toString(), nullptr);
  224. return v;
  225. }
  226. void RelativePointPath::CubicTo::addToPath (Path& path, Expression::Scope* scope) const
  227. {
  228. path.cubicTo (controlPoints[0].resolve (scope),
  229. controlPoints[1].resolve (scope),
  230. controlPoints[2].resolve (scope));
  231. }
  232. RelativePoint* RelativePointPath::CubicTo::getControlPoints (int& numPoints)
  233. {
  234. numPoints = 3;
  235. return controlPoints;
  236. }
  237. RelativePointPath::ElementBase* RelativePointPath::CubicTo::clone() const
  238. {
  239. return new CubicTo (controlPoints[0], controlPoints[1], controlPoints[2]);
  240. }