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.

263 lines
8.0KB

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