Repository: flutter
Issue: When using multiple WidgetSpan, getOffsetForCaret returns incorrect caret positions
Labels: framework,has reproducible steps,P2,team-text-input,triaged-text-input,found in release: 3.24,found in release: 3.26

### Steps to reproduce

1.	Copy the example below to [DartPad](https://dartpad.dev/?sample=counter).
2.	The blue text shows the clicked area, while the red position marks the caret.
<img width="569" alt="image" src="https://github.com/user-attachments/assets/32acde4c-8d46-4d2a-84f4-87cbf4d17f95">

4.	Clicking on “1” or “2” moves the caret to “a” or “b” as expected.
5.	However, clicking on “4” incorrectly moves the caret to “c”, and similarly, clicking on “6” sends it to “d”.

### Expected results

When clicking on 4 and 6, the caret behavior matches that of clicking on 2, where the caret correctly jumps to the right.

### Actual results

The caret positioning is inconsistent with expectations.

### Code sample

<details open><summary>Code sample</summary>

```dart
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorSchemeSeed: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({
    super.key,
    required this.title,
  });

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // Caret position
  Rect rect = const Rect.fromLTWH(10, 10, 30, 30);

  handleTapDown(Offset globalPosition) {
    var paragraph = findParagraph();

    var localPosition = paragraph.globalToLocal(globalPosition);

    // Focus here
    var textPosition = paragraph.getPositionForOffset(localPosition);

    var caretPrototype = const Rect.fromLTWH(0, 0, 1, 40);

    var caretOffset = paragraph.getOffsetForCaret(textPosition, caretPrototype);

    var caretPosition =
        paragraph.localToGlobal(caretOffset) & caretPrototype.size;

    print(textPosition);
    print(caretPosition);
    setState(() {
      rect = caretPosition;
    });
  }

  // ignore this
  RenderParagraph findParagraph() {
    var renderObj = context.findRenderObject();
    late RenderParagraph paragraph;

    find(RenderObject object) {
      if (object is RenderParagraph) paragraph = object;
      object.visitChildren(find);
    }

    find(renderObj!);

    return paragraph;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        onTapDown: (details) {
          handleTapDown(details.globalPosition);
        },
        child: Stack(
          children: [
            Center(
              child: Text.rich(
                style: const TextStyle(
                  fontSize: 48,
                ),
                TextSpan(
                  children: [
                    const TextSpan(text: "A"),
                    WidgetSpan(
                      alignment: PlaceholderAlignment.middle,
                      child: Container(
                        width: 60,
                        height: 40,
                        decoration: BoxDecoration(border: Border.all()),
                      ),
                    ),
                    const TextSpan(text: "A"),
                    WidgetSpan(
                      alignment: PlaceholderAlignment.middle,
                      child: Container(
                        width: 80,
                        height: 40,
                        decoration: BoxDecoration(border: Border.all()),
                      ),
                    ),
                    const TextSpan(text: "A"),
                    WidgetSpan(
                      alignment: PlaceholderAlignment.middle,
                      child: Container(
                        width: 60,
                        height: 40,
                        decoration: BoxDecoration(border: Border.all()),
                      ),
                    ),
                    const TextSpan(text: "A"),
                  ],
                ),
              ),
            ),
            DebugRectWidget(rect: rect),
          ],
        ),
      ),
    );
  }
}

class DebugRectWidget extends StatefulWidget {
  const DebugRectWidget({super.key, required this.rect});

  final Rect rect;

  @override
  State<DebugRectWidget> createState() => _DebugRectWidgetState();
}

class _DebugRectWidgetState extends State<DebugRectWidget> {
  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: RectPainter(widget.rect),
    );
  }
}

class RectPainter extends CustomPainter {
  final Rect rect;

  RectPainter(this.rect);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1;

    canvas.drawRect(rect, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

```

</details>


### Screenshots or Video

<details open>
<summary>Screenshots / Video demonstration</summary>

[Upload media here]

</details>


### Logs

<details open><summary>Logs</summary>

```console
[Paste your logs here]
```

</details>


### Flutter Doctor output

<details open><summary>Doctor output</summary>

```console
[✓] Flutter (Channel stable, 3.24.1, on macOS 14.6.1 23G93 darwin-arm64, locale
    zh-Hans-CN)
    • Flutter version 3.24.1 on channel stable at /Users/xxxx/code/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 5874a72aa4 (4 weeks ago), 2024-08-20 16:46:00 -0500
    • Engine revision c9b9d5780d
    • Dart version 3.5.1
    • DevTools version 2.37.2
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn

[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/to/macos-android-setup for detailed
      instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.


[!] Xcode - develop for iOS and macOS (Xcode 16.0)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 16A242d
    ! iOS 18.0 Simulator not installed; this may be necessary for iOS and macOS
      development.
      To download and install the platform, open Xcode, select Xcode > Settings >
      Platforms,
      and click the GET button for the required platform.

      For more information, please visit:
        https://developer.apple.com/documentation/xcode/installing-additional-simula
        tor-runtimes
    • CocoaPods version 1.15.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (not installed)
    • Android Studio not found; download from
      https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/to/macos-android-setup for detailed
      instructions).

[✓] VS Code (version 1.93.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.96.0

[✓] VS Code (version 1.92.0-insider)
    • VS Code at /Applications/Visual Studio Code - Insiders.app/Contents
    • Flutter extension version 3.92.0

[✓] Connected device (3 available)
    • macOS (desktop)                 • macos                 • darwin-arm64   •
      macOS 14.6.1 23G93 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad • darwin         •
      macOS 14.6.1 23G93 darwin-arm64
    • Chrome (web)                    • chrome                • web-javascript •
      Google Chrome 128.0.6613.138

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 3 categories.
```

</details>