git subrepo clone --branch=sono6good https://github.com/essej/JUCE.git deps/juce
subrepo: subdir: "deps/juce" merged: "b13f9084e" upstream: origin: "https://github.com/essej/JUCE.git" branch: "sono6good" commit: "b13f9084e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
This commit is contained in:
839
deps/juce/modules/juce_graphics/geometry/juce_Path.h
vendored
Normal file
839
deps/juce/modules/juce_graphics/geometry/juce_Path.h
vendored
Normal file
@ -0,0 +1,839 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A path is a sequence of lines and curves that may either form a closed shape
|
||||
or be open-ended.
|
||||
|
||||
To use a path, you can create an empty one, then add lines and curves to it
|
||||
to create shapes, then it can be rendered by a Graphics context or used
|
||||
for geometric operations.
|
||||
|
||||
e.g. @code
|
||||
Path myPath;
|
||||
|
||||
myPath.startNewSubPath (10.0f, 10.0f); // move the current position to (10, 10)
|
||||
myPath.lineTo (100.0f, 200.0f); // draw a line from here to (100, 200)
|
||||
myPath.quadraticTo (0.0f, 150.0f, 5.0f, 50.0f); // draw a curve that ends at (5, 50)
|
||||
myPath.closeSubPath(); // close the subpath with a line back to (10, 10)
|
||||
|
||||
// add an ellipse as well, which will form a second sub-path within the path..
|
||||
myPath.addEllipse (50.0f, 50.0f, 40.0f, 30.0f);
|
||||
|
||||
// double the width of the whole thing..
|
||||
myPath.applyTransform (AffineTransform::scale (2.0f, 1.0f));
|
||||
|
||||
// and draw it to a graphics context with a 5-pixel thick outline.
|
||||
g.strokePath (myPath, PathStrokeType (5.0f));
|
||||
|
||||
@endcode
|
||||
|
||||
A path object can actually contain multiple sub-paths, which may themselves
|
||||
be open or closed.
|
||||
|
||||
@see PathFlatteningIterator, PathStrokeType, Graphics
|
||||
|
||||
@tags{Graphics}
|
||||
*/
|
||||
class JUCE_API Path final
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty path. */
|
||||
Path();
|
||||
|
||||
/** Creates a copy of another path. */
|
||||
Path (const Path&);
|
||||
|
||||
/** Destructor. */
|
||||
~Path();
|
||||
|
||||
/** Copies this path from another one. */
|
||||
Path& operator= (const Path&);
|
||||
|
||||
/** Move constructor */
|
||||
Path (Path&&) noexcept;
|
||||
|
||||
/** Move assignment operator */
|
||||
Path& operator= (Path&&) noexcept;
|
||||
|
||||
bool operator== (const Path&) const noexcept;
|
||||
bool operator!= (const Path&) const noexcept;
|
||||
|
||||
static const float defaultToleranceForTesting;
|
||||
static const float defaultToleranceForMeasurement;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if the path doesn't contain any lines or curves. */
|
||||
bool isEmpty() const noexcept;
|
||||
|
||||
/** Returns the smallest rectangle that contains all points within the path. */
|
||||
Rectangle<float> getBounds() const noexcept;
|
||||
|
||||
/** Returns the smallest rectangle that contains all points within the path
|
||||
after it's been transformed with the given transform matrix.
|
||||
*/
|
||||
Rectangle<float> getBoundsTransformed (const AffineTransform& transform) const noexcept;
|
||||
|
||||
/** Checks whether a point lies within the path.
|
||||
|
||||
This is only relevant for closed paths (see closeSubPath()), and
|
||||
may produce false results if used on a path which has open sub-paths.
|
||||
|
||||
The path's winding rule is taken into account by this method.
|
||||
|
||||
The tolerance parameter is the maximum error allowed when flattening the path,
|
||||
so this method could return a false positive when your point is up to this distance
|
||||
outside the path's boundary.
|
||||
|
||||
@see closeSubPath, setUsingNonZeroWinding
|
||||
*/
|
||||
bool contains (float x, float y,
|
||||
float tolerance = defaultToleranceForTesting) const;
|
||||
|
||||
/** Checks whether a point lies within the path.
|
||||
|
||||
This is only relevant for closed paths (see closeSubPath()), and
|
||||
may produce false results if used on a path which has open sub-paths.
|
||||
|
||||
The path's winding rule is taken into account by this method.
|
||||
|
||||
The tolerance parameter is the maximum error allowed when flattening the path,
|
||||
so this method could return a false positive when your point is up to this distance
|
||||
outside the path's boundary.
|
||||
|
||||
@see closeSubPath, setUsingNonZeroWinding
|
||||
*/
|
||||
bool contains (Point<float> point,
|
||||
float tolerance = defaultToleranceForTesting) const;
|
||||
|
||||
/** Checks whether a line crosses the path.
|
||||
|
||||
This will return positive if the line crosses any of the paths constituent
|
||||
lines or curves. It doesn't take into account whether the line is inside
|
||||
or outside the path, or whether the path is open or closed.
|
||||
|
||||
The tolerance parameter is the maximum error allowed when flattening the path,
|
||||
so this method could return a false positive when your point is up to this distance
|
||||
outside the path's boundary.
|
||||
*/
|
||||
bool intersectsLine (Line<float> line,
|
||||
float tolerance = defaultToleranceForTesting);
|
||||
|
||||
/** Cuts off parts of a line to keep the parts that are either inside or
|
||||
outside this path.
|
||||
|
||||
Note that this isn't smart enough to cope with situations where the
|
||||
line would need to be cut into multiple pieces to correctly clip against
|
||||
a re-entrant shape.
|
||||
|
||||
@param line the line to clip
|
||||
@param keepSectionOutsidePath if true, it's the section outside the path
|
||||
that will be kept; if false its the section inside
|
||||
the path
|
||||
*/
|
||||
Line<float> getClippedLine (Line<float> line, bool keepSectionOutsidePath) const;
|
||||
|
||||
/** Returns the length of the path.
|
||||
@see getPointAlongPath
|
||||
*/
|
||||
float getLength (const AffineTransform& transform = AffineTransform(),
|
||||
float tolerance = defaultToleranceForMeasurement) const;
|
||||
|
||||
/** Returns a point that is the specified distance along the path.
|
||||
If the distance is greater than the total length of the path, this will return the
|
||||
end point.
|
||||
@see getLength
|
||||
*/
|
||||
Point<float> getPointAlongPath (float distanceFromStart,
|
||||
const AffineTransform& transform = AffineTransform(),
|
||||
float tolerance = defaultToleranceForMeasurement) const;
|
||||
|
||||
/** Finds the point along the path which is nearest to a given position.
|
||||
This sets pointOnPath to the nearest point, and returns the distance of this point from the start
|
||||
of the path.
|
||||
*/
|
||||
float getNearestPoint (Point<float> targetPoint,
|
||||
Point<float>& pointOnPath,
|
||||
const AffineTransform& transform = AffineTransform(),
|
||||
float tolerance = defaultToleranceForMeasurement) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Removes all lines and curves, resetting the path completely. */
|
||||
void clear() noexcept;
|
||||
|
||||
/** Begins a new subpath with a given starting position.
|
||||
|
||||
This will move the path's current position to the coordinates passed in and
|
||||
make it ready to draw lines or curves starting from this position.
|
||||
|
||||
After adding whatever lines and curves are needed, you can either
|
||||
close the current sub-path using closeSubPath() or call startNewSubPath()
|
||||
to move to a new sub-path, leaving the old one open-ended.
|
||||
|
||||
@see lineTo, quadraticTo, cubicTo, closeSubPath
|
||||
*/
|
||||
void startNewSubPath (float startX, float startY);
|
||||
|
||||
/** Begins a new subpath with a given starting position.
|
||||
|
||||
This will move the path's current position to the coordinates passed in and
|
||||
make it ready to draw lines or curves starting from this position.
|
||||
|
||||
After adding whatever lines and curves are needed, you can either
|
||||
close the current sub-path using closeSubPath() or call startNewSubPath()
|
||||
to move to a new sub-path, leaving the old one open-ended.
|
||||
|
||||
@see lineTo, quadraticTo, cubicTo, closeSubPath
|
||||
*/
|
||||
void startNewSubPath (Point<float> start);
|
||||
|
||||
/** Closes a the current sub-path with a line back to its start-point.
|
||||
|
||||
When creating a closed shape such as a triangle, don't use 3 lineTo()
|
||||
calls - instead use two lineTo() calls, followed by a closeSubPath()
|
||||
to join the final point back to the start.
|
||||
|
||||
This ensures that closes shapes are recognised as such, and this is
|
||||
important for tasks like drawing strokes, which needs to know whether to
|
||||
draw end-caps or not.
|
||||
|
||||
@see startNewSubPath, lineTo, quadraticTo, cubicTo, closeSubPath
|
||||
*/
|
||||
void closeSubPath();
|
||||
|
||||
/** Adds a line from the shape's last position to a new end-point.
|
||||
|
||||
This will connect the end-point of the last line or curve that was added
|
||||
to a new point, using a straight line.
|
||||
|
||||
See the class description for an example of how to add lines and curves to a path.
|
||||
|
||||
@see startNewSubPath, quadraticTo, cubicTo, closeSubPath
|
||||
*/
|
||||
void lineTo (float endX, float endY);
|
||||
|
||||
/** Adds a line from the shape's last position to a new end-point.
|
||||
|
||||
This will connect the end-point of the last line or curve that was added
|
||||
to a new point, using a straight line.
|
||||
|
||||
See the class description for an example of how to add lines and curves to a path.
|
||||
|
||||
@see startNewSubPath, quadraticTo, cubicTo, closeSubPath
|
||||
*/
|
||||
void lineTo (Point<float> end);
|
||||
|
||||
/** Adds a quadratic bezier curve from the shape's last position to a new position.
|
||||
|
||||
This will connect the end-point of the last line or curve that was added
|
||||
to a new point, using a quadratic spline with one control-point.
|
||||
|
||||
See the class description for an example of how to add lines and curves to a path.
|
||||
|
||||
@see startNewSubPath, lineTo, cubicTo, closeSubPath
|
||||
*/
|
||||
void quadraticTo (float controlPointX,
|
||||
float controlPointY,
|
||||
float endPointX,
|
||||
float endPointY);
|
||||
|
||||
/** Adds a quadratic bezier curve from the shape's last position to a new position.
|
||||
|
||||
This will connect the end-point of the last line or curve that was added
|
||||
to a new point, using a quadratic spline with one control-point.
|
||||
|
||||
See the class description for an example of how to add lines and curves to a path.
|
||||
|
||||
@see startNewSubPath, lineTo, cubicTo, closeSubPath
|
||||
*/
|
||||
void quadraticTo (Point<float> controlPoint,
|
||||
Point<float> endPoint);
|
||||
|
||||
/** Adds a cubic bezier curve from the shape's last position to a new position.
|
||||
|
||||
This will connect the end-point of the last line or curve that was added
|
||||
to a new point, using a cubic spline with two control-points.
|
||||
|
||||
See the class description for an example of how to add lines and curves to a path.
|
||||
|
||||
@see startNewSubPath, lineTo, quadraticTo, closeSubPath
|
||||
*/
|
||||
void cubicTo (float controlPoint1X,
|
||||
float controlPoint1Y,
|
||||
float controlPoint2X,
|
||||
float controlPoint2Y,
|
||||
float endPointX,
|
||||
float endPointY);
|
||||
|
||||
/** Adds a cubic bezier curve from the shape's last position to a new position.
|
||||
|
||||
This will connect the end-point of the last line or curve that was added
|
||||
to a new point, using a cubic spline with two control-points.
|
||||
|
||||
See the class description for an example of how to add lines and curves to a path.
|
||||
|
||||
@see startNewSubPath, lineTo, quadraticTo, closeSubPath
|
||||
*/
|
||||
void cubicTo (Point<float> controlPoint1,
|
||||
Point<float> controlPoint2,
|
||||
Point<float> endPoint);
|
||||
|
||||
/** Returns the last point that was added to the path by one of the drawing methods.
|
||||
*/
|
||||
Point<float> getCurrentPosition() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Adds a rectangle to the path.
|
||||
The rectangle is added as a new sub-path. (Any currently open paths will be left open).
|
||||
@see addRoundedRectangle, addTriangle
|
||||
*/
|
||||
void addRectangle (float x, float y, float width, float height);
|
||||
|
||||
/** Adds a rectangle to the path.
|
||||
The rectangle is added as a new sub-path. (Any currently open paths will be left open).
|
||||
@see addRoundedRectangle, addTriangle
|
||||
*/
|
||||
template <typename ValueType>
|
||||
void addRectangle (Rectangle<ValueType> rectangle)
|
||||
{
|
||||
addRectangle (static_cast<float> (rectangle.getX()), static_cast<float> (rectangle.getY()),
|
||||
static_cast<float> (rectangle.getWidth()), static_cast<float> (rectangle.getHeight()));
|
||||
}
|
||||
|
||||
/** Adds a rectangle with rounded corners to the path.
|
||||
The rectangle is added as a new sub-path. (Any currently open paths will be left open).
|
||||
@see addRectangle, addTriangle
|
||||
*/
|
||||
void addRoundedRectangle (float x, float y, float width, float height,
|
||||
float cornerSize);
|
||||
|
||||
/** Adds a rectangle with rounded corners to the path.
|
||||
The rectangle is added as a new sub-path. (Any currently open paths will be left open).
|
||||
@see addRectangle, addTriangle
|
||||
*/
|
||||
void addRoundedRectangle (float x, float y, float width, float height,
|
||||
float cornerSizeX,
|
||||
float cornerSizeY);
|
||||
|
||||
/** Adds a rectangle with rounded corners to the path.
|
||||
The rectangle is added as a new sub-path. (Any currently open paths will be left open).
|
||||
@see addRectangle, addTriangle
|
||||
*/
|
||||
void addRoundedRectangle (float x, float y, float width, float height,
|
||||
float cornerSizeX, float cornerSizeY,
|
||||
bool curveTopLeft, bool curveTopRight,
|
||||
bool curveBottomLeft, bool curveBottomRight);
|
||||
|
||||
/** Adds a rectangle with rounded corners to the path.
|
||||
The rectangle is added as a new sub-path. (Any currently open paths will be left open).
|
||||
@see addRectangle, addTriangle
|
||||
*/
|
||||
template <typename ValueType>
|
||||
void addRoundedRectangle (Rectangle<ValueType> rectangle, float cornerSizeX, float cornerSizeY)
|
||||
{
|
||||
addRoundedRectangle (static_cast<float> (rectangle.getX()), static_cast<float> (rectangle.getY()),
|
||||
static_cast<float> (rectangle.getWidth()), static_cast<float> (rectangle.getHeight()),
|
||||
cornerSizeX, cornerSizeY);
|
||||
}
|
||||
|
||||
/** Adds a rectangle with rounded corners to the path.
|
||||
The rectangle is added as a new sub-path. (Any currently open paths will be left open).
|
||||
@see addRectangle, addTriangle
|
||||
*/
|
||||
template <typename ValueType>
|
||||
void addRoundedRectangle (Rectangle<ValueType> rectangle, float cornerSize)
|
||||
{
|
||||
addRoundedRectangle (rectangle, cornerSize, cornerSize);
|
||||
}
|
||||
|
||||
/** Adds a triangle to the path.
|
||||
|
||||
The triangle is added as a new closed sub-path. (Any currently open paths will be left open).
|
||||
|
||||
Note that whether the vertices are specified in clockwise or anticlockwise
|
||||
order will affect how the triangle is filled when it overlaps other
|
||||
shapes (the winding order setting will affect this of course).
|
||||
*/
|
||||
void addTriangle (float x1, float y1,
|
||||
float x2, float y2,
|
||||
float x3, float y3);
|
||||
|
||||
/** Adds a triangle to the path.
|
||||
|
||||
The triangle is added as a new closed sub-path. (Any currently open paths will be left open).
|
||||
|
||||
Note that whether the vertices are specified in clockwise or anticlockwise
|
||||
order will affect how the triangle is filled when it overlaps other
|
||||
shapes (the winding order setting will affect this of course).
|
||||
*/
|
||||
void addTriangle (Point<float> point1,
|
||||
Point<float> point2,
|
||||
Point<float> point3);
|
||||
|
||||
/** Adds a quadrilateral to the path.
|
||||
|
||||
The quad is added as a new closed sub-path. (Any currently open paths will be left open).
|
||||
|
||||
Note that whether the vertices are specified in clockwise or anticlockwise
|
||||
order will affect how the quad is filled when it overlaps other
|
||||
shapes (the winding order setting will affect this of course).
|
||||
*/
|
||||
void addQuadrilateral (float x1, float y1,
|
||||
float x2, float y2,
|
||||
float x3, float y3,
|
||||
float x4, float y4);
|
||||
|
||||
/** Adds an ellipse to the path.
|
||||
The shape is added as a new sub-path. (Any currently open paths will be left open).
|
||||
@see addArc
|
||||
*/
|
||||
void addEllipse (float x, float y, float width, float height);
|
||||
|
||||
/** Adds an ellipse to the path.
|
||||
The shape is added as a new sub-path. (Any currently open paths will be left open).
|
||||
@see addArc
|
||||
*/
|
||||
void addEllipse (Rectangle<float> area);
|
||||
|
||||
/** Adds an elliptical arc to the current path.
|
||||
|
||||
Note that when specifying the start and end angles, the curve will be drawn either clockwise
|
||||
or anti-clockwise according to whether the end angle is greater than the start. This means
|
||||
that sometimes you may need to use values greater than 2*Pi for the end angle.
|
||||
|
||||
@param x the left-hand edge of the rectangle in which the elliptical outline fits
|
||||
@param y the top edge of the rectangle in which the elliptical outline fits
|
||||
@param width the width of the rectangle in which the elliptical outline fits
|
||||
@param height the height of the rectangle in which the elliptical outline fits
|
||||
@param fromRadians the angle (clockwise) in radians at which to start the arc segment (where 0 is the
|
||||
top-centre of the ellipse)
|
||||
@param toRadians the angle (clockwise) in radians at which to end the arc segment (where 0 is the
|
||||
top-centre of the ellipse). This angle can be greater than 2*Pi, so for example to
|
||||
draw a curve clockwise from the 9 o'clock position to the 3 o'clock position via
|
||||
12 o'clock, you'd use 1.5*Pi and 2.5*Pi as the start and finish points.
|
||||
@param startAsNewSubPath if true, the arc will begin a new subpath from its starting point; if false,
|
||||
it will be added to the current sub-path, continuing from the current position
|
||||
|
||||
@see addCentredArc, arcTo, addPieSegment, addEllipse
|
||||
*/
|
||||
void addArc (float x, float y, float width, float height,
|
||||
float fromRadians,
|
||||
float toRadians,
|
||||
bool startAsNewSubPath = false);
|
||||
|
||||
/** Adds an arc which is centred at a given point, and can have a rotation specified.
|
||||
|
||||
Note that when specifying the start and end angles, the curve will be drawn either clockwise
|
||||
or anti-clockwise according to whether the end angle is greater than the start. This means
|
||||
that sometimes you may need to use values greater than 2*Pi for the end angle.
|
||||
|
||||
@param centreX the centre x of the ellipse
|
||||
@param centreY the centre y of the ellipse
|
||||
@param radiusX the horizontal radius of the ellipse
|
||||
@param radiusY the vertical radius of the ellipse
|
||||
@param rotationOfEllipse an angle by which the whole ellipse should be rotated about its centre, in radians (clockwise)
|
||||
@param fromRadians the angle (clockwise) in radians at which to start the arc segment (where 0 is the
|
||||
top-centre of the ellipse)
|
||||
@param toRadians the angle (clockwise) in radians at which to end the arc segment (where 0 is the
|
||||
top-centre of the ellipse). This angle can be greater than 2*Pi, so for example to
|
||||
draw a curve clockwise from the 9 o'clock position to the 3 o'clock position via
|
||||
12 o'clock, you'd use 1.5*Pi and 2.5*Pi as the start and finish points.
|
||||
@param startAsNewSubPath if true, the arc will begin a new subpath from its starting point; if false,
|
||||
it will be added to the current sub-path, continuing from the current position
|
||||
|
||||
@see addArc, arcTo
|
||||
*/
|
||||
void addCentredArc (float centreX, float centreY,
|
||||
float radiusX, float radiusY,
|
||||
float rotationOfEllipse,
|
||||
float fromRadians,
|
||||
float toRadians,
|
||||
bool startAsNewSubPath = false);
|
||||
|
||||
/** Adds a "pie-chart" shape to the path.
|
||||
|
||||
The shape is added as a new sub-path. (Any currently open paths will be
|
||||
left open).
|
||||
|
||||
Note that when specifying the start and end angles, the curve will be drawn either clockwise
|
||||
or anti-clockwise according to whether the end angle is greater than the start. This means
|
||||
that sometimes you may need to use values greater than 2*Pi for the end angle.
|
||||
|
||||
@param x the left-hand edge of the rectangle in which the elliptical outline fits
|
||||
@param y the top edge of the rectangle in which the elliptical outline fits
|
||||
@param width the width of the rectangle in which the elliptical outline fits
|
||||
@param height the height of the rectangle in which the elliptical outline fits
|
||||
@param fromRadians the angle (clockwise) in radians at which to start the arc segment (where 0 is the
|
||||
top-centre of the ellipse)
|
||||
@param toRadians the angle (clockwise) in radians at which to end the arc segment (where 0 is the
|
||||
top-centre of the ellipse)
|
||||
@param innerCircleProportionalSize if this is > 0, then the pie will be drawn as a curved band around a hollow
|
||||
ellipse at its centre, where this value indicates the inner ellipse's size with
|
||||
respect to the outer one.
|
||||
@see addArc
|
||||
*/
|
||||
void addPieSegment (float x, float y,
|
||||
float width, float height,
|
||||
float fromRadians,
|
||||
float toRadians,
|
||||
float innerCircleProportionalSize);
|
||||
|
||||
/** Adds a "pie-chart" shape to the path.
|
||||
|
||||
The shape is added as a new sub-path. (Any currently open paths will be left open).
|
||||
|
||||
Note that when specifying the start and end angles, the curve will be drawn either clockwise
|
||||
or anti-clockwise according to whether the end angle is greater than the start. This means
|
||||
that sometimes you may need to use values greater than 2*Pi for the end angle.
|
||||
|
||||
@param segmentBounds the outer rectangle in which the elliptical outline fits
|
||||
@param fromRadians the angle (clockwise) in radians at which to start the arc segment (where 0 is the
|
||||
top-centre of the ellipse)
|
||||
@param toRadians the angle (clockwise) in radians at which to end the arc segment (where 0 is the
|
||||
top-centre of the ellipse)
|
||||
@param innerCircleProportionalSize if this is > 0, then the pie will be drawn as a curved band around a hollow
|
||||
ellipse at its centre, where this value indicates the inner ellipse's size with
|
||||
respect to the outer one.
|
||||
@see addArc
|
||||
*/
|
||||
void addPieSegment (Rectangle<float> segmentBounds,
|
||||
float fromRadians,
|
||||
float toRadians,
|
||||
float innerCircleProportionalSize);
|
||||
|
||||
/** Adds a line with a specified thickness.
|
||||
|
||||
The line is added as a new closed sub-path. (Any currently open paths will be
|
||||
left open).
|
||||
|
||||
@see addArrow
|
||||
*/
|
||||
void addLineSegment (Line<float> line, float lineThickness);
|
||||
|
||||
/** Adds a line with an arrowhead on the end.
|
||||
The arrow is added as a new closed sub-path. (Any currently open paths will be left open).
|
||||
@see PathStrokeType::createStrokeWithArrowheads
|
||||
*/
|
||||
void addArrow (Line<float> line,
|
||||
float lineThickness,
|
||||
float arrowheadWidth,
|
||||
float arrowheadLength);
|
||||
|
||||
/** Adds a polygon shape to the path.
|
||||
@see addStar
|
||||
*/
|
||||
void addPolygon (Point<float> centre,
|
||||
int numberOfSides,
|
||||
float radius,
|
||||
float startAngle = 0.0f);
|
||||
|
||||
/** Adds a star shape to the path.
|
||||
@see addPolygon
|
||||
*/
|
||||
void addStar (Point<float> centre,
|
||||
int numberOfPoints,
|
||||
float innerRadius,
|
||||
float outerRadius,
|
||||
float startAngle = 0.0f);
|
||||
|
||||
/** Adds a speech-bubble shape to the path.
|
||||
|
||||
@param bodyArea the area of the body of the bubble shape
|
||||
@param maximumArea an area which encloses the body area and defines the limits within which
|
||||
the arrow tip can be drawn - if the tip lies outside this area, the bubble
|
||||
will be drawn without an arrow
|
||||
@param arrowTipPosition the location of the tip of the arrow
|
||||
@param cornerSize the size of the rounded corners
|
||||
@param arrowBaseWidth the width of the base of the arrow where it joins the main rectangle
|
||||
*/
|
||||
void addBubble (Rectangle<float> bodyArea,
|
||||
Rectangle<float> maximumArea,
|
||||
const Point<float> arrowTipPosition,
|
||||
const float cornerSize,
|
||||
const float arrowBaseWidth);
|
||||
|
||||
/** Adds another path to this one.
|
||||
|
||||
The new path is added as a new sub-path. (Any currently open paths in this
|
||||
path will be left open).
|
||||
|
||||
@param pathToAppend the path to add
|
||||
*/
|
||||
void addPath (const Path& pathToAppend);
|
||||
|
||||
/** Adds another path to this one, transforming it on the way in.
|
||||
|
||||
The new path is added as a new sub-path, its points being transformed by the given
|
||||
matrix before being added.
|
||||
|
||||
@param pathToAppend the path to add
|
||||
@param transformToApply an optional transform to apply to the incoming vertices
|
||||
*/
|
||||
void addPath (const Path& pathToAppend,
|
||||
const AffineTransform& transformToApply);
|
||||
|
||||
/** Swaps the contents of this path with another one.
|
||||
|
||||
The internal data of the two paths is swapped over, so this is much faster than
|
||||
copying it to a temp variable and back.
|
||||
*/
|
||||
void swapWithPath (Path&) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Preallocates enough space for adding the given number of coordinates to the path.
|
||||
If you're about to add a large number of lines or curves to the path, it can make
|
||||
the task much more efficient to call this first and avoid costly reallocations
|
||||
as the structure grows.
|
||||
The actual value to pass is a bit tricky to calculate because the space required
|
||||
depends on what you're adding - e.g. each lineTo() or startNewSubPath() will
|
||||
require 3 coords (x, y and a type marker). Each quadraticTo() will need 5, and
|
||||
a cubicTo() will require 7. Closing a sub-path will require 1.
|
||||
*/
|
||||
void preallocateSpace (int numExtraCoordsToMakeSpaceFor);
|
||||
|
||||
//==============================================================================
|
||||
/** Applies a 2D transform to all the vertices in the path.
|
||||
|
||||
@see AffineTransform, scaleToFit, getTransformToScaleToFit
|
||||
*/
|
||||
void applyTransform (const AffineTransform& transform) noexcept;
|
||||
|
||||
/** Rescales this path to make it fit neatly into a given space.
|
||||
|
||||
This is effectively a quick way of calling
|
||||
applyTransform (getTransformToScaleToFit (x, y, w, h, preserveProportions))
|
||||
|
||||
@param x the x position of the rectangle to fit the path inside
|
||||
@param y the y position of the rectangle to fit the path inside
|
||||
@param width the width of the rectangle to fit the path inside
|
||||
@param height the height of the rectangle to fit the path inside
|
||||
@param preserveProportions if true, it will fit the path into the space without altering its
|
||||
horizontal/vertical scale ratio; if false, it will distort the
|
||||
path to fill the specified ratio both horizontally and vertically
|
||||
|
||||
@see applyTransform, getTransformToScaleToFit
|
||||
*/
|
||||
void scaleToFit (float x, float y, float width, float height,
|
||||
bool preserveProportions) noexcept;
|
||||
|
||||
/** Returns a transform that can be used to rescale the path to fit into a given space.
|
||||
|
||||
@param x the x position of the rectangle to fit the path inside
|
||||
@param y the y position of the rectangle to fit the path inside
|
||||
@param width the width of the rectangle to fit the path inside
|
||||
@param height the height of the rectangle to fit the path inside
|
||||
@param preserveProportions if true, it will fit the path into the space without altering its
|
||||
horizontal/vertical scale ratio; if false, it will distort the
|
||||
path to fill the specified ratio both horizontally and vertically
|
||||
@param justificationType if the proportions are preserved, the resultant path may be smaller
|
||||
than the available rectangle, so this describes how it should be
|
||||
positioned within the space.
|
||||
@returns an appropriate transformation
|
||||
|
||||
@see applyTransform, scaleToFit
|
||||
|
||||
*/
|
||||
AffineTransform getTransformToScaleToFit (float x, float y, float width, float height,
|
||||
bool preserveProportions,
|
||||
Justification justificationType = Justification::centred) const;
|
||||
|
||||
/** Returns a transform that can be used to rescale the path to fit into a given space.
|
||||
|
||||
@param area the rectangle to fit the path inside
|
||||
@param preserveProportions if true, it will fit the path into the space without altering its
|
||||
horizontal/vertical scale ratio; if false, it will distort the
|
||||
path to fill the specified ratio both horizontally and vertically
|
||||
@param justificationType if the proportions are preserved, the resultant path may be smaller
|
||||
than the available rectangle, so this describes how it should be
|
||||
positioned within the space.
|
||||
@returns an appropriate transformation
|
||||
|
||||
@see applyTransform, scaleToFit
|
||||
|
||||
*/
|
||||
AffineTransform getTransformToScaleToFit (Rectangle<float> area,
|
||||
bool preserveProportions,
|
||||
Justification justificationType = Justification::centred) const;
|
||||
|
||||
/** Creates a version of this path where all sharp corners have been replaced by curves.
|
||||
|
||||
Wherever two lines meet at an angle, this will replace the corner with a curve
|
||||
of the given radius.
|
||||
*/
|
||||
Path createPathWithRoundedCorners (float cornerRadius) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the winding-rule to be used when filling the path.
|
||||
|
||||
If set to true (which is the default), then the path uses a non-zero-winding rule
|
||||
to determine which points are inside the path. If set to false, it uses an
|
||||
alternate-winding rule.
|
||||
|
||||
The winding-rule comes into play when areas of the shape overlap other
|
||||
areas, and determines whether the overlapping regions are considered to be
|
||||
inside or outside.
|
||||
|
||||
Changing this value just sets a flag - it doesn't affect the contents of the
|
||||
path.
|
||||
|
||||
@see isUsingNonZeroWinding
|
||||
*/
|
||||
void setUsingNonZeroWinding (bool isNonZeroWinding) noexcept;
|
||||
|
||||
/** Returns the flag that indicates whether the path should use a non-zero winding rule.
|
||||
|
||||
The default for a new path is true.
|
||||
|
||||
@see setUsingNonZeroWinding
|
||||
*/
|
||||
bool isUsingNonZeroWinding() const { return useNonZeroWinding; }
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** Iterates the lines and curves that a path contains.
|
||||
|
||||
@see Path, PathFlatteningIterator
|
||||
*/
|
||||
class JUCE_API Iterator
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
Iterator (const Path& path) noexcept;
|
||||
~Iterator() noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Moves onto the next element in the path.
|
||||
|
||||
If this returns false, there are no more elements. If it returns true,
|
||||
the elementType variable will be set to the type of the current element,
|
||||
and some of the x and y variables will be filled in with values.
|
||||
*/
|
||||
bool next() noexcept;
|
||||
|
||||
//==============================================================================
|
||||
enum PathElementType
|
||||
{
|
||||
startNewSubPath, /**< For this type, x1 and y1 will be set to indicate the first point in the subpath. */
|
||||
lineTo, /**< For this type, x1 and y1 indicate the end point of the line. */
|
||||
quadraticTo, /**< For this type, x1, y1, x2, y2 indicate the control point and endpoint of a quadratic curve. */
|
||||
cubicTo, /**< For this type, x1, y1, x2, y2, x3, y3 indicate the two control points and the endpoint of a cubic curve. */
|
||||
closePath /**< Indicates that the sub-path is being closed. None of the x or y values are valid in this case. */
|
||||
};
|
||||
|
||||
PathElementType elementType;
|
||||
|
||||
float x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0;
|
||||
|
||||
//==============================================================================
|
||||
private:
|
||||
const Path& path;
|
||||
const float* index;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (Iterator)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Loads a stored path from a data stream.
|
||||
|
||||
The data in the stream must have been written using writePathToStream().
|
||||
|
||||
Note that this will append the stored path to whatever is currently in
|
||||
this path, so you might need to call clear() beforehand.
|
||||
|
||||
@see loadPathFromData, writePathToStream
|
||||
*/
|
||||
void loadPathFromStream (InputStream& source);
|
||||
|
||||
/** Loads a stored path from a block of data.
|
||||
|
||||
This is similar to loadPathFromStream(), but just reads from a block
|
||||
of data. Useful if you're including stored shapes in your code as a
|
||||
block of static data.
|
||||
|
||||
@see loadPathFromStream, writePathToStream
|
||||
*/
|
||||
void loadPathFromData (const void* data, size_t numberOfBytes);
|
||||
|
||||
/** Stores the path by writing it out to a stream.
|
||||
After writing out a path, you can reload it using loadPathFromStream().
|
||||
@see loadPathFromStream, loadPathFromData
|
||||
*/
|
||||
void writePathToStream (OutputStream& destination) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a string containing a textual representation of this path.
|
||||
@see restoreFromString
|
||||
*/
|
||||
String toString() const;
|
||||
|
||||
/** Restores this path from a string that was created with the toString() method.
|
||||
@see toString()
|
||||
*/
|
||||
void restoreFromString (StringRef stringVersion);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
friend class PathFlatteningIterator;
|
||||
friend class Path::Iterator;
|
||||
friend class EdgeTable;
|
||||
|
||||
Array<float> data;
|
||||
|
||||
struct PathBounds
|
||||
{
|
||||
PathBounds() noexcept;
|
||||
Rectangle<float> getRectangle() const noexcept;
|
||||
void reset() noexcept;
|
||||
void reset (float, float) noexcept;
|
||||
void extend (float, float) noexcept;
|
||||
|
||||
template <typename... Coords>
|
||||
void extend (float x, float y, Coords... coords) noexcept
|
||||
{
|
||||
extend (x, y);
|
||||
extend (coords...);
|
||||
}
|
||||
|
||||
float pathXMin = 0, pathXMax = 0, pathYMin = 0, pathYMax = 0;
|
||||
};
|
||||
|
||||
PathBounds bounds;
|
||||
bool useNonZeroWinding = true;
|
||||
|
||||
static const float lineMarker;
|
||||
static const float moveMarker;
|
||||
static const float quadMarker;
|
||||
static const float cubicMarker;
|
||||
static const float closeSubPathMarker;
|
||||
|
||||
JUCE_LEAK_DETECTOR (Path)
|
||||
};
|
||||
|
||||
} // namespace juce
|
Reference in New Issue
Block a user