additionalOverflowHeightFromAtomicPlaceholders method

double additionalOverflowHeightFromAtomicPlaceholders()

Implementation

double additionalOverflowHeightFromAtomicPlaceholders() {
  if (_paragraph == null || _placeholderBoxes.isEmpty || _allPlaceholders.isEmpty) return 0.0;

  // Base paragraph height measured as sum of line heights when available.
  final double baseHeight =
      _paraLines.isEmpty ? (_paragraph?.height ?? 0.0) : _paraLines.fold<double>(0.0, (sum, lm) => sum + lm.height);

  double maxBottom = baseHeight;
  final int n = math.min(_placeholderBoxes.length, _allPlaceholders.length);
  for (int i = 0; i < n; i++) {
    final ph = _allPlaceholders[i];
    if (ph.kind != _PHKind.atomic) continue;
    // Paragraph-reported box for the placeholder position in paragraph space.
    final tb = _placeholderBoxes[i];
    // Map placeholder index to the corresponding render box (may be a wrapper).
    final RenderBox? rb = ph.atomic;
    if (rb == null) continue;

    // Resolve to a RenderBoxModel that carries CSS styles/scrollable sizes.
    final RenderBoxModel? styleBox = _resolveStyleBoxForPlaceholder(rb);
    if (styleBox == null || !styleBox.hasSize) continue;

    // Determine child's effective scrollable height: use scrollableSize when the
    // child is not itself a scroll container (overflow visible); otherwise the
    // element's own box size defines its scroll range contribution.
    final rs = styleBox.renderStyle;
    final bool childScrolls =
        rs.effectiveOverflowX != CSSOverflowType.visible || rs.effectiveOverflowY != CSSOverflowType.visible;
    final Size childExtent = childScrolls ? (styleBox.boxSize ?? styleBox.size) : styleBox.scrollableSize;

    double candidateBottom = tb.top + (childExtent.height.isFinite ? childExtent.height : 0.0);

    // Account for positive downward relative/transform offsets on the atomic box.
    final Offset? rel = CSSPositionedLayout.getRelativeOffset(rs);
    if (rel != null && rel.dy > 0) candidateBottom += rel.dy;
    final Offset? tr = rs.effectiveTransformOffset;
    if (tr != null && tr.dy > 0) candidateBottom += tr.dy;

    if (candidateBottom > maxBottom) {
      maxBottom = candidateBottom;
    }
  }

  final double extra = maxBottom - baseHeight;
  return extra > 0 ? extra : 0.0;
}