Package org.apache.fop.fo.properties

Source Code of org.apache.fop.fo.properties.CommonBorderPaddingBackground$BorderInfo

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id: CommonBorderPaddingBackground.java 627367 2008-02-13 12:03:30Z maxberger $ */

package org.apache.fop.fo.properties;

import java.awt.Color;

import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.datatypes.Length;
import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.datatypes.URISpecification;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.PropertyException;

/**
* Stores all common border and padding properties.
* See Sec. 7.7 of the XSL-FO Standard.
*/
public class CommonBorderPaddingBackground {
    /**
     * The "background-attachment" property.
     */
    public int backgroundAttachment;

    /**
     * The "background-color" property.
     */
    public Color backgroundColor;

    /**
     * The "background-image" property.
     */
    public String backgroundImage;

    /**
     * The "background-repeat" property.
     */
    public int backgroundRepeat;

    /**
     * The "background-position-horizontal" property.
     */
    public Length backgroundPositionHorizontal;

    /**
     * The "background-position-vertical" property.
     */
    public Length backgroundPositionVertical;


    private ImageInfo backgroundImageInfo;


    /** the "before" edge */
    public static final int BEFORE = 0;
    /** the "after" edge */
    public static final int AFTER = 1;
    /** the "start" edge */
    public static final int START = 2;
    /** the "end" edge */
    public static final int END = 3;

    public static class BorderInfo {
        private int mStyle; // Enum for border style
        private Color mColor; // Border color
        private CondLengthProperty mWidth;

        BorderInfo(int style, CondLengthProperty width, Color color) {
            mStyle = style;
            mWidth = width;
            mColor = color;
        }

        public int getStyle() {
            return this.mStyle;
        }

        public Color getColor() {
            return this.mColor;
        }

        public CondLengthProperty getWidth() {
            return this.mWidth;
        }

        public int getRetainedWidth() {
            if ((mStyle == Constants.EN_NONE)
                    || (mStyle == Constants.EN_HIDDEN)) {
                return 0;
            } else {
                return mWidth.getLengthValue();
            }
        }

        /** {@inheritDoc} */
        public String toString() {
            StringBuffer sb = new StringBuffer("BorderInfo");
            sb.append(" {");
            sb.append(mStyle);
            sb.append(", ");
            sb.append(mColor);
            sb.append(", ");
            sb.append(mWidth);
            sb.append("}");
            return sb.toString();
        }
    }

    /**
     * A border info with style none. Used as a singleton, in the collapsing-border model,
     * for elements which don't specify any border on some of their sides.
     */
    private static BorderInfo defaultBorderInfo;

    /**
     * A conditional length of value 0. Returned by the
     * {@link CommonBorderPaddingBackground#getBorderInfo(int)} method when the
     * corresponding border isn't specified, to avoid to callers painful checks for null.
     */
    private static class ConditionalNullLength extends CondLengthProperty {

        /** {@inheritDoc} */
        public Property getComponent(int cmpId) {
            throw new UnsupportedOperationException();
        }

        /** {@inheritDoc} */
        public Property getConditionality() {
            throw new UnsupportedOperationException();
        }

        /** {@inheritDoc} */
        public Length getLength() {
            throw new UnsupportedOperationException();
        }

        /** {@inheritDoc} */
        public Property getLengthComponent() {
            throw new UnsupportedOperationException();
        }

        /** {@inheritDoc} */
        public int getLengthValue() {
            return 0;
        }

        /** {@inheritDoc} */
        public int getLengthValue(PercentBaseContext context) {
            return 0;
        }

        /** {@inheritDoc} */
        public boolean isDiscard() {
            return true;
        }

        /** {@inheritDoc} */
        public void setComponent(int cmpId, Property cmpnValue, boolean isDefault) {
            throw new UnsupportedOperationException();
        }

        /** {@inheritDoc} */
        public String toString() {
            return "CondLength[0mpt, discard]";
        }
    }

    /**
     * Returns a default BorderInfo of style none.
     *
     * @return a BorderInfo instance with style set to {@link Constants#EN_NONE}
     */
    public static synchronized BorderInfo getDefaultBorderInfo() {
        if (defaultBorderInfo == null) {
            /* It is enough to set color to null, as it should never be consulted */
            defaultBorderInfo = new BorderInfo(Constants.EN_NONE,
                    new ConditionalNullLength(), null);
        }
        return defaultBorderInfo;
    }

    private BorderInfo[] borderInfo = new BorderInfo[4];
    private CondLengthProperty[] padding = new CondLengthProperty[4];

    /**
     * Construct a CommonBorderPaddingBackground object.
     */
    public CommonBorderPaddingBackground() {
    }

    /**
     * Construct a CommonBorderPaddingBackground object.
     *
     * @param pList The PropertyList to get properties from.
     * @throws PropertyException if there's an error while binding the properties
     */
    public CommonBorderPaddingBackground(PropertyList pList) throws PropertyException {

        backgroundAttachment = pList.get(Constants.PR_BACKGROUND_ATTACHMENT).getEnum();
        backgroundColor = pList.get(Constants.PR_BACKGROUND_COLOR).getColor(
                                        pList.getFObj().getUserAgent());
        if (backgroundColor.getAlpha() == 0) {
            backgroundColor = null;
        }

        backgroundImage = pList.get(Constants.PR_BACKGROUND_IMAGE).getString();
        if (backgroundImage == null || "none".equals(backgroundImage)) {
            backgroundImage = null;
        } else {
            backgroundRepeat = pList.get(Constants.PR_BACKGROUND_REPEAT).getEnum();
            backgroundPositionHorizontal = pList.get(
                    Constants.PR_BACKGROUND_POSITION_HORIZONTAL).getLength();
            backgroundPositionVertical = pList.get(
                    Constants.PR_BACKGROUND_POSITION_VERTICAL).getLength();

            //Additional processing: preload image
            String uri = URISpecification.getURL(backgroundImage);
            FOUserAgent userAgent = pList.getFObj().getUserAgent();
            ImageManager manager = userAgent.getFactory().getImageManager();
            ImageSessionContext sessionContext = userAgent.getImageSessionContext();
            ImageInfo info;
            try {
                info = manager.getImageInfo(uri, sessionContext);
                this.backgroundImageInfo = info;
            } catch (Exception e) {
                Property.log.error("Background image not available: " + uri);
            }
            //TODO Report to caller so he can decide to throw an exception
        }

        initBorderInfo(pList, BEFORE,
                Constants.PR_BORDER_BEFORE_COLOR,
                Constants.PR_BORDER_BEFORE_STYLE,
                Constants.PR_BORDER_BEFORE_WIDTH,
                Constants.PR_PADDING_BEFORE);
        initBorderInfo(pList, AFTER,
                Constants.PR_BORDER_AFTER_COLOR,
                Constants.PR_BORDER_AFTER_STYLE,
                Constants.PR_BORDER_AFTER_WIDTH,
                Constants.PR_PADDING_AFTER);
        initBorderInfo(pList, START,
                Constants.PR_BORDER_START_COLOR,
                Constants.PR_BORDER_START_STYLE,
                Constants.PR_BORDER_START_WIDTH,
                Constants.PR_PADDING_START);
        initBorderInfo(pList, END,
                Constants.PR_BORDER_END_COLOR,
                Constants.PR_BORDER_END_STYLE,
                Constants.PR_BORDER_END_WIDTH,
                Constants.PR_PADDING_END);

    }

    private void initBorderInfo(PropertyList pList, int side,
                    int colorProp, int styleProp, int widthProp, int paddingProp)
                throws PropertyException {
        padding[side] = pList.get(paddingProp).getCondLength();
        // If style = none, force width to 0, don't get Color (spec 7.7.20)
        int style = pList.get(styleProp).getEnum();
        if (style != Constants.EN_NONE) {
            FOUserAgent ua = pList.getFObj().getUserAgent();
            setBorderInfo(new BorderInfo(style,
                pList.get(widthProp).getCondLength(),
                pList.get(colorProp).getColor(ua)), side);
        }
    }

    /**
     * Sets a border.
     * @param info the border information
     * @param side the side to apply the info to
     */
    public void setBorderInfo(BorderInfo info, int side) {
        this.borderInfo[side] = info;
    }

    /**
     * @param side the side to retrieve
     * @return the border info for a side
     */
    public BorderInfo getBorderInfo(int side) {
        if (this.borderInfo[side] == null) {
            return getDefaultBorderInfo();
        } else {
            return this.borderInfo[side];
        }
    }

    /**
     * Set padding.
     * @param source the padding info to copy from
     */
    public void setPadding(CommonBorderPaddingBackground source) {
        this.padding = source.padding;
    }

    /**
     * @return the background image info object, null if there is
     *     no background image.
     */
    public ImageInfo getImageInfo() {
        return this.backgroundImageInfo;
    }

    /**
     * @param bDiscard indicates whether the .conditionality component should be
     * considered (start of a reference-area)
     */
    public int getBorderStartWidth(boolean bDiscard) {
        return getBorderWidth(START, bDiscard);
    }

    /**
     * @param bDiscard indicates whether the .conditionality component should be
     * considered (end of a reference-area)
     */
    public int getBorderEndWidth(boolean bDiscard) {
        return getBorderWidth(END, bDiscard);
    }

    /**
     * @param bDiscard indicates whether the .conditionality component should be
     * considered (start of a reference-area)
     */
    public int getBorderBeforeWidth(boolean bDiscard) {
        return getBorderWidth(BEFORE, bDiscard);
    }

    /**
     * @param bDiscard indicates whether the .conditionality component should be
     * considered (end of a reference-area)
     */
    public int getBorderAfterWidth(boolean bDiscard) {
        return getBorderWidth(AFTER, bDiscard);
    }

    public int getPaddingStart(boolean bDiscard, PercentBaseContext context) {
        return getPadding(START, bDiscard, context);
    }

    public int getPaddingEnd(boolean bDiscard, PercentBaseContext context) {
        return getPadding(END, bDiscard, context);
    }

    public int getPaddingBefore(boolean bDiscard, PercentBaseContext context) {
        return getPadding(BEFORE, bDiscard, context);
    }

    public int getPaddingAfter(boolean bDiscard, PercentBaseContext context) {
        return getPadding(AFTER, bDiscard, context);
    }

    public int getBorderWidth(int side, boolean bDiscard) {
        if ((borderInfo[side] == null)
                || (borderInfo[side].mStyle == Constants.EN_NONE)
                || (borderInfo[side].mStyle == Constants.EN_HIDDEN)
                || (bDiscard && borderInfo[side].mWidth.isDiscard())) {
            return 0;
        } else {
            return borderInfo[side].mWidth.getLengthValue();
        }
    }

    public Color getBorderColor(int side) {
        if (borderInfo[side] != null) {
            return borderInfo[side].getColor();
        } else {
            return null;
        }
    }

    public int getBorderStyle(int side) {
        if (borderInfo[side] != null) {
            return borderInfo[side].mStyle;
        } else {
            return Constants.EN_NONE;
        }
    }

    public int getPadding(int side, boolean bDiscard, PercentBaseContext context) {
        if ((padding[side] == null) || (bDiscard && padding[side].isDiscard())) {
            return 0;
        } else {
            return padding[side].getLengthValue(context);
        }
    }

    /**
     * Returns the CondLengthProperty for the padding on one side.
     * @param side the side
     * @return the requested CondLengthProperty
     */
    public CondLengthProperty getPaddingLengthProperty(int side) {
        return padding[side];
    }

    /**
     * Return all the border and padding width in the inline progression
     * dimension.
     * @param bDiscard the discard flag.
     * @param context for percentage evaluation.
     * @return all the padding and border width.
     */
    public int getIPPaddingAndBorder(boolean bDiscard, PercentBaseContext context) {
        return getPaddingStart(bDiscard, context)
            + getPaddingEnd(bDiscard, context)
            + getBorderStartWidth(bDiscard)
            + getBorderEndWidth(bDiscard);
    }

    /**
     * Return all the border and padding height in the block progression
     * dimension.
     * @param bDiscard the discard flag.
     * @param context for percentage evaluation
     * @return all the padding and border height.
     */
    public int getBPPaddingAndBorder(boolean bDiscard, PercentBaseContext context) {
        return getPaddingBefore(bDiscard, context) + getPaddingAfter(bDiscard, context)
               + getBorderBeforeWidth(bDiscard) + getBorderAfterWidth(bDiscard);
    }

    /** {@inheritDoc} */
    public String toString() {
        return "CommonBordersAndPadding (Before, After, Start, End):\n"
            + "Borders: (" + getBorderBeforeWidth(false) + ", " + getBorderAfterWidth(false) + ", "
            + getBorderStartWidth(false) + ", " + getBorderEndWidth(false) + ")\n"
            + "Border Colors: (" + getBorderColor(BEFORE) + ", " + getBorderColor(AFTER) + ", "
            + getBorderColor(START) + ", " + getBorderColor(END) + ")\n"
            + "Padding: (" + getPaddingBefore(false, null) + ", " + getPaddingAfter(false, null)
            + ", " + getPaddingStart(false, null) + ", " + getPaddingEnd(false, null) + ")\n";
    }

    /**
     * @return true if there is any kind of background to be painted
     */
    public boolean hasBackground() {
        return ((backgroundColor != null || getImageInfo() != null));
    }

    /** @return true if border is non-zero. */
    public boolean hasBorder() {
        return ((getBorderBeforeWidth(false) + getBorderAfterWidth(false)
                + getBorderStartWidth(false) + getBorderEndWidth(false)) > 0);
    }

    /**
     * @param context for percentage based evaluation.
     * @return true if padding is non-zero.
     */
    public boolean hasPadding(PercentBaseContext context) {
        return ((getPaddingBefore(false, context) + getPaddingAfter(false, context)
                + getPaddingStart(false, context) + getPaddingEnd(false, context)) > 0);
    }

    /** @return true if there are any borders defined. */
    public boolean hasBorderInfo() {
        return (borderInfo[BEFORE] != null || borderInfo[AFTER] != null
                || borderInfo[START] != null || borderInfo[END] != null);
    }
}
TOP

Related Classes of org.apache.fop.fo.properties.CommonBorderPaddingBackground$BorderInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.