postProcess method

  1. @override
void postProcess(
  1. Document document
)
override

Implementation

@override
void postProcess(Document document) {
  final _margin = resolvedMargin!;
  final _mustRotate = mustRotate;
  final pageHeight = _mustRotate ? pageFormat.width : pageFormat.height;
  final pageWidth = _mustRotate ? pageFormat.height : pageFormat.width;
  final pageHeightMargin =
      _mustRotate ? _margin.horizontal : _margin.vertical;
  final pageWidthMargin = _mustRotate ? _margin.vertical : _margin.horizontal;
  final availableWidth = pageWidth - pageWidthMargin;
  final isRTL = pageTheme.textDirection == TextDirection.rtl;
  for (final page in _pages) {
    var offsetStart = pageHeight -
        (_mustRotate ? pageHeightMargin - _margin.bottom : _margin.top);
    var offsetEnd =
        _mustRotate ? pageHeightMargin - _margin.left : _margin.bottom;

    if (pageTheme.buildBackground != null) {
      final child = pageTheme.buildBackground!(page.context);

      child.layout(page.context, page.fullConstraints, parentUsesSize: false);
      assert(child.box != null);
      final xPos = isRTL
          ? _margin.left + (availableWidth - child.box!.width)
          : _margin.left;
      _paintChild(
          page.context, child, xPos, _margin.bottom, pageFormat.height);
    }

    var totalFlex = 0;
    var allocatedSize = 0.0;
    Widget? lastFlexChild;
    for (final widget in page.widgets) {
      final child = widget.child;
      final flex = child is Flexible ? child.flex : 0;
      if (flex > 0) {
        totalFlex += flex;
        lastFlexChild = child;
      } else {
        if (child is SpanningWidget && child.canSpan) {
          child.applyContext(widget.widgetContext!);
        }

        child.layout(page.context, widget.constraints, parentUsesSize: false);
        assert(child.box != null);
        allocatedSize += child.box!.height;
      }
    }

    if (header != null) {
      final headerWidget = header!(page.context);
      headerWidget.layout(page.context, page.constraints,
          parentUsesSize: false);
      assert(headerWidget.box != null);
      offsetStart -= headerWidget.box!.height;
      final xPos = isRTL
          ? _margin.left + (availableWidth - headerWidget.box!.width)
          : _margin.left;
      _paintChild(page.context, headerWidget, xPos,
          page.offsetStart! - headerWidget.box!.height, pageFormat.height);
    }

    if (footer != null) {
      final footerWidget = footer!(page.context);
      footerWidget.layout(page.context, page.constraints,
          parentUsesSize: false);
      assert(footerWidget.box != null);
      final xPos = isRTL
          ? _margin.left + (availableWidth - footerWidget.box!.width)
          : _margin.left;
      offsetEnd += footerWidget.box!.height;
      _paintChild(page.context, footerWidget, xPos, _margin.bottom,
          pageFormat.height);
    }

    final freeSpace = math.max(0.0, offsetStart - offsetEnd - allocatedSize);

    final spacePerFlex = totalFlex > 0 ? (freeSpace / totalFlex) : double.nan;
    var allocatedFlexSpace = 0.0;

    var leadingSpace = 0.0;
    var betweenSpace = 0.0;

    if (totalFlex == 0) {
      final totalChildren = page.widgets.length;

      switch (mainAxisAlignment) {
        case MainAxisAlignment.start:
          leadingSpace = 0.0;
          betweenSpace = 0.0;
          break;
        case MainAxisAlignment.end:
          leadingSpace = freeSpace;
          betweenSpace = 0.0;
          break;
        case MainAxisAlignment.center:
          leadingSpace = freeSpace / 2.0;
          betweenSpace = 0.0;
          break;
        case MainAxisAlignment.spaceBetween:
          leadingSpace = 0.0;
          betweenSpace =
              totalChildren > 1 ? freeSpace / (totalChildren - 1) : 0.0;
          break;
        case MainAxisAlignment.spaceAround:
          betweenSpace = totalChildren > 0 ? freeSpace / totalChildren : 0.0;
          leadingSpace = betweenSpace / 2.0;
          break;
        case MainAxisAlignment.spaceEvenly:
          betweenSpace =
              totalChildren > 0 ? freeSpace / (totalChildren + 1) : 0.0;
          leadingSpace = betweenSpace;
          break;
      }
    }

    for (final widget in page.widgets) {
      final child = widget.child;

      final flex = child is Flexible ? child.flex : 0;
      final fit = child is Flexible ? child.fit : FlexFit.loose;
      if (flex > 0) {
        assert(child is! SpanningWidget || child.canSpan == false,
            'Cannot have a spanning widget flexible');
        final maxChildExtent = child == lastFlexChild
            ? (freeSpace - allocatedFlexSpace)
            : spacePerFlex * flex;
        late double minChildExtent;
        switch (fit) {
          case FlexFit.tight:
            assert(maxChildExtent < double.infinity);
            minChildExtent = maxChildExtent;
            break;
          case FlexFit.loose:
            minChildExtent = 0.0;
            break;
        }

        final innerConstraints = BoxConstraints(
            minWidth: widget.constraints.maxWidth,
            maxWidth: widget.constraints.maxWidth,
            minHeight: minChildExtent,
            maxHeight: maxChildExtent);

        child.layout(page.context, innerConstraints, parentUsesSize: false);
        assert(child.box != null);
        final childSize = child.box!.height;
        assert(childSize <= maxChildExtent);
        allocatedSize += childSize;
        allocatedFlexSpace += maxChildExtent;
      }
    }
    var pos = offsetStart - leadingSpace;
    for (final widget in page.widgets) {
      pos -= widget.child.box!.height;
      late double x;
      switch (crossAxisAlignment) {
        case CrossAxisAlignment.stretch:
        case CrossAxisAlignment.start:
          if (isRTL) {
            x = availableWidth - widget.child.box!.width;
          } else {
            x = 0;
          }
          break;
        case CrossAxisAlignment.end:
          if (isRTL) {
            x = 0;
          } else {
            x = availableWidth - widget.child.box!.width;
          }
          break;
        case CrossAxisAlignment.center:
          x = availableWidth / 2 - widget.child.box!.width / 2;
          break;
      }
      final child = widget.child;
      if (child is SpanningWidget && child.canSpan) {
        child.applyContext(widget.widgetContext!);
      }
      _paintChild(page.context, widget.child, _margin.left + x, pos,
          pageFormat.height);
      pos -= betweenSpace;
    }

    if (pageTheme.buildForeground != null) {
      final child = pageTheme.buildForeground!(page.context);

      child.layout(page.context, page.fullConstraints, parentUsesSize: false);
      assert(child.box != null);
      final xPos = isRTL
          ? _margin.left + (availableWidth - child.box!.width)
          : _margin.left;
      _paintChild(
          page.context, child, xPos, _margin.bottom, pageFormat.height);
    }
  }
}