protected void doLayout()

in fop-core/src/main/java/org/apache/fop/layoutmgr/inline/ImageLayout.java [70:191]


    protected void doLayout() {
        Length len;

        int bpd = -1;
        int ipd = -1;

        len = props.getBlockProgressionDimension().getOptimum(percentBaseContext).getLength();
        if (len.getEnum() != EN_AUTO) {
            bpd = evaluateLength(len, intrinsicSize.height);
        }
        len = props.getBlockProgressionDimension().getMinimum(percentBaseContext).getLength();
        if (bpd == -1 && len.getEnum() != EN_AUTO) {
            bpd = evaluateLength(len, intrinsicSize.height);
        }

        len = props.getInlineProgressionDimension().getOptimum(percentBaseContext).getLength();
        if (len.getEnum() != EN_AUTO) {
            ipd = len.getValue(percentBaseContext);
        }
        len = props.getInlineProgressionDimension().getMinimum(percentBaseContext).getLength();
        if (ipd == -1 && len.getEnum() != EN_AUTO) {
            //Establish minimum viewport size
            ipd = len.getValue(percentBaseContext);
        }

        // if auto then use the intrinsic size of the content scaled
        // to the content-height and content-width
        boolean constrainIntrinsicSize = false;
        int cwidth = -1;
        int cheight = -1;
        len = props.getContentWidth();
        if (len.getEnum() != EN_AUTO) {
            switch (len.getEnum()) {
            case EN_SCALE_TO_FIT:
                if (ipd != -1) {
                    cwidth = ipd;
                }
                constrainIntrinsicSize = true;
                break;
            case EN_SCALE_DOWN_TO_FIT:
                if (ipd != -1 && intrinsicSize.width > ipd) {
                    cwidth = ipd;
                }
                constrainIntrinsicSize = true;
                break;
            case EN_SCALE_UP_TO_FIT:
                if (ipd != -1 && intrinsicSize.width < ipd) {
                    cwidth = ipd;
                }
                constrainIntrinsicSize = true;
                break;
            default:
                cwidth = len.getValue(percentBaseContext);
            }
        }
        len = props.getContentHeight();
        if (len.getEnum() != EN_AUTO) {
            switch (len.getEnum()) {
            case EN_SCALE_TO_FIT:
                if (bpd != -1) {
                    cheight = bpd;
                }
                constrainIntrinsicSize = true;
                break;
            case EN_SCALE_DOWN_TO_FIT:
                if (bpd != -1 && intrinsicSize.height > bpd) {
                    cheight = bpd;
                }
                constrainIntrinsicSize = true;
                break;
            case EN_SCALE_UP_TO_FIT:
                if (bpd != -1 && intrinsicSize.height < bpd) {
                    cheight = bpd;
                }
                constrainIntrinsicSize = true;
                break;
            default:
                cheight = len.getValue(percentBaseContext);
            }
        }

        Dimension constrainedIntrinsicSize;
        if (constrainIntrinsicSize) {
            constrainedIntrinsicSize = constrain(intrinsicSize);
        } else {
            constrainedIntrinsicSize = intrinsicSize;
        }

        //Derive content extents where not explicit
        Dimension adjustedDim = adjustContentSize(cwidth, cheight, constrainedIntrinsicSize);
        cwidth = adjustedDim.width;
        cheight = adjustedDim.height;

        //Adjust viewport if not explicit
        if (ipd == -1) {
            ipd = constrainExtent(cwidth,
                    props.getInlineProgressionDimension(), props.getContentWidth());
        }
        if (bpd == -1) {
            bpd = constrainExtent(cheight,
                    props.getBlockProgressionDimension(), props.getContentHeight());
        }

        this.clip = false;
        int overflow = props.getOverflow();
        if (overflow == EN_HIDDEN) {
            this.clip = true;
        } else if (overflow == EN_ERROR_IF_OVERFLOW) {
            if (cwidth > ipd || cheight > bpd) {
                //TODO Don't use logging to report error!
                log.error("Object overflows the viewport: clipping");
            }
            this.clip = true;
        }

        int xoffset = computeXOffset(ipd, cwidth);
        int yoffset = computeYOffset(bpd, cheight);

        //Build calculation results
        this.viewportSize.setSize(ipd, bpd);
        this.placement = new Rectangle(xoffset, yoffset, cwidth, cheight);
    }