computeChildPaintExtent method

Size computeChildPaintExtent(
  1. Offset layoutOffset,
  2. Size childSize
)

Computes the portion of the child that is visible, assuming that only the region from the ViewportOffset.pixels of both dimensions to the cacheExtent is visible, and that the relationship between scroll offsets and paint offsets is linear.

For example, if the ViewportOffsets each have a scroll offset of 100 and the arguments to this method describe a child with layoutOffset of Offset(50.0, 50.0), with a size of Size(200.0, 200.0), then the returned value would be Size(150.0, 150.0), representing the visible extent of the child.

Implementation

Size computeChildPaintExtent(Offset layoutOffset, Size childSize) {
  if (childSize == Size.zero || childSize.height == 0.0 || childSize.width == 0.0) {
    return Size.zero;
  }
  // Horizontal extent
  final double width;
  if (layoutOffset.dx < 0.0) {
    // The child is positioned beyond the leading edge of the viewport.
    if (layoutOffset.dx + childSize.width <= 0.0) {
      // The child does not extend into the viewable area, it is not visible.
      return Size.zero;
    }
    // If the child is positioned starting at -50, then the paint extent is
    // the width + (-50).
    width = layoutOffset.dx + childSize.width;
  } else if (layoutOffset.dx >= viewportDimension.width) {
    // The child is positioned after the trailing edge of the viewport, also
    // not visible.
    return Size.zero;
  } else {
    // The child is positioned within the viewport bounds, but may extend
    // beyond it.
    assert(layoutOffset.dx >= 0 && layoutOffset.dx < viewportDimension.width);
    if (layoutOffset.dx + childSize.width > viewportDimension.width) {
      width = viewportDimension.width - layoutOffset.dx;
    } else {
      assert(layoutOffset.dx + childSize.width <= viewportDimension.width);
      width = childSize.width;
    }
  }

  // Vertical extent
  final double height;
  if (layoutOffset.dy < 0.0) {
    // The child is positioned beyond the leading edge of the viewport.
    if (layoutOffset.dy + childSize.height <= 0.0) {
      // The child does not extend into the viewable area, it is not visible.
      return Size.zero;
    }
    // If the child is positioned starting at -50, then the paint extent is
    // the width + (-50).
    height = layoutOffset.dy + childSize.height;
  } else if (layoutOffset.dy >= viewportDimension.height) {
    // The child is positioned after the trailing edge of the viewport, also
    // not visible.
    return Size.zero;
  } else {
    // The child is positioned within the viewport bounds, but may extend
    // beyond it.
    assert(layoutOffset.dy >= 0 && layoutOffset.dy < viewportDimension.height);
    if (layoutOffset.dy + childSize.height > viewportDimension.height) {
      height = viewportDimension.height - layoutOffset.dy;
    } else {
      assert(layoutOffset.dy + childSize.height <= viewportDimension.height);
      height = childSize.height;
    }
  }

  return Size(width, height);
}