private List getNextKnuthElementsAbsolute()

in fop-core/src/main/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java [422:573]


    private List<ListElement> getNextKnuthElementsAbsolute(LayoutContext context) {
        autoHeight = false;

        boolean bpDirectionChanges = blockProgressionDirectionChanges();
        Point offset = getAbsOffset();
        int allocBPD;
        int allocIPD;
        if (height.getEnum() == EN_AUTO
                || (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) {
            //auto height when height="auto" or "if that dimension is not specified explicitly
            //(i.e., it depends on content's blockprogression-dimension)" (XSL 1.0, 7.14.1)
            allocBPD = 0;
            if (abProps.bottom.getEnum() != EN_AUTO) {
                int availHeight;
                if (isFixed()) {
                    availHeight = (int)getCurrentPV().getViewArea().getHeight();
                } else {
                    availHeight = context.getStackLimitBP().getOpt();
                }
                allocBPD = availHeight;
                allocBPD -= offset.y;
                if (abProps.bottom.getEnum() != EN_AUTO) {
                    allocBPD -= abProps.bottom.getValue(this);
                    if (allocBPD < 0) {
                        //TODO Fix absolute b-c layout, layout may need to be defferred until
                        //after page breaking when the size of the containing box is known.
                        /* Warning disabled due to a interpretation mistake.
                         * See: http://marc.theaimsgroup.com/?l=fop-dev&m=113189981926163&w=2
                        log.error("The current combination of top and bottom properties results"
                                + " in a negative extent for the block-container. 'bottom' may be"
                                + " at most " + (allocBPD + abProps.bottom.getValue(this)) + " mpt,"
                                + " but was actually " + abProps.bottom.getValue(this) + " mpt."
                                + " The nominal available height is " + availHeight + " mpt.");
                        */
                        allocBPD = 0;
                    }
                } else {
                    if (allocBPD < 0) {
                        /* Warning disabled due to a interpretation mistake.
                         * See: http://marc.theaimsgroup.com/?l=fop-dev&m=113189981926163&w=2
                        log.error("The current combination of top and bottom properties results"
                                + " in a negative extent for the block-container. 'top' may be"
                                + " at most " + availHeight + " mpt,"
                                + " but was actually " + offset.y + " mpt."
                                + " The nominal available height is " + availHeight + " mpt.");
                        */
                        allocBPD = 0;
                    }
                }
            } else {
                allocBPD = context.getStackLimitBP().getOpt();
                if (!bpDirectionChanges) {
                    autoHeight = true;
                }
            }
        } else {
            allocBPD = height.getValue(this); //this is the content-height
            allocBPD += getBPIndents();
        }
        if (width.getEnum() == EN_AUTO) {
            int availWidth;
            if (isFixed()) {
                availWidth = (int)getCurrentPV().getViewArea().getWidth();
            } else {
                availWidth = context.getRefIPD();
            }
            allocIPD = availWidth;
            if (abProps.left.getEnum() != EN_AUTO) {
                allocIPD -= abProps.left.getValue(this);
            }
            if (abProps.right.getEnum() != EN_AUTO) {
                allocIPD -= abProps.right.getValue(this);
                if (allocIPD < 0) {
                    /* Warning disabled due to a interpretation mistake.
                     * See: http://marc.theaimsgroup.com/?l=fop-dev&m=113189981926163&w=2
                    log.error("The current combination of left and right properties results"
                            + " in a negative extent for the block-container. 'right' may be"
                            + " at most " + (allocIPD + abProps.right.getValue(this)) + " mpt,"
                            + " but was actually " + abProps.right.getValue(this) + " mpt."
                            + " The nominal available width is " + availWidth + " mpt.");
                    */
                    allocIPD = 0;
                }
            } else {
                if (allocIPD < 0) {
                    /* Warning disabled due to a interpretation mistake.
                     * See: http://marc.theaimsgroup.com/?l=fop-dev&m=113189981926163&w=2
                    log.error("The current combination of left and right properties results"
                            + " in a negative extent for the block-container. 'left' may be"
                            + " at most " + allocIPD + " mpt,"
                            + " but was actually " + abProps.left.getValue(this) + " mpt."
                            + " The nominal available width is " + availWidth + " mpt.");
                    */
                    allocIPD = 0;
                }
                if (bpDirectionChanges) {
                    autoHeight = true;
                }
            }
        } else {
            allocIPD = width.getValue(this); //this is the content-width
            allocIPD += getIPIndents();
        }

        vpContentBPD = allocBPD - getBPIndents();
        setContentAreaIPD(allocIPD - getIPIndents());

        contentRectOffsetX = 0;
        contentRectOffsetY = 0;
        updateRelDims();

        MinOptMax range = MinOptMax.getInstance(relDims.ipd);
        BlockContainerBreaker breaker = new BlockContainerBreaker(this, range);
        breaker.doLayout((autoHeight ? 0 : relDims.bpd), autoHeight);
        boolean contentOverflows = breaker.isOverflow();
        if (autoHeight) {
            //Update content BPD now that it is known
            int newHeight = breaker.deferredAlg.totalWidth;
            if (bpDirectionChanges) {
                setContentAreaIPD(newHeight);
            } else {
                vpContentBPD = newHeight;
            }
            updateRelDims();
        }
        List<ListElement> returnList = new LinkedList<ListElement>();
        if (!breaker.isEmpty()) {
            Position bcPosition = new BlockContainerPosition(this, breaker);
            returnList.add(new KnuthBox(0, notifyPos(bcPosition), false));

            //TODO Maybe check for page overflow when autoHeight=true
            if (!autoHeight & (contentOverflows)) {
                BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
                        getBlockContainerFO().getUserAgent().getEventBroadcaster());
                boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
                eventProducer.viewportBPDOverflow(this, getBlockContainerFO().getName(),
                        breaker.getOverflowAmount(), needClip(), canRecover,
                        getBlockContainerFO().getLocator());
            }
            // this handles the IPD (horizontal) overflow
            if (this.horizontalOverflow > 0) {
                BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider
                        .get(getBlockContainerFO().getUserAgent().getEventBroadcaster());
                boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
                eventProducer.viewportIPDOverflow(this, getBlockContainerFO().getName(),
                        this.horizontalOverflow, needClip(), canRecover, getBlockContainerFO().getLocator());
            }
        }

        setFinished(true);
        return returnList;
    }