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.

300 lines
9.5KB

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