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

fr.opensagres.odfdom.converter.pdf.internal.stylable.StylableList Maven / Gradle / Ivy

There is a newer version: 2.0.6
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.odfdom.converter.pdf.internal.stylable;

import java.util.ArrayList;
import java.util.Map;

import com.lowagie.text.Chunk;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.Image;
import com.lowagie.text.List;
import com.lowagie.text.Phrase;
import com.lowagie.text.factories.RomanAlphabetFactory;
import com.lowagie.text.factories.RomanNumberFactory;

import fr.opensagres.odfdom.converter.pdf.internal.styles.Style;
import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleLineHeight;
import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleListProperties;
import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleNumFormat;
import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleParagraphProperties;
import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleTextProperties;

/**
 * fixes for pdf conversion by Leszek Piotrowicz 
 */
public class StylableList
    extends List
    implements IStylableContainer
{
    private IStylableContainer parent;

    private int listLevel;

    private boolean romanNumbered = false;

    private Style lastStyleApplied = null;

    public StylableList( StylableDocument ownerDocument, IStylableContainer parent, int listLevel )
    {
        this.parent = parent;
        this.listLevel = listLevel;
        // set defaults
        super.setNumbered( false );
        super.setLettered( false );
        super.setLowercase( false );
        super.setPreSymbol( "" );
        super.setPostSymbol( "" );
        super.setListSymbol( "" );
        super.setAutoindent( false );
    }

    public int getIndex()
    {
        return first + list.size();
    }

    public void setFirst( int first )
    {
        this.first = first;
    }

    public void addElement( Element element )
    {
        if ( element instanceof StylableListItem )
        {
            StylableListItem li = (StylableListItem) element;
            boolean first = true;
            for ( Element e : li.getElements() )
            {
                addElement( e, first );
                first = false;
            }
        }
    }

    @SuppressWarnings( "unchecked" )
    private void addElement( Element element, boolean addLabel )
    {
        if ( element instanceof Chunk )
        {
            // may it happen?
            Chunk ch = (Chunk) element;
            StylableParagraph p = new StylableParagraph( null, null );
            p.setFont( ch.getFont() );
            p.addElement( ch );
            element = p.getElement();
        }
        if ( element instanceof Phrase )
        {
            Phrase p = (Phrase) element;
            StylableListItem li = new StylableListItem( p );
            // determine font, it may be set explicitly or use paragraph font
            Font symbolFont = symbol.getFont();
            if ( symbolFont.isStandardFont() )
            {
                ArrayList chunks = p.getChunks();
                for ( Chunk chunk : chunks )
                {
                    // use first specified font
                    if ( !chunk.getFont().isStandardFont() )
                    {
                        symbolFont = chunk.getFont();
                        break;
                    }
                }
                if ( symbolFont.isStandardFont() )
                {
                    // use paragraph font
                    symbolFont = p.getFont();
                }
            }
            // determine line height
            float lineHeight = StylableParagraph.DEFAULT_LINE_HEIGHT;
            boolean lineHeightProportional = true;
            if ( element instanceof IStylableElement )
            {
                IStylableElement stylableElement = (IStylableElement) element;
                Style style = stylableElement.getLastStyleApplied();
                if ( style != null )
                {
                    StyleParagraphProperties paragraphProperties = style.getParagraphProperties();
                    StyleLineHeight lineHeightObj = paragraphProperties.getLineHeight();
                    if ( lineHeightObj != null && lineHeightObj.getLineHeight() != null )
                    {
                        lineHeight = lineHeightObj.getLineHeight();
                        lineHeightProportional = lineHeightObj.isLineHeightProportional();
                    }
                }
            }
            if ( addLabel )
            {
                if ( numbered || lettered || romanNumbered )
                {
                    StringBuilder sbuf = new StringBuilder( preSymbol );
                    int index = first + list.size();
                    if ( lettered )
                    {
                        sbuf.append( RomanAlphabetFactory.getString( index, lowercase ) );
                    }
                    else if ( romanNumbered )
                    {
                        sbuf.append( RomanNumberFactory.getString( index, lowercase ) );
                    }
                    else
                    {
                        sbuf.append( index );
                    }
                    sbuf.append( postSymbol );
                    li.setListSymbol( sbuf.toString(), symbolFont, lineHeight, lineHeightProportional );
                }
                else
                {
                    li.setListSymbol( symbol.getContent(), symbolFont, lineHeight, lineHeightProportional );
                }
            }
            else
            {
                li.setListSymbol( "", symbolFont, lineHeight, lineHeightProportional );
            }
            li.setIndentationLeft( symbolIndent );
            li.setIndentationRight( 0.0f );
            list.add( li );
        }
        else if ( element instanceof List )
        {
            List l = (List) element;
            // open office specifies absolute list indentation
            // but iText computes indentation relative to parent list
            // so we have to set difference
            l.setIndentationLeft( l.getIndentationLeft() - this.getIndentationLeft() );
            first--;
            list.add( l );
        }
    }

    public static StyleListProperties getListProperties( Map listPropertiesMap, int level )
    {
        StyleListProperties listProperties = null;
        for ( int i = level; i >= 0 && listProperties == null; i-- )
        {
            // find style for current or nearest lower list level
            listProperties = listPropertiesMap.get( i );
        }
        return listProperties;
    }

    public void applyStyles( Style style )
    {
        this.lastStyleApplied = style;

        Map listPropertiesMap = style.getListPropertiesMap();
        if ( listPropertiesMap != null )
        {
            StyleListProperties listProperties = getListProperties( listPropertiesMap, listLevel );
            if ( listProperties != null )
            {
                String bulletChar = listProperties.getBulletChar();
                if ( bulletChar != null )
                {
                    // list item label is a char
                    Chunk symbol = new Chunk( bulletChar );

                    StyleTextProperties textProperties = listProperties.getTextProperties();
                    if ( textProperties != null )
                    {
                        Font font = textProperties.getFont();
                        if ( font != null )
                        {
                            symbol.setFont( font );
                        }
                    }

                    super.setListSymbol( symbol );
                }

                Image image = listProperties.getImage();
                if ( image != null )
                {
                    // list item label is an image
                    Float width = listProperties.getWidth();
                    if ( width != null )
                    {
                        image.scaleAbsoluteWidth( width );
                    }

                    Float height = listProperties.getHeight();
                    if ( height != null )
                    {
                        image.scaleAbsoluteHeight( height );
                    }

                    super.setListSymbol( new Chunk( image, 0.0f, 0.0f ) );
                }

                if ( bulletChar == null && image == null )
                {
                    // list item label is a number
                    Chunk symbol = new Chunk( "" );

                    StyleTextProperties textProperties = listProperties.getTextProperties();
                    if ( textProperties != null )
                    {
                        Font font = textProperties.getFont();
                        if ( font != null )
                        {
                            symbol.setFont( font );
                        }
                    }

                    Integer startValue = listProperties.getStartValue();
                    if ( startValue != null )
                    {
                        super.setFirst( startValue );
                    }

                    StyleNumFormat numFormat = listProperties.getNumFormat();
                    if ( numFormat != null )
                    {
                        String numPrefix = listProperties.getNumPrefix();
                        if ( numPrefix != null )
                        {
                            super.setPreSymbol( numPrefix );
                            symbol = new Chunk( numPrefix, symbol.getFont() );
                        }

                        String numSuffix = listProperties.getNumSuffix();
                        if ( numSuffix != null )
                        {
                            super.setPostSymbol( numSuffix );
                            symbol.append( numSuffix );
                        }

                        super.setNumbered( true );
                        super.setLettered( numFormat.isAlphabetical() );
                        this.romanNumbered = numFormat.isRoman();
                        super.setLowercase( numFormat.isLowercase() );
                    }

                    super.setListSymbol( symbol );
                }

                // set indentation, it is specified in different way by Open Office and MsWord
                Float marginLeft = listProperties.getMarginLeft();
                Float textIndent = listProperties.getTextIndent();
                Float spaceBefore = listProperties.getSpaceBefore();
                Float minLabelWidth = listProperties.getMinLabelWidth();
                if ( marginLeft != null && textIndent != null )
                {
                    // ODT generated by Open Office
                    super.setIndentationLeft( Math.max( marginLeft + textIndent, 0.0f ) );
                    super.setSymbolIndent( Math.max( -textIndent, 0.0f ) );
                }
                else if ( spaceBefore != null && minLabelWidth != null )
                {
                    // ODT generated by MsWord
                    super.setIndentationLeft( Math.max( spaceBefore, 0.0f ) );
                    super.setSymbolIndent( Math.max( minLabelWidth, 0.0f ) );
                }
            }
        }
    }

    public Style getLastStyleApplied()
    {
        return lastStyleApplied;
    }

    public IStylableContainer getParent()
    {
        return parent;
    }

    public Element getElement()
    {
        return this;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy