All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.humbleui.skija.Path Maven / Gradle / Ivy

package io.github.humbleui.skija;

import java.lang.ref.*;
import org.jetbrains.annotations.*;
import io.github.humbleui.skija.impl.*;
import io.github.humbleui.types.*;

/**
 * 

Path contain geometry. Path may be empty, or contain one or more verbs that * outline a figure. Path always starts with a move verb to a Cartesian coordinate, * and may be followed by additional verbs that add lines or curves.

* *

Adding a close verb makes the geometry into a continuous loop, a closed contour. * Path may contain any number of contours, each beginning with a move verb.

* *

Path contours may contain only a move verb, or may also contain lines, * quadratic beziers, conics, and cubic beziers. Path contours may be open or * closed.

* *

When used to draw a filled area, Path describes whether the fill is inside or * outside the geometry. Path also describes the winding rule used to fill * overlapping contours.

* *

Internally, Path lazily computes metrics likes bounds and convexity. Call * {@link #updateBoundsCache()} to make Path thread safe.

*/ public class Path extends Managed implements Iterable { static { Library.staticLoad(); } @ApiStatus.Internal public static class _FinalizerHolder { public static final long PTR = _nGetFinalizer(); } /** * Constructs an empty Path. By default, Path has no verbs, no {@link Point}, and no weights. * FillMode is set to {@link PathFillMode#WINDING}. */ public Path() { this(_nMake()); Stats.onNativeCall(); } @NotNull public static Path makeFromSVGString(String svg) { long res = _nMakeFromSVGString(svg); if (res == 0) throw new IllegalArgumentException("Failed to parse SVG Path string: " + svg); else return new Path(res); } /** * Compares this path and o; Returns true if {@link PathFillMode}, verb array, Point array, and weights * are equivalent. * * @param other Path to compare * @return true if this and Path are equivalent */ @ApiStatus.Internal @Override public boolean _nativeEquals(Native other) { try { return _nEquals(_ptr, Native.getPtr(other)); } finally { Reference.reachabilityFence(this); Reference.reachabilityFence(other); } } /** *

Returns true if Path contain equal verbs and equal weights. * If Path contain one or more conics, the weights must match.

* *

{@link #conicTo(float, float, float, float, float)} may add different verbs * depending on conic weight, so it is not trivial to interpolate a pair of Path * containing conics with different conic weight values.

* * @param compare Path to compare * @return true if Path verb array and weights are equivalent * * @see https://fiddle.skia.org/c/@Path_isInterpolatable */ public boolean isInterpolatable(Path compare) { try { Stats.onNativeCall(); return _nIsInterpolatable(_ptr, Native.getPtr(compare)); } finally { Reference.reachabilityFence(this); Reference.reachabilityFence(compare); } } /** *

Interpolates between Path with {@link Point} array of equal size. * Copy verb array and weights to out, and set out Point array to a weighted * average of this Point array and ending Point array, using the formula: * *

{@code (Path Point * weight) + ending Point * (1 - weight)} * *

weight is most useful when between zero (ending Point array) and * one (this Point_Array); will work with values outside of this * range.

* *

interpolate() returns null if Point array is not * the same size as ending Point array. Call {@link #isInterpolatable(Path)} to check Path * compatibility prior to calling interpolate().

* * @param ending Point array averaged with this Point array * @param weight contribution of this Point array, and * one minus contribution of ending Point array * @return interpolated Path if Path contain same number of Point, null otherwise * * @see https://fiddle.skia.org/c/@Path_interpolate */ public Path makeLerp(Path ending, float weight) { try { Stats.onNativeCall(); long ptr = _nMakeLerp(_ptr, Native.getPtr(ending), weight); if (ptr == 0) throw new IllegalArgumentException("Point array is not the same size as ending Point array"); return new Path(ptr); } finally { Reference.reachabilityFence(this); Reference.reachabilityFence(ending); } } public PathFillMode getFillMode() { try { Stats.onNativeCall(); return PathFillMode._values[_nGetFillMode(_ptr)]; } finally { Reference.reachabilityFence(this); } } public Path setFillMode(PathFillMode fillMode) { Stats.onNativeCall(); _nSetFillMode(_ptr, fillMode.ordinal()); return this; } /** * Returns true if the path is convex. If necessary, it will first compute the convexity. * * @return true or false */ public boolean isConvex() { try { Stats.onNativeCall(); return _nIsConvex(_ptr); } finally { Reference.reachabilityFence(this); } } /** * Returns oval bounds if this path is recognized as an oval or circle. * * @return bounds is recognized as an oval or circle, null otherwise * * @see https://fiddle.skia.org/c/@Path_isOval */ public Rect isOval() { try { Stats.onNativeCall(); return _nIsOval(_ptr); } finally { Reference.reachabilityFence(this); } } /** * Returns {@link RRect} if this path is recognized as an oval, circle or RRect. * * @return bounds is recognized as an oval, circle or RRect, null otherwise * * @see https://fiddle.skia.org/c/@Path_isRRect */ public RRect isRRect() { try { Stats.onNativeCall(); return _nIsRRect(_ptr); } finally { Reference.reachabilityFence(this); } } /** *

Sets Path to its initial state.

* *

Removes verb array, Point array, and weights, and sets FillMode to {@link PathFillMode#WINDING}. * Internal storage associated with Path is released.

* * @return this * * @see https://fiddle.skia.org/c/@Path_reset */ public Path reset() { Stats.onNativeCall(); _nReset(_ptr); return this; } /** *

Sets Path to its initial state, preserving internal storage. * Removes verb array, Point array, and weights, and sets FillMode to kWinding. * Internal storage associated with Path is retained.

* *

Use {@link #rewind()} instead of {@link #reset()} if Path storage will be reused and performance * is critical.

* * @return this * * @see https://fiddle.skia.org/c/@Path_rewind */ public Path rewind() { Stats.onNativeCall(); _nRewind(_ptr); return this; } /** *

Returns if Path is empty.

* *

Empty Path may have FillMode but has no {@link Point}, {@link PathVerb}, or conic weight. * {@link Path()} constructs empty Path; {@link #reset()} and {@link #rewind()} make Path empty.

* * @return true if the path contains no Verb array */ public boolean isEmpty() { try { Stats.onNativeCall(); return _nIsEmpty(_ptr); } finally { Reference.reachabilityFence(this); } } /** *

Returns if contour is closed.

* *

Contour is closed if Path Verb array was last modified by {@link #closePath()}. When stroked, * closed contour draws {@link PaintStrokeJoin} instead of {@link PaintStrokeCap} at first and last Point.

* * @return true if the last contour ends with a {@link PathVerb#CLOSE} * * @see https://fiddle.skia.org/c/@Path_isLastContourClosed */ public boolean isLastContourClosed() { try { Stats.onNativeCall(); return _nIsLastContourClosed(_ptr); } finally { Reference.reachabilityFence(this); } } /** * Returns true for finite Point array values between negative Float.MIN_VALUE and * positive Float.MAX_VALUE. Returns false for any Point array value of * Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, or Float.NaN. * * @return true if all Point values are finite */ public boolean isFinite() { try { Stats.onNativeCall(); return _nIsFinite(_ptr); } finally { Reference.reachabilityFence(this); } } /** * Returns true if the path is volatile; it will not be altered or discarded * by the caller after it is drawn. Path by default have volatile set false, allowing * {@link Surface} to attach a cache of data which speeds repeated drawing. If true, {@link Surface} * may not speed repeated drawing. * * @return true if caller will alter Path after drawing */ public boolean isVolatile() { try { Stats.onNativeCall(); return _nIsVolatile(_ptr); } finally { Reference.reachabilityFence(this); } } /** *

Specifies whether Path is volatile; whether it will be altered or discarded * by the caller after it is drawn. Path by default have volatile set false, allowing * SkBaseDevice to attach a cache of data which speeds repeated drawing.

* *

Mark temporary paths, discarded or modified after use, as volatile * to inform SkBaseDevice that the path need not be cached.

* *

Mark animating Path volatile to improve performance. * Mark unchanging Path non-volatile to improve repeated rendering.

* *

raster surface Path draws are affected by volatile for some shadows. * GPU surface Path draws are affected by volatile for some shadows and concave geometries.

* * @param isVolatile true if caller will alter Path after drawing * @return this */ public Path setVolatile(boolean isVolatile) { Stats.onNativeCall(); _nSetVolatile(_ptr, isVolatile); return this; } /** *

Tests if line between Point pair is degenerate.

* *

Line with no length or that moves a very short distance is degenerate; it is * treated as a point.

* *

exact changes the equality test. If true, returns true only if p1 equals p2. * If false, returns true if p1 equals or nearly equals p2.

* * @param p1 line start point * @param p2 line end point * @param exact if false, allow nearly equals * @return true if line is degenerate; its length is effectively zero * * @see https://fiddle.skia.org/c/@Path_IsLineDegenerate */ public static boolean isLineDegenerate(Point p1, Point p2, boolean exact) { Stats.onNativeCall(); return _nIsLineDegenerate(p1._x, p1._y, p2._x, p2._y, exact); } /** *

Tests if quad is degenerate.

* *

Quad with no length or that moves a very short distance is degenerate; it is * treated as a point.

* * @param p1 quad start point * @param p2 quad control point * @param p3 quad end point * @param exact if true, returns true only if p1, p2, and p3 are equal; * if false, returns true if p1, p2, and p3 are equal or nearly equal * @return true if quad is degenerate; its length is effectively zero */ public static boolean isQuadDegenerate(Point p1, Point p2, Point p3, boolean exact) { Stats.onNativeCall(); return _nIsQuadDegenerate(p1._x, p1._y, p2._x, p2._y, p3._x, p3._y, exact); } /** *

Tests if cubic is degenerate.

* *

Cubic with no length or that moves a very short distance is degenerate; it is * treated as a point.

* * @param p1 cubic start point * @param p2 cubic control point 1 * @param p3 cubic control point 2 * @param p4 cubic end point * @param exact if true, returns true only if p1, p2, p3, and p4 are equal; * if false, returns true if p1, p2, p3, and p4 are equal or nearly equal * @return true if cubic is degenerate; its length is effectively zero */ public static boolean isCubicDegenerate(Point p1, Point p2, Point p3, Point p4, boolean exact) { Stats.onNativeCall(); return _nIsCubicDegenerate(p1._x, p1._y, p2._x, p2._y, p3._x, p3._y, p4._x, p4._y, exact); } /** * Returns array of two points if Path contains only one line; * Verb array has two entries: {@link PathVerb#MOVE}, {@link PathVerb#LINE}. * Returns null if Path is not one line. * * @return Point[2] if Path contains exactly one line, null otherwise * * @see https://fiddle.skia.org/c/@Path_isLine */ public Point[] getAsLine() { try { Stats.onNativeCall(); return _nMaybeGetAsLine(_ptr); } finally { Reference.reachabilityFence(this); } } /** * Returns the number of points in Path. * Point count is initially zero. * * @return Path Point array length * * @see https://fiddle.skia.org/c/@Path_countPoints */ public int getPointsCount() { try { Stats.onNativeCall(); return _nGetPointsCount(_ptr); } finally { Reference.reachabilityFence(this); } } /** *

Returns Point at index in Point array. Valid range for index is * 0 to countPoints() - 1.

* *

Returns (0, 0) if index is out of range.

* * @param index Point array element selector * @return Point array value or (0, 0) * * @see https://fiddle.skia.org/c/@Path_getPoint */ public Point getPoint(int index) { try { Stats.onNativeCall(); return _nGetPoint(_ptr, index); } finally { Reference.reachabilityFence(this); } } /** *

Returns all points in Path.

* * @return Path Point array length * * @see https://fiddle.skia.org/c/@Path_getPoints */ public Point[] getPoints() { Point[] res = new Point[getPointsCount()]; getPoints(res, res.length); return res; } /** *

Returns number of points in Path. Up to max points are copied.

* *

points may be null; then, max must be zero. * If max is greater than number of points, excess points storage is unaltered.

* * @param points storage for Path Point array. May be null * @param max maximum to copy; must be greater than or equal to zero * @return Path Point array length * * @see https://fiddle.skia.org/c/@Path_getPoints */ public int getPoints(Point[] points, int max) { try { assert points == null ? max == 0 : true; Stats.onNativeCall(); return _nGetPoints(_ptr, points, max); } finally { Reference.reachabilityFence(this); } } /** * Returns the number of verbs: {@link PathVerb#MOVE}, {@link PathVerb#LINE}, {@link PathVerb#QUAD}, {@link PathVerb#CONIC}, * {@link PathVerb#CUBIC}, and {@link PathVerb#CLOSE}; added to Path. * * @return length of verb array * * @see https://fiddle.skia.org/c/@Path_countVerbs */ public int getVerbsCount() { try { Stats.onNativeCall(); return _nCountVerbs(_ptr); } finally { Reference.reachabilityFence(this); } } public PathVerb[] getVerbs() { PathVerb[] res = new PathVerb[getVerbsCount()]; getVerbs(res, res.length); return res; } /** * Returns the number of verbs in the path. Up to max verbs are copied. * * @param verbs storage for verbs, may be null * @param max maximum number to copy into verbs * @return the actual number of verbs in the path * * @see https://fiddle.skia.org/c/@Path_getVerbs */ public int getVerbs(PathVerb[] verbs, int max) { try { assert verbs == null ? max == 0 : true; Stats.onNativeCall(); byte[] out = verbs == null ? null : new byte[max]; int count = _nGetVerbs(_ptr, out, max); if (verbs != null) for (int i = 0; i < Math.min(count, max); ++i) verbs[i] = PathVerb._values[out[i]]; return count; } finally { Reference.reachabilityFence(this); } } /** * Returns the approximate byte size of the Path in memory. * * @return approximate size */ public long getApproximateBytesUsed() { try { Stats.onNativeCall(); return _nApproximateBytesUsed(_ptr); } finally { Reference.reachabilityFence(this); } } /** *

Exchanges the verb array, Point array, weights, and FillMode with other. * Cached state is also exchanged. swap() internally exchanges pointers, so * it is lightweight and does not allocate memory.

* * @param other Path exchanged by value * @return this * * @see https://fiddle.skia.org/c/@Path_swap */ public Path swap(Path other) { try { Stats.onNativeCall(); _nSwap(_ptr, Native.getPtr(other)); return this; } finally { Reference.reachabilityFence(other); } } /** *

Returns minimum and maximum axes values of Point array.

* *

Returns (0, 0, 0, 0) if Path contains no points. Returned bounds width and height may * be larger or smaller than area affected when Path is drawn.

* *

Rect returned includes all Point added to Path, including Point associated with * {@link PathVerb#MOVE} that define empty contours.

* * @return bounds of all Point in Point array */ public Rect getBounds() { try { Stats.onNativeCall(); return _nGetBounds(_ptr); } finally { Reference.reachabilityFence(this); } } /** *

Updates internal bounds so that subsequent calls to {@link #getBounds()} are instantaneous. * Unaltered copies of Path may also access cached bounds through {@link #getBounds()}.

* *

For now, identical to calling {@link #getBounds()} and ignoring the returned value.

* *

Call to prepare Path subsequently drawn from multiple threads, * to avoid a race condition where each draw separately computes the bounds.

* * @return this */ public Path updateBoundsCache() { Stats.onNativeCall(); _nUpdateBoundsCache(_ptr); return this; } /** *

Returns minimum and maximum axes values of the lines and curves in Path. * Returns (0, 0, 0, 0) if Path contains no points. * Returned bounds width and height may be larger or smaller than area affected * when Path is drawn.

* *

Includes Point associated with {@link PathVerb#MOVE} that define empty * contours.

* * Behaves identically to {@link #getBounds()} when Path contains * only lines. If Path contains curves, computed bounds includes * the maximum extent of the quad, conic, or cubic; is slower than {@link #getBounds()}; * and unlike {@link #getBounds()}, does not cache the result. * * @return tight bounds of curves in Path * * @see https://fiddle.skia.org/c/@Path_computeTightBounds */ public Rect computeTightBounds() { try { Stats.onNativeCall(); return _nComputeTightBounds(_ptr); } finally { Reference.reachabilityFence(this); } } /** *

Returns true if rect is contained by Path. * May return false when rect is contained by Path.

* *

For now, only returns true if Path has one contour and is convex. * rect may share points and edges with Path and be contained. * Returns true if rect is empty, that is, it has zero width or height; and * the Point or line described by rect is contained by Path.

* * @param rect Rect, line, or Point checked for containment * @return true if rect is contained * * @see https://fiddle.skia.org/c/@Path_conservativelyContainsRect */ public boolean conservativelyContainsRect(Rect rect) { try { Stats.onNativeCall(); return _nConservativelyContainsRect(_ptr, rect._left, rect._top, rect._right, rect._bottom); } finally { Reference.reachabilityFence(this); } } /** *

Grows Path verb array and Point array to contain extraPtCount additional Point. * May improve performance and use less memory by * reducing the number and size of allocations when creating Path.

* * @param extraPtCount number of additional Point to allocate * @return this * * @see https://fiddle.skia.org/c/@Path_incReserve */ public Path incReserve(int extraPtCount) { Stats.onNativeCall(); _nIncReserve(_ptr, extraPtCount); return this; } /** * Adds beginning of contour at Point (x, y). * * @param x x-axis value of contour start * @param y y-axis value of contour start * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_moveTo */ public Path moveTo(float x, float y) { Stats.onNativeCall(); _nMoveTo(_ptr, x, y); return this; } /** * Adds beginning of contour at Point p. * * @param p contour start * @return this */ public Path moveTo(Point p) { return moveTo(p._x, p._y); } /** *

Adds beginning of contour relative to last point.

* *

If Path is empty, starts contour at (dx, dy). * Otherwise, start contour at last point offset by (dx, dy). * Function name stands for "relative move to".

* * @param dx offset from last point to contour start on x-axis * @param dy offset from last point to contour start on y-axis * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_rMoveTo */ public Path rMoveTo(float dx, float dy) { Stats.onNativeCall(); _nRMoveTo(_ptr, dx, dy); return this; } /** *

Adds line from last point to (x, y). If Path is empty, or last Verb is * {@link PathVerb#CLOSE}, last point is set to (0, 0) before adding line.

* *

lineTo() appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, if needed. * lineTo() then appends {@link PathVerb#LINE} to verb array and (x, y) to Point array.

* * @param x end of added line on x-axis * @param y end of added line on y-axis * @return this * * @see https://fiddle.skia.org/c/@Path_lineTo */ public Path lineTo(float x, float y) { Stats.onNativeCall(); _nLineTo(_ptr, x, y); return this; } /** *

Adds line from last point to Point p. If Path is empty, or last {@link PathVerb} is * {@link PathVerb#CLOSE}, last point is set to (0, 0) before adding line.

* *

lineTo() first appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, if needed. * lineTo() then appends {@link PathVerb#LINE} to verb array and Point p to Point array.

* * @param p end Point of added line * @return reference to Path */ public Path lineTo(Point p) { return lineTo(p._x, p._y); } /** *

Adds line from last point to vector (dx, dy). If Path is empty, or last {@link PathVerb} is * {@link PathVerb#CLOSE}, last point is set to (0, 0) before adding line.

* *

Appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, if needed; * then appends {@link PathVerb#LINE} to verb array and line end to Point array.

* *

Line end is last point plus vector (dx, dy).

* *

Function name stands for "relative line to".

* * @param dx offset from last point to line end on x-axis * @param dy offset from last point to line end on y-axis * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_rLineTo * @see https://fiddle.skia.org/c/@Quad_a * @see https://fiddle.skia.org/c/@Quad_b */ public Path rLineTo(float dx, float dy) { Stats.onNativeCall(); _nRLineTo(_ptr, dx, dy); return this; } /** * Adds quad from last point towards (x1, y1), to (x2, y2). * If Path is empty, or last {@link PathVerb} is {@link PathVerb#CLOSE}, last point is set to (0, 0) * before adding quad. * * Appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, if needed; * then appends {@link PathVerb#QUAD} to verb array; and (x1, y1), (x2, y2) * to Point array. * * @param x1 control Point of quad on x-axis * @param y1 control Point of quad on y-axis * @param x2 end Point of quad on x-axis * @param y2 end Point of quad on y-axis * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_quadTo */ public Path quadTo(float x1, float y1, float x2, float y2) { Stats.onNativeCall(); _nQuadTo(_ptr, x1, y1, x2, y2); return this; } /** *

Adds quad from last point towards Point p1, to Point p2.

* *

If Path is empty, or last {@link PathVerb} is {@link PathVerb#CLOSE}, last point is set to (0, 0) * before adding quad.

* *

Appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, if needed; * then appends {@link PathVerb#QUAD} to verb array; and Point p1, p2 * to Point array.

* * @param p1 control Point of added quad * @param p2 end Point of added quad * @return reference to Path */ public Path quadTo(Point p1, Point p2) { return quadTo(p1._x, p1._y, p2._x, p2._y); } /** *

Adds quad from last point towards vector (dx1, dy1), to vector (dx2, dy2). * If Path is empty, or last {@link PathVerb} * is {@link PathVerb#CLOSE}, last point is set to (0, 0) before adding quad.

* *

Appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, * if needed; then appends {@link PathVerb#QUAD} to verb array; and appends quad * control and quad end to Point array.

* *

Quad control is last point plus vector (dx1, dy1).

* *

Quad end is last point plus vector (dx2, dy2).

* *

Function name stands for "relative quad to".

* * @param dx1 offset from last point to quad control on x-axis * @param dy1 offset from last point to quad control on y-axis * @param dx2 offset from last point to quad end on x-axis * @param dy2 offset from last point to quad end on y-axis * @return reference to Path * * @see https://fiddle.skia.org/c/@Conic_Weight_a * @see https://fiddle.skia.org/c/@Conic_Weight_b * @see https://fiddle.skia.org/c/@Conic_Weight_c * @see https://fiddle.skia.org/c/@Path_rQuadTo */ public Path rQuadTo(float dx1, float dy1, float dx2, float dy2) { Stats.onNativeCall(); _nRQuadTo(_ptr, dx1, dy1, dx2, dy2); return this; } /** *

Adds conic from last point towards (x1, y1), to (x2, y2), weighted by w.

* *

If Path is empty, or last {@link PathVerb} is {@link PathVerb#CLOSE}, last point is set to (0, 0) * before adding conic.

* *

Appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, if needed.

* *

If w is finite and not one, appends {@link PathVerb#CONIC} to verb array; * and (x1, y1), (x2, y2) to Point array; and w to conic weights.

* *

If w is one, appends {@link PathVerb#QUAD} to verb array, and * (x1, y1), (x2, y2) to Point array.

* *

If w is not finite, appends {@link PathVerb#LINE} twice to verb array, and * (x1, y1), (x2, y2) to Point array.

* * @param x1 control Point of conic on x-axis * @param y1 control Point of conic on y-axis * @param x2 end Point of conic on x-axis * @param y2 end Point of conic on y-axis * @param w weight of added conic * @return reference to Path */ public Path conicTo(float x1, float y1, float x2, float y2, float w) { Stats.onNativeCall(); _nConicTo(_ptr, x1, y1, x2, y2, w); return this; } /** *

Adds conic from last point towards Point p1, to Point p2, weighted by w.

* *

If Path is empty, or last {@link PathVerb} is {@link PathVerb#CLOSE}, last point is set to (0, 0) * before adding conic.

* *

Appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, if needed.

* *

If w is finite and not one, appends {@link PathVerb#CONIC} to verb array; * and Point p1, p2 to Point array; and w to conic weights.

* *

If w is one, appends {@link PathVerb#QUAD} to verb array, and Point p1, p2 * to Point array.

* *

If w is not finite, appends {@link PathVerb#LINE} twice to verb array, and * Point p1, p2 to Point array.

* * @param p1 control Point of added conic * @param p2 end Point of added conic * @param w weight of added conic * @return reference to Path */ public Path conicTo(Point p1, Point p2, float w) { return conicTo(p1._x, p1._y, p2._x, p2._y, w); } /** *

Adds conic from last point towards vector (dx1, dy1), to vector (dx2, dy2), * weighted by w. If Path is empty, or last {@link PathVerb} * is {@link PathVerb#CLOSE}, last point is set to (0, 0) before adding conic.

* *

Appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, * if needed.

* *

If w is finite and not one, next appends {@link PathVerb#CONIC} to verb array, * and w is recorded as conic weight; otherwise, if w is one, appends * {@link PathVerb#QUAD} to verb array; or if w is not finite, appends {@link PathVerb#LINE} * twice to verb array.

* *

In all cases appends Point control and end to Point array. * control is last point plus vector (dx1, dy1). * end is last point plus vector (dx2, dy2).

* *

Function name stands for "relative conic to".

* * @param dx1 offset from last point to conic control on x-axis * @param dy1 offset from last point to conic control on y-axis * @param dx2 offset from last point to conic end on x-axis * @param dy2 offset from last point to conic end on y-axis * @param w weight of added conic * @return reference to Path */ public Path rConicTo(float dx1, float dy1, float dx2, float dy2, float w) { Stats.onNativeCall(); _nRConicTo(_ptr, dx1, dy1, dx2, dy2, w); return this; } /** *

Adds cubic from last point towards (x1, y1), then towards (x2, y2), ending at * (x3, y3). If Path is empty, or last {@link PathVerb} is {@link PathVerb#CLOSE}, last point is set to * (0, 0) before adding cubic.

* *

Appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, if needed; * then appends {@link PathVerb#CUBIC} to verb array; and (x1, y1), (x2, y2), (x3, y3) * to Point array.

* * @param x1 first control Point of cubic on x-axis * @param y1 first control Point of cubic on y-axis * @param x2 second control Point of cubic on x-axis * @param y2 second control Point of cubic on y-axis * @param x3 end Point of cubic on x-axis * @param y3 end Point of cubic on y-axis * @return reference to Path */ public Path cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) { Stats.onNativeCall(); _nCubicTo(_ptr, x1, y1, x2, y2, x3, y3); return this; } /** *

Adds cubic from last point towards Point p1, then towards Point p2, ending at * Point p3. If Path is empty, or last {@link PathVerb} is {@link PathVerb#CLOSE}, last point is set to * (0, 0) before adding cubic.

* *

Appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, if needed; * then appends {@link PathVerb#CUBIC} to verb array; and Point p1, p2, p3 * to Point array.

* * @param p1 first control Point of cubic * @param p2 second control Point of cubic * @param p3 end Point of cubic * @return reference to Path */ public Path cubicTo(Point p1, Point p2, Point p3) { return cubicTo(p1._x, p1._y, p2._x, p2._y, p3._x, p3._y); } /** *

Adds cubic from last point towards vector (dx1, dy1), then towards * vector (dx2, dy2), to vector (dx3, dy3). * If Path is empty, or last {@link PathVerb} * is {@link PathVerb#CLOSE}, last point is set to (0, 0) before adding cubic.

* *

Appends {@link PathVerb#MOVE} to verb array and (0, 0) to Point array, * if needed; then appends {@link PathVerb#CUBIC} to verb array; and appends cubic * control and cubic end to Point array.

* *

Cubic control is last point plus vector (dx1, dy1).

* *

Cubic end is last point plus vector (dx2, dy2).

* *

Function name stands for "relative cubic to".

* * @param dx1 offset from last point to first cubic control on x-axis * @param dy1 offset from last point to first cubic control on y-axis * @param dx2 offset from last point to second cubic control on x-axis * @param dy2 offset from last point to second cubic control on y-axis * @param dx3 offset from last point to cubic end on x-axis * @param dy3 offset from last point to cubic end on y-axis * @return reference to Path */ public Path rCubicTo(float dx1, float dy1, float dx2, float dy2, float dx3, float dy3) { Stats.onNativeCall(); _nRCubicTo(_ptr, dx1, dy1, dx2, dy2, dx3, dy3); return this; } /** *

Appends arc to Path. Arc added is part of ellipse * bounded by oval, from startAngle through sweepAngle. Both startAngle and * sweepAngle are measured in degrees, where zero degrees is aligned with the * positive x-axis, and positive sweeps extends arc clockwise.

* *

arcTo() adds line connecting Path last Point to initial arc Point if forceMoveTo * is false and Path is not empty. Otherwise, added contour begins with first point * of arc. Angles greater than -360 and less than 360 are treated modulo 360.

* * @param oval bounds of ellipse containing arc * @param startAngle starting angle of arc in degrees * @param sweepAngle sweep, in degrees. Positive is clockwise; treated modulo 360 * @param forceMoveTo true to start a new contour with arc * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_arcTo */ public Path arcTo(Rect oval, float startAngle, float sweepAngle, boolean forceMoveTo) { Stats.onNativeCall(); _nArcTo(_ptr, oval._left, oval._top, oval._right, oval._bottom, startAngle, sweepAngle, forceMoveTo); return this; } /** *

Appends arc to Path, after appending line if needed. Arc is implemented by conic * weighted to describe part of circle. Arc is contained by tangent from * last Path point to (x1, y1), and tangent from (x1, y1) to (x2, y2). Arc * is part of circle sized to radius, positioned so it touches both tangent lines.

* *

If last Path Point does not start Arc, tangentArcTo appends connecting Line to Path. * The length of Vector from (x1, y1) to (x2, y2) does not affect Arc.

* *

Arc sweep is always less than 180 degrees. If radius is zero, or if * tangents are nearly parallel, tangentArcTo appends Line from last Path Point to (x1, y1).

* *

tangentArcTo appends at most one Line and one conic.

* *

tangentArcTo implements the functionality of PostScript arct and HTML Canvas tangentArcTo.

* * @param x1 x-axis value common to pair of tangents * @param y1 y-axis value common to pair of tangents * @param x2 x-axis value end of second tangent * @param y2 y-axis value end of second tangent * @param radius distance from arc to circle center * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_arcTo_2_a * @see https://fiddle.skia.org/c/@Path_arcTo_2_b * @see https://fiddle.skia.org/c/@Path_arcTo_2_c */ public Path tangentArcTo(float x1, float y1, float x2, float y2, float radius) { Stats.onNativeCall(); _nTangentArcTo(_ptr, x1, y1, x2, y2, radius); return this; } /** *

Appends arc to Path, after appending line if needed. Arc is implemented by conic * weighted to describe part of circle. Arc is contained by tangent from * last Path point to p1, and tangent from p1 to p2. Arc * is part of circle sized to radius, positioned so it touches both tangent lines.

* *

If last Path Point does not start arc, tangentArcTo() appends connecting line to Path. * The length of vector from p1 to p2 does not affect arc.

* *

Arc sweep is always less than 180 degrees. If radius is zero, or if * tangents are nearly parallel, tangentArcTo() appends line from last Path Point to p1.

* *

tangentArcTo() appends at most one line and one conic.

* *

tangentArcTo() implements the functionality of PostScript arct and HTML Canvas tangentArcTo.

* * @param p1 Point common to pair of tangents * @param p2 end of second tangent * @param radius distance from arc to circle center * @return reference to Path */ public Path tangentArcTo(Point p1, Point p2, float radius) { return tangentArcTo(p1._x, p1._y, p2._x, p2._y, radius); } /**

Appends arc to Path. Arc is implemented by one or more conics weighted to * describe part of oval with radii (rx, ry) rotated by xAxisRotate degrees. Arc * curves from last Path Point to (x, y), choosing one of four possible routes: * clockwise or counterclockwise, and smaller or larger.

* *

Arc sweep is always less than 360 degrees. ellipticalArcTo() appends line to (x, y) if * either radii are zero, or if last Path Point equals (x, y). ellipticalArcTo() scales radii * (rx, ry) to fit last Path Point and (x, y) if both are greater than zero but * too small.

* *

ellipticalArcTo() appends up to four conic curves.

* *

ellipticalArcTo() implements the functionality of SVG arc, although SVG sweep-flag value * is opposite the integer value of sweep; SVG sweep-flag uses 1 for clockwise, * while {@link PathDirection#CLOCKWISE} cast to int is zero.

* * @param rx radius on x-axis before x-axis rotation * @param ry radius on y-axis before x-axis rotation * @param xAxisRotate x-axis rotation in degrees; positive values are clockwise * @param arc chooses smaller or larger arc * @param direction chooses clockwise or counterclockwise arc * @param x end of arc * @param y end of arc * @return reference to Path */ public Path ellipticalArcTo(float rx, float ry, float xAxisRotate, PathEllipseArc arc, PathDirection direction, float x, float y) { Stats.onNativeCall(); _nEllipticalArcTo(_ptr, rx, ry, xAxisRotate, arc.ordinal(), direction.ordinal(), x, y); return this; } /** *

Appends arc to Path. Arc is implemented by one or more conic weighted to describe * part of oval with radii (r.fX, r.fY) rotated by xAxisRotate degrees. Arc curves * from last Path Point to (xy.fX, xy.fY), choosing one of four possible routes: * clockwise or counterclockwise, and smaller or larger.

* *

Arc sweep is always less than 360 degrees. ellipticalArcTo() appends line to xy if either * radii are zero, or if last Path Point equals (xy.fX, xy.fY). ellipticalArcTo() scales radii r to * fit last Path Point and xy if both are greater than zero but too small to describe * an arc.

* *

ellipticalArcTo() appends up to four conic curves.

* *

ellipticalArcTo() implements the functionality of SVG arc, although SVG sweep-flag value is * opposite the integer value of sweep; SVG sweep-flag uses 1 for clockwise, while * {@link PathDirection#CLOCKWISE} cast to int is zero.

* * @param r radii on axes before x-axis rotation * @param xAxisRotate x-axis rotation in degrees; positive values are clockwise * @param arc chooses smaller or larger arc * @param direction chooses clockwise or counterclockwise arc * @param xy end of arc * @return reference to Path */ public Path ellipticalArcTo(Point r, float xAxisRotate, PathEllipseArc arc, PathDirection direction, Point xy) { return ellipticalArcTo(r._x, r._y, xAxisRotate, arc, direction, xy._x, xy._y); } /** *

Appends arc to Path, relative to last Path Point. Arc is implemented by one or * more conic, weighted to describe part of oval with radii (rx, ry) rotated by * xAxisRotate degrees. Arc curves from last Path Point to relative end Point: * (dx, dy), choosing one of four possible routes: clockwise or * counterclockwise, and smaller or larger. If Path is empty, the start arc Point * is (0, 0).

* *

Arc sweep is always less than 360 degrees. rEllipticalArcTo() appends line to end Point * if either radii are zero, or if last Path Point equals end Point. * rEllipticalArcTo() scales radii (rx, ry) to fit last Path Point and end Point if both are * greater than zero but too small to describe an arc.

* *

rEllipticalArcTo() appends up to four conic curves.

* *

rEllipticalArcTo() implements the functionality of svg arc, although SVG "sweep-flag" value is * opposite the integer value of sweep; SVG "sweep-flag" uses 1 for clockwise, while * {@link PathDirection#CLOCKWISE} cast to int is zero.

* * @param rx radius before x-axis rotation * @param ry radius before x-axis rotation * @param xAxisRotate x-axis rotation in degrees; positive values are clockwise * @param arc chooses smaller or larger arc * @param direction chooses clockwise or counterclockwise arc * @param dx x-axis offset end of arc from last Path Point * @param dy y-axis offset end of arc from last Path Point * @return reference to Path */ public Path rEllipticalArcTo(float rx, float ry, float xAxisRotate, PathEllipseArc arc, PathDirection direction, float dx, float dy) { Stats.onNativeCall(); _nREllipticalArcTo(_ptr, rx, ry, xAxisRotate, arc.ordinal(), direction.ordinal(), dx, dy); return this; } /** *

Appends {@link PathVerb#CLOSE} to Path. A closed contour connects the first and last Point * with line, forming a continuous loop. Open and closed contour draw the same * with {@link PaintMode#FILL}. With {@link PaintMode#STROKE}, open contour draws * {@link PaintStrokeCap} at contour start and end; closed contour draws * {@link PaintStrokeJoin} at contour start and end.

* *

closePath() has no effect if Path is empty or last Path {@link PathVerb} is {@link PathVerb#CLOSE}.

* * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_close */ public Path closePath() { Stats.onNativeCall(); _nClosePath(_ptr); return this; } /** *

Approximates conic with quad array. Conic is constructed from start Point p0, * control Point p1, end Point p2, and weight w.

* *

Quad array is stored in pts; this storage is supplied by caller.

* *

Maximum quad count is 2 to the pow2.

* *

Every third point in array shares last Point of previous quad and first Point of * next quad. Maximum pts storage size is given by: {@code (1 + 2 * (1 << pow2)).

}

* *

Returns quad count used the approximation, which may be smaller * than the number requested.

* *

conic weight determines the amount of influence conic control point has on the curve.

* *

w less than one represents an elliptical section. w greater than one represents * a hyperbolic section. w equal to one represents a parabolic section.

* *

Two quad curves are sufficient to approximate an elliptical conic with a sweep * of up to 90 degrees; in this case, set pow2 to one.

* * @param p0 conic start Point * @param p1 conic control Point * @param p2 conic end Point * @param w conic weight * @param pow2 quad count, as power of two, normally 0 to 5 (1 to 32 quad curves) * @return number of quad curves written to pts */ public static Point[] convertConicToQuads(Point p0, Point p1, Point p2, float w, int pow2) { Stats.onNativeCall(); return _nConvertConicToQuads(p0._x, p0._y, p1._x, p1._y, p2._x, p2._y, w, pow2); } /** *

Returns Rect if Path is equivalent to Rect when filled.

* * rect may be smaller than the Path bounds. Path bounds may include {@link PathVerb#MOVE} points * that do not alter the area drawn by the returned rect. * * @return bounds if Path contains Rect, null otherwise * * @see https://fiddle.skia.org/c/@Path_isRect */ public Rect isRect() { try { Stats.onNativeCall(); return _nIsRect(_ptr); } finally { Reference.reachabilityFence(this); } } /** * Adds Rect to Path, appending {@link PathVerb#MOVE}, three {@link PathVerb#LINE}, and {@link PathVerb#CLOSE}, * starting with top-left corner of Rect; followed by top-right, bottom-right, * and bottom-left. * * @param rect Rect to add as a closed contour * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addRect */ public Path addRect(Rect rect) { return addRect(rect, PathDirection.CLOCKWISE, 0); } /** * Adds Rect to Path, appending {@link PathVerb#MOVE}, three {@link PathVerb#LINE}, and {@link PathVerb#CLOSE}, * starting with top-left corner of Rect; followed by top-right, bottom-right, * and bottom-left if dir is {@link PathDirection#CLOCKWISE}; or followed by bottom-left, * bottom-right, and top-right if dir is {@link PathDirection#COUNTER_CLOCKWISE}. * * @param rect Rect to add as a closed contour * @param dir Direction to wind added contour * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addRect */ public Path addRect(Rect rect, PathDirection dir) { return addRect(rect, dir, 0); } /** * Adds Rect to Path, appending {@link PathVerb#MOVE}, three {@link PathVerb#LINE}, and {@link PathVerb#CLOSE}. * If dir is {@link PathDirection#CLOCKWISE}, Rect corners are added clockwise; if dir is * {@link PathDirection#COUNTER_CLOCKWISE}, Rect corners are added counterclockwise. * start determines the first corner added. * * @param rect Rect to add as a closed contour * @param dir Direction to wind added contour * @param start initial corner of Rect to add. 0 for top left, 1 for top right, 2 for lower right, 3 for lower left * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addRect_2 */ public Path addRect(Rect rect, PathDirection dir, int start) { Stats.onNativeCall(); _nAddRect(_ptr, rect._left, rect._top, rect._right, rect._bottom, dir.ordinal(), start); return this; } /** *

Adds oval to path, appending {@link PathVerb#MOVE}, four {@link PathVerb#CONIC}, and {@link PathVerb#CLOSE}.

* *

Oval is upright ellipse bounded by Rect oval with radii equal to half oval width * and half oval height. Oval begins at (oval.fRight, oval.centerY()) and continues * clockwise.

* * @param oval bounds of ellipse added * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addOval */ public Path addOval(Rect oval) { return addOval(oval, PathDirection.CLOCKWISE, 1); } /** *

Adds oval to path, appending {@link PathVerb#MOVE}, four {@link PathVerb#CONIC}, and {@link PathVerb#CLOSE}.

* *

Oval is upright ellipse bounded by Rect oval with radii equal to half oval width * and half oval height. Oval begins at (oval.fRight, oval.centerY()) and continues * clockwise if dir is {@link PathDirection#CLOCKWISE}, counterclockwise if dir is {@link PathDirection#COUNTER_CLOCKWISE}.

* * @param oval bounds of ellipse added * @param dir Direction to wind ellipse * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addOval */ public Path addOval(Rect oval, PathDirection dir) { return addOval(oval, dir, 1); } /** * Adds oval to Path, appending {@link PathVerb#MOVE}, four {@link PathVerb#CONIC}, and {@link PathVerb#CLOSE}. * Oval is upright ellipse bounded by Rect oval with radii equal to half oval width * and half oval height. Oval begins at start and continues * clockwise if dir is {@link PathDirection#CLOCKWISE}, counterclockwise if dir is {@link PathDirection#COUNTER_CLOCKWISE}. * * @param oval bounds of ellipse added * @param dir Direction to wind ellipse * @param start index of initial point of ellipse. 0 for top, 1 for right, 2 for bottom, 3 for left * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addOval_2 */ public Path addOval(Rect oval, PathDirection dir, int start) { Stats.onNativeCall(); _nAddOval(_ptr, oval._left, oval._top, oval._right, oval._bottom, dir.ordinal(), start); return this; } /** *

Adds circle centered at (x, y) of size radius to Path, appending {@link PathVerb#MOVE}, * four {@link PathVerb#CONIC}, and {@link PathVerb#CLOSE}. Circle begins at: (x + radius, y)

* *

Has no effect if radius is zero or negative.

* * @param x center of circle * @param y center of circle * @param radius distance from center to edge * @return reference to Path */ public Path addCircle(float x, float y, float radius) { return addCircle(x, y, radius, PathDirection.CLOCKWISE); } /** *

Adds circle centered at (x, y) of size radius to Path, appending {@link PathVerb#MOVE}, * four {@link PathVerb#CONIC}, and {@link PathVerb#CLOSE}. Circle begins at: (x + radius, y), continuing * clockwise if dir is {@link PathDirection#CLOCKWISE}, and counterclockwise if dir is {@link PathDirection#COUNTER_CLOCKWISE}.

* *

Has no effect if radius is zero or negative.

* * @param x center of circle * @param y center of circle * @param radius distance from center to edge * @param dir Direction to wind circle * @return reference to Path */ public Path addCircle(float x, float y, float radius, PathDirection dir) { Stats.onNativeCall(); _nAddCircle(_ptr, x, y, radius, dir.ordinal()); return this; } /** *

Appends arc to Path, as the start of new contour. Arc added is part of ellipse * bounded by oval, from startAngle through sweepAngle. Both startAngle and * sweepAngle are measured in degrees, where zero degrees is aligned with the * positive x-axis, and positive sweeps extends arc clockwise.

* *

If sweepAngle ≤ -360, or sweepAngle ≥ 360; and startAngle modulo 90 is nearly * zero, append oval instead of arc. Otherwise, sweepAngle values are treated * modulo 360, and arc may or may not draw depending on numeric rounding.

* * @param oval bounds of ellipse containing arc * @param startAngle starting angle of arc in degrees * @param sweepAngle sweep, in degrees. Positive is clockwise; treated modulo 360 * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addArc */ public Path addArc(Rect oval, float startAngle, float sweepAngle) { Stats.onNativeCall(); _nAddArc(_ptr, oval._left, oval._top, oval._right, oval._bottom, startAngle, sweepAngle); return this; } /** *

Adds rrect to Path, creating a new closed contour. RRect starts at top-left of the lower-left corner and * winds clockwise.

* *

After appending, Path may be empty, or may contain: Rect, Oval, or RRect.

* * @param rrect bounds and radii of rounded rectangle * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addRRect */ public Path addRRect(RRect rrect) { return addRRect(rrect, PathDirection.CLOCKWISE, 6); } /** *

Adds rrect to Path, creating a new closed contour. If * dir is {@link PathDirection#CLOCKWISE}, rrect starts at top-left of the lower-left corner and * winds clockwise. If dir is {@link PathDirection#COUNTER_CLOCKWISE}, rrect starts at the bottom-left * of the upper-left corner and winds counterclockwise.

* *

After appending, Path may be empty, or may contain: Rect, Oval, or RRect.

* * @param rrect bounds and radii of rounded rectangle * @param dir Direction to wind RRect * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addRRect */ public Path addRRect(RRect rrect, PathDirection dir) { return addRRect(rrect, dir, dir == PathDirection.CLOCKWISE ? 6 : 7); } /** *

Adds rrect to Path, creating a new closed contour. If dir is {@link PathDirection#CLOCKWISE}, rrect * winds clockwise; if dir is {@link PathDirection#COUNTER_CLOCKWISE}, rrect winds counterclockwise. * start determines the first point of rrect to add.

* * @param rrect bounds and radii of rounded rectangle * @param dir Direction to wind RRect * @param start index of initial point of RRect. 0 for top-right end of the arc at top left, * 1 for top-left end of the arc at top right, 2 for bottom-right end of top right arc, etc. * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addRRect_2 */ public Path addRRect(RRect rrect, PathDirection dir, int start) { Stats.onNativeCall(); _nAddRRect(_ptr, rrect._left, rrect._top, rrect._right, rrect._bottom, rrect._radii, dir.ordinal(), start); return this; } /** *

Adds contour created from line array, adding (pts.length - 1) line segments. * Contour added starts at pts[0], then adds a line for every additional Point * in pts array. If close is true, appends {@link PathVerb#CLOSE} to Path, connecting * pts[pts.length - 1] and pts[0].

* *

If pts is empty, append {@link PathVerb#MOVE} to path.

* * @param pts array of line sharing end and start Point * @param close true to add line connecting contour end and start * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addPoly */ public Path addPoly(Point[] pts, boolean close) { float[] flat = new float[pts.length * 2]; for (int i = 0; i < pts.length; ++i) { flat[i * 2] = pts[i]._x; flat[i * 2 + 1] = pts[i]._y; } return addPoly(flat, close); } /** *

Adds contour created from line array, adding (pts.length / 2 - 1) line segments. * Contour added starts at (pts[0], pts[1]), then adds a line for every additional pair of floats * in pts array. If close is true, appends {@link PathVerb#CLOSE} to Path, connecting * (pts[count - 2], pts[count - 1]) and (pts[0], pts[1]).

* *

If pts is empty, append {@link PathVerb#MOVE} to path.

* * @param pts flat array of line sharing end and start Point * @param close true to add line connecting contour end and start * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_addPoly */ public Path addPoly(float[] pts, boolean close) { assert pts.length % 2 == 0 : "Expected even amount of pts, got " + pts.length; Stats.onNativeCall(); _nAddPoly(_ptr, pts, close); return this; } /** *

Appends src to Path.

* *

src verb array, Point array, and conic weights are * added unaltered.

* * @param src Path verbs, Point, and conic weights to add * @return reference to Path */ public Path addPath(Path src) { return addPath(src, false); } /** *

Appends src to Path.

* *

If extend is false, src verb array, Point array, and conic weights are * added unaltered. If extend is true, add line before appending * verbs, Point, and conic weights.

* * @param src Path verbs, Point, and conic weights to add * @param extend if should add a line before appending verbs * @return reference to Path */ public Path addPath(Path src, boolean extend) { try { Stats.onNativeCall(); _nAddPath(_ptr, Native.getPtr(src), extend); return this; } finally { Reference.reachabilityFence(src); } } /** *

Appends src to Path, offset by (dx, dy).

* *

Src verb array, Point array, and conic weights are * added unaltered.

* * @param src Path verbs, Point, and conic weights to add * @param dx offset added to src Point array x-axis coordinates * @param dy offset added to src Point array y-axis coordinates * @return reference to Path */ public Path addPath(Path src, float dx, float dy) { return addPath(src, dx, dy, false); } /** *

Appends src to Path, offset by (dx, dy).

* *

If extend is false, src verb array, Point array, and conic weights are * added unaltered. If extend is true, add line before appending * verbs, Point, and conic weights.

* * @param src Path verbs, Point, and conic weights to add * @param dx offset added to src Point array x-axis coordinates * @param dy offset added to src Point array y-axis coordinates * @param extend if should add a line before appending verbs * @return reference to Path */ public Path addPath(Path src, float dx, float dy, boolean extend) { try { Stats.onNativeCall(); _nAddPathOffset(_ptr, Native.getPtr(src), dx, dy, extend); return this; } finally { Reference.reachabilityFence(src); } } /** *

Appends src to Path, transformed by matrix. Transformed curves may have different * verbs, Point, and conic weights.

* *

Src verb array, Point array, and conic weights are * added unaltered.

* * @param src Path verbs, Point, and conic weights to add * @param matrix transform applied to src * @return reference to Path */ public Path addPath(Path src, Matrix33 matrix) { return addPath(src, matrix, false); } /** *

Appends src to Path, transformed by matrix. Transformed curves may have different * verbs, Point, and conic weights.

* *

If extend is false, src verb array, Point array, and conic weights are * added unaltered. If extend is true, add line before appending * verbs, Point, and conic weights.

* * @param src Path verbs, Point, and conic weights to add * @param matrix transform applied to src * @param extend if should add a line before appending verbs * @return reference to Path */ public Path addPath(Path src, Matrix33 matrix, boolean extend) { try { Stats.onNativeCall(); _nAddPathTransform(_ptr, Native.getPtr(src), matrix.getMat(), extend); return this; } finally { Reference.reachabilityFence(src); } } /** * Appends src to Path, from back to front. * Reversed src always appends a new contour to Path. * * @param src Path verbs, Point, and conic weights to add * @return reference to Path * * @see https://fiddle.skia.org/c/@Path_reverseAddPath */ public Path reverseAddPath(Path src) { try { Stats.onNativeCall(); _nReverseAddPath(_ptr, Native.getPtr(src)); return this; } finally { Reference.reachabilityFence(src); } } /** * Offsets Point array by (dx, dy). Path is replaced by offset data. * * @param dx offset added to Point array x-axis coordinates * @param dy offset added to Point array y-axis coordinates * @return this */ public Path offset(float dx, float dy) { return offset(dx, dy, null); } /** * Offsets Point array by (dx, dy). Offset Path replaces dst. * If dst is null, Path is replaced by offset data. * * @param dx offset added to Point array x-axis coordinates * @param dy offset added to Point array y-axis coordinates * @param dst overwritten, translated copy of Path; may be null * @return this * * @see https://fiddle.skia.org/c/@Path_offset */ public Path offset(float dx, float dy, Path dst) { try { Stats.onNativeCall(); _nOffset(_ptr, dx, dy, Native.getPtr(dst)); return this; } finally { Reference.reachabilityFence(dst); } } /** * Transforms verb array, Point array, and weight by matrix. * transform may change verbs and increase their number. * Path is replaced by transformed data. * * @param matrix matrix to apply to Path * @return this */ public Path transform(Matrix33 matrix) { return transform(matrix, null, true); } /** * Transforms verb array, Point array, and weight by matrix. * transform may change verbs and increase their number. * Path is replaced by transformed data. * * @param matrix matrix to apply to Path * @param applyPerspectiveClip whether to apply perspective clipping * @return this */ public Path transform(Matrix33 matrix, boolean applyPerspectiveClip) { return transform(matrix, null, applyPerspectiveClip); } /** * Transforms verb array, Point array, and weight by matrix. * transform may change verbs and increase their number. * Transformed Path replaces dst; if dst is null, original data * is replaced. * * @param matrix matrix to apply to Path * @param dst overwritten, transformed copy of Path; may be null * @return this * * @see https://fiddle.skia.org/c/@Path_transform */ public Path transform(Matrix33 matrix, Path dst) { return transform(matrix, dst, true); } /** * Transforms verb array, Point array, and weight by matrix. * transform may change verbs and increase their number. * Transformed Path replaces dst; if dst is null, original data * is replaced. * * @param matrix matrix to apply to Path * @param dst overwritten, transformed copy of Path; may be null * @param applyPerspectiveClip whether to apply perspective clipping * @return this * * @see https://fiddle.skia.org/c/@Path_transform */ public Path transform(Matrix33 matrix, Path dst, boolean applyPerspectiveClip) { try { Stats.onNativeCall(); _nTransform(_ptr, matrix.getMat(), Native.getPtr(dst), applyPerspectiveClip); return this; } finally { Reference.reachabilityFence(dst); } } /** * Returns last point on Path in lastPt. Returns null if Point array is empty. * * @return point if Point array contains one or more Point, null otherwise * * @see https://fiddle.skia.org/c/@Path_getLastPt */ public Point getLastPt() { try { Stats.onNativeCall(); return _nGetLastPt(_ptr); } finally { Reference.reachabilityFence(this); } } /** * Sets last point to (x, y). If Point array is empty, append {@link PathVerb#MOVE} to * verb array and append (x, y) to Point array. * * @param x set x-axis value of last point * @param y set y-axis value of last point * @return this * * @see https://fiddle.skia.org/c/@Path_setLastPt */ public Path setLastPt(float x, float y) { Stats.onNativeCall(); _nSetLastPt(_ptr, x, y); return this; } /** * Sets the last point on the path. If Point array is empty, append {@link PathVerb#MOVE} to * verb array and append p to Point array. * * @param p set value of last point * @return this */ public Path setLastPt(Point p) { return setLastPt(p._x, p._y); } /** *

Returns a mask, where each set bit corresponds to a SegmentMask constant * if Path contains one or more verbs of that type.

* *

Returns zero if Path contains no lines, or curves: quads, conics, or cubics.

* *

getSegmentMasks() returns a cached result; it is very fast.

* * @return SegmentMask bits or zero * * @see PathSegmentMask#LINE * @see PathSegmentMask#QUAD * @see PathSegmentMask#CONIC * @see PathSegmentMask#CUBIC */ public int getSegmentMasks() { try { Stats.onNativeCall(); return _nGetSegmentMasks(_ptr); } finally { Reference.reachabilityFence(this); } } @Override public PathSegmentIterator iterator() { return iterator(false); } public PathSegmentIterator iterator(boolean forceClose) { return PathSegmentIterator.make(this, forceClose); } /** * Returns true if the point (x, y) is contained by Path, taking into * account {@link PathFillMode}. * * @param x x-axis value of containment test * @param y y-axis value of containment test * @return true if Point is in Path * * @see https://fiddle.skia.org/c/@Path_contains */ public boolean contains(float x, float y) { try { Stats.onNativeCall(); return _nContains(_ptr, x, y); } finally { Reference.reachabilityFence(this); } } /** * Returns true if the point is contained by Path, taking into * account {@link PathFillMode}. * * @param p point of containment test * @return true if Point is in Path * * @see https://fiddle.skia.org/c/@Path_contains */ public boolean contains(Point p) { return contains(p._x, p._y); } /** * Writes text representation of Path to standard output. The representation may be * directly compiled as C++ code. Floating point values are written * with limited precision; it may not be possible to reconstruct original Path * from output. * * @return this * * @see https://fiddle.skia.org/c/@Path_dump_2 */ public Path dump() { Stats.onNativeCall(); _nDump(_ptr); return this; } /** *

Writes text representation of Path to standard output. The representation may be * directly compiled as C++ code. Floating point values are written * in hexadecimal to preserve their exact bit pattern. The output reconstructs the * original Path.

* *

Use instead of {@link dump()} when submitting

* * @return this * * @see https://fiddle.skia.org/c/@Path_dumpHex */ public Path dumpHex() { Stats.onNativeCall(); _nDumpHex(_ptr); return this; } /** *

Writes Path to byte buffer.

* *

Writes {@link PathFillMode}, verb array, Point array, conic weight, and * additionally writes computed information like path convexity and bounds.

* *

Use only be used in concert with {@link makeFromBytes(byte[])}; * the format used for Path in memory is not guaranteed.

* * @return serialized Path; length always a multiple of 4 * * @see https://fiddle.skia.org/c/@Path_writeToMemory */ public byte[] serializeToBytes() { try { Stats.onNativeCall(); return _nSerializeToBytes(_ptr); } finally { Reference.reachabilityFence(this); } } /** *

Returns Path that is the result of applying the Op to the first path and the second path. *

The resulting path will be constructed from non-overlapping contours. *

The curve order is reduced where possible so that cubics may be turned * into quadratics, and quadratics maybe turned into lines. * * @param one The first operand (for difference, the minuend) * @param two The second operand (for difference, the subtrahend) * @param op The operator to apply. * @return Path if operation was able to produce a result, null otherwise */ @Nullable public static Path makeCombining(@NotNull Path one, @NotNull Path two, PathOp op) { try { Stats.onNativeCall(); long ptr = _nMakeCombining(Native.getPtr(one), Native.getPtr(two), op.ordinal()); return ptr == 0 ? null : new Path(ptr); } finally { Reference.reachabilityFence(one); Reference.reachabilityFence(two); } } /** *

Initializes Path from byte buffer. Returns null if the buffer is * data is inconsistent, or the length is too small.

* *

Reads {@link PathFillMode}, verb array, Point array, conic weight, and * additionally reads computed information like path convexity and bounds.

* *

Used only in concert with {@link serializeToBytes()}; * the format used for Path in memory is not guaranteed.

* * @param data storage for Path * @return reconstructed Path * * @see https://fiddle.skia.org/c/@Path_readFromMemory */ public static Path makeFromBytes(byte[] data) { Stats.onNativeCall(); return new Path(_nMakeFromBytes(data)); } /** *

Returns a non-zero, globally unique value. A different value is returned * if verb array, Point array, or conic weight changes.

* *

Setting {@link PathFillMode} does not change generation identifier.

* *

Each time the path is modified, a different generation identifier will be returned. * {@link PathFillMode} does affect generation identifier on Android framework.

* * @return non-zero, globally unique value * * @see https://fiddle.skia.org/c/@Path_getGenerationID * @see https://bugs.chromium.org/p/skia/issues/detail?id=1762 */ public int getGenerationId() { try { Stats.onNativeCall(); return _nGetGenerationId(_ptr); } finally { Reference.reachabilityFence(this); } } /** * Returns if Path data is consistent. Corrupt Path data is detected if * internal values are out of range or internal storage does not match * array dimensions. * * @return true if Path data is consistent */ public boolean isValid() { try { Stats.onNativeCall(); return _nIsValid(_ptr); } finally { Reference.reachabilityFence(this); } } @ApiStatus.Internal public Path(long ptr) { super(ptr, _FinalizerHolder.PTR); } public static native long _nGetFinalizer(); public static native long _nMake(); public static native long _nMakeFromSVGString(String s); public static native boolean _nEquals(long aPtr, long bPtr); public static native boolean _nIsInterpolatable(long ptr, long comparePtr); public static native long _nMakeLerp(long ptr, long endingPtr, float weight); public static native int _nGetFillMode(long ptr); public static native void _nSetFillMode(long ptr, int fillMode); public static native boolean _nIsConvex(long ptr); public static native Rect _nIsOval(long ptr); public static native RRect _nIsRRect(long ptr); public static native void _nReset(long ptr); public static native void _nRewind(long ptr); public static native boolean _nIsEmpty(long ptr); public static native boolean _nIsLastContourClosed(long ptr); public static native boolean _nIsFinite(long ptr); public static native boolean _nIsVolatile(long ptr); public static native void _nSetVolatile(long ptr, boolean isVolatile); public static native boolean _nIsLineDegenerate(float x0, float y0, float x1, float y1, boolean exact); public static native boolean _nIsQuadDegenerate(float x0, float y0, float x1, float y1, float x2, float y2, boolean exact); public static native boolean _nIsCubicDegenerate(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, boolean exact); public static native Point[] _nMaybeGetAsLine(long ptr); public static native int _nGetPointsCount(long ptr); public static native Point _nGetPoint(long ptr, int index); public static native int _nGetPoints(long ptr, Point[] points, int max); public static native int _nCountVerbs(long ptr); public static native int _nGetVerbs(long ptr, byte[] verbs, int max); public static native long _nApproximateBytesUsed(long ptr); public static native void _nSwap(long ptr, long otherPtr); public static native Rect _nGetBounds(long ptr); public static native void _nUpdateBoundsCache(long ptr); public static native Rect _nComputeTightBounds(long ptr); public static native boolean _nConservativelyContainsRect(long ptr, float l, float t, float r, float b); public static native void _nIncReserve(long ptr, int extraPtCount); public static native void _nMoveTo(long ptr, float x, float y); public static native void _nRMoveTo(long ptr, float dx, float dy); public static native void _nLineTo(long ptr, float x, float y); public static native void _nRLineTo(long ptr, float dx, float dy); public static native void _nQuadTo(long ptr, float x1, float y1, float x2, float y2); public static native void _nRQuadTo(long ptr, float dx1, float dy1, float dx2, float dy2); public static native void _nConicTo(long ptr, float x1, float y1, float x2, float y2, float w); public static native void _nRConicTo(long ptr, float dx1, float dy1, float dx2, float dy2, float w); public static native void _nCubicTo(long ptr, float x1, float y1, float x2, float y2, float x3, float y3); public static native void _nRCubicTo(long ptr, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3); public static native void _nArcTo(long ptr, float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo); public static native void _nTangentArcTo(long ptr, float x1, float y1, float x2, float y2, float radius); public static native void _nEllipticalArcTo(long ptr, float rx, float ry, float xAxisRotate, int size, int direction, float x, float y); public static native void _nREllipticalArcTo(long ptr, float rx, float ry, float xAxisRotate, int size, int direction, float dx, float dy); public static native void _nClosePath(long ptr); public static native Point[] _nConvertConicToQuads(float x0, float y0, float x1, float y1, float x2, float y2, float w, int pow2); public static native Rect _nIsRect(long ptr); public static native void _nAddRect(long ptr, float l, float t, float r, float b, int dir, int start); public static native void _nAddOval(long ptr, float l, float t, float r, float b, int dir, int start); public static native void _nAddCircle(long ptr, float x, float y, float r, int dir); public static native void _nAddArc(long ptr, float l, float t, float r, float b, float startAngle, float sweepAngle); public static native void _nAddRRect(long ptr, float l, float t, float r, float b, float[] radii, int dir, int start); public static native void _nAddPoly(long ptr, float[] coords, boolean close); public static native void _nAddPath(long ptr, long srcPtr, boolean extend); public static native void _nAddPathOffset(long ptr, long srcPtr, float dx, float dy, boolean extend); public static native void _nAddPathTransform(long ptr, long srcPtr, float[] matrix, boolean extend); public static native void _nReverseAddPath(long ptr, long srcPtr); public static native void _nOffset(long ptr, float dx, float dy, long dst); public static native void _nTransform(long ptr, float[] matrix, long dst, boolean applyPerspectiveClip); public static native Point _nGetLastPt(long ptr); public static native void _nSetLastPt(long ptr, float x, float y); public static native int _nGetSegmentMasks(long ptr); public static native boolean _nContains(long ptr, float x, float y); public static native void _nDump(long ptr); public static native void _nDumpHex(long ptr); public static native byte[] _nSerializeToBytes(long ptr); public static native long _nMakeCombining(long onePtr, long twoPtr, int op); public static native long _nMakeFromBytes(byte[] data); public static native int _nGetGenerationId(long ptr); public static native boolean _nIsValid(long ptr); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy