[two_dimensional_scrollables] Fix paint bug when rows/columns are pinned and axes are reversed (#5038)

Fixes https://github.com/flutter/flutter/issues/135386

This adds one more golden to verify the painting, but once public mock_canvas rolls to stable in flutter_test, we can remove all of the goldens and just verify using the `paints` method.
diff --git a/packages/two_dimensional_scrollables/CHANGELOG.md b/packages/two_dimensional_scrollables/CHANGELOG.md
index e99a4bd..570519e 100644
--- a/packages/two_dimensional_scrollables/CHANGELOG.md
+++ b/packages/two_dimensional_scrollables/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.0.3
+
+* Fixes paint issue when axes are reversed and TableView has pinned rows and columns.
+
 ## 0.0.2
 
 * Fixes override of default TwoDimensionalChildBuilderDelegate.addRepaintBoundaries.
diff --git a/packages/two_dimensional_scrollables/lib/src/table_view/table.dart b/packages/two_dimensional_scrollables/lib/src/table_view/table.dart
index 4b1b5a9..b8829f0 100644
--- a/packages/two_dimensional_scrollables/lib/src/table_view/table.dart
+++ b/packages/two_dimensional_scrollables/lib/src/table_view/table.dart
@@ -723,8 +723,12 @@
         needsCompositing,
         offset,
         Rect.fromLTWH(
-          _pinnedColumnsExtent,
-          _pinnedRowsExtent,
+          axisDirectionIsReversed(horizontalAxisDirection)
+              ? 0.0
+              : _pinnedColumnsExtent,
+          axisDirectionIsReversed(verticalAxisDirection)
+              ? 0.0
+              : _pinnedRowsExtent,
           viewportDimension.width - _pinnedColumnsExtent,
           viewportDimension.height - _pinnedRowsExtent,
         ),
@@ -750,8 +754,12 @@
         needsCompositing,
         offset,
         Rect.fromLTWH(
-          0.0,
-          _pinnedRowsExtent,
+          axisDirectionIsReversed(horizontalAxisDirection)
+              ? viewportDimension.width - _pinnedColumnsExtent
+              : 0.0,
+          axisDirectionIsReversed(verticalAxisDirection)
+              ? 0.0
+              : _pinnedRowsExtent,
           _pinnedColumnsExtent,
           viewportDimension.height - _pinnedRowsExtent,
         ),
@@ -778,8 +786,12 @@
         needsCompositing,
         offset,
         Rect.fromLTWH(
-          _pinnedColumnsExtent,
-          0.0,
+          axisDirectionIsReversed(horizontalAxisDirection)
+              ? 0.0
+              : _pinnedColumnsExtent,
+          axisDirectionIsReversed(horizontalAxisDirection)
+              ? viewportDimension.height - _pinnedRowsExtent
+              : 0.0,
           viewportDimension.width - _pinnedColumnsExtent,
           _pinnedRowsExtent,
         ),
diff --git a/packages/two_dimensional_scrollables/pubspec.yaml b/packages/two_dimensional_scrollables/pubspec.yaml
index fba32c5..bd30a01 100644
--- a/packages/two_dimensional_scrollables/pubspec.yaml
+++ b/packages/two_dimensional_scrollables/pubspec.yaml
@@ -1,6 +1,6 @@
 name: two_dimensional_scrollables
 description: Widgets that scroll using the two dimensional scrolling foundation.
-version: 0.0.2
+version: 0.0.3
 repository: https://github.com/flutter/packages/tree/main/packages/two_dimensional_scrollables
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+two_dimensional_scrollables%22+
 
diff --git a/packages/two_dimensional_scrollables/test/table_view/goldens/reversed.pinned.painting.png b/packages/two_dimensional_scrollables/test/table_view/goldens/reversed.pinned.painting.png
new file mode 100644
index 0000000..f3355f0
--- /dev/null
+++ b/packages/two_dimensional_scrollables/test/table_view/goldens/reversed.pinned.painting.png
Binary files differ
diff --git a/packages/two_dimensional_scrollables/test/table_view/goldens/tableSpanDecoration.defaultMainAxis.png b/packages/two_dimensional_scrollables/test/table_view/goldens/tableSpanDecoration.defaultMainAxis.png
index 8fe4353..baf2cd3 100644
--- a/packages/two_dimensional_scrollables/test/table_view/goldens/tableSpanDecoration.defaultMainAxis.png
+++ b/packages/two_dimensional_scrollables/test/table_view/goldens/tableSpanDecoration.defaultMainAxis.png
Binary files differ
diff --git a/packages/two_dimensional_scrollables/test/table_view/goldens/tableSpanDecoration.horizontalMainAxis.png b/packages/two_dimensional_scrollables/test/table_view/goldens/tableSpanDecoration.horizontalMainAxis.png
index f9a1bc8..6a04b91 100644
--- a/packages/two_dimensional_scrollables/test/table_view/goldens/tableSpanDecoration.horizontalMainAxis.png
+++ b/packages/two_dimensional_scrollables/test/table_view/goldens/tableSpanDecoration.horizontalMainAxis.png
Binary files differ
diff --git a/packages/two_dimensional_scrollables/test/table_view/table_test.dart b/packages/two_dimensional_scrollables/test/table_view/table_test.dart
index 3fbd4e7..75cdfb0 100644
--- a/packages/two_dimensional_scrollables/test/table_view/table_test.dart
+++ b/packages/two_dimensional_scrollables/test/table_view/table_test.dart
@@ -957,11 +957,13 @@
         columnBuilder: (int index) => TableSpan(
           extent: const FixedTableSpanExtent(200.0),
           foregroundDecoration: const TableSpanDecoration(
-              border: TableSpanBorder(
-                  trailing: BorderSide(
-            color: Colors.orange,
-            width: 3,
-          ))),
+            border: TableSpanBorder(
+              trailing: BorderSide(
+                color: Colors.orange,
+                width: 3,
+              ),
+            ),
+          ),
           backgroundDecoration: TableSpanDecoration(
             color: index.isEven ? Colors.red : null,
           ),
@@ -969,11 +971,13 @@
         rowBuilder: (int index) => TableSpan(
           extent: const FixedTableSpanExtent(200.0),
           foregroundDecoration: const TableSpanDecoration(
-              border: TableSpanBorder(
-                  leading: BorderSide(
-            color: Colors.green,
-            width: 3,
-          ))),
+            border: TableSpanBorder(
+              leading: BorderSide(
+                color: Colors.green,
+                width: 3,
+              ),
+            ),
+          ),
           backgroundDecoration: TableSpanDecoration(
             color: index.isOdd ? Colors.blue : null,
           ),
@@ -1002,11 +1006,13 @@
         columnBuilder: (int index) => TableSpan(
           extent: const FixedTableSpanExtent(200.0),
           foregroundDecoration: const TableSpanDecoration(
-              border: TableSpanBorder(
-                  trailing: BorderSide(
-            color: Colors.orange,
-            width: 3,
-          ))),
+            border: TableSpanBorder(
+              trailing: BorderSide(
+                color: Colors.orange,
+                width: 3,
+              ),
+            ),
+          ),
           backgroundDecoration: TableSpanDecoration(
             color: index.isEven ? Colors.red : null,
           ),
@@ -1014,11 +1020,13 @@
         rowBuilder: (int index) => TableSpan(
           extent: const FixedTableSpanExtent(200.0),
           foregroundDecoration: const TableSpanDecoration(
-              border: TableSpanBorder(
-                  leading: BorderSide(
-            color: Colors.green,
-            width: 3,
-          ))),
+            border: TableSpanBorder(
+              leading: BorderSide(
+                color: Colors.green,
+                width: 3,
+              ),
+            ),
+          ),
           backgroundDecoration: TableSpanDecoration(
             color: index.isOdd ? Colors.blue : null,
           ),
@@ -1040,6 +1048,63 @@
       );
     });
 
+    testWidgets('paint rects are correct when reversed and pinned',
+        (WidgetTester tester) async {
+      // TODO(Piinks): Rewrite this to remove golden files from this repo when
+      //  mock_canvas is public - https://github.com/flutter/flutter/pull/131631
+      // foreground, background, and precedence per mainAxis
+      final TableView tableView = TableView.builder(
+        verticalDetails: const ScrollableDetails.vertical(reverse: true),
+        horizontalDetails: const ScrollableDetails.horizontal(reverse: true),
+        rowCount: 2,
+        pinnedRowCount: 1,
+        columnCount: 2,
+        pinnedColumnCount: 1,
+        columnBuilder: (int index) => TableSpan(
+          extent: const FixedTableSpanExtent(200.0),
+          foregroundDecoration: const TableSpanDecoration(
+            border: TableSpanBorder(
+              trailing: BorderSide(
+                color: Colors.orange,
+                width: 3,
+              ),
+            ),
+          ),
+          backgroundDecoration: TableSpanDecoration(
+            color: index.isEven ? Colors.red : null,
+          ),
+        ),
+        rowBuilder: (int index) => TableSpan(
+          extent: const FixedTableSpanExtent(200.0),
+          foregroundDecoration: const TableSpanDecoration(
+            border: TableSpanBorder(
+              leading: BorderSide(
+                color: Colors.green,
+                width: 3,
+              ),
+            ),
+          ),
+          backgroundDecoration: TableSpanDecoration(
+            color: index.isOdd ? Colors.blue : null,
+          ),
+        ),
+        cellBuilder: (_, TableVicinity vicinity) {
+          return const SizedBox.square(
+            dimension: 200,
+            child: Center(child: FlutterLogo()),
+          );
+        },
+      );
+
+      await tester.pumpWidget(MaterialApp(home: tableView));
+      await tester.pumpAndSettle();
+      await expectLater(
+        find.byType(TableView),
+        matchesGoldenFile('goldens/reversed.pinned.painting.png'),
+        skip: !runGoldens,
+      );
+    });
+
     testWidgets('mouse handling', (WidgetTester tester) async {
       int enterCounter = 0;
       int exitCounter = 0;