Fix line breaks being lost when copying after selection gesture in SelectableRegion (#184421)

Original discussion: https://github.com/flutter/flutter/pull/184043

Fixes #154253 

Before this change the `_rect` used by `_SelectableFragment` was
calculated using `getBoxesForSelection` which defaults to a
`BoxHeightStyle` of `BoxHeightStyle.tight`. This style ensures the boxes
returned from `getBoxesForSelection` tightly wrap each character. This
was causing an issue when text ended or was split on new lines because
the `SelectableFragment._rect` did not include the region that actually
had the new lines. So when `_SelectableFragment` internally used
`SelectionUtils.adjustDragOffset` to clamp the position to the
selectable rect, the selectable rect is inaccurate and always results in
a position that is above the new line and not on it.

After this change the `_rect` used by `_SelectableFragment` is
calculated using `getBoxesForSelection` with a `BoxHeightStyle` of
`BoxHeightStyle.max`. This style ensures the boxes returned from
`getBoxesForSelection` cover the entire height of the line, and as a
result including the new line character region.

Other notes:

`TextPainter.getBoxesForSelection` explicitly notes that leading or
trailing new line characters will be represented by zero-width boxes.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [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.
- [x] 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.
- [x] All existing and new tests are passing.

---------

Co-authored-by: Renzo Olivares <roliv@google.com>
diff --git a/examples/api/test/material/selection_area/selection_area.2_test.dart b/examples/api/test/material/selection_area/selection_area.2_test.dart
index 91ed4ac..d97c35b 100644
--- a/examples/api/test/material/selection_area/selection_area.2_test.dart
+++ b/examples/api/test/material/selection_area/selection_area.2_test.dart
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'package:flutter/foundation.dart';
 import 'package:flutter/gestures.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/rendering.dart';
@@ -9,6 +10,17 @@
     as example;
 import 'package:flutter_test/flutter_test.dart';
 
+// This was taken directly from selectable_region_test.dart
+// in the frameworks' Widget library tests.
+Offset textOffsetToPosition(RenderParagraph paragraph, int offset) {
+  const Rect caret = Rect.fromLTWH(0.0, 0.0, 2.0, 20.0);
+  final Offset localOffset =
+      paragraph.getOffsetForCaret(TextPosition(offset: offset), caret) +
+      Offset(0.0, paragraph.preferredLineHeight);
+  return paragraph.localToGlobal(localOffset) +
+      const Offset(kIsWeb ? 1.0 : 0.0, -2.0);
+}
+
 void main() {
   testWidgets('SelectionArea Color Text Red Example Smoke Test', (
     WidgetTester tester,
@@ -80,14 +92,12 @@
       );
       // Drag to select from paragraph 1 position 4 to paragraph 3 position 25.
       final TestGesture gesture = await tester.startGesture(
-        tester.getRect(paragraph1Finder).topLeft + const Offset(50.0, 10.0),
+        textOffsetToPosition(paragraph1, 4),
         kind: PointerDeviceKind.mouse,
       );
       addTearDown(gesture.removePointer);
       await tester.pump();
-      await gesture.moveTo(
-        tester.getRect(paragraph3Finder).centerLeft + const Offset(360.0, 0.0),
-      );
+      await gesture.moveTo(textOffsetToPosition(paragraph3, 25));
       await tester.pump();
       await gesture.up();
       await tester.pumpAndSettle();
@@ -97,7 +107,7 @@
       expect(paragraph1.selections.length, 1);
       expect(
         paragraph1.selections[0],
-        const TextSelection(baseOffset: 4, extentOffset: 27),
+        const TextSelection(baseOffset: 4, extentOffset: 28),
       );
       // Bulleted list.
       for (final RenderParagraph paragraphBullet in bullets) {
@@ -263,7 +273,7 @@
         ((paragraph3ResultingSpan.children![0] as TextSpan).children![0]
                 as TextSpan)
             .text,
-        'This is some text in ano',
+        'This is some text in anot',
       );
       expect(
         (paragraph3ResultingSpan.children![0] as TextSpan).children![0].style,