buildSelectionPath function

(Path?, List<Rect>) buildSelectionPath({
  1. required TextLayoutClient layout,
  2. required String text,
  3. required TextSelection selection,
  4. bool skipWhitespace = true,
})

Build a path for a selection using any TextLayoutClient.

Implementation

(Path?, List<Rect>) buildSelectionPath({
  required TextLayoutClient layout,
  required String text,
  required TextSelection selection,
  bool skipWhitespace = true,
}) {
  final int rawStart =
      selection.start < selection.end ? selection.start : selection.end;
  final int rawEnd =
      selection.start > selection.end ? selection.start : selection.end;
  final int start = rawStart.clamp(0, text.length);
  final int end = rawEnd.clamp(0, text.length);
  if (start >= end) return (null, []);

  if (skipWhitespace) {
    final selectedText = text.substring(start, end);
    final matches = RegExp(r'\S+').allMatches(selectedText);
    if (matches.isEmpty) return (null, const <Rect>[]);

    final path = Path();
    final boxList = <Rect>[];
    for (final match in matches) {
      final runStart = start + match.start;
      final runEnd = start + match.end;
      final boxes = layout.getBoxesForSelection(
        TextSelection(baseOffset: runStart, extentOffset: runEnd),
      );
      for (final box in boxes) {
        final rect = box.toRect();
        boxList.add(rect);
        path.addRect(rect);
      }
    }

    return boxList.isEmpty ? (null, const <Rect>[]) : (path, boxList);
  }

  final boxes = layout.getBoxesForSelection(
    TextSelection(baseOffset: start, extentOffset: end),
  );
  if (boxes.isEmpty) return (null, const <Rect>[]);

  final path = Path();
  final boxList = <Rect>[];
  for (final box in boxes) {
    final rect = box.toRect();
    boxList.add(rect);
    path.addRect(rect);
  }

  return (path, boxList);
}