[go: nahoru, domu]

blob: 03a682795109926ae33bf242232451a8002fb661 [file] [log] [blame]
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.ui.graphics
import androidx.ui.geometry.Offset
import androidx.ui.geometry.RRect
import androidx.ui.geometry.Rect
import androidx.ui.graphics.vectormath.degrees
expect fun Path(): Path
expect class NativePathEffect
/* expect class */ interface Path {
/**
* Determines how the interior of this path is calculated.
*
* Defaults to the non-zero winding rule, [PathFillType.nonZero].
*/
var fillType: PathFillType
/**
* Returns the path's convexity, as defined by the content of the path.
*
* A path is convex if it has a single contour, and only ever curves in a
* single direction.
*
* This function will calculate the convexity of the path from its control
* points, and cache the result.
*/
val isConvex: Boolean
/**
* Returns true if the path is empty (contains no lines or curves)
*
* @return true if the path is empty (contains no lines or curves)
*/
val isEmpty: Boolean
/**
* Starts a new subpath at the given coordinate
*/
fun moveTo(x: Float, y: Float)
/**
* Starts a new subpath at the given offset from the current point
*/
fun relativeMoveTo(dx: Float, dy: Float)
/**
* Adds a straight line segment from the current point to the given point
*/
fun lineTo(x: Float, y: Float)
/**
* Adds a straight line segment from the current point to the point
* at the given offset from the current point.
*/
fun relativeLineTo(dx: Float, dy: Float)
/**
* Adds a quadratic bezier segment that curves from the current
* point to the given point ([x2], [y2]), using the control point
* ([x1], [y1]).
*/
fun quadraticBezierTo(x1: Float, y1: Float, x2: Float, y2: Float)
/**
* Adds a quadratic bezier segment that curves from the current
* point to the point at the offset ([dx2], [dy2]) from the current point,
* using the control point at the offset ([dx1], [dy1]) from the current
* point.
*/
fun relativeQuadraticBezierTo(dx1: Float, dy1: Float, dx2: Float, dy2: Float)
/**
* Adds a cubic bezier segment that curves from the current point
* to the given point ([x3], [y3]), using the control points ([x1], [y1]) and
* ([x2], [y2]).
*/
fun cubicTo(x1: Float, y1: Float, x2: Float, y2: Float, x3: Float, y3: Float)
/**
* Adds a cubic bezier segment that curves from the current point
* to the point at the offset ([dx3], [dy3]) from the current point, using
* the control points at the offsets ([dx1], [dy1]) and ([dx2], [dy2]) from the
* current point.
*/
fun relativeCubicTo(dx1: Float, dy1: Float, dx2: Float, dy2: Float, dx3: Float, dy3: Float)
/**
* If the [forceMoveTo] argument is false, adds a straight line
* segment and an arc segment.
*
* If the [forceMoveTo] argument is true, starts a new subpath
* consisting of an arc segment.
*
* In either case, the arc segment consists of the arc that follows
* the edge of the oval bounded by the given rectangle, from
* startAngle radians around the oval up to startAngle + sweepAngle
* radians around the oval, with zero radians being the point on
* the right hand side of the oval that crosses the horizontal line
* that intersects the center of the rectangle and with positive
* angles going clockwise around the oval.
*
* The line segment added if `forceMoveTo` is false starts at the
* current point and ends at the start of the arc.
*/
fun arcToRad(
rect: Rect,
startAngleRadians: Float,
sweepAngleRadians: Float,
forceMoveTo: Boolean
) {
arcTo(rect, degrees(startAngleRadians), degrees(sweepAngleRadians), forceMoveTo)
}
/**
* If the [forceMoveTo] argument is false, adds a straight line
* segment and an arc segment.
*
* If the [forceMoveTo] argument is true, starts a new subpath
* consisting of an arc segment.
*
* In either case, the arc segment consists of the arc that follows
* the edge of the oval bounded by the given rectangle, from
* startAngle degrees around the oval up to startAngle + sweepAngle
* degrees around the oval, with zero degrees being the point on
* the right hand side of the oval that crosses the horizontal line
* that intersects the center of the rectangle and with positive
* angles going clockwise around the oval.
*
* The line segment added if `forceMoveTo` is false starts at the
* current point and ends at the start of the arc.
*/
fun arcTo(
rect: Rect,
startAngleDegrees: Float,
sweepAngleDegrees: Float,
forceMoveTo: Boolean
)
/**
* Adds a new subpath that consists of four lines that outline the
* given rectangle.
*/
fun addRect(rect: Rect)
/**
* Adds a new subpath that consists of a curve that forms the
* ellipse that fills the given rectangle.
*
* To add a circle, pass an appropriate rectangle as `oval`. [Rect.fromCircle]
* can be used to easily describe the circle's center [Offset] and radius.
*/
fun addOval(oval: Rect)
/**
* Adds a new subpath with one arc segment that consists of the arc
* that follows the edge of the oval bounded by the given
* rectangle, from startAngle radians around the oval up to
* startAngle + sweepAngle radians around the oval, with zero
* radians being the point on the right hand side of the oval that
* crosses the horizontal line that intersects the center of the
* rectangle and with positive angles going clockwise around the
* oval.
*/
fun addArcRad(oval: Rect, startAngleRadians: Float, sweepAngleRadians: Float)
/**
* Adds a new subpath with one arc segment that consists of the arc
* that follows the edge of the oval bounded by the given
* rectangle, from startAngle degrees around the oval up to
* startAngle + sweepAngle degrees around the oval, with zero
* degrees being the point on the right hand side of the oval that
* crosses the horizontal line that intersects the center of the
* rectangle and with positive angles going clockwise around the
* oval.
*/
fun addArc(oval: Rect, startAngleDegrees: Float, sweepAngleDegrees: Float)
/**
* Add a round rectangle shape to the path from the given [RRect]
*/
fun addRRect(rrect: RRect)
/**
* Adds a new subpath that consists of the given `path` offset by the given
* `offset`.
*
* If `matrix4` is specified, the path will be transformed by this matrix
* after the matrix is translated by the given offset. The matrix is a 4x4
* matrix stored in column major order.
*/
fun addPath(path: Path, offset: Offset = Offset.Zero)
/**
* Closes the last subpath, as if a straight line had been drawn
* from the current point to the first point of the subpath.
*/
fun close()
/**
* Clears the [Path] object of all subpaths, returning it to the
* same state it had when it was created. The _current point_ is
* reset to the origin.
*/
fun reset()
/**
* Translates all the segments of every subpath by the given offset.
*/
fun shift(offset: Offset)
/**
* Compute the bounds of the control points of the path, and write the
* answer into bounds. If the path contains 0 or 1 points, the bounds is
* set to (0,0,0,0)
*/
fun getBounds(): Rect
/**
* Set this path to the result of applying the Op to the two specified paths.
* 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 path1 The first operand (for difference, the minuend)
* @param path2 The second operand (for difference, the subtrahend)
*
* @return True if operation succeeded, false otherwise and this path remains unmodified.
*/
fun op(
path1: Path,
path2: Path,
operation: PathOperation
): Boolean
companion object {
/**
* Combines the two paths according to the manner specified by the given
* `operation`.
*
* 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.
*
* Throws [IllegalArgumentException] as Android framework does not support this API
*/
fun combine(
operation: PathOperation,
path1: Path,
path2: Path
): Path {
val path = Path()
if (path.op(path1, path2, operation)) {
return path
}
throw IllegalArgumentException("Path.combine() failed. This may be due an invalid " +
"path; in particular, check for NaN values.")
}
}
}