describeApproximatePaintClip method Null safety

  1. @override
Rect? describeApproximatePaintClip(
  1. covariant RenderSliver child
)
override

Returns a rect in this object's coordinate system that describes the approximate bounding box of the clip rect that would be applied to the given child during the paint phase, if any.

Returns null if the child would not be clipped.

This is used in the semantics phase to avoid including children that are not physically visible.

RenderObjects that respect a Clip behavior when painting must respect that same behavior when describing this value. For example, if passing Clip.none to PaintingContext.pushClipRect as the clipBehavior, then the implementation of this method must return null.

Implementation

@override
Rect? describeApproximatePaintClip(RenderSliver child) {
  switch (clipBehavior) {
    case Clip.none:
      return null;
    case Clip.hardEdge:
    case Clip.antiAlias:
    case Clip.antiAliasWithSaveLayer:
      break;
  }

  final Rect viewportClip = Offset.zero & size;
  // The child's viewportMainAxisExtent can be infinite when a
  // RenderShrinkWrappingViewport is given infinite constraints, such as when
  // it is the child of a Row or Column (depending on orientation).
  //
  // For example, a shrink wrapping render sliver may have infinite
  // constraints along the viewport's main axis but may also have bouncing
  // scroll physics, which will allow for some scrolling effect to occur.
  // We should just use the viewportClip - the start of the overlap is at
  // double.infinity and so it is effectively meaningless.
  if (child.constraints.overlap == 0 || !child.constraints.viewportMainAxisExtent.isFinite) {
    return viewportClip;
  }

  // Adjust the clip rect for this sliver by the overlap from the previous sliver.
  double left = viewportClip.left;
  double right = viewportClip.right;
  double top = viewportClip.top;
  double bottom = viewportClip.bottom;
  final double startOfOverlap = child.constraints.viewportMainAxisExtent - child.constraints.remainingPaintExtent;
  final double overlapCorrection = startOfOverlap + child.constraints.overlap;
  switch (applyGrowthDirectionToAxisDirection(axisDirection, child.constraints.growthDirection)) {
    case AxisDirection.down:
      top += overlapCorrection;
      break;
    case AxisDirection.up:
      bottom -= overlapCorrection;
      break;
    case AxisDirection.right:
      left += overlapCorrection;
      break;
    case AxisDirection.left:
      right -= overlapCorrection;
      break;
  }
  return Rect.fromLTRB(left, top, right, bottom);
}