private void performSpaceResolutionRules2to3()

in fop-core/src/main/java/org/apache/fop/layoutmgr/SpaceResolver.java [206:334]


    private void performSpaceResolutionRules2to3(UnresolvedListElement[] elems,
            MinOptMax[] lengths, int start, int end) {
        if (LOG.isTraceEnabled()) {
            LOG.trace("rule 2-3: " + start + "-" + end);
        }
        SpaceElement space;
        int remaining;

        //Rule 2 (4.3.1, XSL 1.0)
        boolean hasForcing = false;
        remaining = 0;
        for (int i = start; i <= end; i++) {
            if (lengths[i] == null) {
                continue;
            }
            remaining++;
            space = (SpaceElement)elems[i];
            if (space.isForcing()) {
                hasForcing = true;
                break;
            }
        }
        if (remaining == 0) {
            return; //shortcut
        }
        if (hasForcing) {
            for (int i = start; i <= end; i++) {
                if (lengths[i] == null) {
                    continue;
                }
                space = (SpaceElement)elems[i];
                if (!space.isForcing()) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Nulling non-forcing space-specifier using 4.3.1, rule 2: "
                                + elems[i]);
                    }
                    lengths[i] = null;
                }
            }
            return; //If rule is triggered skip rule 3
        }

        //Rule 3 (4.3.1, XSL 1.0)
        //Determine highes precedence
        int highestPrecedence = Integer.MIN_VALUE;
        for (int i = start; i <= end; i++) {
            if (lengths[i] == null) {
                continue;
            }
            space = (SpaceElement)elems[i];
            highestPrecedence = Math.max(highestPrecedence, space.getPrecedence());
        }
        if (highestPrecedence != 0 && LOG.isDebugEnabled()) {
            LOG.debug("Highest precedence is " + highestPrecedence);
        }
        //Suppress space-specifiers with lower precedence
        remaining = 0;
        int greatestOptimum = Integer.MIN_VALUE;
        for (int i = start; i <= end; i++) {
            if (lengths[i] == null) {
                continue;
            }
            space = (SpaceElement)elems[i];
            if (space.getPrecedence() != highestPrecedence) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Nulling space-specifier with precedence "
                            + space.getPrecedence() + " using 4.3.1, rule 3: "
                            + elems[i]);
                }
                lengths[i] = null;
            } else {
                greatestOptimum = Math.max(greatestOptimum, space.getLength().getOpt());
                remaining++;
            }
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("Greatest optimum: " + greatestOptimum);
        }
        if (remaining <= 1) {
            return;
        }
        //Suppress space-specifiers with smaller optimum length
        remaining = 0;
        for (int i = start; i <= end; i++) {
            if (lengths[i] == null) {
                continue;
            }
            space = (SpaceElement)elems[i];
            if (space.getLength().getOpt() < greatestOptimum) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Nulling space-specifier with smaller optimum length "
                            + "using 4.3.1, rule 3: "
                            + elems[i]);
                }
                lengths[i] = null;
            } else {
                remaining++;
            }
        }
        if (remaining <= 1) {
            return;
        }
        //Construct resolved space-specifier from the remaining spaces
        int min = Integer.MIN_VALUE;
        int max = Integer.MAX_VALUE;
        for (int i = start; i <= end; i++) {
            if (lengths[i] == null) {
                continue;
            }
            space = (SpaceElement)elems[i];
            min = Math.max(min, space.getLength().getMin());
            max = Math.min(max, space.getLength().getMax());
            if (remaining > 1) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Nulling non-last space-specifier using 4.3.1, rule 3, second part: "
                            + elems[i]);
                }
                lengths[i] = null;
                remaining--;
            } else {
                lengths[i] = MinOptMax.getInstance(min, lengths[i].getOpt(), max);
            }
        }

        if (LOG.isTraceEnabled() && elems.length > 0) {
            LOG.trace("Remaining spaces: " + remaining);
            LOG.trace("-->Resulting list: " + toString(elems, lengths));
        }
    }