Audio plugin host https://kx.studio/carla
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.

293 lines
9.5KB

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