未验证 提交 8eebf82c 编写于 作者: F Ferhat 提交者: GitHub

Fix path.contains failure when devicepixelratio != 1.0 (#15743)

* Fix path contains failure due to devicepixelratio
上级 97f919cb
......@@ -89,7 +89,8 @@ class SurfacePaint implements ui.Paint {
_paintData = _paintData.clone();
_frozen = false;
}
_paintData.color = value.runtimeType == ui.Color ? value : ui.Color(value.value);
_paintData.color =
value.runtimeType == ui.Color ? value : ui.Color(value.value);
}
@override
......@@ -286,8 +287,7 @@ class SurfacePath implements ui.Path {
///
/// This copy is fast and does not require additional memory unless either
/// the `source` path or the path returned by this constructor are modified.
SurfacePath.from(SurfacePath source)
: subpaths = _deepCopy(source.subpaths);
SurfacePath.from(SurfacePath source) : subpaths = _deepCopy(source.subpaths);
SurfacePath._shallowCopy(SurfacePath source)
: subpaths = List<Subpath>.from(source.subpaths);
......@@ -418,8 +418,8 @@ class SurfacePath implements ui.Path {
void relativeCubicTo(
double x1, double y1, double x2, double y2, double x3, double y3) {
_ensurePathStarted();
_commands.add(BezierCurveTo(x1 + _currentX, y1 + _currentY,
x2 + _currentX, y2 + _currentY, x3 + _currentX, y3 + _currentY));
_commands.add(BezierCurveTo(x1 + _currentX, y1 + _currentY, x2 + _currentX,
y2 + _currentY, x3 + _currentX, y3 + _currentY));
_setCurrentPoint(x3 + _currentX, y3 + _currentY);
}
......@@ -431,7 +431,7 @@ class SurfacePath implements ui.Path {
@override
void conicTo(double x1, double y1, double x2, double y2, double w) {
final List<ui.Offset> quads =
Conic(_currentX, _currentY, x1, y1, x2, y2, w).toQuads();
Conic(_currentX, _currentY, x1, y1, x2, y2, w).toQuads();
final int len = quads.length;
for (int i = 1; i < len; i += 2) {
quadraticBezierTo(
......@@ -504,12 +504,12 @@ class SurfacePath implements ui.Path {
/// as reference for implementation.
@override
void arcToPoint(
ui.Offset arcEnd, {
ui.Radius radius = ui.Radius.zero,
double rotation = 0.0,
bool largeArc = false,
bool clockwise = true,
}) {
ui.Offset arcEnd, {
ui.Radius radius = ui.Radius.zero,
double rotation = 0.0,
bool largeArc = false,
bool clockwise = true,
}) {
assert(offsetIsValid(arcEnd));
assert(radiusIsValid(radius));
// _currentX, _currentY are the coordinates of start point on path,
......@@ -631,15 +631,16 @@ class SurfacePath implements ui.Path {
/// describe an arc.
@override
void relativeArcToPoint(
ui.Offset arcEndDelta, {
ui.Radius radius = ui.Radius.zero,
double rotation = 0.0,
bool largeArc = false,
bool clockwise = true,
}) {
ui.Offset arcEndDelta, {
ui.Radius radius = ui.Radius.zero,
double rotation = 0.0,
bool largeArc = false,
bool clockwise = true,
}) {
assert(offsetIsValid(arcEndDelta));
assert(radiusIsValid(radius));
arcToPoint(ui.Offset(_currentX + arcEndDelta.dx, _currentY + arcEndDelta.dy),
arcToPoint(
ui.Offset(_currentX + arcEndDelta.dx, _currentY + arcEndDelta.dy),
radius: radius,
rotation: rotation,
largeArc: largeArc,
......@@ -652,8 +653,7 @@ class SurfacePath implements ui.Path {
void addRect(ui.Rect rect) {
assert(rectIsValid(rect));
_openNewSubpath(rect.left, rect.top);
_commands
.add(RectCommand(rect.left, rect.top, rect.width, rect.height));
_commands.add(RectCommand(rect.left, rect.top, rect.width, rect.height));
}
/// Adds a new subpath that consists of a curve that forms the
......@@ -767,7 +767,8 @@ class SurfacePath implements ui.Path {
}
}
void _addPathWithMatrix(SurfacePath path, double dx, double dy, Float64List matrix) {
void _addPathWithMatrix(
SurfacePath path, double dx, double dy, Float64List matrix) {
final Matrix4 transform = Matrix4.fromFloat64List(matrix);
transform.translate(dx, dy);
subpaths.addAll(path.transform(transform.storage).subpaths);
......@@ -909,16 +910,25 @@ class SurfacePath implements ui.Path {
}
return true;
}
// TODO: For improved performance, handle Ellipse special case.
}
}
final ui.Size size = window.physicalSize / window.devicePixelRatio;
final ui.Size size = window.physicalSize;
// If device pixel ratio has changed we can't reuse prior raw recorder.
if (_rawRecorder != null &&
_rawRecorder._devicePixelRatio !=
EngineWindow.browserDevicePixelRatio) {
_rawRecorder = null;
}
_rawRecorder ??= ui.RawRecordingCanvas(size);
// Account for the shift due to padding.
_rawRecorder.translate(-BitmapCanvas.kPaddingPixels.toDouble(),
-BitmapCanvas.kPaddingPixels.toDouble());
_rawRecorder.drawPath(
this, (SurfacePaint()..color = const ui.Color(0xFF000000)).paintData);
final bool result = _rawRecorder._canvasPool.context.isPointInPath(pointX, pointY);
final double recorderDevicePixelRatio = _rawRecorder._devicePixelRatio;
final bool result = _rawRecorder._canvasPool.context.isPointInPath(
pointX * recorderDevicePixelRatio, pointY * recorderDevicePixelRatio);
_rawRecorder.dispose();
return result;
}
......
......@@ -3,7 +3,9 @@
// found in the LICENSE file.
import 'package:test/test.dart';
import 'package:ui/ui.dart';
import 'dart:js_util' as js_util;
import 'dart:html' as html;
import 'package:ui/ui.dart' hide window;
import 'package:ui/src/engine.dart';
import 'matchers.dart';
......@@ -252,4 +254,21 @@ void main() {
// Expect original path to stay the same.
expect(path.getBounds(), const Rect.fromLTRB(25, 30, 100, 200));
});
// Regression test for https://github.com/flutter/flutter/issues/44470
test('Should handle contains for devicepixelratio != 1.0', () {
js_util.setProperty(html.window, 'devicePixelRatio', 4.0);
window.debugOverrideDevicePixelRatio(4.0);
final path = Path()
..moveTo(50, 0)
..lineTo(100, 100)
..lineTo(0, 100)
..lineTo(50, 0)
..close();
expect(path.contains(Offset(50, 50)), isTrue);
js_util.setProperty(html.window, 'devicePixelRatio', 1.0);
window.debugOverrideDevicePixelRatio(1.0);
// TODO: Investigate failure on CI. Locally this passes.
// [Exception... "Failure" nsresult: "0x80004005 (NS_ERROR_FAILURE)"
}, skip: browserEngine == BrowserEngine.firefox);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册