layoutOverflow method

void layoutOverflow()

Implementation

void layoutOverflow() {
  final bool didOverflowWidth = _didVisualOverflow();
  layoutOfficalOverflow(didOverflowWidth);
  _overflowRect = null;
  _overflowRects = null;
  if (overflowWidget != null) {
    // #97, the overflowWidget is already added, we must layout it as official.
    lastChild!.layout(
      BoxConstraints(
        maxWidth: constraints.maxWidth,
        maxHeight:
            overflowWidget!.maxHeight ?? textPainter.preferredLineHeight,
      ),
      parentUsesSize: true,
    );

    if (!_hasVisualOverflow) {
      return;
    }
    //assert(textPainter.width >= lastChild!.size.width);

    final TextParentData textParentData =
        lastChild!.parentData as TextParentData;
    textParentData.scale = 1.0;

    final Rect rect = Offset.zero & size;
    final Size overflowWidgetSize = lastChild!.size;
    final TextOverflowPosition textOverflowPosition =
        overflowWidget!.position;
    final int maxOffset = text!.toPlainText().runes.length;
    if (textOverflowPosition == TextOverflowPosition.end) {
      final TextSelection overflowSelection = TextSelection(
        baseOffset: textPainter
            .getPositionForOffset(rect.bottomRight -
                Offset(
                    overflowWidgetSize.width, overflowWidgetSize.height / 2))
            .offset,
        extentOffset:
            textPainter.getPositionForOffset(rect.bottomRight).offset,
      );

      textParentData.offset = rect.bottomRight -
          Offset(overflowWidgetSize.width, overflowWidgetSize.height);

      _setOverflowRect(
        overflowSelection,
        overflowWidgetSize,
        textParentData,
        rect,
        maxOffset,
        overflowWidget!.position,
      );
    }
    // middle/start
    else {
      assert(textPainter.maxLines != null);

      int start = 0;
      int end = 0;
      final int maxLines = textPainter.maxLines!;
      final bool even = maxLines % 2 == 0;

      // middle
      if (textOverflowPosition == TextOverflowPosition.middle) {
        // Rect textRect = Offset.zero & reversedTextPainter.size;

        // TextPosition position = reversedTextPainter.getPositionForOffset(even
        //     ? textRect.centerRight - Offset(overflowWidgetSize.width, 0)
        //     : textRect.center - Offset(overflowWidgetSize.width / 2, 0));

        // end = maxOffset - position.offset;

        TextPosition position = textPainter.getPositionForOffset(even
            ? Offset(
                0, rect.centerLeft.dy + textPainter.preferredLineHeight / 2.0)
            : rect.center - Offset(overflowWidgetSize.width / 2, 0));
        position =
            convertTextPainterPostionToTextInputPostion(text!, position)!;

        start = position.offset;
        end = start + 1;
      }
      // start
      else {
        // final TextPainter reversedTextPainter = _copyTextPainter(
        //   inlineSpan: _reversedSpan(text!),
        //   maxLines: textPainter.maxLines,
        // );
        // reversedTextPainter.setPlaceholderDimensions(
        //     placeholderDimensions?.reversed.toList());
        // reversedTextPainter.layout(
        //   minWidth: constraints.minWidth,
        //   maxWidth: constraints.maxWidth,
        // );
        // final TextPosition position =
        //     reversedTextPainter.getPositionForOffset(rect.bottomRight);
        TextPosition position = textPainter.getPositionForOffset(Offset(
            overflowWidgetSize.width, textPainter.preferredLineHeight / 2));
        position =
            convertTextPainterPostionToTextInputPostion(text!, position)!;

        end = position.offset;
      }

      final _TextRange range =
          _TextRange(math.min(start, end), math.max(start, end));
      final List<int> hideWidgets = <int>[];

      final TextPainter testTextPainter = _findNoOverflow(range, hideWidgets);

      assert(!_hasVisualOverflow);

      final InlineSpan oldSpan = textPainter.text!;
      // recreate text
      textPainter.text = testTextPainter.text;
      extractPlaceholderSpans(textPainter.text!);
      _cachedPlainText = null;
      layoutChildren(constraints, hideWidgets: hideWidgets);
      layoutText(
        minWidth: constraints.minWidth,
        maxWidth: constraints.maxWidth,
        forceLayout: true,
      );

      setParentData();

      final Size textSize = textPainter.size;
      size = constraints.constrain(textSize);

      if (textOverflowPosition == TextOverflowPosition.start) {
        final TextSelection overflowSelection = TextSelection(
          baseOffset: textPainter.getPositionForOffset(Offset.zero).offset,
          extentOffset: textPainter
              .getPositionForOffset(Offset(overflowWidgetSize.width, 0))
              .offset,
        );

        textParentData.offset = getCaretOffset(
          TextPosition(offset: overflowSelection.baseOffset),
        );

        _setOverflowRect(
          overflowSelection,
          overflowWidgetSize,
          textParentData,
          rect,
          maxOffset,
          overflowWidget!.position,
        );
      }
      // middle
      else {
        TextSelection overflowSelection = TextSelection(
          baseOffset: range.start,
          extentOffset: range.start + math.max(1, range.end - range.start),
        );

        overflowSelection = convertTextInputSelectionToTextPainterSelection(
            oldSpan, overflowSelection);

        final List<ui.TextBox> boxs = textPainter.getBoxesForSelection(
          overflowSelection,
          boxWidthStyle: selectionWidthStyle,
          boxHeightStyle: selectionHeightStyle,
        );
        _overflowRects ??= <Rect>[];
        for (final ui.TextBox box in boxs) {
          final Rect boxRect = box.toRect();
          if (boxRect.width == 0) {
            continue;
          }
          if (boxRect.left + overflowWidgetSize.width < rect.width) {
            textParentData.offset = boxRect.topLeft;

            overflowSelection = TextSelection(
                baseOffset: textPainter
                    .getPositionForOffset(boxRect.centerLeft)
                    .offset,
                extentOffset: textPainter
                    .getPositionForOffset(boxRect.centerLeft +
                        Offset(overflowWidgetSize.width, 0))
                    .offset);

            break;
          } else {
            _overflowRects?.add(boxRect);
          }
        }

        _setOverflowRect(
          overflowSelection,
          overflowWidgetSize,
          textParentData,
          rect,
          maxOffset,
          overflowWidget!.position,
        );
      }
    }
  }
}