/** * Copyright (C) 2011-2015 The XDocReport Team <xdocreport@googlegroups.com> * * 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; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.odftoolkit.odfdom.doc.OdfDocument; import org.odftoolkit.odfdom.dom.attribute.fo.FoBreakBeforeAttribute; import org.odftoolkit.odfdom.dom.attribute.fo.FoFontStyleAttribute; import org.odftoolkit.odfdom.dom.attribute.fo.FoFontWeightAttribute; import org.odftoolkit.odfdom.dom.attribute.fo.FoKeepTogetherAttribute; import org.odftoolkit.odfdom.dom.attribute.fo.FoTextAlignAttribute; import org.odftoolkit.odfdom.dom.attribute.style.StyleFontStyleAsianAttribute; import org.odftoolkit.odfdom.dom.attribute.style.StyleFontStyleComplexAttribute; import org.odftoolkit.odfdom.dom.attribute.style.StyleFontWeightAsianAttribute; import org.odftoolkit.odfdom.dom.attribute.style.StyleFontWeightComplexAttribute; import org.odftoolkit.odfdom.dom.attribute.style.StyleNumFormatAttribute; import org.odftoolkit.odfdom.dom.attribute.style.StylePrintOrientationAttribute; import org.odftoolkit.odfdom.dom.attribute.style.StyleTextLineThroughStyleAttribute; import org.odftoolkit.odfdom.dom.attribute.style.StyleTextUnderlineStyleAttribute; import org.odftoolkit.odfdom.dom.attribute.style.StyleTypeAttribute; import org.odftoolkit.odfdom.dom.attribute.style.StyleVerticalAlignAttribute; import org.odftoolkit.odfdom.dom.attribute.style.StyleWrapAttribute; import org.odftoolkit.odfdom.dom.attribute.table.TableAlignAttribute; import org.odftoolkit.odfdom.dom.element.OdfStyleBase; import org.odftoolkit.odfdom.dom.element.office.OfficeAutomaticStylesElement; import org.odftoolkit.odfdom.dom.element.office.OfficeMasterStylesElement; import org.odftoolkit.odfdom.dom.element.office.OfficeStylesElement; import org.odftoolkit.odfdom.dom.element.style.StyleBackgroundImageElement; import org.odftoolkit.odfdom.dom.element.style.StyleColumnElement; import org.odftoolkit.odfdom.dom.element.style.StyleColumnsElement; import org.odftoolkit.odfdom.dom.element.style.StyleDefaultStyleElement; import org.odftoolkit.odfdom.dom.element.style.StyleFooterStyleElement; import org.odftoolkit.odfdom.dom.element.style.StyleGraphicPropertiesElement; import org.odftoolkit.odfdom.dom.element.style.StyleHeaderFooterPropertiesElement; import org.odftoolkit.odfdom.dom.element.style.StyleListLevelLabelAlignmentElement; import org.odftoolkit.odfdom.dom.element.style.StyleListLevelPropertiesElement; import org.odftoolkit.odfdom.dom.element.style.StylePageLayoutElement; import org.odftoolkit.odfdom.dom.element.style.StylePageLayoutPropertiesElement; import org.odftoolkit.odfdom.dom.element.style.StyleParagraphPropertiesElement; import org.odftoolkit.odfdom.dom.element.style.StyleSectionPropertiesElement; import org.odftoolkit.odfdom.dom.element.style.StyleStyleElement; import org.odftoolkit.odfdom.dom.element.style.StyleTabStopElement; import org.odftoolkit.odfdom.dom.element.style.StyleTabStopsElement; import org.odftoolkit.odfdom.dom.element.style.StyleTableCellPropertiesElement; import org.odftoolkit.odfdom.dom.element.style.StyleTablePropertiesElement; import org.odftoolkit.odfdom.dom.element.style.StyleTableRowPropertiesElement; import org.odftoolkit.odfdom.dom.element.style.StyleTextPropertiesElement; import org.odftoolkit.odfdom.dom.element.text.TextListLevelStyleBulletElement; import org.odftoolkit.odfdom.dom.element.text.TextListLevelStyleImageElement; import org.odftoolkit.odfdom.dom.element.text.TextListLevelStyleNumberElement; import org.odftoolkit.odfdom.dom.element.text.TextListStyleElement; import org.odftoolkit.odfdom.dom.element.text.TextOutlineLevelStyleElement; import org.odftoolkit.odfdom.dom.element.text.TextOutlineStyleElement; import org.odftoolkit.odfdom.dom.style.OdfStyleFamily; import org.odftoolkit.odfdom.pkg.OdfElement; import org.w3c.dom.Node; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.Image; import fr.opensagres.odfdom.converter.core.AbstractStyleEngine; import fr.opensagres.odfdom.converter.core.utils.ODFUtils; import fr.opensagres.odfdom.converter.pdf.PdfOptions; import fr.opensagres.odfdom.converter.pdf.internal.stylable.StylableImage; import fr.opensagres.odfdom.converter.pdf.internal.styles.Style; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleBorder; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleBreak; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleColumnProperties; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleGraphicProperties; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleHeaderFooterProperties; 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.StylePageLayoutProperties; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleParagraphProperties; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleSectionProperties; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleTabStopProperties; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleTableCellProperties; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleTableProperties; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleTableRowProperties; import fr.opensagres.odfdom.converter.pdf.internal.styles.StyleTextProperties; import fr.opensagres.xdocreport.itext.extension.PageOrientation; import fr.opensagres.xdocreport.utils.BorderType; import fr.opensagres.xdocreport.utils.StringUtils; /** * fixes for pdf conversion by Leszek Piotrowicz <leszekp@safe-mail.net> */ public class StyleEngineForIText extends AbstractStyleEngine { private static final String OUTLINE = "outline"; private Style currentStyle = null; private Map<Integer, StyleListProperties> currentListPropertiesMap; private StyleListProperties currentListProperties; private List<StyleTabStopProperties> currentTabStopPropertiesList; private List<StyleColumnProperties> currentColumnPropertiesList; private BackgroundImage backgroundImage = null; private final PdfOptions options; private final Map<String, Style> stylesMap = new HashMap<String, Style>(); public StyleEngineForIText( OdfDocument odfDocument, PdfOptions options ) { super(odfDocument); this.options = options != null ? options : PdfOptions.getDefault(); } public BackgroundImage getBackgroundImage() { return backgroundImage; } public void visit(StyleBackgroundImageElement ele) { String href = ele.getXlinkHrefAttribute(); if (StringUtils.isNotEmpty(href)) { byte[] imageStream = odfDocument.getPackage().getBytes(href); try { if (imageStream != null) { BackgroundImage.Builder builder = new BackgroundImage.Builder(imageStream); Node parentNode = ele.getParentNode(); builder.setRepeat(BackgroundImage.Repeat.fromODT(ele.getStyleRepeatAttribute())); builder.setPosition(BackgroundImage.Position.fromODT(ele.getStylePositionAttribute())); if (parentNode instanceof StylePageLayoutPropertiesElement) { StylePageLayoutPropertiesElement layout = (StylePageLayoutPropertiesElement) parentNode; String svgWidth = layout.getFoPageWidthAttribute(); if (StringUtils.isNotEmpty(svgWidth)) builder.setPageWidth(ODFUtils.getDimensionAsPoint(svgWidth)); String svgHeight = layout.getFoPageHeightAttribute(); if (StringUtils.isNotEmpty(svgHeight)) builder.setPageHeight(ODFUtils.getDimensionAsPoint(svgHeight)); String leftMargin = layout.getFoMarginLeftAttribute(); if (StringUtils.isNotEmpty(leftMargin)) builder.setLeftMargin(ODFUtils.getDimensionAsPoint(leftMargin)); String rightMargin = layout.getFoMarginRightAttribute(); if (StringUtils.isNotEmpty(rightMargin)) builder.setRightMargin(ODFUtils.getDimensionAsPoint(rightMargin)); String topMargin = layout.getFoMarginTopAttribute(); if (StringUtils.isNotEmpty(topMargin)) builder.setTopMargin(ODFUtils.getDimensionAsPoint(topMargin)); String bottomMargin = layout.getFoMarginBottomAttribute(); if (StringUtils.isNotEmpty(bottomMargin)) builder.setBottomMargin(ODFUtils.getDimensionAsPoint(bottomMargin)); } backgroundImage = builder.build(); } } catch (Exception e) { throw new RuntimeException(e); } } } public void visit( OfficeStylesElement ele ) { super.visit( ele ); } public void visit( OfficeAutomaticStylesElement ele ) { super.visit( ele ); } public void visit( OfficeMasterStylesElement ele ) { super.visit( ele ); } public void visit( StyleDefaultStyleElement ele ) { computeStyle( ele, true ); } public void visit( StyleStyleElement ele ) { computeStyle( ele, false ); } public void visit( StylePageLayoutElement ele ) { computeStyle( ele, false ); } private Style computeStyle( OdfElement odfElement, boolean isDefaultStyle ) { if ( odfElement == null ) { return null; } OdfStyleBase styleBase = odfElement instanceof OdfStyleBase ? (OdfStyleBase) odfElement : null; // 1) Check if style is in the cache String familyName = styleBase != null ? styleBase.getFamilyName() : OUTLINE; String styleName = null; String masterPageName = null; if ( !isDefaultStyle ) { if ( styleBase instanceof StyleStyleElement ) { StyleStyleElement styleElement = (StyleStyleElement) styleBase; styleName = styleElement.getStyleNameAttribute(); masterPageName = styleElement.getStyleMasterPageNameAttribute(); } else if ( styleBase instanceof StylePageLayoutElement ) { styleName = ( (StylePageLayoutElement) styleBase ).getStyleNameAttribute(); } else if ( styleBase instanceof TextListStyleElement ) { styleName = ( (TextListStyleElement) styleBase ).getStyleNameAttribute(); } } String styleId = getStyleId( familyName, styleName ); Style style = stylesMap.get( styleId ); if ( style != null ) { // style already computed return style; } // 3) Create style style = new Style( options.getFontProvider(), styleName, familyName, masterPageName ); // 4) Apply default style if needed // Style defaultStyle = null; // if (!isDefaultStyle) { // OdfDefaultStyle odfDefaultStyle = odfDocument.getDocumentStyles() // .getDefaultStyle(styleBase.getFamily()); // if (odfDefaultStyle != null) { // defaultStyle = computeStyle(odfDefaultStyle, true); // } // if (defaultStyle != null) { // style.merge(defaultStyle); // } // } // 5) Apply Parent style List<Style> parentsStyles = null; OdfStyleBase parentStyleBase = styleBase != null ? styleBase.getParentStyle() : null; while ( parentStyleBase != null ) { Style parentStyle = computeStyle( parentStyleBase, isDefaultStyle ); if ( parentStyle != null ) { if ( parentsStyles == null ) { parentsStyles = new ArrayList<Style>(); } parentsStyles.add( 0, parentStyle ); } parentStyleBase = parentStyleBase.getParentStyle(); } if ( parentsStyles != null ) { for ( Style parentsStyle : parentsStyles ) { style.merge( parentsStyle, false ); } } // 6) Apply current style currentStyle = style; super.visit( odfElement ); // 7) register style in the cache stylesMap.put( styleId, style ); return style; } public void visit( StylePageLayoutPropertiesElement ele ) { StylePageLayoutProperties pageLayoutProperties = currentStyle.getPageLayoutProperties(); if ( pageLayoutProperties == null ) { pageLayoutProperties = new StylePageLayoutProperties(); currentStyle.setPageLayoutProperties( pageLayoutProperties ); } // background-color String backgroundColor = ele.getFoBackgroundColorAttribute(); if ( StringUtils.isNotEmpty( backgroundColor ) ) { // cssStyleSheet.setCSSProperty("background-color", // backgroundColor); } // border String border = ele.getFoBorderAttribute(); if ( StringUtils.isNotEmpty( border ) ) { // cssStyleSheet.setCSSProperty("border", border); } // border-bottom String borderBottom = ele.getFoBorderBottomAttribute(); if ( StringUtils.isNotEmpty( borderBottom ) ) { // cssStyleSheet.setCSSProperty("border-bottom", borderBottom); } // border-left String borderLeft = ele.getFoBorderLeftAttribute(); if ( StringUtils.isNotEmpty( borderLeft ) ) { // cssStyleSheet.setCSSProperty("border-left", borderLeft); } // border-bottom String borderRight = ele.getFoBorderRightAttribute(); if ( StringUtils.isNotEmpty( borderRight ) ) { // cssStyleSheet.setCSSProperty("border-right", borderRight); } // border-top String borderTop = ele.getFoBorderTopAttribute(); if ( StringUtils.isNotEmpty( borderTop ) ) { // cssStyleSheet.setCSSProperty("border-top", borderTop); } // margin String margin = ele.getFoMarginAttribute(); if ( StringUtils.isNotEmpty( margin ) ) { pageLayoutProperties.setMargin( ODFUtils.getDimensionAsPoint( margin ) ); } // margin-bottom String marginBottom = ele.getFoMarginBottomAttribute(); if ( StringUtils.isNotEmpty( marginBottom ) ) { pageLayoutProperties.setMarginBottom( ODFUtils.getDimensionAsPoint( marginBottom ) ); } // margin-left String marginLeft = ele.getFoMarginLeftAttribute(); if ( StringUtils.isNotEmpty( marginLeft ) ) { pageLayoutProperties.setMarginLeft( ODFUtils.getDimensionAsPoint( marginLeft ) ); } // margin-right String marginRight = ele.getFoMarginRightAttribute(); if ( StringUtils.isNotEmpty( marginRight ) ) { pageLayoutProperties.setMarginRight( ODFUtils.getDimensionAsPoint( marginRight ) ); } // margin-top String marginTop = ele.getFoMarginTopAttribute(); if ( StringUtils.isNotEmpty( marginTop ) ) { pageLayoutProperties.setMarginTop( ODFUtils.getDimensionAsPoint( marginTop ) ); } // padding String padding = ele.getFoPaddingAttribute(); if ( StringUtils.isNotEmpty( padding ) ) { // cssStyleSheet.setCSSProperty("padding", padding); } // padding-bottom String paddingBottom = ele.getFoPaddingBottomAttribute(); if ( StringUtils.isNotEmpty( paddingBottom ) ) { // cssStyleSheet.setCSSProperty("padding-bottom", paddingBottom); } // padding-left String paddingLeft = ele.getFoPaddingLeftAttribute(); if ( StringUtils.isNotEmpty( paddingLeft ) ) { // cssStyleSheet.setCSSProperty("padding-left", paddingLeft); } // padding-bottom String paddingRight = ele.getFoPaddingRightAttribute(); if ( StringUtils.isNotEmpty( paddingRight ) ) { // cssStyleSheet.setCSSProperty("padding-right", paddingRight); } // padding-top String paddingTop = ele.getFoPaddingTopAttribute(); if ( StringUtils.isNotEmpty( paddingTop ) ) { // cssStyleSheet.setCSSProperty("padding-top", paddingTop); } // height String height = ele.getFoPageHeightAttribute(); if ( StringUtils.isNotEmpty( height ) ) { pageLayoutProperties.setHeight( ODFUtils.getDimensionAsPoint( height ) ); } // width String width = ele.getFoPageWidthAttribute(); if ( StringUtils.isNotEmpty( width ) ) { pageLayoutProperties.setWidth( ODFUtils.getDimensionAsPoint( width ) ); } // orientation String orientation = ele.getStylePrintOrientationAttribute(); if ( StringUtils.isNotEmpty( orientation ) ) { if ( StylePrintOrientationAttribute.Value.LANDSCAPE.toString().equals( orientation ) ) { pageLayoutProperties.setOrientation( PageOrientation.Landscape ); } else if ( StylePrintOrientationAttribute.Value.PORTRAIT.toString().equals( orientation ) ) { pageLayoutProperties.setOrientation( PageOrientation.Portrait ); } } super.visit( ele ); } public void visit( StyleHeaderFooterPropertiesElement ele ) { Node parentNode = ele.getParentNode(); boolean footer = StyleFooterStyleElement.ELEMENT_NAME.getLocalName().equals( parentNode.getLocalName() ); StyleHeaderFooterProperties headerFooterProperties = null; if ( !footer ) { headerFooterProperties = currentStyle.getHeaderProperties(); if ( headerFooterProperties == null ) { headerFooterProperties = new StyleHeaderFooterProperties(); currentStyle.setHeaderProperties( headerFooterProperties ); } } else { headerFooterProperties = currentStyle.getFooterProperties(); if ( headerFooterProperties == null ) { headerFooterProperties = new StyleHeaderFooterProperties(); currentStyle.setFooterProperties( headerFooterProperties ); } } // min-height String minHeight = ele.getFoMinHeightAttribute(); if ( StringUtils.isNotEmpty( minHeight ) ) { headerFooterProperties.setMinHeight( ODFUtils.getDimensionAsPoint( minHeight ) ); } // margin String margin = ele.getFoMarginAttribute(); if ( StringUtils.isNotEmpty( margin ) ) { headerFooterProperties.setMargin( ODFUtils.getDimensionAsPoint( margin ) ); } // margin-bottom String marginBottom = ele.getFoMarginBottomAttribute(); if ( StringUtils.isNotEmpty( marginBottom ) ) { headerFooterProperties.setMarginBottom( ODFUtils.getDimensionAsPoint( marginBottom ) ); } // margin-left String marginLeft = ele.getFoMarginLeftAttribute(); if ( StringUtils.isNotEmpty( marginLeft ) ) { headerFooterProperties.setMarginLeft( ODFUtils.getDimensionAsPoint( marginLeft ) ); } // margin-right String marginRight = ele.getFoMarginRightAttribute(); if ( StringUtils.isNotEmpty( marginRight ) ) { headerFooterProperties.setMarginRight( ODFUtils.getDimensionAsPoint( marginRight ) ); } // margin-top String marginTop = ele.getFoMarginTopAttribute(); if ( StringUtils.isNotEmpty( marginTop ) ) { headerFooterProperties.setMarginTop( ODFUtils.getDimensionAsPoint( marginTop ) ); } // height String height = ele.getSvgHeightAttribute(); if ( StringUtils.isNotEmpty( height ) ) { headerFooterProperties.setHeight(ODFUtils.getDimensionAsPoint(height)); } } // visit //style:paragraph-properties @Override public void visit( StyleParagraphPropertiesElement ele ) { StyleParagraphProperties paragraphProperties = currentStyle.getParagraphProperties(); if ( paragraphProperties == null ) { paragraphProperties = new StyleParagraphProperties(); currentStyle.setParagraphProperties( paragraphProperties ); } // background-color String backgroundColor = ele.getFoBackgroundColorAttribute(); if ( StringUtils.isNotEmpty( backgroundColor ) ) { paragraphProperties.setBackgroundColor( ColorRegistry.getInstance().getColor( backgroundColor ) ); } // border String border = ele.getFoBorderAttribute(); if ( StringUtils.isNotEmpty( border ) ) { paragraphProperties.setBorder( new StyleBorder( border, BorderType.ALL ) ); } // border-bottom String borderBottom = ele.getFoBorderBottomAttribute(); if ( StringUtils.isNotEmpty( borderBottom ) ) { paragraphProperties.setBorderBottom( new StyleBorder( borderBottom, BorderType.BOTTOM ) ); } // border-left String borderLeft = ele.getFoBorderLeftAttribute(); if ( StringUtils.isNotEmpty( borderLeft ) ) { paragraphProperties.setBorderLeft( new StyleBorder( borderLeft, BorderType.LEFT ) ); } // border-bottom String borderRight = ele.getFoBorderRightAttribute(); if ( StringUtils.isNotEmpty( borderRight ) ) { paragraphProperties.setBorderRight( new StyleBorder( borderRight, BorderType.RIGHT ) ); } // border-top String borderTop = ele.getFoBorderTopAttribute(); if ( StringUtils.isNotEmpty( borderTop ) ) { paragraphProperties.setBorderTop( new StyleBorder( borderTop, BorderType.TOP ) ); } // join-border Boolean joinBorder = ele.getStyleJoinBorderAttribute(); if ( joinBorder != null ) { paragraphProperties.setJoinBorder( joinBorder ); } // line-height String lineHeight = ele.getFoLineHeightAttribute(); if ( StringUtils.isNotEmpty( lineHeight ) ) { paragraphProperties.setLineHeight( new StyleLineHeight( ODFUtils.getDimensionAsPoint( lineHeight ), ODFUtils.hasPercentUnit( lineHeight ) ) ); } // margin String margin = ele.getFoMarginAttribute(); if ( StringUtils.isNotEmpty( margin ) ) { paragraphProperties.setMargin( ODFUtils.getDimensionAsPoint( margin ) ); } // margin-bottom String marginBottom = ele.getFoMarginBottomAttribute(); if ( StringUtils.isNotEmpty( marginBottom ) ) { paragraphProperties.setMarginBottom( ODFUtils.getDimensionAsPoint( marginBottom ) ); } // margin-left String marginLeft = ele.getFoMarginLeftAttribute(); if ( StringUtils.isNotEmpty( marginLeft ) ) { paragraphProperties.setMarginLeft( ODFUtils.getDimensionAsPoint( marginLeft ) ); } // margin-right String marginRight = ele.getFoMarginRightAttribute(); if ( StringUtils.isNotEmpty( marginRight ) ) { paragraphProperties.setMarginRight( ODFUtils.getDimensionAsPoint( marginRight ) ); } // margin-top String marginTop = ele.getFoMarginTopAttribute(); if ( StringUtils.isNotEmpty( marginTop ) ) { paragraphProperties.setMarginTop( ODFUtils.getDimensionAsPoint( marginTop ) ); } // padding String padding = ele.getFoPaddingAttribute(); if ( StringUtils.isNotEmpty( padding ) ) { paragraphProperties.setPadding( ODFUtils.getDimensionAsPoint( padding ) ); } // padding-bottom String paddingBottom = ele.getFoPaddingBottomAttribute(); if ( StringUtils.isNotEmpty( paddingBottom ) ) { paragraphProperties.setPaddingBottom( ODFUtils.getDimensionAsPoint( paddingBottom ) ); } // padding-left String paddingLeft = ele.getFoPaddingLeftAttribute(); if ( StringUtils.isNotEmpty( paddingLeft ) ) { paragraphProperties.setPaddingLeft( ODFUtils.getDimensionAsPoint( paddingLeft ) ); } // padding-right String paddingRight = ele.getFoPaddingRightAttribute(); if ( StringUtils.isNotEmpty( paddingRight ) ) { paragraphProperties.setPaddingRight( ODFUtils.getDimensionAsPoint( paddingRight ) ); } // padding-top String paddingTop = ele.getFoPaddingTopAttribute(); if ( StringUtils.isNotEmpty( paddingTop ) ) { paragraphProperties.setPaddingTop( ODFUtils.getDimensionAsPoint( paddingTop ) ); } // text-align String textAlign = ele.getFoTextAlignAttribute(); if ( StringUtils.isNotEmpty( textAlign ) ) { int alignment = Element.ALIGN_UNDEFINED; if ( FoTextAlignAttribute.Value.START.toString().equals( textAlign ) ) { alignment = Element.ALIGN_LEFT; } else if ( FoTextAlignAttribute.Value.END.toString().equals( textAlign ) ) { alignment = Element.ALIGN_RIGHT; } else if ( FoTextAlignAttribute.Value.LEFT.toString().equals( textAlign ) ) { alignment = Element.ALIGN_LEFT; } else if ( FoTextAlignAttribute.Value.RIGHT.toString().equals( textAlign ) ) { alignment = Element.ALIGN_RIGHT; } else if ( FoTextAlignAttribute.Value.CENTER.toString().equals( textAlign ) ) { alignment = Element.ALIGN_CENTER; } else if ( FoTextAlignAttribute.Value.JUSTIFY.toString().equals( textAlign ) ) { alignment = Element.ALIGN_JUSTIFIED; } paragraphProperties.setAlignment( alignment ); } // auto-text-indent Boolean autoTextIndent = ele.getStyleAutoTextIndentAttribute(); if ( autoTextIndent != null ) { paragraphProperties.setAutoTextIndent( autoTextIndent ); } // text-indent String textIndent = ele.getFoTextIndentAttribute(); if ( StringUtils.isNotEmpty( textIndent ) ) { paragraphProperties.setTextIndent( ODFUtils.getDimensionAsPoint( textIndent ) ); } // keep-together String keepTogether = ele.getFoKeepTogetherAttribute(); if ( StringUtils.isNotEmpty( keepTogether ) ) { if ( FoKeepTogetherAttribute.Value.ALWAYS.toString().equals( keepTogether ) ) { paragraphProperties.setKeepTogether( Boolean.TRUE ); } else { paragraphProperties.setKeepTogether( Boolean.FALSE ); } } // fo:break-before String breakBefore = ele.getFoBreakBeforeAttribute(); if ( StringUtils.isNotEmpty( breakBefore ) ) { if ( FoBreakBeforeAttribute.Value.PAGE.toString().equals( breakBefore ) ) { paragraphProperties.setBreakBefore( StyleBreak.createWithPageBreak() ); } else if ( FoBreakBeforeAttribute.Value.COLUMN.toString().equals( breakBefore ) ) { paragraphProperties.setBreakBefore( StyleBreak.createWithColumnBreak() ); } else { paragraphProperties.setBreakBefore( StyleBreak.createWithNoBreak() ); } } super.visit( ele ); } @Override public void visit( StyleTabStopsElement ele ) { currentTabStopPropertiesList = new ArrayList<StyleTabStopProperties>(); super.visit( ele ); currentStyle.setTabStopPropertiesList( currentTabStopPropertiesList ); currentTabStopPropertiesList = null; } @Override public void visit( StyleTabStopElement ele ) { if ( currentTabStopPropertiesList == null ) { return; } StyleTabStopProperties tabStopProperties = new StyleTabStopProperties(); currentTabStopPropertiesList.add( tabStopProperties ); // leader-text String leaderText = ele.getStyleLeaderTextAttribute(); if ( StringUtils.isNotEmpty( leaderText ) ) { tabStopProperties.setLeaderText( leaderText ); } // position String position = ele.getStylePositionAttribute(); if ( StringUtils.isNotEmpty( position ) ) { tabStopProperties.setPosition( ODFUtils.getDimensionAsPoint( position ) ); } // type String type = ele.getStyleTypeAttribute(); if ( StringUtils.isNotEmpty( type ) ) { if ( StyleTypeAttribute.Value.LEFT.toString().equals( type ) ) { tabStopProperties.setType( Element.ALIGN_LEFT ); } else if ( StyleTypeAttribute.Value.RIGHT.toString().equals( type ) ) { tabStopProperties.setType( Element.ALIGN_RIGHT ); } else { tabStopProperties.setType( Element.ALIGN_CENTER ); } } super.visit( ele ); } @Override public void visit( StyleTextPropertiesElement ele ) { StyleTextProperties textProperties = currentStyle.getTextProperties(); if ( textProperties == null ) { textProperties = new StyleTextProperties( options.getFontProvider() ); currentStyle.setTextProperties( textProperties ); } // set font encoding from options textProperties.setFontEncoding( options.getFontEncoding() ); // background-color String backgroundColor = ele.getFoBackgroundColorAttribute(); if ( StringUtils.isNotEmpty( backgroundColor ) ) { textProperties.setBackgroundColor( ColorRegistry.getInstance().getColor( backgroundColor ) ); } // color String color = ele.getFoColorAttribute(); if ( StringUtils.isNotEmpty( color ) ) { textProperties.setFontColor( ColorRegistry.getInstance().getColor( color ) ); } // font-family String fontFamily = ele.getFoFontFamilyAttribute(); if ( StringUtils.isNotEmpty( fontFamily ) ) { textProperties.setFontName( ODFUtils.stripTrailingDigits( fontFamily ) ); } String fontFamilyAsian = ele.getStyleFontFamilyAsianAttribute(); if ( StringUtils.isNotEmpty( fontFamilyAsian ) ) { textProperties.setFontNameAsian( ODFUtils.stripTrailingDigits( fontFamilyAsian ) ); } String fontFamilyComplex = ele.getStyleFontFamilyComplexAttribute(); if ( StringUtils.isNotEmpty( fontFamilyComplex ) ) { textProperties.setFontNameComplex( ODFUtils.stripTrailingDigits( fontFamilyComplex ) ); } // font-name String fontName = ele.getStyleFontNameAttribute(); if ( StringUtils.isNotEmpty( fontName ) ) { textProperties.setFontName( ODFUtils.stripTrailingDigits( fontName ) ); } String fontNameAsian = ele.getStyleFontNameAsianAttribute(); if ( StringUtils.isNotEmpty( fontNameAsian ) ) { textProperties.setFontNameAsian( ODFUtils.stripTrailingDigits( fontNameAsian ) ); } String fontNameComplex = ele.getStyleFontNameComplexAttribute(); if ( StringUtils.isNotEmpty( fontNameComplex ) ) { textProperties.setFontNameComplex( ODFUtils.stripTrailingDigits( fontNameComplex ) ); } // font-size String fontSize = ele.getFoFontSizeAttribute(); if ( StringUtils.isNotEmpty( fontSize ) ) { if ( ODFUtils.hasPercentUnit( fontSize ) ) { // relative if ( textProperties.getFontSize() != Font.UNDEFINED ) { textProperties.setFontSize( textProperties.getFontSize() * ODFUtils.getDimensionAsPoint( fontSize ) ); } } else { // absolute textProperties.setFontSize( ODFUtils.getDimensionAsPoint( fontSize ) ); } } String fontSizeAsian = ele.getStyleFontSizeAsianAttribute(); if ( StringUtils.isNotEmpty( fontSizeAsian ) ) { if ( ODFUtils.hasPercentUnit( fontSizeAsian ) ) { // relative if ( textProperties.getFontSizeAsian() != Font.UNDEFINED ) { textProperties.setFontSizeAsian( textProperties.getFontSizeAsian() * ODFUtils.getDimensionAsPoint( fontSizeAsian ) ); } } else { // absolute textProperties.setFontSizeAsian( ODFUtils.getDimensionAsPoint( fontSizeAsian ) ); } } String fontSizeComplex = ele.getStyleFontSizeComplexAttribute(); if ( StringUtils.isNotEmpty( fontSizeComplex ) ) { if ( ODFUtils.hasPercentUnit( fontSizeComplex ) ) { // relative if ( textProperties.getFontSizeComplex() != Font.UNDEFINED ) { textProperties.setFontSizeComplex( textProperties.getFontSizeComplex() * ODFUtils.getDimensionAsPoint( fontSizeComplex ) ); } } else { // absolute textProperties.setFontSizeComplex( ODFUtils.getDimensionAsPoint( fontSizeComplex ) ); } } // font-style String fontStyle = ele.getFoFontStyleAttribute(); if ( StringUtils.isNotEmpty( fontStyle ) ) { if ( FoFontStyleAttribute.Value.NORMAL.toString().equals( fontStyle ) ) { textProperties.setFontItalic( Boolean.FALSE ); } else { // interpret other values as italic textProperties.setFontItalic( Boolean.TRUE ); } } String fontStyleAsian = ele.getStyleFontStyleAsianAttribute(); if ( StringUtils.isNotEmpty( fontStyleAsian ) ) { if ( StyleFontStyleAsianAttribute.Value.NORMAL.toString().equals( fontStyleAsian ) ) { textProperties.setFontItalicAsian( Boolean.FALSE ); } else { // interpret other values as italic textProperties.setFontItalicAsian( Boolean.TRUE ); } } String fontStyleComplex = ele.getStyleFontStyleComplexAttribute(); if ( StringUtils.isNotEmpty( fontStyleComplex ) ) { if ( StyleFontStyleComplexAttribute.Value.NORMAL.toString().equals( fontStyleComplex ) ) { textProperties.setFontItalicComplex( Boolean.FALSE ); } else { // interpret other values as italic textProperties.setFontItalicComplex( Boolean.TRUE ); } } // font-variant String fontVariant = ele.getFoFontVariantAttribute(); if ( StringUtils.isNotEmpty( fontVariant ) ) { } // font-weight String fontWeight = ele.getFoFontWeightAttribute(); if ( StringUtils.isNotEmpty( fontWeight ) ) { if ( FoFontWeightAttribute.Value.NORMAL.toString().equals( fontWeight ) ) { textProperties.setFontBold( Boolean.FALSE ); } else { // interpret other values as bold textProperties.setFontBold( Boolean.TRUE ); } } String fontWeightAsian = ele.getStyleFontWeightAsianAttribute(); if ( StringUtils.isNotEmpty( fontWeightAsian ) ) { if ( StyleFontWeightAsianAttribute.Value.NORMAL.toString().equals( fontWeightAsian ) ) { textProperties.setFontBoldAsian( Boolean.FALSE ); } else { // interpret other values as bold textProperties.setFontBoldAsian( Boolean.TRUE ); } } String fontWeightComplex = ele.getStyleFontWeightComplexAttribute(); if ( StringUtils.isNotEmpty( fontWeightComplex ) ) { if ( StyleFontWeightComplexAttribute.Value.NORMAL.toString().equals( fontWeightComplex ) ) { textProperties.setFontBoldComplex( Boolean.FALSE ); } else { // interpret other values as bold textProperties.setFontBoldComplex( Boolean.TRUE ); } } // text-underline-style String underlineStyle = ele.getStyleTextUnderlineStyleAttribute(); if ( StringUtils.isNotEmpty( underlineStyle ) ) { if ( StyleTextUnderlineStyleAttribute.Value.NONE.toString().equals( underlineStyle ) ) { textProperties.setFontUnderline( Boolean.FALSE ); } else { // interpret other values as underline textProperties.setFontUnderline( Boolean.TRUE ); } } // text-underline-type String underlineType = ele.getStyleTextUnderlineTypeAttribute(); if ( StringUtils.isNotEmpty( underlineType ) ) { } // text-line-through-style String lineThroughStyle = ele.getStyleTextLineThroughStyleAttribute(); if ( StringUtils.isNotEmpty( lineThroughStyle ) ) { if ( StyleTextLineThroughStyleAttribute.Value.NONE.toString().equals( lineThroughStyle ) ) { textProperties.setFontStrikeThru( Boolean.FALSE ); } else { // interpret other values as strike thru textProperties.setFontStrikeThru( Boolean.TRUE ); } } // text-position String textPositionStyle = ele.getStyleTextPositionAttribute(); if ( StringUtils.isNotEmpty( textPositionStyle ) ) { if ( textPositionStyle.contains( "super" ) ) { textProperties.setTextPosition( 5.0f ); } else if ( textPositionStyle.contains( "sub" ) ) { textProperties.setTextPosition( -2.0f ); } } super.visit( ele ); } @Override public void visit( StyleTablePropertiesElement ele ) { StyleTableProperties tableProperties = new StyleTableProperties(); currentStyle.setTableProperties( tableProperties ); // background-color String backgroundColor = ele.getFoBackgroundColorAttribute(); if ( StringUtils.isNotEmpty( backgroundColor ) ) { tableProperties.setBackgroundColor( ColorRegistry.getInstance().getColor( backgroundColor ) ); } // width String width = ele.getStyleWidthAttribute(); if ( StringUtils.isNotEmpty( width ) ) { tableProperties.setWidth( ODFUtils.getDimensionAsPoint( width ) ); } // align String align = ele.getTableAlignAttribute(); if ( StringUtils.isNotEmpty( align ) ) { if ( TableAlignAttribute.Value.LEFT.toString().equals( align ) ) { tableProperties.setAlignment( Element.ALIGN_LEFT ); } else if ( TableAlignAttribute.Value.RIGHT.toString().equals( align ) ) { tableProperties.setAlignment( Element.ALIGN_RIGHT ); } else { tableProperties.setAlignment( Element.ALIGN_CENTER ); } } // margin String margin = ele.getFoMarginAttribute(); if ( StringUtils.isNotEmpty( margin ) ) { tableProperties.setMargin( ODFUtils.getDimensionAsPoint( margin ) ); } // margin-bottom String marginBottom = ele.getFoMarginBottomAttribute(); if ( StringUtils.isNotEmpty( marginBottom ) ) { tableProperties.setMarginBottom( ODFUtils.getDimensionAsPoint( marginBottom ) ); } // margin-left String marginLeft = ele.getFoMarginLeftAttribute(); if ( StringUtils.isNotEmpty( marginLeft ) ) { tableProperties.setMarginLeft( ODFUtils.getDimensionAsPoint( marginLeft ) ); } // margin-right String marginRight = ele.getFoMarginRightAttribute(); if ( StringUtils.isNotEmpty( marginRight ) ) { tableProperties.setMarginRight( ODFUtils.getDimensionAsPoint( marginRight ) ); } // margin-top String marginTop = ele.getFoMarginTopAttribute(); if ( StringUtils.isNotEmpty( marginTop ) ) { tableProperties.setMarginTop( ODFUtils.getDimensionAsPoint( marginTop ) ); } // may-break-between-rows Boolean mayBreakBetweenRows = ele.getStyleMayBreakBetweenRowsAttribute(); if ( mayBreakBetweenRows != null ) { tableProperties.setMayBreakBetweenRows( mayBreakBetweenRows ); } super.visit( ele ); } @Override public void visit( StyleTableRowPropertiesElement ele ) { StyleTableRowProperties tableRowProperties = currentStyle.getTableRowProperties(); if ( tableRowProperties == null ) { tableRowProperties = new StyleTableRowProperties(); currentStyle.setTableRowProperties( tableRowProperties ); } // min-height String minHeight = ele.getStyleMinRowHeightAttribute(); if ( StringUtils.isNotEmpty( minHeight ) ) { tableRowProperties.setMinRowHeight( ODFUtils.getDimensionAsPoint( minHeight ) ); } // height String height = ele.getStyleRowHeightAttribute(); if ( StringUtils.isNotEmpty( height ) ) { tableRowProperties.setRowHeight( ODFUtils.getDimensionAsPoint( height ) ); } // keep-together String keepTogether = ele.getFoKeepTogetherAttribute(); if ( StringUtils.isNotEmpty( keepTogether ) ) { if ( FoKeepTogetherAttribute.Value.ALWAYS.toString().equals( keepTogether ) ) { tableRowProperties.setKeepTogether( Boolean.TRUE ); } else { tableRowProperties.setKeepTogether( Boolean.FALSE ); } } } @Override public void visit( StyleTableCellPropertiesElement ele ) { StyleTableCellProperties tableCellProperties = currentStyle.getTableCellProperties(); if ( tableCellProperties == null ) { tableCellProperties = new StyleTableCellProperties(); currentStyle.setTableCellProperties( tableCellProperties ); } // background-color String backgroundColor = ele.getFoBackgroundColorAttribute(); if ( StringUtils.isNotEmpty( backgroundColor ) ) { tableCellProperties.setBackgroundColor( ColorRegistry.getInstance().getColor( backgroundColor ) ); } // border String border = ele.getFoBorderAttribute(); if ( StringUtils.isNotEmpty( border ) ) { tableCellProperties.setBorder( new StyleBorder( border, BorderType.ALL ) ); } // border-bottom String borderBottom = ele.getFoBorderBottomAttribute(); if ( StringUtils.isNotEmpty( borderBottom ) ) { tableCellProperties.setBorderBottom( new StyleBorder( borderBottom, BorderType.BOTTOM ) ); } // border-left String borderLeft = ele.getFoBorderLeftAttribute(); if ( StringUtils.isNotEmpty( borderLeft ) ) { tableCellProperties.setBorderLeft( new StyleBorder( borderLeft, BorderType.LEFT ) ); } // border-bottom String borderRight = ele.getFoBorderRightAttribute(); if ( StringUtils.isNotEmpty( borderRight ) ) { tableCellProperties.setBorderRight( new StyleBorder( borderRight, BorderType.RIGHT ) ); } // border-top String borderTop = ele.getFoBorderTopAttribute(); if ( StringUtils.isNotEmpty( borderTop ) ) { tableCellProperties.setBorderTop( new StyleBorder( borderTop, BorderType.TOP ) ); } // padding String padding = ele.getFoPaddingAttribute(); if ( StringUtils.isNotEmpty( padding ) ) { tableCellProperties.setPadding( ODFUtils.getDimensionAsPoint( padding ) ); } // padding-bottom String paddingBottom = ele.getFoPaddingBottomAttribute(); if ( StringUtils.isNotEmpty( paddingBottom ) ) { tableCellProperties.setPaddingBottom( ODFUtils.getDimensionAsPoint( paddingBottom ) ); } // padding-left String paddingLeft = ele.getFoPaddingLeftAttribute(); if ( StringUtils.isNotEmpty( paddingLeft ) ) { tableCellProperties.setPaddingLeft( ODFUtils.getDimensionAsPoint( paddingLeft ) ); } // padding-right String paddingRight = ele.getFoPaddingRightAttribute(); if ( StringUtils.isNotEmpty( paddingRight ) ) { tableCellProperties.setPaddingRight( ODFUtils.getDimensionAsPoint( paddingRight ) ); } // padding-top String paddingTop = ele.getFoPaddingTopAttribute(); if ( StringUtils.isNotEmpty( paddingTop ) ) { tableCellProperties.setPaddingTop( ODFUtils.getDimensionAsPoint( paddingTop ) ); } // vertical-align String verticalAlign = ele.getStyleVerticalAlignAttribute(); if ( StringUtils.isNotEmpty( verticalAlign ) ) { if ( StyleVerticalAlignAttribute.Value.BASELINE.toString().equals( verticalAlign ) ) { tableCellProperties.setVerticalAlignment( Element.ALIGN_BASELINE ); } else if ( StyleVerticalAlignAttribute.Value.TOP.toString().equals( verticalAlign ) ) { tableCellProperties.setVerticalAlignment( Element.ALIGN_TOP ); } else if ( StyleVerticalAlignAttribute.Value.MIDDLE.toString().equals( verticalAlign ) ) { tableCellProperties.setVerticalAlignment( Element.ALIGN_MIDDLE ); } else if ( StyleVerticalAlignAttribute.Value.BOTTOM.toString().equals( verticalAlign ) ) { tableCellProperties.setVerticalAlignment( Element.ALIGN_BOTTOM ); } } super.visit( ele ); } // visit //style:graphic-properties @Override public void visit( StyleGraphicPropertiesElement ele ) { StyleGraphicProperties graphicProperties = currentStyle.getGraphicProperties(); if ( graphicProperties == null ) { graphicProperties = new StyleGraphicProperties(); currentStyle.setGraphicProperties( graphicProperties ); } // wrap String wrap = ele.getStyleWrapAttribute(); if ( StringUtils.isNotEmpty( wrap ) ) { if ( StyleWrapAttribute.Value.RUN_THROUGH.toString().equals( wrap ) ) { graphicProperties.setRunThrough( Boolean.TRUE ); } else { // other values are not supported graphicProperties.setRunThrough( Boolean.FALSE ); } } super.visit( ele ); } // list styling is a bit complicated because of nesting // we flatten the structure into a map of {list-level->StyleListProperties} // // 1st level - text:list-style --- enclosing style // 2nd level --- text:list-level-style-bullet --- if list item label is a char // 2nd level --- text:list-level-style-image --- if list item label is an image // 2nd level --- text:list-level-style-number --- if list item label is a number // 3rd level ----- style:list-level-properties --- image dimensions, indentation info // 4th level ------- style:list-level-label-alignment --- indentation info @Override public void visit( TextListStyleElement ele ) { currentListPropertiesMap = new HashMap<Integer, StyleListProperties>(); computeStyle( ele, false ); currentStyle.setListPropertiesMap( currentListPropertiesMap ); currentListPropertiesMap = null; } @Override public void visit( TextListLevelStyleBulletElement ele ) { Integer textLevel = ele.getTextLevelAttribute(); if ( currentListPropertiesMap == null || textLevel == null ) { return; } StyleListProperties listProperties = new StyleListProperties(); currentListPropertiesMap.put( textLevel, listProperties ); // text style to apply to list item label String styleName = ele.getTextStyleNameAttribute(); if ( StringUtils.isNotEmpty( styleName ) ) { // TODO what if this style is not computed yet? Style style = getStyle( OdfStyleFamily.Text.getName(), styleName, null ); if ( style != null ) { listProperties.setTextProperties( style.getTextProperties() ); } } // bullet-char String bulletChar = ele.getTextBulletCharAttribute(); if ( StringUtils.isNotEmpty( bulletChar ) ) { listProperties.setBulletChar( bulletChar ); } // num-prefix String numPrefix = ele.getStyleNumPrefixAttribute(); if ( StringUtils.isNotEmpty( numPrefix ) ) { listProperties.setNumPrefix( numPrefix ); } // num-suffix String numSuffix = ele.getStyleNumSuffixAttribute(); if ( StringUtils.isNotEmpty( numSuffix ) ) { listProperties.setNumSuffix( numSuffix ); } currentListProperties = listProperties; super.visit( ele ); currentListProperties = null; } @Override public void visit( TextListLevelStyleImageElement ele ) { Integer textLevel = ele.getTextLevelAttribute(); if ( currentListPropertiesMap == null || textLevel == null ) { return; } StyleListProperties listProperties = new StyleListProperties(); currentListPropertiesMap.put( textLevel, listProperties ); // image href String href = ele.getXlinkHrefAttribute(); if ( StringUtils.isNotEmpty( href ) ) { byte[] imageStream = odfDocument.getPackage().getBytes( href ); if ( imageStream != null ) { Image imageObj = StylableImage.getImage( imageStream ); if ( imageObj != null ) { listProperties.setImage( imageObj ); } } } currentListProperties = listProperties; super.visit( ele ); currentListProperties = null; } @Override public void visit( TextListLevelStyleNumberElement ele ) { Integer textLevel = ele.getTextLevelAttribute(); if ( currentListPropertiesMap == null || textLevel == null ) { return; } StyleListProperties listProperties = new StyleListProperties(); currentListPropertiesMap.put( textLevel, listProperties ); // text style to apply to list item label String styleName = ele.getTextStyleNameAttribute(); if ( StringUtils.isNotEmpty( styleName ) ) { // TODO what if this style is not computed yet? Style style = getStyle( OdfStyleFamily.Text.getName(), styleName, null ); if ( style != null ) { listProperties.setTextProperties( style.getTextProperties() ); } } // start-value Integer startValue = ele.getTextStartValueAttribute(); if ( startValue != null ) { listProperties.setStartValue( startValue ); } // display-levels Integer displayLevels = ele.getTextDisplayLevelsAttribute(); if ( displayLevels != null ) { listProperties.setDisplayLevels( displayLevels ); } // num-prefix String numPrefix = ele.getStyleNumPrefixAttribute(); if ( StringUtils.isNotEmpty( numPrefix ) ) { listProperties.setNumPrefix( numPrefix ); } // num-suffix String numSuffix = ele.getStyleNumSuffixAttribute(); if ( StringUtils.isNotEmpty( numSuffix ) ) { listProperties.setNumSuffix( numSuffix ); } // num-format String numFormat = ele.getStyleNumFormatAttribute(); if ( StringUtils.isNotEmpty( numFormat ) ) { if ( StyleNumFormatAttribute.Value.a.toString().equals( numFormat ) ) { listProperties.setNumFormat( StyleNumFormat.createAlphabetical( true ) ); } else if ( StyleNumFormatAttribute.Value.A.toString().equals( numFormat ) ) { listProperties.setNumFormat( StyleNumFormat.createAlphabetical( false ) ); } else if ( StyleNumFormatAttribute.Value.i.toString().equals( numFormat ) ) { listProperties.setNumFormat( StyleNumFormat.createRoman( true ) ); } else if ( StyleNumFormatAttribute.Value.I.toString().equals( numFormat ) ) { listProperties.setNumFormat( StyleNumFormat.createRoman( false ) ); } else { listProperties.setNumFormat( StyleNumFormat.createNumerical() ); } } currentListProperties = listProperties; super.visit( ele ); currentListProperties = null; } @Override public void visit( StyleListLevelPropertiesElement ele ) { if ( currentListProperties == null ) { return; } StyleListProperties listProperties = currentListProperties; // width String width = ele.getFoWidthAttribute(); if ( StringUtils.isNotEmpty( width ) ) { listProperties.setWidth( ODFUtils.getDimensionAsPoint( width ) ); } // height String height = ele.getFoHeightAttribute(); if ( StringUtils.isNotEmpty( height ) ) { listProperties.setHeight( ODFUtils.getDimensionAsPoint( height ) ); } // space-before String spaceBefore = ele.getTextSpaceBeforeAttribute(); if ( StringUtils.isNotEmpty( spaceBefore ) ) { listProperties.setSpaceBefore( ODFUtils.getDimensionAsPoint( spaceBefore ) ); } // min-label-width String minLabelWidth = ele.getTextMinLabelWidthAttribute(); if ( StringUtils.isNotEmpty( minLabelWidth ) ) { listProperties.setMinLabelWidth( ODFUtils.getDimensionAsPoint( minLabelWidth ) ); } super.visit( ele ); } @Override public void visit( StyleListLevelLabelAlignmentElement ele ) { if ( currentListProperties == null ) { return; } StyleListProperties listProperties = currentListProperties; // margin-left String marginLeft = ele.getFoMarginLeftAttribute(); if ( StringUtils.isNotEmpty( marginLeft ) ) { listProperties.setMarginLeft( ODFUtils.getDimensionAsPoint( marginLeft ) ); } // text-indent String textIndent = ele.getFoTextIndentAttribute(); if ( StringUtils.isNotEmpty( textIndent ) ) { listProperties.setTextIndent( ODFUtils.getDimensionAsPoint( textIndent ) ); } super.visit( ele ); } // outline styling is similar to list styling, use the same data structures // we flatten the structure into a map of {outline-level->StyleListProperties} // there may be only one default outline style // // 1st level - text:outline-style --- enclosing style // 2nd level --- text:outline-level-style --- number format, start value, ... // 3rd level ----- style:list-level-properties --- ignored @Override public void visit( TextOutlineStyleElement ele ) { currentListPropertiesMap = new HashMap<Integer, StyleListProperties>(); computeStyle( ele, true ); currentStyle.setOutlinePropertiesMap( currentListPropertiesMap ); currentListPropertiesMap = null; } @Override public void visit( TextOutlineLevelStyleElement ele ) { Integer textLevel = ele.getTextLevelAttribute(); if ( currentListPropertiesMap == null || textLevel == null ) { return; } StyleListProperties listProperties = new StyleListProperties(); currentListPropertiesMap.put( textLevel, listProperties ); // text style to apply to list item label String styleName = ele.getTextStyleNameAttribute(); if ( StringUtils.isNotEmpty( styleName ) ) { // TODO what if this style is not computed yet? Style style = getStyle( OdfStyleFamily.Text.getName(), styleName, null ); if ( style != null ) { listProperties.setTextProperties( style.getTextProperties() ); } } // start-value Integer startValue = ele.getTextStartValueAttribute(); if ( startValue != null ) { listProperties.setStartValue( startValue ); } // display-levels Integer displayLevels = ele.getTextDisplayLevelsAttribute(); if ( displayLevels != null ) { listProperties.setDisplayLevels( displayLevels ); } // num-prefix String numPrefix = ele.getStyleNumPrefixAttribute(); if ( StringUtils.isNotEmpty( numPrefix ) ) { listProperties.setNumPrefix( numPrefix ); } // num-suffix String numSuffix = ele.getStyleNumSuffixAttribute(); if ( StringUtils.isNotEmpty( numSuffix ) ) { listProperties.setNumSuffix( numSuffix ); } // num-format String numFormat = ele.getStyleNumFormatAttribute(); if ( StringUtils.isNotEmpty( numFormat ) ) { if ( StyleNumFormatAttribute.Value.a.toString().equals( numFormat ) ) { listProperties.setNumFormat( StyleNumFormat.createAlphabetical( true ) ); } else if ( StyleNumFormatAttribute.Value.A.toString().equals( numFormat ) ) { listProperties.setNumFormat( StyleNumFormat.createAlphabetical( false ) ); } else if ( StyleNumFormatAttribute.Value.i.toString().equals( numFormat ) ) { listProperties.setNumFormat( StyleNumFormat.createRoman( true ) ); } else if ( StyleNumFormatAttribute.Value.I.toString().equals( numFormat ) ) { listProperties.setNumFormat( StyleNumFormat.createRoman( false ) ); } else { listProperties.setNumFormat( StyleNumFormat.createNumerical() ); } } currentListProperties = listProperties; super.visit( ele ); currentListProperties = null; } // visit //style:section-properties @Override public void visit( StyleSectionPropertiesElement ele ) { StyleSectionProperties sectionProperties = currentStyle.getSectionProperties(); if ( sectionProperties == null ) { sectionProperties = new StyleSectionProperties(); currentStyle.setSectionProperties( sectionProperties ); } // background-color String backgroundColor = ele.getFoBackgroundColorAttribute(); if ( StringUtils.isNotEmpty( backgroundColor ) ) { sectionProperties.setBackgroundColor( ColorRegistry.getInstance().getColor( backgroundColor ) ); } // dont-balance-text-columns Boolean dontBalanceTextColumns = ele.getTextDontBalanceTextColumnsAttribute(); if ( dontBalanceTextColumns != null ) { sectionProperties.setDontBalanceTextColumns( dontBalanceTextColumns ); } // margin-left String marginLeft = ele.getFoMarginLeftAttribute(); if ( StringUtils.isNotEmpty( marginLeft ) ) { sectionProperties.setMarginLeft( ODFUtils.getDimensionAsPoint( marginLeft ) ); } // margin-right String marginRight = ele.getFoMarginRightAttribute(); if ( StringUtils.isNotEmpty( marginRight ) ) { sectionProperties.setMarginRight( ODFUtils.getDimensionAsPoint( marginRight ) ); } super.visit( ele ); } // visit //style:columns @Override public void visit( StyleColumnsElement ele ) { StyleSectionProperties sectionProperties = currentStyle.getSectionProperties(); if ( sectionProperties == null ) { sectionProperties = new StyleSectionProperties(); currentStyle.setSectionProperties( sectionProperties ); } // column-count Integer columnCount = ele.getFoColumnCountAttribute(); if ( columnCount != null ) { sectionProperties.setColumnCount( columnCount ); } // column-gap String columnGap = ele.getFoColumnGapAttribute(); if ( StringUtils.isNotEmpty( columnGap ) ) { sectionProperties.setColumnGap( ODFUtils.getDimensionAsPoint( columnGap ) ); } currentColumnPropertiesList = new ArrayList<StyleColumnProperties>(); super.visit( ele ); currentStyle.setColumnPropertiesList( currentColumnPropertiesList ); currentColumnPropertiesList = null; } // visit //style:column @Override public void visit( StyleColumnElement ele ) { if ( currentColumnPropertiesList == null ) { return; } StyleColumnProperties columnProperties = new StyleColumnProperties(); currentColumnPropertiesList.add( columnProperties ); // rel-width String relWidth = ele.getStyleRelWidthAttribute(); if ( StringUtils.isNotEmpty( relWidth ) ) { columnProperties.setRelWidth( ODFUtils.getRelativeSize( relWidth ) ); } // start-indent String startIndent = ele.getFoStartIndentAttribute(); if ( StringUtils.isNotEmpty( startIndent ) ) { columnProperties.setStartIndent( ODFUtils.getDimensionAsPoint( startIndent ) ); } // end-indent String endIndent = ele.getFoEndIndentAttribute(); if ( StringUtils.isNotEmpty( endIndent ) ) { columnProperties.setEndIndent( ODFUtils.getDimensionAsPoint( endIndent ) ); } super.visit( ele ); } private String getStyleId( String familyName, String styleName ) { StringBuilder className = new StringBuilder(); // style:family className.append( familyName ); // style:name if ( styleName != null ) { className.append( '_' ); className.append( StringUtils.replaceAll( styleName, ".", "_" ) ); } return className.toString(); } private Style getStyle( String familyName, String styleName ) { return stylesMap.get( getStyleId( familyName, styleName ) ); } public Style getStyle( String familyName, String styleName, Style parentElementStyle ) { String newStyleName = null; String newFamilyName = null; String newMasterPageName = null; Style style = getStyle( familyName, styleName ); if ( style != null ) { newStyleName = style.getStyleName(); newFamilyName = style.getFamilyName(); newMasterPageName = style.getMasterPageName(); } else if ( parentElementStyle != null ) { newStyleName = parentElementStyle.getStyleName(); newFamilyName = parentElementStyle.getFamilyName(); newMasterPageName = parentElementStyle.getMasterPageName(); } // create style // merge order should be: // 1 default style // 2 parent element style // 3 current style Style newStyle = new Style( options.getFontProvider(), newStyleName, newFamilyName, newMasterPageName ); if ( parentElementStyle != null ) { // parent element style contains default style newStyle.merge( parentElementStyle, true ); } else { // merge default styles for ( Style s : stylesMap.values() ) { if ( s.getStyleName() == null ) { newStyle.merge( s, true ); } } } // merge current style if ( style != null ) { newStyle.merge( style, true ); } return newStyle; } }