Skip to content

Commit 9a04500

Browse files
authored
Fix the drawing position of OutlineInputBorder (#158440)
Fixes #150109. 1. There are two golden file tests broken. I have read the document for the golden file test, but I'm not sure if I should do something else. 2. Modify the test because of drawing position changes. ## Changes ```dart import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( body: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Directionality( textDirection: TextDirection.ltr, child: RepaintBoundary( child: InputDecorator( isFocused: true, isEmpty: true, decoration: InputDecoration( labelText: 'label', border: OutlineInputBorder( borderRadius: BorderRadius.circular(30.0), gapPadding: 0.0, ), ), ), ), ), Directionality( textDirection: TextDirection.rtl, child: RepaintBoundary( child: InputDecorator( isFocused: true, isEmpty: true, decoration: InputDecoration( labelText: 'label', border: OutlineInputBorder( borderRadius: BorderRadius.circular(30.0), gapPadding: 0.0, ), ), ), ), ), ], ), ), ), )); } ``` | Before | After | | ---------------------------------------- | ------------------------------------------------------ | | ![Before](https://github.com/user-attachments/assets/98fcda4d-9cfa-4b7a-a68e-f978d4c63481) | ![After](https://github.com/user-attachments/assets/d677e3a8-a88a-44d8-8997-64187537c438) | ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent 2e7b562 commit 9a04500

File tree

2 files changed

+11
-13
lines changed

2 files changed

+11
-13
lines changed

packages/flutter/lib/src/material/input_border.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ class OutlineInputBorder extends InputBorder {
428428
@override
429429
bool get preferPaintInterior => true;
430430

431-
Path _gapBorderPath(Canvas canvas, RRect center, double start, double extent) {
431+
Path _gapBorderPath(Canvas canvas, RRect center, double outerWidth, double start, double extent) {
432432
// When the corner radii on any side add up to be greater than the
433433
// given height, each radius has to be scaled to not exceed the
434434
// size of the width/height of the RRect.
@@ -482,14 +482,14 @@ class OutlineInputBorder extends InputBorder {
482482
// Draw top border from gap end to top right corner and draw top right corner.
483483
const double trCornerArcStart = (3 * math.pi) / 2.0;
484484
const double trCornerArcSweep = cornerArcSweep;
485-
if (start + extent < scaledRRect.width - scaledRRect.trRadiusX) {
485+
if (start + extent < outerWidth - scaledRRect.trRadiusX) {
486486
path.moveTo(scaledRRect.left + start + extent, scaledRRect.top);
487487
path.lineTo(scaledRRect.right - scaledRRect.trRadiusX, scaledRRect.top);
488488
if (scaledRRect.trRadius != Radius.zero) {
489489
path.addArc(trCorner, trCornerArcStart, trCornerArcSweep);
490490
}
491-
} else if (start + extent < scaledRRect.width) {
492-
final double dx = scaledRRect.width - (start + extent);
491+
} else if (start + extent < outerWidth) {
492+
final double dx = outerWidth - (start + extent);
493493
final double sweep = math.asin(clampDouble(1 - dx / scaledRRect.trRadiusX, 0.0, 1.0));
494494
path.addArc(trCorner, trCornerArcStart + sweep, trCornerArcSweep - sweep);
495495
}
@@ -546,7 +546,7 @@ class OutlineInputBorder extends InputBorder {
546546
TextDirection.rtl => gapStart + gapPadding - extent,
547547
TextDirection.ltr => gapStart - gapPadding,
548548
};
549-
final Path path = _gapBorderPath(canvas, center, math.max(0.0, start), extent);
549+
final Path path = _gapBorderPath(canvas, center, outer.width, math.max(0.0, start), extent);
550550
canvas.drawPath(path, paint);
551551
}
552552
}

packages/flutter/test/material/input_decorator_test.dart

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,8 +1634,9 @@ void main() {
16341634
);
16351635
});
16361636

1637+
// Regression test for https://github.com/flutter/flutter/issues/82321.
1638+
// Regression test for https://github.com/flutter/flutter/issues/150109.
16371639
testWidgets('OutlineBorder starts at the right position when border radius is taller than horizontal content padding', (WidgetTester tester) async {
1638-
// This is a regression test for https://github.com/flutter/flutter/issues/82321.
16391640
Widget buildFrame(TextDirection textDirection) {
16401641
return MaterialApp(
16411642
home: Scaffold(
@@ -1677,8 +1678,8 @@ void main() {
16771678
],
16781679
// The points just before the label bottom left corner should be part of the border.
16791680
includes: <Offset>[
1680-
labelBottomLeftLocalToBorder - const Offset(1, 0),
1681-
labelBottomLeftLocalToBorder - const Offset(1, 1),
1681+
labelBottomLeftLocalToBorder + const Offset(-1, 0),
1682+
labelBottomLeftLocalToBorder + const Offset(-1, -1),
16821683
],
16831684
)
16841685
..restore(),
@@ -1687,10 +1688,7 @@ void main() {
16871688
await tester.pumpWidget(buildFrame(TextDirection.rtl));
16881689
borderBox = InputDecorator.containerOf(tester.element(findBorderPainter()))!;
16891690
// Convert label bottom right offset to border path coordinate system.
1690-
Offset labelBottomRightLocalToBorder = borderBox.globalToLocal(getLabelRect(tester).bottomRight);
1691-
// TODO(bleroux): determine why the position has to be moved by 2 pixels to the right.
1692-
// See https://github.com/flutter/flutter/issues/150109.
1693-
labelBottomRightLocalToBorder += const Offset(2, 0);
1691+
final Offset labelBottomRightLocalToBorder = borderBox.globalToLocal(getLabelRect(tester).bottomRight);
16941692

16951693
expect(findBorderPainter(), paints
16961694
..save()
@@ -1702,7 +1700,7 @@ void main() {
17021700
// The points just after the label bottom right corner should be part of the border.
17031701
includes: <Offset>[
17041702
labelBottomRightLocalToBorder + const Offset(1, 0),
1705-
labelBottomRightLocalToBorder + const Offset(1, 1),
1703+
labelBottomRightLocalToBorder + const Offset(1, -1),
17061704
],
17071705
)
17081706
..restore(),

0 commit comments

Comments
 (0)