Unverified Commit 64173f75 authored by LongCatIsLooong's avatar LongCatIsLooong Committed by GitHub

Check if a double is NaN before converting to it int (#61940)

parent 056e455e
......@@ -127,6 +127,13 @@ class MatrixUtils {
///
/// This function assumes the given point has a z-coordinate of 0.0. The
/// z-coordinate of the result is ignored.
///
/// While not common, this method may return (NaN, NaN), iff the given `point`
/// results in a "point at infinity" in homogeneous coordinates after applying
/// the `transform`. For example, a [RenderObject] may set its transform to
/// the zero matrix to indicate its content is currently not visible. Trying
/// to convert an `Offset` to its coordinate space always results in
/// (NaN, NaN).
static Offset transformPoint(Matrix4 transform, Offset point) {
final Float64List storage = transform.storage;
final double x = point.dx;
......
......@@ -2293,7 +2293,9 @@ abstract class RenderBox extends RenderObject {
/// coordinate system of `ancestor` (which must be an ancestor of this render
/// object) instead of to the global coordinate system.
///
/// This method is implemented in terms of [getTransformTo].
/// This method is implemented in terms of [getTransformTo]. If the transform
/// matrix puts the given `point` on the line at infinity (for instance, when
/// the transform matrix is the zero matrix), this method returns (NaN, NaN).
Offset localToGlobal(Offset point, { RenderObject ancestor }) {
return MatrixUtils.transformPoint(getTransformTo(ancestor), point);
}
......
......@@ -1936,10 +1936,12 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
Offset _getPixelPerfectCursorOffset(Rect caretRect) {
final Offset caretPosition = localToGlobal(caretRect.topLeft);
final double pixelMultiple = 1.0 / _devicePixelRatio;
final int quotientX = (caretPosition.dx / pixelMultiple).round();
final int quotientY = (caretPosition.dy / pixelMultiple).round();
final double pixelPerfectOffsetX = quotientX * pixelMultiple - caretPosition.dx;
final double pixelPerfectOffsetY = quotientY * pixelMultiple - caretPosition.dy;
final double pixelPerfectOffsetX = caretPosition.dx.isFinite
? (caretPosition.dx / pixelMultiple).round() * pixelMultiple - caretPosition.dx
: caretPosition.dx;
final double pixelPerfectOffsetY = caretPosition.dy.isFinite
? (caretPosition.dy / pixelMultiple).round() * pixelMultiple - caretPosition.dy
: caretPosition.dy;
return Offset(pixelPerfectOffsetX, pixelPerfectOffsetY);
}
......
......@@ -4321,6 +4321,30 @@ void main() {
expect(scrollController.offset, 0);
});
testWidgets('getLocalRectForCaret does not throw when it sees an infinite point', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: SkipPainting(
child: Transform(
transform: Matrix4.zero(),
child: EditableText(
controller: TextEditingController(),
focusNode: FocusNode(),
style: textStyle,
cursorColor: Colors.blue,
backgroundCursorColor: Colors.grey,
),
),
),
),
);
final EditableTextState state = tester.state<EditableTextState>(find.byType(EditableText));
final Rect rect = state.renderEditable.getLocalRectForCaret(const TextPosition(offset: 0));
expect(rect.isFinite, false);
expect(tester.takeException(), isNull);
});
testWidgets('obscured multiline fields throw an exception', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
expect(
......@@ -5350,3 +5374,15 @@ class NoImplicitScrollPhysics extends AlwaysScrollableScrollPhysics {
return NoImplicitScrollPhysics(parent: buildParent(ancestor));
}
}
class SkipPainting extends SingleChildRenderObjectWidget {
const SkipPainting({ Key key, Widget child }): super(key: key, child: child);
@override
SkipPaintingRenderObject createRenderObject(BuildContext context) => SkipPaintingRenderObject();
}
class SkipPaintingRenderObject extends RenderProxyBox {
@override
void paint(PaintingContext context, Offset offset) { }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment