mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Make Rect and RRect use 64 bit doubles, and make them const-able (flutter/engine#8565)
* Make Rect and RRect 64bit and const-able
This commit is contained in:
parent
fb3a80f7bb
commit
d98c2e2df0
@ -98,7 +98,7 @@ class SceneBuilder extends NativeFieldWrapperClass2 {
|
||||
EngineLayer pushClipRRect(RRect rrect, {Clip clipBehavior = Clip.antiAlias}) {
|
||||
assert(clipBehavior != null);
|
||||
assert(clipBehavior != Clip.none);
|
||||
return _pushClipRRect(rrect._value, clipBehavior.index);
|
||||
return _pushClipRRect(rrect._value32, clipBehavior.index);
|
||||
}
|
||||
EngineLayer _pushClipRRect(Float32List rrect, int clipBehavior) native 'SceneBuilder_pushClipRRect';
|
||||
|
||||
|
||||
@ -619,66 +619,53 @@ class Size extends OffsetBase {
|
||||
/// Rect myRect = const Offset(1.0, 2.0) & const Size(3.0, 4.0);
|
||||
/// ```
|
||||
class Rect {
|
||||
Rect._();
|
||||
|
||||
/// Construct a rectangle from its left, top, right, and bottom edges.
|
||||
@pragma('vm:entry-point')
|
||||
Rect.fromLTRB(double left, double top, double right, double bottom) {
|
||||
_value
|
||||
..[0] = left
|
||||
..[1] = top
|
||||
..[2] = right
|
||||
..[3] = bottom;
|
||||
}
|
||||
const Rect.fromLTRB(this.left, this.top, this.right, this.bottom)
|
||||
: assert(left != null),
|
||||
assert(top != null),
|
||||
assert(right != null),
|
||||
assert(bottom != null);
|
||||
|
||||
/// Construct a rectangle from its left and top edges, its width, and its
|
||||
/// height.
|
||||
///
|
||||
/// To construct a [Rect] from an [Offset] and a [Size], you can use the
|
||||
/// rectangle constructor operator `&`. See [Offset.&].
|
||||
Rect.fromLTWH(double left, double top, double width, double height) {
|
||||
_value
|
||||
..[0] = left
|
||||
..[1] = top
|
||||
..[2] = left + width
|
||||
..[3] = top + height;
|
||||
}
|
||||
const Rect.fromLTWH(double left, double top, double width, double height) : this.fromLTRB(left, top, left + width, top + height);
|
||||
|
||||
/// Construct a rectangle that bounds the given circle.
|
||||
///
|
||||
/// The `center` argument is assumed to be an offset from the origin.
|
||||
Rect.fromCircle({ Offset center, double radius }) {
|
||||
_value
|
||||
..[0] = center.dx - radius
|
||||
..[1] = center.dy - radius
|
||||
..[2] = center.dx + radius
|
||||
..[3] = center.dy + radius;
|
||||
}
|
||||
Rect.fromCircle({ Offset center, double radius }) : this.fromLTRB(
|
||||
center.dx - radius,
|
||||
center.dy - radius,
|
||||
center.dx + radius,
|
||||
center.dy + radius,
|
||||
);
|
||||
|
||||
/// Construct the smallest rectangle that encloses the given offsets, treating
|
||||
/// them as vectors from the origin.
|
||||
Rect.fromPoints(Offset a, Offset b) {
|
||||
_value
|
||||
..[0] = math.min(a.dx, b.dx)
|
||||
..[1] = math.min(a.dy, b.dy)
|
||||
..[2] = math.max(a.dx, b.dx)
|
||||
..[3] = math.max(a.dy, b.dy);
|
||||
}
|
||||
Rect.fromPoints(Offset a, Offset b) : this.fromLTRB(
|
||||
math.min(a.dx, b.dx),
|
||||
math.min(a.dy, b.dy),
|
||||
math.max(a.dx, b.dx),
|
||||
math.max(a.dy, b.dy),
|
||||
);
|
||||
|
||||
static const int _kDataSize = 4;
|
||||
final Float32List _value = new Float32List(_kDataSize);
|
||||
Float32List get _value32 => Float32List.fromList(<double>[left, top, right, bottom]);
|
||||
|
||||
/// The offset of the left edge of this rectangle from the x axis.
|
||||
double get left => _value[0];
|
||||
final double left;
|
||||
|
||||
/// The offset of the top edge of this rectangle from the y axis.
|
||||
double get top => _value[1];
|
||||
final double top;
|
||||
|
||||
/// The offset of the right edge of this rectangle from the x axis.
|
||||
double get right => _value[2];
|
||||
final double right;
|
||||
|
||||
/// The offset of the bottom edge of this rectangle from the y axis.
|
||||
double get bottom => _value[3];
|
||||
final double bottom;
|
||||
|
||||
/// The distance between the left and right edges of this rectangle.
|
||||
double get width => right - left;
|
||||
@ -690,8 +677,11 @@ class Rect {
|
||||
/// this rectangle.
|
||||
Size get size => new Size(width, height);
|
||||
|
||||
/// Whether any of the dimensions are `NaN`.
|
||||
bool get hasNaN => left.isNaN || top.isNaN || right.isNaN || bottom.isNaN;
|
||||
|
||||
/// A rectangle with left, top, right, and bottom edges all at zero.
|
||||
static final Rect zero = new Rect._();
|
||||
static const Rect zero = Rect.fromLTRB(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
static const double _giantScalar = 1.0E+9; // matches kGiantRect from layer.h
|
||||
|
||||
@ -699,7 +689,7 @@ class Rect {
|
||||
///
|
||||
/// This covers the space from -1e9,-1e9 to 1e9,1e9.
|
||||
/// This is the space over which graphics operations are valid.
|
||||
static final Rect largest = new Rect.fromLTRB(-_giantScalar, -_giantScalar, _giantScalar, _giantScalar);
|
||||
static const Rect largest = Rect.fromLTRB(-_giantScalar, -_giantScalar, _giantScalar, _giantScalar);
|
||||
|
||||
/// Whether any of the coordinates of this rectangle are equal to positive infinity.
|
||||
// included for consistency with Offset and Size
|
||||
@ -879,18 +869,17 @@ class Rect {
|
||||
if (runtimeType != other.runtimeType)
|
||||
return false;
|
||||
final Rect typedOther = other;
|
||||
for (int i = 0; i < _kDataSize; i += 1) {
|
||||
if (_value[i] != typedOther._value[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return left == typedOther.left &&
|
||||
top == typedOther.top &&
|
||||
right == typedOther.right &&
|
||||
bottom == typedOther.bottom;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => hashList(_value);
|
||||
int get hashCode => hashValues(left, top, right, bottom);
|
||||
|
||||
@override
|
||||
String toString() => 'Rect.fromLTRB(${left.toStringAsFixed(1)}, ${top.toStringAsFixed(1)}, ${right.toStringAsFixed(1)}, ${bottom.toStringAsFixed(1)})';
|
||||
String toString() => 'Rect.fromLTRB(${left.toStringAsFixed(1)} ${top.toStringAsFixed(1)}, ${right.toStringAsFixed(1)}, ${bottom.toStringAsFixed(1)})';
|
||||
}
|
||||
|
||||
/// A radius for either circular or elliptical shapes.
|
||||
@ -1018,81 +1007,78 @@ class Radius {
|
||||
|
||||
/// An immutable rounded rectangle with the custom radii for all four corners.
|
||||
class RRect {
|
||||
RRect._();
|
||||
|
||||
/// Construct a rounded rectangle from its left, top, right, and bottom edges,
|
||||
/// and the same radii along its horizontal axis and its vertical axis.
|
||||
RRect.fromLTRBXY(double left, double top, double right, double bottom,
|
||||
double radiusX, double radiusY) {
|
||||
_value
|
||||
..[0] = left
|
||||
..[1] = top
|
||||
..[2] = right
|
||||
..[3] = bottom
|
||||
..[4] = radiusX
|
||||
..[5] = radiusY
|
||||
..[6] = radiusX
|
||||
..[7] = radiusY
|
||||
..[8] = radiusX
|
||||
..[9] = radiusY
|
||||
..[10] = radiusX
|
||||
..[11] = radiusY;
|
||||
}
|
||||
const RRect.fromLTRBXY(double left, double top, double right, double bottom,
|
||||
double radiusX, double radiusY) : this._raw(
|
||||
top: top,
|
||||
left: left,
|
||||
right: right,
|
||||
bottom: bottom,
|
||||
tlRadiusX: radiusX,
|
||||
tlRadiusY: radiusY,
|
||||
trRadiusX: radiusX,
|
||||
trRadiusY: radiusY,
|
||||
blRadiusX: radiusX,
|
||||
blRadiusY: radiusY,
|
||||
brRadiusX: radiusX,
|
||||
brRadiusY: radiusY,
|
||||
);
|
||||
|
||||
/// Construct a rounded rectangle from its left, top, right, and bottom edges,
|
||||
/// and the same radius in each corner.
|
||||
RRect.fromLTRBR(double left, double top, double right, double bottom,
|
||||
Radius radius) {
|
||||
_value
|
||||
..[0] = left
|
||||
..[1] = top
|
||||
..[2] = right
|
||||
..[3] = bottom
|
||||
..[4] = radius.x
|
||||
..[5] = radius.y
|
||||
..[6] = radius.x
|
||||
..[7] = radius.y
|
||||
..[8] = radius.x
|
||||
..[9] = radius.y
|
||||
..[10] = radius.x
|
||||
..[11] = radius.y;
|
||||
}
|
||||
Radius radius)
|
||||
: this._raw(
|
||||
top: top,
|
||||
left: left,
|
||||
right: right,
|
||||
bottom: bottom,
|
||||
tlRadiusX: radius.x,
|
||||
tlRadiusY: radius.y,
|
||||
trRadiusX: radius.x,
|
||||
trRadiusY: radius.y,
|
||||
blRadiusX: radius.x,
|
||||
blRadiusY: radius.y,
|
||||
brRadiusX: radius.x,
|
||||
brRadiusY: radius.y,
|
||||
);
|
||||
|
||||
/// Construct a rounded rectangle from its bounding box and the same radii
|
||||
/// along its horizontal axis and its vertical axis.
|
||||
RRect.fromRectXY(Rect rect, double radiusX, double radiusY) {
|
||||
_value
|
||||
..[0] = rect.left
|
||||
..[1] = rect.top
|
||||
..[2] = rect.right
|
||||
..[3] = rect.bottom
|
||||
..[4] = radiusX
|
||||
..[5] = radiusY
|
||||
..[6] = radiusX
|
||||
..[7] = radiusY
|
||||
..[8] = radiusX
|
||||
..[9] = radiusY
|
||||
..[10] = radiusX
|
||||
..[11] = radiusY;
|
||||
}
|
||||
RRect.fromRectXY(Rect rect, double radiusX, double radiusY)
|
||||
: this._raw(
|
||||
top: rect.top,
|
||||
left: rect.left,
|
||||
right: rect.right,
|
||||
bottom: rect.bottom,
|
||||
tlRadiusX: radiusX,
|
||||
tlRadiusY: radiusY,
|
||||
trRadiusX: radiusX,
|
||||
trRadiusY: radiusY,
|
||||
blRadiusX: radiusX,
|
||||
blRadiusY: radiusY,
|
||||
brRadiusX: radiusX,
|
||||
brRadiusY: radiusY,
|
||||
);
|
||||
|
||||
/// Construct a rounded rectangle from its bounding box and a radius that is
|
||||
/// the same in each corner.
|
||||
RRect.fromRectAndRadius(Rect rect, Radius radius) {
|
||||
_value
|
||||
..[0] = rect.left
|
||||
..[1] = rect.top
|
||||
..[2] = rect.right
|
||||
..[3] = rect.bottom
|
||||
..[4] = radius.x
|
||||
..[5] = radius.y
|
||||
..[6] = radius.x
|
||||
..[7] = radius.y
|
||||
..[8] = radius.x
|
||||
..[9] = radius.y
|
||||
..[10] = radius.x
|
||||
..[11] = radius.y;
|
||||
}
|
||||
RRect.fromRectAndRadius(Rect rect, Radius radius)
|
||||
: this._raw(
|
||||
top: rect.top,
|
||||
left: rect.left,
|
||||
right: rect.right,
|
||||
bottom: rect.bottom,
|
||||
tlRadiusX: radius.x,
|
||||
tlRadiusY: radius.y,
|
||||
trRadiusX: radius.x,
|
||||
trRadiusY: radius.y,
|
||||
blRadiusX: radius.x,
|
||||
blRadiusY: radius.y,
|
||||
brRadiusX: radius.x,
|
||||
brRadiusY: radius.y,
|
||||
);
|
||||
|
||||
/// Construct a rounded rectangle from its left, top, right, and bottom edges,
|
||||
/// and topLeft, topRight, bottomRight, and bottomLeft radii.
|
||||
@ -1107,21 +1093,20 @@ class RRect {
|
||||
Radius topRight: Radius.zero,
|
||||
Radius bottomRight: Radius.zero,
|
||||
Radius bottomLeft: Radius.zero,
|
||||
}) {
|
||||
_value
|
||||
..[0] = left
|
||||
..[1] = top
|
||||
..[2] = right
|
||||
..[3] = bottom
|
||||
..[4] = topLeft.x
|
||||
..[5] = topLeft.y
|
||||
..[6] = topRight.x
|
||||
..[7] = topRight.y
|
||||
..[8] = bottomRight.x
|
||||
..[9] = bottomRight.y
|
||||
..[10] = bottomLeft.x
|
||||
..[11] = bottomLeft.y;
|
||||
}
|
||||
}) : this._raw(
|
||||
top: top,
|
||||
left: left,
|
||||
right: right,
|
||||
bottom: bottom,
|
||||
tlRadiusX: topLeft.x,
|
||||
tlRadiusY: topLeft.y,
|
||||
trRadiusX: topRight.x,
|
||||
trRadiusY: topRight.y,
|
||||
blRadiusX: bottomLeft.x,
|
||||
blRadiusY: bottomLeft.y,
|
||||
brRadiusX: bottomRight.x,
|
||||
brRadiusY: bottomRight.y,
|
||||
);
|
||||
|
||||
/// Construct a rounded rectangle from its bounding box and and topLeft,
|
||||
/// topRight, bottomRight, and bottomLeft radii.
|
||||
@ -1135,132 +1120,147 @@ class RRect {
|
||||
Radius bottomRight: Radius.zero,
|
||||
Radius bottomLeft: Radius.zero
|
||||
}
|
||||
) {
|
||||
_value
|
||||
..[0] = rect.left
|
||||
..[1] = rect.top
|
||||
..[2] = rect.right
|
||||
..[3] = rect.bottom
|
||||
..[4] = topLeft.x
|
||||
..[5] = topLeft.y
|
||||
..[6] = topRight.x
|
||||
..[7] = topRight.y
|
||||
..[8] = bottomRight.x
|
||||
..[9] = bottomRight.y
|
||||
..[10] = bottomLeft.x
|
||||
..[11] = bottomLeft.y;
|
||||
}
|
||||
) : this._raw(
|
||||
top: rect.top,
|
||||
left: rect.left,
|
||||
right: rect.right,
|
||||
bottom: rect.bottom,
|
||||
tlRadiusX: topLeft.x,
|
||||
tlRadiusY: topLeft.y,
|
||||
trRadiusX: topRight.x,
|
||||
trRadiusY: topRight.y,
|
||||
blRadiusX: bottomLeft.x,
|
||||
blRadiusY: bottomLeft.y,
|
||||
brRadiusX: bottomRight.x,
|
||||
brRadiusY: bottomRight.y,
|
||||
);
|
||||
|
||||
RRect._fromList(List<double> list) {
|
||||
for (int i = 0; i < _kDataSize; i += 1)
|
||||
_value[i] = list[i];
|
||||
}
|
||||
const RRect._raw({
|
||||
this.left = 0.0,
|
||||
this.top = 0.0,
|
||||
this.right = 0.0,
|
||||
this.bottom = 0.0,
|
||||
this.tlRadiusX = 0.0,
|
||||
this.tlRadiusY = 0.0,
|
||||
this.trRadiusX = 0.0,
|
||||
this.trRadiusY = 0.0,
|
||||
this.brRadiusX = 0.0,
|
||||
this.brRadiusY = 0.0,
|
||||
this.blRadiusX = 0.0,
|
||||
this.blRadiusY = 0.0,
|
||||
}) : assert(left != null),
|
||||
assert(top != null),
|
||||
assert(right != null),
|
||||
assert(bottom != null),
|
||||
assert(tlRadiusX != null),
|
||||
assert(tlRadiusY != null),
|
||||
assert(trRadiusX != null),
|
||||
assert(trRadiusY != null),
|
||||
assert(brRadiusX != null),
|
||||
assert(brRadiusY != null),
|
||||
assert(blRadiusX != null),
|
||||
assert(blRadiusY != null);
|
||||
|
||||
static const int _kDataSize = 12;
|
||||
final Float32List _value = new Float32List(_kDataSize);
|
||||
RRect _scaled; // same RRect with scaled radii per side
|
||||
Float32List get _value32 => Float32List.fromList(<double>[
|
||||
left,
|
||||
top,
|
||||
right,
|
||||
bottom,
|
||||
tlRadiusX,
|
||||
tlRadiusY,
|
||||
trRadiusX,
|
||||
trRadiusY,
|
||||
brRadiusX,
|
||||
brRadiusY,
|
||||
blRadiusX,
|
||||
blRadiusY,
|
||||
]);
|
||||
|
||||
/// The offset of the left edge of this rectangle from the x axis.
|
||||
double get left => _value[0];
|
||||
final double left;
|
||||
|
||||
/// The offset of the top edge of this rectangle from the y axis.
|
||||
double get top => _value[1];
|
||||
final double top;
|
||||
|
||||
/// The offset of the right edge of this rectangle from the x axis.
|
||||
double get right => _value[2];
|
||||
final double right;
|
||||
|
||||
/// The offset of the bottom edge of this rectangle from the y axis.
|
||||
double get bottom => _value[3];
|
||||
final double bottom;
|
||||
|
||||
/// The top-left horizontal radius.
|
||||
double get tlRadiusX => _value[4];
|
||||
final double tlRadiusX;
|
||||
|
||||
/// The top-left vertical radius.
|
||||
double get tlRadiusY => _value[5];
|
||||
final double tlRadiusY;
|
||||
|
||||
/// The top-left [Radius].
|
||||
Radius get tlRadius => new Radius.elliptical(_value[4], _value[5]);
|
||||
Radius get tlRadius => new Radius.elliptical(tlRadiusX, tlRadiusY);
|
||||
|
||||
/// The top-right horizontal radius.
|
||||
double get trRadiusX => _value[6];
|
||||
final double trRadiusX;
|
||||
|
||||
/// The top-right vertical radius.
|
||||
double get trRadiusY => _value[7];
|
||||
final double trRadiusY;
|
||||
|
||||
/// The top-right [Radius].
|
||||
Radius get trRadius => new Radius.elliptical(_value[6], _value[7]);
|
||||
Radius get trRadius => new Radius.elliptical(trRadiusX, trRadiusY);
|
||||
|
||||
/// The bottom-right horizontal radius.
|
||||
double get brRadiusX => _value[8];
|
||||
final double brRadiusX;
|
||||
|
||||
/// The bottom-right vertical radius.
|
||||
double get brRadiusY => _value[9];
|
||||
final double brRadiusY;
|
||||
|
||||
/// The bottom-right [Radius].
|
||||
Radius get brRadius => new Radius.elliptical(_value[8], _value[9]);
|
||||
Radius get brRadius => new Radius.elliptical(brRadiusX, brRadiusY);
|
||||
|
||||
/// The bottom-left horizontal radius.
|
||||
double get blRadiusX => _value[10];
|
||||
final double blRadiusX;
|
||||
|
||||
/// The bottom-left vertical radius.
|
||||
double get blRadiusY => _value[11];
|
||||
final double blRadiusY;
|
||||
|
||||
/// The bottom-left [Radius].
|
||||
Radius get blRadius => new Radius.elliptical(_value[10], _value[11]);
|
||||
Radius get blRadius => new Radius.elliptical(blRadiusX, blRadiusY);
|
||||
|
||||
/// A rounded rectangle with all the values set to zero.
|
||||
static final RRect zero = new RRect._();
|
||||
static const RRect zero = RRect._raw();
|
||||
|
||||
/// Returns a new [RRect] translated by the given offset.
|
||||
RRect shift(Offset offset) {
|
||||
return new RRect.fromLTRBAndCorners(
|
||||
_value[0] + offset.dx,
|
||||
_value[1] + offset.dy,
|
||||
_value[2] + offset.dx,
|
||||
_value[3] + offset.dy,
|
||||
topLeft: new Radius.elliptical(
|
||||
_value[4],
|
||||
_value[5]
|
||||
),
|
||||
topRight: new Radius.elliptical(
|
||||
_value[6],
|
||||
_value[7]
|
||||
),
|
||||
bottomRight: new Radius.elliptical(
|
||||
_value[8],
|
||||
_value[9]
|
||||
),
|
||||
bottomLeft: new Radius.elliptical(
|
||||
_value[10],
|
||||
_value[11]
|
||||
)
|
||||
return new RRect._raw(
|
||||
left: left + offset.dx,
|
||||
top: top + offset.dy,
|
||||
right: right + offset.dx,
|
||||
bottom: bottom + offset.dy,
|
||||
tlRadiusX: tlRadiusX,
|
||||
tlRadiusY: tlRadiusY,
|
||||
trRadiusX: trRadiusX,
|
||||
trRadiusY: trRadiusY,
|
||||
blRadiusX: blRadiusX,
|
||||
blRadiusY: blRadiusY,
|
||||
brRadiusX: brRadiusX,
|
||||
brRadiusY: brRadiusY,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns a new [RRect] with edges and radii moved outwards by the given
|
||||
/// delta.
|
||||
RRect inflate(double delta) {
|
||||
return new RRect.fromLTRBAndCorners(
|
||||
_value[0] - delta,
|
||||
_value[1] - delta,
|
||||
_value[2] + delta,
|
||||
_value[3] + delta,
|
||||
topLeft: new Radius.elliptical(
|
||||
_value[4] + delta,
|
||||
_value[5] + delta
|
||||
),
|
||||
topRight: new Radius.elliptical(
|
||||
_value[6] + delta,
|
||||
_value[7] + delta
|
||||
),
|
||||
bottomRight: new Radius.elliptical(
|
||||
_value[8] + delta,
|
||||
_value[9] + delta
|
||||
),
|
||||
bottomLeft: new Radius.elliptical(
|
||||
_value[10] + delta,
|
||||
_value[11] + delta
|
||||
)
|
||||
return new RRect._raw(
|
||||
left: left - delta,
|
||||
top: top - delta,
|
||||
right: right + delta,
|
||||
bottom: bottom + delta,
|
||||
tlRadiusX: tlRadiusX + delta,
|
||||
tlRadiusY: tlRadiusY + delta,
|
||||
trRadiusX: trRadiusX + delta,
|
||||
trRadiusY: trRadiusY + delta,
|
||||
blRadiusX: blRadiusX + delta,
|
||||
blRadiusY: blRadiusY + delta,
|
||||
brRadiusX: brRadiusX + delta,
|
||||
brRadiusY: brRadiusY + delta,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1389,6 +1389,10 @@ class RRect {
|
||||
/// rounded rectangle.
|
||||
double get longestSide => math.max(width.abs(), height.abs());
|
||||
|
||||
/// Whether any of the dimensions are `NaN`.
|
||||
bool get hasNaN => left.isNaN || top.isNaN || right.isNaN || bottom.isNaN ||
|
||||
trRadiusX.isNaN || trRadiusY.isNaN || tlRadiusX.isNaN || tlRadiusY.isNaN ||
|
||||
brRadiusX.isNaN || brRadiusY.isNaN || blRadiusX.isNaN || blRadiusY.isNaN;
|
||||
|
||||
/// The offset to the point halfway between the left and right and the top and
|
||||
/// bottom edges of this rectangle.
|
||||
@ -1408,23 +1412,39 @@ class RRect {
|
||||
//
|
||||
// Inspired from:
|
||||
// https://github.com/google/skia/blob/master/src/core/SkRRect.cpp#L164
|
||||
void _scaleRadii() {
|
||||
if (_scaled == null) {
|
||||
double scale = 1.0;
|
||||
final List<double> scaled = new List<double>.from(_value);
|
||||
RRect _scaleRadii() {
|
||||
double scale = 1.0;
|
||||
scale = _getMin(scale, blRadiusY, tlRadiusY, height);
|
||||
scale = _getMin(scale, tlRadiusX, trRadiusX, width);
|
||||
scale = _getMin(scale, trRadiusY, brRadiusY, height);
|
||||
scale = _getMin(scale, brRadiusX, blRadiusX, width);
|
||||
|
||||
scale = _getMin(scale, scaled[11], scaled[5], height);
|
||||
scale = _getMin(scale, scaled[4], scaled[6], width);
|
||||
scale = _getMin(scale, scaled[7], scaled[9], height);
|
||||
scale = _getMin(scale, scaled[8], scaled[10], width);
|
||||
double scaledLeft = left;
|
||||
double scaledTop = top;
|
||||
double scaledRight = right;
|
||||
double scaledBottom = bottom;
|
||||
|
||||
if (scale < 1.0) {
|
||||
for (int i = 4; i < _kDataSize; i += 1)
|
||||
scaled[i] *= scale;
|
||||
}
|
||||
|
||||
_scaled = new RRect._fromList(scaled);
|
||||
if (scale < 1.0) {
|
||||
scaledTop *= scale;
|
||||
scaledLeft *= scale;
|
||||
scaledRight *= scale;
|
||||
scaledBottom *= scale;
|
||||
}
|
||||
|
||||
return new RRect._raw(
|
||||
top: scaledTop,
|
||||
left: scaledLeft,
|
||||
right: scaledRight,
|
||||
bottom: scaledBottom,
|
||||
tlRadiusX: tlRadiusX,
|
||||
tlRadiusY: tlRadiusY,
|
||||
trRadiusX: trRadiusX,
|
||||
trRadiusY: trRadiusY,
|
||||
blRadiusX: blRadiusX,
|
||||
blRadiusY: blRadiusY,
|
||||
brRadiusX: brRadiusX,
|
||||
brRadiusY: brRadiusY,
|
||||
);
|
||||
}
|
||||
|
||||
/// Whether the point specified by the given offset (which is assumed to be
|
||||
@ -1438,7 +1458,7 @@ class RRect {
|
||||
if (point.dx < left || point.dx >= right || point.dy < top || point.dy >= bottom)
|
||||
return false; // outside bounding box
|
||||
|
||||
_scaleRadii();
|
||||
final RRect scaled = _scaleRadii();
|
||||
|
||||
double x;
|
||||
double y;
|
||||
@ -1446,30 +1466,30 @@ class RRect {
|
||||
double radiusY;
|
||||
// check whether point is in one of the rounded corner areas
|
||||
// x, y -> translate to ellipse center
|
||||
if (point.dx < left + _scaled.tlRadiusX &&
|
||||
point.dy < top + _scaled.tlRadiusY) {
|
||||
x = point.dx - left - _scaled.tlRadiusX;
|
||||
y = point.dy - top - _scaled.tlRadiusY;
|
||||
radiusX = _scaled.tlRadiusX;
|
||||
radiusY = _scaled.tlRadiusY;
|
||||
} else if (point.dx > right - _scaled.trRadiusX &&
|
||||
point.dy < top + _scaled.trRadiusY) {
|
||||
x = point.dx - right + _scaled.trRadiusX;
|
||||
y = point.dy - top - _scaled.trRadiusY;
|
||||
radiusX = _scaled.trRadiusX;
|
||||
radiusY = _scaled.trRadiusY;
|
||||
} else if (point.dx > right - _scaled.brRadiusX &&
|
||||
point.dy > bottom - _scaled.brRadiusY) {
|
||||
x = point.dx - right + _scaled.brRadiusX;
|
||||
y = point.dy - bottom + _scaled.brRadiusY;
|
||||
radiusX = _scaled.brRadiusX;
|
||||
radiusY = _scaled.brRadiusY;
|
||||
} else if (point.dx < left + _scaled.blRadiusX &&
|
||||
point.dy > bottom - _scaled.blRadiusY) {
|
||||
x = point.dx - left - _scaled.blRadiusX;
|
||||
y = point.dy - bottom + _scaled.blRadiusY;
|
||||
radiusX = _scaled.blRadiusX;
|
||||
radiusY = _scaled.blRadiusY;
|
||||
if (point.dx < left + scaled.tlRadiusX &&
|
||||
point.dy < top + scaled.tlRadiusY) {
|
||||
x = point.dx - left - scaled.tlRadiusX;
|
||||
y = point.dy - top - scaled.tlRadiusY;
|
||||
radiusX = scaled.tlRadiusX;
|
||||
radiusY = scaled.tlRadiusY;
|
||||
} else if (point.dx > right - scaled.trRadiusX &&
|
||||
point.dy < top + scaled.trRadiusY) {
|
||||
x = point.dx - right + scaled.trRadiusX;
|
||||
y = point.dy - top - scaled.trRadiusY;
|
||||
radiusX = scaled.trRadiusX;
|
||||
radiusY = scaled.trRadiusY;
|
||||
} else if (point.dx > right - scaled.brRadiusX &&
|
||||
point.dy > bottom - scaled.brRadiusY) {
|
||||
x = point.dx - right + scaled.brRadiusX;
|
||||
y = point.dy - bottom + scaled.brRadiusY;
|
||||
radiusX = scaled.brRadiusX;
|
||||
radiusY = scaled.brRadiusY;
|
||||
} else if (point.dx < left + scaled.blRadiusX &&
|
||||
point.dy > bottom - scaled.blRadiusY) {
|
||||
x = point.dx - left - scaled.blRadiusX;
|
||||
y = point.dy - bottom + scaled.blRadiusY;
|
||||
radiusX = scaled.blRadiusX;
|
||||
radiusY = scaled.blRadiusY;
|
||||
} else {
|
||||
return true; // inside and not within the rounded corner area
|
||||
}
|
||||
@ -1502,52 +1522,52 @@ class RRect {
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
if (a == null) {
|
||||
return new RRect._fromList(<double>[
|
||||
b.left * t,
|
||||
b.top * t,
|
||||
b.right * t,
|
||||
b.bottom * t,
|
||||
b.tlRadiusX * t,
|
||||
b.tlRadiusY * t,
|
||||
b.trRadiusX * t,
|
||||
b.trRadiusY * t,
|
||||
b.brRadiusX * t,
|
||||
b.brRadiusY * t,
|
||||
b.blRadiusX * t,
|
||||
b.blRadiusY * t,
|
||||
]);
|
||||
return new RRect._raw(
|
||||
left: b.left * t,
|
||||
top: b.top * t,
|
||||
right: b.right * t,
|
||||
bottom: b.bottom * t,
|
||||
tlRadiusX: b.tlRadiusX * t,
|
||||
tlRadiusY: b.tlRadiusY * t,
|
||||
trRadiusX: b.trRadiusX * t,
|
||||
trRadiusY: b.trRadiusY * t,
|
||||
brRadiusX: b.brRadiusX * t,
|
||||
brRadiusY: b.brRadiusY * t,
|
||||
blRadiusX: b.blRadiusX * t,
|
||||
blRadiusY: b.blRadiusY * t,
|
||||
);
|
||||
}
|
||||
if (b == null) {
|
||||
final double k = 1.0 - t;
|
||||
return new RRect._fromList(<double>[
|
||||
a.left * k,
|
||||
a.top * k,
|
||||
a.right * k,
|
||||
a.bottom * k,
|
||||
a.tlRadiusX * k,
|
||||
a.tlRadiusY * k,
|
||||
a.trRadiusX * k,
|
||||
a.trRadiusY * k,
|
||||
a.brRadiusX * k,
|
||||
a.brRadiusY * k,
|
||||
a.blRadiusX * k,
|
||||
a.blRadiusY * k,
|
||||
]);
|
||||
return new RRect._raw(
|
||||
left: a.left * k,
|
||||
top: a.top * k,
|
||||
right: a.right * k,
|
||||
bottom: a.bottom * k,
|
||||
tlRadiusX: a.tlRadiusX * k,
|
||||
tlRadiusY: a.tlRadiusY * k,
|
||||
trRadiusX: a.trRadiusX * k,
|
||||
trRadiusY: a.trRadiusY * k,
|
||||
brRadiusX: a.brRadiusX * k,
|
||||
brRadiusY: a.brRadiusY * k,
|
||||
blRadiusX: a.blRadiusX * k,
|
||||
blRadiusY: a.blRadiusY * k,
|
||||
);
|
||||
}
|
||||
return new RRect._fromList(<double>[
|
||||
lerpDouble(a.left, b.left, t),
|
||||
lerpDouble(a.top, b.top, t),
|
||||
lerpDouble(a.right, b.right, t),
|
||||
lerpDouble(a.bottom, b.bottom, t),
|
||||
lerpDouble(a.tlRadiusX, b.tlRadiusX, t),
|
||||
lerpDouble(a.tlRadiusY, b.tlRadiusY, t),
|
||||
lerpDouble(a.trRadiusX, b.trRadiusX, t),
|
||||
lerpDouble(a.trRadiusY, b.trRadiusY, t),
|
||||
lerpDouble(a.brRadiusX, b.brRadiusX, t),
|
||||
lerpDouble(a.brRadiusY, b.brRadiusY, t),
|
||||
lerpDouble(a.blRadiusX, b.blRadiusX, t),
|
||||
lerpDouble(a.blRadiusY, b.blRadiusY, t),
|
||||
]);
|
||||
return new RRect._raw(
|
||||
left: lerpDouble(a.left, b.left, t),
|
||||
top: lerpDouble(a.top, b.top, t),
|
||||
right: lerpDouble(a.right, b.right, t),
|
||||
bottom: lerpDouble(a.bottom, b.bottom, t),
|
||||
tlRadiusX: lerpDouble(a.tlRadiusX, b.tlRadiusX, t),
|
||||
tlRadiusY: lerpDouble(a.tlRadiusY, b.tlRadiusY, t),
|
||||
trRadiusX: lerpDouble(a.trRadiusX, b.trRadiusX, t),
|
||||
trRadiusY: lerpDouble(a.trRadiusY, b.trRadiusY, t),
|
||||
brRadiusX: lerpDouble(a.brRadiusX, b.brRadiusX, t),
|
||||
brRadiusY: lerpDouble(a.brRadiusY, b.brRadiusY, t),
|
||||
blRadiusX: lerpDouble(a.blRadiusX, b.blRadiusX, t),
|
||||
blRadiusY: lerpDouble(a.blRadiusY, b.blRadiusY, t),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -1557,15 +1577,24 @@ class RRect {
|
||||
if (runtimeType != other.runtimeType)
|
||||
return false;
|
||||
final RRect typedOther = other;
|
||||
for (int i = 0; i < _kDataSize; i += 1) {
|
||||
if (_value[i] != typedOther._value[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return left == typedOther.left &&
|
||||
top == typedOther.top &&
|
||||
right == typedOther.right &&
|
||||
bottom == typedOther.bottom &&
|
||||
tlRadiusX == typedOther.tlRadiusX &&
|
||||
tlRadiusY == typedOther.tlRadiusY &&
|
||||
trRadiusX == typedOther.trRadiusX &&
|
||||
trRadiusY == typedOther.trRadiusY &&
|
||||
blRadiusX == typedOther.blRadiusX &&
|
||||
blRadiusY == typedOther.blRadiusY &&
|
||||
brRadiusX == typedOther.brRadiusX &&
|
||||
brRadiusY == typedOther.brRadiusY;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => hashList(_value);
|
||||
int get hashCode => hashValues(left, top, right, bottom,
|
||||
tlRadiusX, tlRadiusY, trRadiusX, trRadiusY,
|
||||
blRadiusX, blRadiusY, brRadiusX, brRadiusY);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
|
||||
@ -23,13 +23,13 @@ part of dart.ui;
|
||||
|
||||
bool _rectIsValid(Rect rect) {
|
||||
assert(rect != null, 'Rect argument was null.');
|
||||
assert(!rect._value.any((double value) => value.isNaN), 'Rect argument contained a NaN value.');
|
||||
assert(!rect.hasNaN, 'Rect argument contained a NaN value.');
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _rrectIsValid(RRect rrect) {
|
||||
assert(rrect != null, 'RRect argument was null.');
|
||||
assert(!rrect._value.any((double value) => value.isNaN), 'RRect argument contained a NaN value.');
|
||||
assert(!rrect.hasNaN, 'RRect argument contained a NaN value.');
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2028,7 +2028,7 @@ class Path extends NativeFieldWrapperClass2 {
|
||||
/// argument.
|
||||
void addRRect(RRect rrect) {
|
||||
assert(_rrectIsValid(rrect));
|
||||
_addRRect(rrect._value);
|
||||
_addRRect(rrect._value32);
|
||||
}
|
||||
void _addRRect(Float32List rrect) native 'Path_addRRect';
|
||||
|
||||
@ -3259,7 +3259,7 @@ class Canvas extends NativeFieldWrapperClass2 {
|
||||
void clipRRect(RRect rrect, {bool doAntiAlias = true}) {
|
||||
assert(_rrectIsValid(rrect));
|
||||
assert(doAntiAlias != null);
|
||||
_clipRRect(rrect._value, doAntiAlias);
|
||||
_clipRRect(rrect._value32, doAntiAlias);
|
||||
}
|
||||
void _clipRRect(Float32List rrect, bool doAntiAlias) native 'Canvas_clipRRect';
|
||||
|
||||
@ -3336,7 +3336,7 @@ class Canvas extends NativeFieldWrapperClass2 {
|
||||
void drawRRect(RRect rrect, Paint paint) {
|
||||
assert(_rrectIsValid(rrect));
|
||||
assert(paint != null);
|
||||
_drawRRect(rrect._value, paint._objects, paint._data);
|
||||
_drawRRect(rrect._value32, paint._objects, paint._data);
|
||||
}
|
||||
void _drawRRect(Float32List rrect,
|
||||
List<dynamic> paintObjects,
|
||||
@ -3351,7 +3351,7 @@ class Canvas extends NativeFieldWrapperClass2 {
|
||||
assert(_rrectIsValid(outer));
|
||||
assert(_rrectIsValid(inner));
|
||||
assert(paint != null);
|
||||
_drawDRRect(outer._value, inner._value, paint._objects, paint._data);
|
||||
_drawDRRect(outer._value32, inner._value32, paint._objects, paint._data);
|
||||
}
|
||||
void _drawDRRect(Float32List outer,
|
||||
Float32List inner,
|
||||
@ -3651,7 +3651,7 @@ class Canvas extends NativeFieldWrapperClass2 {
|
||||
}
|
||||
|
||||
final Int32List colorBuffer = colors.isEmpty ? null : _encodeColorList(colors);
|
||||
final Float32List cullRectBuffer = cullRect?._value;
|
||||
final Float32List cullRectBuffer = cullRect?._value32;
|
||||
|
||||
_drawAtlas(
|
||||
paint._objects, paint._data, atlas, rstTransformBuffer, rectBuffer,
|
||||
@ -3698,7 +3698,7 @@ class Canvas extends NativeFieldWrapperClass2 {
|
||||
|
||||
_drawAtlas(
|
||||
paint._objects, paint._data, atlas, rstTransforms, rects,
|
||||
colors, blendMode.index, cullRect?._value
|
||||
colors, blendMode.index, cullRect?._value32
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
test('rect accessors', () {
|
||||
final Rect r = Rect.fromLTRB(1.0, 3.0, 5.0, 7.0);
|
||||
const Rect r = Rect.fromLTRB(1.0, 3.0, 5.0, 7.0);
|
||||
expect(r.left, equals(1.0));
|
||||
expect(r.top, equals(3.0));
|
||||
expect(r.right, equals(5.0));
|
||||
@ -16,7 +16,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('rect created by width and height', () {
|
||||
final Rect r = Rect.fromLTWH(1.0, 3.0, 5.0, 7.0);
|
||||
const Rect r = Rect.fromLTWH(1.0, 3.0, 5.0, 7.0);
|
||||
expect(r.left, equals(1.0));
|
||||
expect(r.top, equals(3.0));
|
||||
expect(r.right, equals(6.0));
|
||||
@ -26,8 +26,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('rect intersection', () {
|
||||
final Rect r1 = Rect.fromLTRB(0.0, 0.0, 100.0, 100.0);
|
||||
final Rect r2 = Rect.fromLTRB(50.0, 50.0, 200.0, 200.0);
|
||||
const Rect r1 = Rect.fromLTRB(0.0, 0.0, 100.0, 100.0);
|
||||
const Rect r2 = Rect.fromLTRB(50.0, 50.0, 200.0, 200.0);
|
||||
final Rect r3 = r1.intersect(r2);
|
||||
expect(r3.left, equals(50.0));
|
||||
expect(r3.top, equals(50.0));
|
||||
@ -38,8 +38,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('rect expandToInclude overlapping rects', () {
|
||||
final Rect r1 = Rect.fromLTRB(0.0, 0.0, 100.0, 100.0);
|
||||
final Rect r2 = Rect.fromLTRB(50.0, 50.0, 200.0, 200.0);
|
||||
const Rect r1 = Rect.fromLTRB(0.0, 0.0, 100.0, 100.0);
|
||||
const Rect r2 = Rect.fromLTRB(50.0, 50.0, 200.0, 200.0);
|
||||
final Rect r3 = r1.expandToInclude(r2);
|
||||
expect(r3.left, equals(0.0));
|
||||
expect(r3.top, equals(0.0));
|
||||
@ -50,8 +50,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('rect expandToInclude crossing rects', () {
|
||||
final Rect r1 = Rect.fromLTRB(50.0, 0.0, 50.0, 200.0);
|
||||
final Rect r2 = Rect.fromLTRB(0.0, 50.0, 200.0, 50.0);
|
||||
const Rect r1 = Rect.fromLTRB(50.0, 0.0, 50.0, 200.0);
|
||||
const Rect r2 = Rect.fromLTRB(0.0, 50.0, 200.0, 50.0);
|
||||
final Rect r3 = r1.expandToInclude(r2);
|
||||
expect(r3.left, equals(0.0));
|
||||
expect(r3.top, equals(0.0));
|
||||
@ -70,7 +70,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('rounded rect created from rect and radii', () {
|
||||
final Rect baseRect = Rect.fromLTWH(1.0, 3.0, 5.0, 7.0);
|
||||
const Rect baseRect = Rect.fromLTWH(1.0, 3.0, 5.0, 7.0);
|
||||
final RRect r = RRect.fromRectXY(baseRect, 1.0, 1.0);
|
||||
expect(r.left, equals(1.0));
|
||||
expect(r.top, equals(3.0));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user