All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylesDocument Maven / Gradle / Ivy

Go to download

The Apache Commons Codec package contains simple encoder and decoders for various formats such as Base64 and Hexadecimal. In addition to these widely used encoders and decoders, the codec package also maintains a collection of phonetic encoding utilities.

There is a newer version: 62
Show newest version
/**
 * Copyright (C) 2011-2015 The XDocReport Team 
 *
 * All rights reserved.
 *
 * Permission is hereby granted, free  of charge, to any person obtaining
 * a  copy  of this  software  and  associated  documentation files  (the
 * "Software"), to  deal in  the Software without  restriction, including
 * without limitation  the rights to  use, copy, modify,  merge, publish,
 * distribute,  sublicense, and/or sell  copies of  the Software,  and to
 * permit persons to whom the Software  is furnished to do so, subject to
 * the following conditions:
 *
 * The  above  copyright  notice  and  this permission  notice  shall  be
 * included in all copies or substantial portions of the Software.
 *
 * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
 * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
 * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package fr.opensagres.poi.xwpf.converter.xhtml.internal.styles;

import static fr.opensagres.poi.xwpf.converter.xhtml.internal.XHTMLConstants.P_ELEMENT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.XHTMLConstants.SPAN_ELEMENT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.XHTMLConstants.TABLE_ELEMENT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.XHTMLConstants.TD_ELEMENT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.XHTMLConstants.TR_ELEMENT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.BACKGROUND_COLOR;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.COLOR;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.FONT_FAMILY;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.FONT_SIZE;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.FONT_STYLE;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.FONT_STYLE_ITALIC;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.FONT_WEIGHT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.FONT_WEIGHT_BOLD;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.HEIGHT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.MARGIN_LEFT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.MARGIN_RIGHT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.MARGIN_BOTTOM;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.MARGIN_TOP;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.MIN_HEIGHT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.TEXT_ALIGN;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.TEXT_ALIGN_CENTER;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.TEXT_ALIGN_JUSTIFIED;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.TEXT_ALIGN_LEFT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.TEXT_ALIGN_RIGHT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.TEXT_DECORATION;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.TEXT_DECORATION_UNDERLINE;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.TEXT_INDENT;
import static fr.opensagres.poi.xwpf.converter.xhtml.internal.styles.CSSStylePropertyConstants.WIDTH;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.UnderlinePatterns;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPrBase;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTextDirection;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextDirection;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

import fr.opensagres.poi.xwpf.converter.core.Color;
import fr.opensagres.poi.xwpf.converter.core.TableHeight;
import fr.opensagres.poi.xwpf.converter.core.TableWidth;
import fr.opensagres.poi.xwpf.converter.core.styles.XWPFStylesDocument;
import fr.opensagres.poi.xwpf.converter.core.utils.StringUtils;
import fr.opensagres.poi.xwpf.converter.core.utils.XWPFUtils;
import fr.opensagres.poi.xwpf.converter.xhtml.internal.XHTMLConstants;
import fr.opensagres.poi.xwpf.converter.xhtml.internal.utils.SAXHelper;

public class CSSStylesDocument
    extends XWPFStylesDocument
{

    private static final String CR = "\n";

    private static final String PT_UNIT = "pt";

    private static final Object PERCENT_UNIT = "%";

    private List cssStyles;

    private final boolean ignoreStylesIfUnused;

    private final Integer indent;

    public CSSStylesDocument( XWPFDocument document, boolean ignoreStylesIfUnused, Integer indent )
        throws XmlException, IOException
    {
        super( document, false );
        this.ignoreStylesIfUnused = ignoreStylesIfUnused;
        this.indent = indent;
        this.initialize();
    }

    @Override
    protected void initialize()
        throws XmlException, IOException
    {
        // default paragraph
        CSSStyle defaultPStyle = new CSSStyle( P_ELEMENT, null );
        defaultPStyle.addProperty( MARGIN_TOP, "0pt" );
        defaultPStyle.addProperty( MARGIN_BOTTOM, "1pt" );
        getCSSStyles().add( defaultPStyle );

        super.initialize();
    }

    @Override
    protected void visitStyle( CTStyle style, boolean defaultStyle )
    {
        String styleId = style.getStyleId();
        if ( StringUtils.isNotEmpty( styleId ) )
        {
            String className = getClassName( styleId );
            visitStyle( className, style.getPPr(), defaultStyle );
            visitStyle( className, style.getRPr(), defaultStyle );
            visitStyle( className, style.getTblPr(), defaultStyle );
            visitStyle( className, style.getTrPr(), defaultStyle );
            visitStyle( className, style.getTcPr(), defaultStyle );
        }
    }

    // -------------------------------- Paragraph styles

    /**
     * @param className
     * @param pPr
     * @param defaultStyle
     */
    private void visitStyle( String className, CTPPr pPr, boolean defaultStyle )
    {
        CSSStyle style = createCSSStyle( pPr, className );
        if ( style != null )
        {
            getCSSStyles().add( style );
        }
    }

    public CSSStyle createCSSStyle( CTPPr pPr )
    {
        return createCSSStyle( pPr, null );
    }

    public CSSStyle createCSSStyle( CTPPr pPr, String className )
    {
        if ( pPr != null )
        {
            String tagName = P_ELEMENT;
            CSSStyle style = ignoreStylesIfUnused ? null : getOrCreateStyle( null, tagName, className );
            
            // indentation left
            Float indentationLeft = super.getIndentationLeft( pPr );
            if ( indentationLeft != null )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( MARGIN_LEFT, getValueAsPoint( indentationLeft ) );
            }
            // indentation right
            Float indentationRight = super.getIndentationRight( pPr );
            if ( indentationRight != null )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( MARGIN_RIGHT, getValueAsPoint( indentationRight ) );
            }
            // indentation first line
            Float indentationFirstLine = super.getIndentationFirstLine( pPr );
            if ( indentationFirstLine != null )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( TEXT_INDENT, getValueAsPoint( indentationFirstLine ) );
            }

            // Aligment
            ParagraphAlignment alignment = super.getParagraphAlignment( pPr );
            if ( alignment != null )
            {
                switch ( alignment )
                {
                    case LEFT:
                        style = getOrCreateStyle( style, tagName, className );
                        style.addProperty( TEXT_ALIGN, TEXT_ALIGN_LEFT );
                        break;
                    case RIGHT:
                        style = getOrCreateStyle( style, tagName, className );
                        style.addProperty( TEXT_ALIGN, TEXT_ALIGN_RIGHT );
                        break;
                    case CENTER:
                        style = getOrCreateStyle( style, tagName, className );
                        style.addProperty( TEXT_ALIGN, TEXT_ALIGN_CENTER );
                        break;

                    case BOTH:
                        style = getOrCreateStyle( style, tagName, className );
                        style.addProperty( TEXT_ALIGN, TEXT_ALIGN_JUSTIFIED );
                        break;
                }
            }
            // Margin bottom/top
            Float spacingBefore = super.getSpacingBefore( pPr );
            if ( spacingBefore != null )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( MARGIN_TOP, getValueAsPoint( spacingBefore ) );
            }
            Float spacingAfter = super.getSpacingAfter( pPr );
            if ( spacingAfter != null )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( MARGIN_BOTTOM, getValueAsPoint( spacingAfter ) );
            }
            // Background color
            Color backgroundColor = super.getBackgroundColor( pPr );
            if ( backgroundColor != null )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( BACKGROUND_COLOR, XWPFUtils.toHexString( backgroundColor ) );
            }
            return style;
        }
        return null;
    }

    // -------------------------------- Run styles

    private void visitStyle( String className, CTRPr rPr, boolean defaultStyle )
    {

        CSSStyle style = createCSSStyle( rPr, className );
        if ( style != null )
        {
            getCSSStyles().add( style );
        }
    }

    public CSSStyle createCSSStyle( CTRPr rPr )
    {
        return createCSSStyle( rPr, null );
    }

    public CSSStyle createCSSStyle( CTRPr rPr, String className )
    {
        if ( rPr != null )
        {
            String tagName = SPAN_ELEMENT;
            CSSStyle style = ignoreStylesIfUnused ? null : getOrCreateStyle( null, tagName, className );

            // Font family
            String fontFamily = super.getFontFamilyAscii( rPr );
            if ( StringUtils.isNotEmpty( fontFamily ) )
            {
                fontFamily = new StringBuilder( "'" ).append( fontFamily ).append( "'" ).toString();
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( FONT_FAMILY, fontFamily );
            }
            // Font size
            Float fontSize = super.getFontSize( rPr );
            if ( fontSize != null )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( FONT_SIZE, getValueAsPoint( fontSize ) );
            }
            // Font Bold
            Boolean bold = super.getFontStyleBold( rPr );
            if ( bold != null && bold )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( FONT_WEIGHT, FONT_WEIGHT_BOLD );
            }
            // Font Italic
            Boolean italic = super.getFontStyleItalic( rPr );
            if ( italic != null && italic )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( FONT_STYLE, FONT_STYLE_ITALIC );
            }
            // Font color
            Color fontColor = super.getFontColor( rPr );
            if ( fontColor != null )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( COLOR, XWPFUtils.toHexString( fontColor ) );
            }
            // Underlines
            UnderlinePatterns underlinePatterns = super.getUnderline( rPr );
            if ( underlinePatterns != null )
            {
                switch ( underlinePatterns )
                {
                    case SINGLE:
                        style = getOrCreateStyle( style, tagName, className );
                        style.addProperty( TEXT_DECORATION, TEXT_DECORATION_UNDERLINE );
                        break;
                    default:
                        break;
                }
            }
            // Background color
            Color backgroundColor = super.getBackgroundColor( rPr );
            if ( backgroundColor != null )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( BACKGROUND_COLOR, XWPFUtils.toHexString( backgroundColor ) );
            }
            return style;
        }
        return null;
    }

    // -------------------------------- Table styles

    /**
     * @param className
     * @param tblPr
     * @param defaultStyle
     */
    private void visitStyle( String className, CTTblPrBase tblPr, boolean defaultStyle )
    {
        CSSStyle style = createCSSStyle( tblPr, className );
        if ( style != null )
        {
            getCSSStyles().add( style );
        }
    }

    public CSSStyle createCSSStyle( CTTblPrBase tblPr )
    {
        return createCSSStyle( tblPr, null );
    }

    public CSSStyle createCSSStyle( CTTblPrBase tblPr, String className )
    {
        if ( tblPr != null )
        {
            String tagName = TABLE_ELEMENT;
            CSSStyle style = ignoreStylesIfUnused ? null : getOrCreateStyle( null, tagName, className );

            TableWidth tableWidth = super.getTableWidth( tblPr );
            if ( tableWidth != null && tableWidth.width > 0 )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( WIDTH, getStyleWidth( tableWidth ) );
            }

            return style;
        }
        return null;
    }

    private String getStyleWidth( TableWidth tableWidth )
    {
        return tableWidth.percentUnit ? getValueAsPercent( tableWidth.width ) : getValueAsPoint( tableWidth.width );
    }

    // -------------------------------- Table row styles

    /**
     * @param className
     * @param trPr
     * @param defaultStyle
     */
    private void visitStyle( String className, CTTrPr trPr, boolean defaultStyle )
    {
        CSSStyle style = createCSSStyle( trPr, className );
        if ( style != null )
        {
            getCSSStyles().add( style );
        }
    }

    public CSSStyle createCSSStyle( CTTrPr trPr )
    {
        return createCSSStyle( trPr, null );
    }

    public CSSStyle createCSSStyle( CTTrPr trPr, String className )
    {
        if ( trPr != null )
        {
            String tagName = TR_ELEMENT;
            CSSStyle style = ignoreStylesIfUnused ? null : getOrCreateStyle( null, tagName, className );

            // min-height / height
            TableHeight tableHeight = super.getTableRowHeight( trPr );
            if ( tableHeight != null )
            {
                if ( tableHeight.minimum )
                {
                    style = getOrCreateStyle( style, tagName, className );
                    style.addProperty( MIN_HEIGHT, getValueAsPoint( tableHeight.height ) );
                }
                else
                {
                    style = getOrCreateStyle( style, tagName, className );
                    style.addProperty( HEIGHT, getValueAsPoint( tableHeight.height ) );
                }
            }
            return style;
        }
        return null;
    }

    // -------------------------------- Table cell styles

    /**
     * @param className
     * @param tcPr
     * @param defaultStyle
     */
    private void visitStyle( String className, CTTcPr tcPr, boolean defaultStyle )
    {
        CSSStyle style = createCSSStyle( tcPr, className );
        if ( style != null )
        {
            getCSSStyles().add( style );
        }
    }

    public CSSStyle createCSSStyle( CTTcPr tcPr )
    {
        return createCSSStyle( tcPr, null );
    }

    public CSSStyle createCSSStyle( CTTcPr tcPr, String className )
    {
        if ( tcPr != null )
        {
            String tagName = TD_ELEMENT;
            CSSStyle style = ignoreStylesIfUnused ? null : getOrCreateStyle( null, tagName, className );

            // cell width
            TableWidth cellWidth = super.getTableCellWith( tcPr );
            if ( cellWidth != null )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( WIDTH, getStyleWidth( cellWidth ) );
            }
            // background color
            Color backgroundColor = super.getTableCellBackgroundColor( tcPr );
            if ( backgroundColor != null )
            {
                style = getOrCreateStyle( style, tagName, className );
                style.addProperty( BACKGROUND_COLOR, XWPFUtils.toHexString( backgroundColor ) );
            }
            CTTextDirection direction = super.getTextDirection( tcPr );
            if ( direction != null )
            {
                // see http://www.css3maker.com/text-rotation.html
                int dir = direction.getVal().intValue();
                switch ( dir )
                {
                    case STTextDirection.INT_BT_LR:
                        style = getOrCreateStyle( style, tagName, className );
                        style.addProperty( "-webkit-transform", "rotate(270deg)" );
                        style.addProperty( "-moz-transform", "rotate(270deg)" );
                        style.addProperty( "-o-transform", "rotate(270deg)" );
                        style.addProperty( "writing-mode", "bt-lr" ); // For IE
                        break;
                    case STTextDirection.INT_TB_RL:
                        style = getOrCreateStyle( style, tagName, className );
                        style.addProperty( "-webkit-transform", "rotate(90deg)" );
                        style.addProperty( "-moz-transform", "rotate(90deg)" );
                        style.addProperty( "-o-transform", "rotate(90deg)" );                        
                        style.addProperty( "writing-mode", "tb-rl" ); // For IE
                        break;
                }
            }
            return style;
        }
        return null;
    }

    public List getCSSStyles()
    {
        if ( cssStyles == null )
        {
            cssStyles = new ArrayList();
        }
        return cssStyles;
    }

    public void save( ContentHandler contentHandler )
        throws SAXException
    {
        List cssStyles = getCSSStyles();
        if ( ignoreStylesIfUnused && cssStyles.size() < 1 )
        {
            return;
        }

        SAXHelper.startElement( contentHandler, XHTMLConstants.STYLE_ELEMENT, null );
        for ( CSSStyle style : cssStyles )
        {
            if ( indent != null )
            {
                SAXHelper.characters( contentHandler, CR );
            }
            style.save( contentHandler );
        }
        SAXHelper.endElement( contentHandler, XHTMLConstants.STYLE_ELEMENT );
    }

    public String getValueAsPoint( float value )
    {
        return new StringBuilder( String.valueOf( value ) ).append( PT_UNIT ).toString();
    }

    private String getValueAsPercent( float value )
    {
        return new StringBuilder( String.valueOf( value ) ).append( PERCENT_UNIT ).toString();
    }

    public String getClassNames( String styleID )
    {
        if ( StringUtils.isEmpty( styleID ) )
        {
            return null;
        }
        StringBuilder classNames = new StringBuilder( getClassName( styleID ) );
        CTStyle style = super.getStyle( styleID );
        while ( style != null )
        {
            style = super.getStyle( style.getBasedOn() );
            if ( style != null )
            {
                classNames.insert( 0, getClassName( style.getStyleId(), true ) );
            }
        }

        return classNames.toString();
    }

    private String getClassName( String styleId )
    {
        return getClassName( styleId, false );
    }

    private String getClassName( String styleId, boolean spaceAfter )
    {
        StringBuilder className = new StringBuilder();
        char firstChar = styleId.charAt( 0 );
        if ( Character.isDigit( firstChar ) )
        {
            // class name must not started with a number (Chrome doesn't works with that).
            className.append( 'X' ).toString();
        }
        if ( spaceAfter )
        {
            return className.append( styleId ).append( ' ' ).toString();
        }
        return className.append( styleId ).toString();
    }

    private CSSStyle getOrCreateStyle( CSSStyle style, String tagName, String className )
    {
        if ( style != null )
        {
            return style;
        }
        return new CSSStyle( tagName, className );
    }

    // private String () {
    // // see http://www.css3maker.com/text-rotation.html
    // -webkit-transform: rotate(90deg);
    // -moz-transform: rotate(90deg);
    // -ms-transform: matrix(1.239,-0.124,-0.547,0.843,0,0);
    // -o-transform: matrix(1.239,-0.124,-0.547,0.843,0,0);
    // transform: matrix(1.239,-0.124,-0.547,0.843,0,0);
    // }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy