/* ============================================================================== This file is part of the JUCE library. Copyright (c) 2015 - ROLI Ltd. Permission is granted to use this software under the terms of either: a) the GPL v2 (or any later version) b) the Affero GPL v3 Details of these licenses can be found at: www.gnu.org/licenses JUCE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ------------------------------------------------------------------------------ To release a closed-source product which uses JUCE, commercial licenses are available: visit www.juce.com for more information. ============================================================================== */ #ifndef JUCE_RELATIVEPOINTPATH_H_INCLUDED #define JUCE_RELATIVEPOINTPATH_H_INCLUDED //============================================================================== /** A path object that consists of RelativePoint coordinates rather than the normal fixed ones. One of these paths can be converted into a Path object for drawing and manipulation, but unlike a Path, its points can be dynamic instead of just fixed. @see RelativePoint, RelativeCoordinate */ class JUCE_API RelativePointPath { public: //============================================================================== RelativePointPath(); RelativePointPath (const RelativePointPath&); explicit RelativePointPath (const Path& path); ~RelativePointPath(); bool operator== (const RelativePointPath&) const noexcept; bool operator!= (const RelativePointPath&) const noexcept; //============================================================================== /** Resolves this points in this path and adds them to a normal Path object. */ void createPath (Path& path, Expression::Scope* scope) const; /** Returns true if the path contains any non-fixed points. */ bool containsAnyDynamicPoints() const; /** Quickly swaps the contents of this path with another. */ void swapWith (RelativePointPath&) noexcept; //============================================================================== /** The types of element that may be contained in this path. @see RelativePointPath::ElementBase */ enum ElementType { nullElement, startSubPathElement, closeSubPathElement, lineToElement, quadraticToElement, cubicToElement }; //============================================================================== /** Base class for the elements that make up a RelativePointPath. */ class JUCE_API ElementBase { public: ElementBase (ElementType type); virtual ~ElementBase() {} virtual ValueTree createTree() const = 0; virtual void addToPath (Path& path, Expression::Scope*) const = 0; virtual RelativePoint* getControlPoints (int& numPoints) = 0; virtual ElementBase* clone() const = 0; bool isDynamic(); const ElementType type; private: JUCE_DECLARE_NON_COPYABLE (ElementBase) }; //============================================================================== class JUCE_API StartSubPath : public ElementBase { public: StartSubPath (const RelativePoint& pos); ValueTree createTree() const; void addToPath (Path& path, Expression::Scope*) const; RelativePoint* getControlPoints (int& numPoints); ElementBase* clone() const; RelativePoint startPos; private: JUCE_DECLARE_NON_COPYABLE (StartSubPath) }; //============================================================================== class JUCE_API CloseSubPath : public ElementBase { public: CloseSubPath(); ValueTree createTree() const; void addToPath (Path& path, Expression::Scope*) const; RelativePoint* getControlPoints (int& numPoints); ElementBase* clone() const; private: JUCE_DECLARE_NON_COPYABLE (CloseSubPath) }; //============================================================================== class JUCE_API LineTo : public ElementBase { public: LineTo (const RelativePoint& endPoint); ValueTree createTree() const; void addToPath (Path& path, Expression::Scope*) const; RelativePoint* getControlPoints (int& numPoints); ElementBase* clone() const; RelativePoint endPoint; private: JUCE_DECLARE_NON_COPYABLE (LineTo) }; //============================================================================== class JUCE_API QuadraticTo : public ElementBase { public: QuadraticTo (const RelativePoint& controlPoint, const RelativePoint& endPoint); ValueTree createTree() const; void addToPath (Path& path, Expression::Scope*) const; RelativePoint* getControlPoints (int& numPoints); ElementBase* clone() const; RelativePoint controlPoints[2]; private: JUCE_DECLARE_NON_COPYABLE (QuadraticTo) }; //============================================================================== class JUCE_API CubicTo : public ElementBase { public: CubicTo (const RelativePoint& controlPoint1, const RelativePoint& controlPoint2, const RelativePoint& endPoint); ValueTree createTree() const; void addToPath (Path& path, Expression::Scope*) const; RelativePoint* getControlPoints (int& numPoints); ElementBase* clone() const; RelativePoint controlPoints[3]; private: JUCE_DECLARE_NON_COPYABLE (CubicTo) }; //============================================================================== void addElement (ElementBase* newElement); //============================================================================== OwnedArray elements; bool usesNonZeroWinding; private: class Positioner; friend class Positioner; bool containsDynamicPoints; void applyTo (DrawablePath& path) const; RelativePointPath& operator= (const RelativePointPath&); JUCE_LEAK_DETECTOR (RelativePointPath) }; #endif // JUCE_RELATIVEPOINTPATH_H_INCLUDED