fr.opensagres.poi.xwpf.converter.pdf.internal.FastPdfMapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apache-poi-ooxml Show documentation
Show all versions of apache-poi-ooxml Show documentation
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.
/**
* 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.pdf.internal;
import static fr.opensagres.poi.xwpf.converter.core.utils.DxaUtil.emu2points;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.List;
import java.util.logging.Logger;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.UnderlinePatterns;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.STRelFromH;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.STRelFromV;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.STWrapText;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPTab;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabs;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import com.lowagie.text.Chunk;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.Image;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import fr.opensagres.poi.xwpf.converter.core.Color;
import fr.opensagres.poi.xwpf.converter.core.ListItemContext;
import fr.opensagres.poi.xwpf.converter.core.ParagraphLineSpacing;
import fr.opensagres.poi.xwpf.converter.core.TableWidth;
import fr.opensagres.poi.xwpf.converter.core.openxmlformats.IOpenXMLFormatsPartProvider;
import fr.opensagres.poi.xwpf.converter.core.openxmlformats.OpenXMlFormatsVisitor;
import fr.opensagres.poi.xwpf.converter.core.utils.DxaUtil;
import fr.opensagres.poi.xwpf.converter.core.utils.StringUtils;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import fr.opensagres.poi.xwpf.converter.pdf.internal.elements.StylableAnchor;
import fr.opensagres.poi.xwpf.converter.pdf.internal.elements.StylableDocument;
import fr.opensagres.poi.xwpf.converter.pdf.internal.elements.StylableHeaderFooter;
import fr.opensagres.poi.xwpf.converter.pdf.internal.elements.StylableMasterPage;
import fr.opensagres.poi.xwpf.converter.pdf.internal.elements.StylableParagraph;
import fr.opensagres.poi.xwpf.converter.pdf.internal.elements.StylableTable;
import fr.opensagres.poi.xwpf.converter.pdf.internal.elements.StylableTableCell;
import fr.opensagres.xdocreport.itext.extension.ExtendedChunk;
import fr.opensagres.xdocreport.itext.extension.ExtendedImage;
import fr.opensagres.xdocreport.itext.extension.ExtendedParagraph;
import fr.opensagres.xdocreport.itext.extension.ExtendedPdfPCell;
import fr.opensagres.xdocreport.itext.extension.ExtendedPdfPTable;
import fr.opensagres.xdocreport.itext.extension.IITextContainer;
import fr.opensagres.xdocreport.itext.extension.font.FontGroup;
public class FastPdfMapper
extends OpenXMlFormatsVisitor
{
private static final String TAB = "\t";
/**
* Logger for this class
*/
private static final Logger LOGGER = Logger.getLogger( FastPdfMapper.class.getName() );
private final OutputStream out;
// Instance of PDF document
private StylableDocument pdfDocument;
private Font currentRunFontAscii;
private Font currentRunFontEastAsia;
private Font currentRunFontHAnsi;
private UnderlinePatterns currentRunUnderlinePatterns;
private Color currentRunBackgroundColor;
private Float currentRunX;
private Float currentPageWidth;
public FastPdfMapper( IOpenXMLFormatsPartProvider provider, OutputStream out, PdfOptions options )
throws Exception
{
super( provider, options != null ? options : PdfOptions.getDefault() );
this.out = out;
}
// ------------------------- Document
@Override
protected IITextContainer startVisitDocument()
throws Exception
{
// Create instance of PDF document
this.pdfDocument = new StylableDocument( out, options.getConfiguration() );
this.pdfDocument.setMasterPageManager( getMasterPageManager() );
return pdfDocument;
}
@Override
protected void endVisitDocument()
throws Exception
{
pdfDocument.close();
out.close();
}
public void setActiveMasterPage( StylableMasterPage masterPage )
{
pdfDocument.setActiveMasterPage( masterPage );
}
public StylableMasterPage createMasterPage( CTSectPr sectPr )
{
return new StylableMasterPage( sectPr );
}
@Override
protected void pageBreak()
throws Exception
{
pdfDocument.pageBreak();
}
@Override
protected IITextContainer startVisitParagraph( CTP paragraph, ListItemContext itemContext,
IITextContainer pdfParentContainer )
throws Exception
{
// create PDF paragraph
StylableParagraph pdfParagraph = pdfDocument.createParagraph( pdfParentContainer );
CTTbl parentTable = super.getParentTable();
// indentation left
Float indentationLeft = stylesDocument.getIndentationLeft( paragraph, parentTable );
if ( indentationLeft != null )
{
pdfParagraph.setIndentationLeft( indentationLeft );
}
// indentation right
Float indentationRight = stylesDocument.getIndentationRight( paragraph, parentTable );
if ( indentationRight != null )
{
pdfParagraph.setIndentationRight( indentationRight );
}
// indentation first line
Float indentationFirstLine = stylesDocument.getIndentationFirstLine( paragraph, parentTable );
if ( indentationFirstLine != null )
{
pdfParagraph.setFirstLineIndent( indentationFirstLine );
}
// indentation hanging (remove first line)
Float indentationHanging = stylesDocument.getIndentationHanging( paragraph, parentTable );
if ( indentationHanging != null )
{
pdfParagraph.setFirstLineIndent( -indentationHanging );
}
// // spacing before
Float spacingBefore = stylesDocument.getSpacingBefore( paragraph, parentTable );
if ( spacingBefore != null )
{
pdfParagraph.setSpacingBefore( spacingBefore );
}
// spacing after
// one more pargraph, spacing after should be applied.
Float spacingAfter = stylesDocument.getSpacingAfter( paragraph, parentTable );
if ( spacingAfter != null )
{
pdfParagraph.setSpacingAfter( spacingAfter );
}
ParagraphLineSpacing lineSpacing = stylesDocument.getParagraphSpacing( paragraph, parentTable );
if ( lineSpacing != null )
{
if ( lineSpacing.getLeading() != null && lineSpacing.getMultipleLeading() != null )
{
pdfParagraph.setLeading( lineSpacing.getLeading(), lineSpacing.getMultipleLeading() );
}
else
{
if ( lineSpacing.getLeading() != null )
{
pdfParagraph.setLeading( lineSpacing.getLeading() );
}
if ( lineSpacing.getMultipleLeading() != null )
{
pdfParagraph.setMultipliedLeading( lineSpacing.getMultipleLeading() );
}
}
}
// text-align
ParagraphAlignment alignment = stylesDocument.getParagraphAlignment( paragraph, parentTable );
if ( alignment != null )
{
switch ( alignment )
{
case LEFT:
pdfParagraph.setAlignment( Element.ALIGN_LEFT );
break;
case RIGHT:
pdfParagraph.setAlignment( Element.ALIGN_RIGHT );
break;
case CENTER:
pdfParagraph.setAlignment( Element.ALIGN_CENTER );
break;
case BOTH:
pdfParagraph.setAlignment( Element.ALIGN_JUSTIFIED );
break;
default:
break;
}
}
return pdfParagraph;
}
@Override
protected void endVisitParagraph( CTP paragraph, IITextContainer pdfParentContainer,
IITextContainer pdfParagraphContainer )
throws Exception
{
// add the iText paragraph in the current parent container.
ExtendedParagraph pdfParagraph = (ExtendedParagraph) pdfParagraphContainer;
pdfParentContainer.addElement( pdfParagraph.getElement() );
}
@Override
protected void visitRun( CTR run, CTP paragraph, boolean pageNumber, String url,
IITextContainer pdfParagraphContainer )
throws Exception
{
// Font family
String fontFamilyAscii = stylesDocument.getFontFamilyAscii( run, paragraph );
String fontFamilyEastAsia = stylesDocument.getFontFamilyEastAsia( run, paragraph );
String fontFamilyHAnsi = stylesDocument.getFontFamilyHAnsi( run, paragraph );
// Get font size
Float fontSize = stylesDocument.getFontSize( run, paragraph );
if ( fontSize == null )
{
fontSize = -1f;
}
// Get font style
int fontStyle = Font.NORMAL;
Boolean bold = stylesDocument.getFontStyleBold( run, paragraph );
if ( bold != null && bold )
{
fontStyle |= Font.BOLD;
}
Boolean italic = stylesDocument.getFontStyleItalic( run, paragraph );
if ( italic != null && italic )
{
fontStyle |= Font.ITALIC;
}
Boolean strike = stylesDocument.getFontStyleStrike( run, paragraph );
if ( strike != null && strike )
{
fontStyle |= Font.STRIKETHRU;
}
// Font color
Color fontColor = stylesDocument.getFontColor( run, paragraph );
// Font
this.currentRunFontAscii = getFont( fontFamilyAscii, fontSize, fontStyle, fontColor );
this.currentRunFontEastAsia = getFont( fontFamilyEastAsia, fontSize, fontStyle, fontColor );
this.currentRunFontHAnsi = getFont( fontFamilyHAnsi, fontSize, fontStyle, fontColor );
// Underline patterns
this.currentRunUnderlinePatterns = stylesDocument.getUnderline( run, paragraph );
// background color
this.currentRunBackgroundColor = stylesDocument.getBackgroundColor( run, paragraph );
// highlight
if ( currentRunBackgroundColor == null )
{
this.currentRunBackgroundColor = stylesDocument.getTextHighlighting( run, paragraph );
}
StylableParagraph pdfParagraph = (StylableParagraph) pdfParagraphContainer;
pdfParagraph.adjustMultipliedLeading( currentRunFontAscii );
// addd symbol list item chunk if needed.
String listItemText = pdfParagraph.getListItemText();
if ( StringUtils.isNotEmpty( listItemText ) )
{
// FIXME: add some space after the list item
listItemText += " ";
String listItemFontFamily = pdfParagraph.getListItemFontFamily();
Float listItemFontSize = pdfParagraph.getListItemFontSize();
int listItemFontStyle = pdfParagraph.getListItemFontStyle();
java.awt.Color listItemFontColor = pdfParagraph.getListItemFontColor();
Font listItemFont =
options.getFontProvider().getFont( listItemFontFamily != null ? listItemFontFamily : fontFamilyAscii,
options.getFontEncoding(),
listItemFontSize != null ? listItemFontSize : fontSize,
listItemFontStyle != Font.NORMAL ? listItemFontStyle : fontStyle,
listItemFontColor != null ? listItemFontColor : Converter.toAwtColor(fontColor) );
Chunk symbol =
createTextChunk( listItemText, false, listItemFont, currentRunUnderlinePatterns,
currentRunBackgroundColor );
pdfParagraph.add( symbol );
pdfParagraph.setListItemText( null );
}
IITextContainer container = pdfParagraphContainer;
if ( url != null )
{
// URL is not null, generate a PDF hyperlink.
StylableAnchor pdfAnchor = new StylableAnchor();
pdfAnchor.setReference( url );
pdfAnchor.setITextContainer( container );
container = pdfAnchor;
}
super.visitRun( run, paragraph, pageNumber, url, pdfParagraphContainer );
if ( url != null )
{
// URL is not null, add the PDF hyperlink in the PDF paragraph
pdfParagraphContainer.addElement( (StylableAnchor) container );
}
this.currentRunFontAscii = null;
this.currentRunFontEastAsia = null;
this.currentRunFontHAnsi = null;
this.currentRunUnderlinePatterns = null;
this.currentRunBackgroundColor = null;
}
private Font getFont( String fontFamily, Float fontSize, int fontStyle, Color fontColor )
{
String fontToUse = stylesDocument.getFontNameToUse( fontFamily );
if ( StringUtils.isNotEmpty( fontToUse ) )
{
return options.getFontProvider().getFont( fontToUse, options.getFontEncoding(), fontSize, fontStyle,
Converter.toAwtColor(fontColor) );
}
Font font =
options.getFontProvider().getFont( fontFamily, options.getFontEncoding(), fontSize, fontStyle, Converter.toAwtColor(fontColor) );
if ( !isFontExists( font ) )
{
// font is not found
try
{
List altNames = stylesDocument.getFontsAltName( fontFamily );
if ( altNames != null )
{
// Loop for each alternative names font (from the fontTable.xml) to find the well font.
for ( String altName : altNames )
{
// check if the current font name is not the same that original (o avoid StackOverFlow : see
// https://code.google.com/p/xdocreport/issues/detail?id=393)
if ( !fontFamily.equals( altName ) )
{
font = getFont( altName, fontSize, fontStyle, fontColor );
if ( isFontExists( font ) )
{
stylesDocument.setFontNameToUse( fontFamily, altName );
return font;
}
}
}
}
}
catch ( Exception e )
{
LOGGER.severe( e.getMessage() );
}
}
return font;
}
/**
* Returns true if the iText font exists and false otherwise.
*
* @param font
* @return
*/
private boolean isFontExists( Font font )
{
// FIXME : is it like this to test that font exists?
return font != null && font.getBaseFont() != null;
}
@Override
protected void visitText( CTText docxText, boolean pageNumber, IITextContainer pdfParagraphContainer )
throws Exception
{
Font font = currentRunFontAscii;
Font fontAsian = currentRunFontEastAsia;
Font fontComplex = currentRunFontHAnsi;
createAndAddChunks( pdfParagraphContainer, docxText.getStringValue(), currentRunUnderlinePatterns,
currentRunBackgroundColor, pageNumber, font, fontAsian, fontComplex );
}
private Chunk createTextChunk( String text, boolean pageNumber, Font currentRunFont,
UnderlinePatterns currentRunUnderlinePatterns, Color currentRunBackgroundColor )
{
Chunk textChunk =
pageNumber ? new ExtendedChunk( pdfDocument, true, currentRunFont ) : new Chunk( text, currentRunFont );
if ( currentRunUnderlinePatterns != null )
{
// underlined
boolean singleUnderlined = false;
switch ( currentRunUnderlinePatterns )
{
case SINGLE:
singleUnderlined = true;
break;
default:
break;
}
if ( singleUnderlined )
{
textChunk.setUnderline( 1, -2 );
}
}
// background color
if ( currentRunBackgroundColor != null )
{
textChunk.setBackground( Converter.toAwtColor(currentRunBackgroundColor) );
}
if ( currentRunX != null )
{
this.currentRunX += textChunk.getWidthPoint();
}
return textChunk;
}
private void createAndAddChunks( IITextContainer parent, String textContent, UnderlinePatterns underlinePatterns,
Color backgroundColor, boolean pageNumber, Font font, Font fontAsian,
Font fontComplex )
{
StringBuilder sbuf = new StringBuilder();
FontGroup currentGroup = FontGroup.WESTERN;
for ( int i = 0; i < textContent.length(); i++ )
{
char ch = textContent.charAt( i );
FontGroup group = FontGroup.getUnicodeGroup( ch, font, fontAsian, fontComplex );
if ( sbuf.length() == 0 || currentGroup.equals( group ) )
{
// continue current chunk
sbuf.append( ch );
}
else
{
// end chunk
Font chunkFont = getFont( font, fontAsian, fontComplex, currentGroup );
Chunk chunk =
createTextChunk( sbuf.toString(), pageNumber, chunkFont, underlinePatterns, backgroundColor );
parent.addElement( chunk );
// start new chunk
sbuf.setLength( 0 );
sbuf.append( ch );
}
currentGroup = group;
}
// end chunk
Font chunkFont = getFont( font, fontAsian, fontComplex, currentGroup );
Chunk chunk = createTextChunk( sbuf.toString(), pageNumber, chunkFont, underlinePatterns, backgroundColor );
parent.addElement( chunk );
}
private Font getFont( Font font, Font fontAsian, Font fontComplex, FontGroup group )
{
switch ( group )
{
case WESTERN:
return font;
case ASIAN:
return fontAsian;
case COMPLEX:
return fontComplex;
}
return font;
}
@Override
protected void visitTab( CTPTab o, IITextContainer paragraphContainer )
throws Exception
{
// TODO Auto-generated method stub
}
@Override
protected void visitTabs( CTTabs tabs, IITextContainer paragraphContainer )
throws Exception
{
// TODO Auto-generated method stub
}
@Override
protected void visitBookmark( CTBookmark bookmark, CTP paragraph, IITextContainer paragraphContainer )
throws Exception
{
// TODO Auto-generated method stub
}
@Override
protected void addNewLine( CTBr br, IITextContainer paragraphContainer )
throws Exception
{
paragraphContainer.addElement( Chunk.NEWLINE );
}
@Override
protected void visitHeader( CTHdrFtr currentHeader, CTHdrFtrRef headerRef, CTSectPr sectPr,
StylableMasterPage masterPage )
throws Exception
{
BigInteger headerY = sectPr.getPgMar() != null ? sectPr.getPgMar().getHeader() : null;
this.currentPageWidth = sectPr.getPgMar() != null ? DxaUtil.dxa2points( sectPr.getPgSz().getW() ) : null;
StylableHeaderFooter pdfHeader = new StylableHeaderFooter( pdfDocument, headerY, false );
StylableTableCell tableCell = pdfHeader.getTableCell();
visitBodyElements( currentHeader, tableCell );
masterPage.setHeader( pdfHeader );
this.currentPageWidth = null;
}
@Override
protected void visitFooter( CTHdrFtr currentFooter, CTHdrFtrRef footerRef, CTSectPr sectPr,
StylableMasterPage masterPage )
throws Exception
{
BigInteger footerY = sectPr.getPgMar() != null ? sectPr.getPgMar().getFooter() : null;
this.currentPageWidth = sectPr.getPgMar() != null ? DxaUtil.dxa2points( sectPr.getPgSz().getW() ) : null;
StylableHeaderFooter pdfFooter = new StylableHeaderFooter( pdfDocument, footerY, false );
StylableTableCell tableCell = pdfFooter.getTableCell();
visitBodyElements( currentFooter, tableCell );
masterPage.setFooter( pdfFooter );
this.currentPageWidth = null;
}
// ----------------- Table
@Override
protected IITextContainer startVisitTable( CTTbl table, float[] colWidths, IITextContainer pdfParentContainer )
throws Exception
{
StylableTable pdfPTable = createPDFTable( table, colWidths, pdfParentContainer );
return pdfPTable;
}
private StylableTable createPDFTable( CTTbl table, float[] colWidths, IITextContainer pdfParentContainer )
throws DocumentException
{
// 2) Compute tableWith
TableWidth tableWidth = stylesDocument.getTableWidth( table );
StylableTable pdfPTable = pdfDocument.createTable( pdfParentContainer, colWidths.length );
pdfPTable.setTotalWidth( colWidths );
if ( tableWidth != null && tableWidth.width > 0 )
{
if ( tableWidth.percentUnit )
{
pdfPTable.setWidthPercentage( tableWidth.width );
}
else
{
pdfPTable.setTotalWidth( tableWidth.width );
}
}
pdfPTable.setLockedWidth( true );
// Table alignment
ParagraphAlignment alignment = stylesDocument.getTableAlignment( table );
if ( alignment != null )
{
switch ( alignment )
{
case LEFT:
pdfPTable.setHorizontalAlignment( Element.ALIGN_LEFT );
break;
case RIGHT:
pdfPTable.setHorizontalAlignment( Element.ALIGN_RIGHT );
break;
case CENTER:
pdfPTable.setHorizontalAlignment( Element.ALIGN_CENTER );
break;
case BOTH:
pdfPTable.setHorizontalAlignment( Element.ALIGN_JUSTIFIED );
break;
default:
break;
}
}
// Table indentation
Float indentation = stylesDocument.getTableIndentation( table );
if ( indentation != null )
{
pdfPTable.setPaddingLeft( indentation );
}
return pdfPTable;
}
@Override
protected void endVisitTable( CTTbl table, IITextContainer parentContainer, IITextContainer tableContainer )
throws Exception
{
parentContainer.addElement( ( (ExtendedPdfPTable) tableContainer ).getElement() );
}
// ------------------------- Table Row
@Override
protected void startVisitTableRow( CTRow row, IITextContainer tableContainer, boolean headerRow )
throws Exception
{
if ( headerRow )
{
PdfPTable table = (PdfPTable) tableContainer;
table.setHeaderRows( table.getHeaderRows() + 1 );
}
}
@Override
protected IITextContainer startVisitTableCell( CTTc cell, IITextContainer tableContainer )
throws Exception
{
StylableTable pdfPTable = (StylableTable) tableContainer;
StylableTableCell pdfPCell = pdfDocument.createTableCell( pdfPTable );
// Background Color
Color backgroundColor = stylesDocument.getTableCellBackgroundColor( cell );
if ( backgroundColor != null )
{
pdfPCell.setBackgroundColor( Converter.toAwtColor(backgroundColor) );
}
return pdfPCell;
}
@Override
protected void endVisitTableCell( CTTc cell, IITextContainer tableContainer, IITextContainer tableCellContainer )
throws Exception
{
ExtendedPdfPTable pdfPTable = (ExtendedPdfPTable) tableContainer;
ExtendedPdfPCell pdfPCell = (ExtendedPdfPCell) tableCellContainer;
pdfPTable.addCell( pdfPCell );
}
// ------------------------- Image
@Override
protected void visitPicture( CTPicture picture,
Float offsetX,
org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.STRelFromH.Enum relativeFromH,
Float offsetY,
org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.STRelFromV.Enum relativeFromV,
STWrapText.Enum wrapText, IITextContainer pdfParentContainer )
throws Exception
{
CTPositiveSize2D ext = picture.getSpPr().getXfrm().getExt();
long x = ext.getCx();
long y = ext.getCy();
byte[] pictureData = super.getPictureBytes( picture );
if ( pictureData != null )
{
try
{
Image img = Image.getInstance( pictureData );
img.scaleAbsolute( emu2points( x ), emu2points( y ) );
IITextContainer parentOfParentContainer = pdfParentContainer.getITextContainer();
if ( parentOfParentContainer != null && parentOfParentContainer instanceof PdfPCell )
{
parentOfParentContainer.addElement( img );
}
else
{
float chunkOffsetX = 0;
if ( offsetX != null )
{
if ( STRelFromH.CHARACTER.equals( relativeFromH ) )
{
chunkOffsetX = offsetX;
}
else if ( STRelFromH.COLUMN.equals( relativeFromH ) )
{
chunkOffsetX = offsetX;
}
else if ( STRelFromH.INSIDE_MARGIN.equals( relativeFromH ) )
{
chunkOffsetX = offsetX;
}
else if ( STRelFromH.LEFT_MARGIN.equals( relativeFromH ) )
{
chunkOffsetX = offsetX;
}
else if ( STRelFromH.MARGIN.equals( relativeFromH ) )
{
chunkOffsetX = pdfDocument.left() + offsetX;
}
else if ( STRelFromH.OUTSIDE_MARGIN.equals( relativeFromH ) )
{
chunkOffsetX = offsetX;
}
else if ( STRelFromH.PAGE.equals( relativeFromH ) )
{
chunkOffsetX = offsetX - pdfDocument.left();
}
}
float chunkOffsetY = 0;
boolean useExtendedImage = false;
if ( STRelFromV.PARAGRAPH.equals( relativeFromV ) )
{
useExtendedImage = true;
}
if ( useExtendedImage )
{
ExtendedImage extImg = new ExtendedImage( img, -offsetY );
if ( STRelFromV.PARAGRAPH.equals( relativeFromV ) )
{
chunkOffsetY = -extImg.getScaledHeight();
}
Chunk chunk = new Chunk( extImg, chunkOffsetX, chunkOffsetY, false );
pdfParentContainer.addElement( chunk );
}
/*
* float chunkOffsetY = 0; if ( wrapText != null ) { chunkOffsetY = -img.getScaledHeight(); }
* boolean useExtendedImage = offsetY != null; // if ( STRelFromV.PARAGRAPH.equals( relativeFromV )
* ) // { // useExtendedImage = true; // } // if ( useExtendedImage ) { float imgY = -offsetY; if (
* pdfHeader != null ) { float headerY = pdfHeader.getY() != null ? pdfHeader.getY() : 0; imgY += -
* img.getScaledHeight() + headerY; } ExtendedImage extImg = new ExtendedImage( img, imgY ); // if (
* STRelFromV.PARAGRAPH.equals( relativeFromV ) ) // { // chunkOffsetY = -extImg.getScaledHeight();
* // } Chunk chunk = new Chunk( extImg, chunkOffsetX, chunkOffsetY, false );
* pdfParentContainer.addElement( chunk ); }
*/
else
{
if ( pdfParentContainer instanceof Paragraph )
{
// I don't know why but we need add some spacing before in the paragraph
// otherwise the image cut the text of the below paragraph (see FormattingTests JUnit)?
Paragraph paragraph = (Paragraph) pdfParentContainer;
paragraph.setSpacingBefore( paragraph.getSpacingBefore() + 5f );
}
pdfParentContainer.addElement( new Chunk( img, chunkOffsetX, chunkOffsetY, false ) );
}
}
}
catch ( Exception e )
{
LOGGER.severe( e.getMessage() );
}
}
}
}