summaryrefslogtreecommitdiff
path: root/sdext
diff options
context:
space:
mode:
Diffstat (limited to 'sdext')
-rw-r--r--sdext/source/pdfimport/config/description.xml7
-rw-r--r--sdext/source/pdfimport/images/pdfiext.pngbin0 -> 1965 bytes
-rw-r--r--sdext/source/pdfimport/images/pdfiext_hc.pngbin0 -> 1160 bytes
-rwxr-xr-xsdext/source/pdfimport/inc/wrapper.hxx8
-rw-r--r--sdext/source/pdfimport/makefile.mk10
-rw-r--r--sdext/source/pdfimport/pdfiadaptor.cxx19
-rw-r--r--sdext/source/pdfimport/pdfiadaptor.hxx2
-rwxr-xr-xsdext/source/pdfimport/test/tests.cxx6
-rw-r--r--sdext/source/pdfimport/tree/drawtreevisiting.cxx12
-rw-r--r--sdext/source/pdfimport/tree/genericelements.hxx3
-rw-r--r--sdext/source/pdfimport/tree/pdfiprocessor.cxx106
-rwxr-xr-xsdext/source/pdfimport/wrapper/wrapper.cxx166
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/makefile.mk3
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx244
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx6
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx411
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/pnghelper.hxx92
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx50
18 files changed, 997 insertions, 148 deletions
diff --git a/sdext/source/pdfimport/config/description.xml b/sdext/source/pdfimport/config/description.xml
index eebb9c1f65d7..9feff443b421 100644
--- a/sdext/source/pdfimport/config/description.xml
+++ b/sdext/source/pdfimport/config/description.xml
@@ -16,7 +16,7 @@
</simple-license>
</registration>
- <version value="0.3.2" />
+ <version value="1.0" />
<platform value="UPDATED_SUPPORTED_PLATFORM" />
@@ -28,4 +28,9 @@
<name lang="en-US">PDF Import Extension</name>
</display-name>
+ <icon>
+ <default xlink:href="images/pdfiext.png" />
+ <high-contrast xlink:href="images/pdfiext_hc.png" />
+ </icon>
+
</description>
diff --git a/sdext/source/pdfimport/images/pdfiext.png b/sdext/source/pdfimport/images/pdfiext.png
new file mode 100644
index 000000000000..31f48ea8fb69
--- /dev/null
+++ b/sdext/source/pdfimport/images/pdfiext.png
Binary files differ
diff --git a/sdext/source/pdfimport/images/pdfiext_hc.png b/sdext/source/pdfimport/images/pdfiext_hc.png
new file mode 100644
index 000000000000..3870cc4709d4
--- /dev/null
+++ b/sdext/source/pdfimport/images/pdfiext_hc.png
Binary files differ
diff --git a/sdext/source/pdfimport/inc/wrapper.hxx b/sdext/source/pdfimport/inc/wrapper.hxx
index 4ef1574b36ee..c51f33a4edc4 100755
--- a/sdext/source/pdfimport/inc/wrapper.hxx
+++ b/sdext/source/pdfimport/inc/wrapper.hxx
@@ -47,14 +47,20 @@ namespace com { namespace sun { namespace star {
namespace pdfi
{
- bool xpdf_ImportFromFile( const ::rtl::OUString& rURL,
+ bool xpdf_ImportFromFile( const rtl::OUString& rURL,
const ContentSinkSharedPtr& rSink,
const com::sun::star::uno::Reference<
+ com::sun::star::task::XInteractionHandler >& xIHdl,
+ const rtl::OUString& rPwd,
+ const com::sun::star::uno::Reference<
com::sun::star::uno::XComponentContext >& xContext );
bool xpdf_ImportFromStream( const com::sun::star::uno::Reference<
com::sun::star::io::XInputStream >& xInput,
const ContentSinkSharedPtr& rSink,
const com::sun::star::uno::Reference<
+ com::sun::star::task::XInteractionHandler >& xIHdl,
+ const rtl::OUString& rPwd,
+ const com::sun::star::uno::Reference<
com::sun::star::uno::XComponentContext >& xContext );
}
diff --git a/sdext/source/pdfimport/makefile.mk b/sdext/source/pdfimport/makefile.mk
index df11c43ce9d4..d6cd4783454f 100644
--- a/sdext/source/pdfimport/makefile.mk
+++ b/sdext/source/pdfimport/makefile.mk
@@ -125,7 +125,11 @@ COMPONENT_HELP= \
COMPONENT_LIBRARIES= \
$(EXTENSIONDIR)$/$(SHL1TARGET)$(DLLPOST)
-EXTENSION_PACKDEPS=$(CONVERTER_FILE) $(COMPONENT_DIALOGS) $(COMPONENT_HELP) makefile.mk
+COMPONENT_IMAGES=\
+ $(EXTENSIONDIR)$/images$/pdfiext.png \
+ $(EXTENSIONDIR)$/images$/pdfiext_hc.png
+
+EXTENSION_PACKDEPS=$(CONVERTER_FILE) $(COMPONENT_DIALOGS) $(COMPONENT_HELP) $(COMPONENT_IMAGES) makefile.mk
.INCLUDE : extension_pre.mk
.INCLUDE : target.mk
@@ -142,3 +146,7 @@ $(COMPONENT_DIALOGS) : dialogs$/$$(@:f)
$(COMPONENT_HELP) : help$/$$(@:f)
@@-$(MKDIRHIER) $(@:d)
$(COPY) $< $@
+
+$(COMPONENT_IMAGES) : images$/$$(@:f)
+ @@-$(MKDIRHIER) $(@:d)
+ $(COPY) $< $@
diff --git a/sdext/source/pdfimport/pdfiadaptor.cxx b/sdext/source/pdfimport/pdfiadaptor.cxx
index 8b6db0ff972d..43f11c173d1c 100644
--- a/sdext/source/pdfimport/pdfiadaptor.cxx
+++ b/sdext/source/pdfimport/pdfiadaptor.cxx
@@ -238,6 +238,8 @@ void PDFIRawAdaptor::setTreeVisitorFactory(const TreeVisitorFactorySharedPtr& rV
}
bool PDFIRawAdaptor::parse( const uno::Reference<io::XInputStream>& xInput,
+ const uno::Reference<task::XInteractionHandler>& xIHdl,
+ const rtl::OUString& rPwd,
const uno::Reference<task::XStatusIndicator>& xStatus,
const XmlEmitterSharedPtr& rEmitter,
const rtl::OUString& rURL )
@@ -253,9 +255,9 @@ bool PDFIRawAdaptor::parse( const uno::Reference<io::XInputStream>& xInput
bool bSuccess=false;
if( xInput.is() && (!rURL.getLength() || rURL.compareToAscii( "file:", 5 ) != 0) )
- bSuccess = xpdf_ImportFromStream( xInput, pSink, m_xContext );
+ bSuccess = xpdf_ImportFromStream( xInput, pSink, xIHdl, rPwd, m_xContext );
else
- bSuccess = xpdf_ImportFromFile( rURL, pSink, m_xContext );
+ bSuccess = xpdf_ImportFromFile( rURL, pSink, xIHdl, rPwd, m_xContext );
if( bSuccess )
pSink->emit(*rEmitter,*m_pVisitorFactory);
@@ -268,7 +270,10 @@ bool PDFIRawAdaptor::odfConvert( const rtl::OUString& r
const uno::Reference<task::XStatusIndicator>& xStatus )
{
XmlEmitterSharedPtr pEmitter = createOdfEmitter(xOutput);
- const bool bSuccess = parse(uno::Reference<io::XInputStream>(),xStatus,pEmitter,rURL);
+ const bool bSuccess = parse(uno::Reference<io::XInputStream>(),
+ uno::Reference<task::XInteractionHandler>(),
+ rtl::OUString(),
+ xStatus,pEmitter,rURL);
// tell input stream that it is no longer needed
xOutput->closeOutput();
@@ -284,7 +289,9 @@ sal_Bool SAL_CALL PDFIRawAdaptor::importer( const uno::Sequence< beans::Property
// get the InputStream carrying the PDF content
uno::Reference< io::XInputStream > xInput;
uno::Reference< task::XStatusIndicator > xStatus;
+ uno::Reference< task::XInteractionHandler > xInteractionHandler;
rtl::OUString aURL;
+ rtl::OUString aPwd;
const beans::PropertyValue* pAttribs = rSourceData.getConstArray();
sal_Int32 nAttribs = rSourceData.getLength();
for( sal_Int32 i = 0; i < nAttribs; i++, pAttribs++ )
@@ -296,12 +303,16 @@ sal_Bool SAL_CALL PDFIRawAdaptor::importer( const uno::Sequence< beans::Property
pAttribs->Value >>= aURL;
else if( pAttribs->Name.equalsAscii( "StatusIndicator" ) )
pAttribs->Value >>= xStatus;
+ else if( pAttribs->Name.equalsAscii( "InteractionHandler" ) )
+ pAttribs->Value >>= xInteractionHandler;
+ else if( pAttribs->Name.equalsAscii( "Password" ) )
+ pAttribs->Value >>= aPwd;
}
if( !xInput.is() )
return sal_False;
XmlEmitterSharedPtr pEmitter = createSaxEmitter(rHdl);
- const bool bSuccess = parse(xInput,xStatus,pEmitter,aURL);
+ const bool bSuccess = parse(xInput,xInteractionHandler, aPwd, xStatus,pEmitter,aURL);
// tell input stream that it is no longer needed
xInput->closeInput();
diff --git a/sdext/source/pdfimport/pdfiadaptor.hxx b/sdext/source/pdfimport/pdfiadaptor.hxx
index 37779ab7e3a8..2ccbcc7b6a10 100644
--- a/sdext/source/pdfimport/pdfiadaptor.hxx
+++ b/sdext/source/pdfimport/pdfiadaptor.hxx
@@ -96,6 +96,8 @@ namespace pdfi
bool m_bEnableToplevelText;
bool parse( const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInput,
+ const com::sun::star::uno::Reference<com::sun::star::task::XInteractionHandler>& xIHdl,
+ const rtl::OUString& rPwd,
const com::sun::star::uno::Reference<com::sun::star::task::XStatusIndicator>& xStatus,
const XmlEmitterSharedPtr& rEmitter,
const rtl::OUString& rURL );
diff --git a/sdext/source/pdfimport/test/tests.cxx b/sdext/source/pdfimport/test/tests.cxx
index 6eb8fb29b413..b66e1812d9e0 100755
--- a/sdext/source/pdfimport/test/tests.cxx
+++ b/sdext/source/pdfimport/test/tests.cxx
@@ -444,6 +444,10 @@ namespace
xMask[1].Name.compareToAscii( "InputStream" ) == 0 );
}
+ virtual void setTextRenderMode( sal_Int32 )
+ {
+ }
+
typedef std::hash_map<sal_Int32,FontAttributes> IdToFontMap;
typedef std::hash_map<FontAttributes,sal_Int32,FontAttrHash> FontToIdMap;
@@ -517,6 +521,8 @@ namespace
pdfi::ContentSinkSharedPtr pSink( new TestSink() );
pdfi::xpdf_ImportFromFile( msBaseDir + rtl::OUString::createFromAscii("pdfi_unittest_test.pdf"),
pSink,
+ uno::Reference< task::XInteractionHandler >(),
+ rtl::OUString(),
mxCtx );
// make destruction explicit, a bunch of things are
diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.cxx b/sdext/source/pdfimport/tree/drawtreevisiting.cxx
index 151cff129c91..71928fd98fcf 100644
--- a/sdext/source/pdfimport/tree/drawtreevisiting.cxx
+++ b/sdext/source/pdfimport/tree/drawtreevisiting.cxx
@@ -175,6 +175,11 @@ void DrawXmlEmitter::fillFrameProps( DrawElement& rElem,
// TODO(F2): general transformation case missing; if implemented, note
// that ODF rotation is oriented the other way
+ // vertical mirroring is done by horizontally mirroring and rotaing 180 degree
+ // quaint !
+ if( rElem.MirrorVertical )
+ fRotate += M_PI;
+
// build transformation string
if( fShearX != 0.0 )
{
@@ -854,6 +859,13 @@ void DrawXmlFinalizer::visit( FrameElement& elem, const std::list< Element* >::c
aGCProps[ USTR("fo:padding-right") ] = USTR("0cm");
aGCProps[ USTR("fo:padding-bottom") ] = USTR("0cm");
+ // remark: vertical mirroring is done in current OOO by
+ // mirroring horzontally and rotating 180 degrees
+ // this is quaint, but unfortunately it seems
+ // mirror=vertical is defined but not implemented in current code
+ if( elem.MirrorVertical )
+ aGCProps[ USTR("style:mirror") ] = USTR("horizontal");
+
StyleContainer::Style aStyle( "style:style", aProps );
StyleContainer::Style aSubStyle( "style:graphic-properties", aGCProps );
aStyle.SubStyles.push_back( &aSubStyle );
diff --git a/sdext/source/pdfimport/tree/genericelements.hxx b/sdext/source/pdfimport/tree/genericelements.hxx
index 34fbdf6391de..029032579d57 100644
--- a/sdext/source/pdfimport/tree/genericelements.hxx
+++ b/sdext/source/pdfimport/tree/genericelements.hxx
@@ -133,10 +133,11 @@ namespace pdfi
{
protected:
GraphicalElement( Element* pParent, sal_Int32 nGCId )
- : Element( pParent ), GCId(nGCId ) {}
+ : Element( pParent ), GCId( nGCId ), MirrorVertical( false ) {}
public:
sal_Int32 GCId;
+ bool MirrorVertical;
};
struct DrawElement : public GraphicalElement
diff --git a/sdext/source/pdfimport/tree/pdfiprocessor.cxx b/sdext/source/pdfimport/tree/pdfiprocessor.cxx
index a478bef72d2d..ccfc273124e1 100644
--- a/sdext/source/pdfimport/tree/pdfiprocessor.cxx
+++ b/sdext/source/pdfimport/tree/pdfiprocessor.cxx
@@ -369,9 +369,10 @@ void PDFIProcessor::processGlyphLine()
else
{
if (
- ( m_GlyphsList[i].getPrevGlyphsSpace()<= fPreAvarageSpaceValue )&&
- ( fPrevDiffCharSpace<=fAvarageDiffCharSpaceValue )&&
- ( fPostDiffCharSpace<=fAvarageDiffCharSpaceValue ) ||
+ ( ( m_GlyphsList[i].getPrevGlyphsSpace()<= fPreAvarageSpaceValue )&&
+ ( fPrevDiffCharSpace<=fAvarageDiffCharSpaceValue )&&
+ ( fPostDiffCharSpace<=fAvarageDiffCharSpaceValue )
+ ) ||
( m_GlyphsList[i].getPrevGlyphsSpace() == 0.0 )
)
{
@@ -446,7 +447,6 @@ void PDFIProcessor::drawGlyphLine( const rtl::OUString& rGlyphs,
const geometry::Matrix2D& rFontMatrix )
{
double isFirstLine= fYPrevTextPosition+ fXPrevTextPosition+ fPrevTextHeight+ fPrevTextWidth ;
-
if(
( ( ( fYPrevTextPosition!= rRect.Y1 ) ) ||
( ( fXPrevTextPosition > rRect.X2 ) ) ||
@@ -456,8 +456,6 @@ void PDFIProcessor::drawGlyphLine( const rtl::OUString& rGlyphs,
{
processGlyphLine();
- }
-
CharGlyph aGlyph;
aGlyph.setGlyph ( rGlyphs );
@@ -485,6 +483,36 @@ void PDFIProcessor::drawGlyphLine( const rtl::OUString& rGlyphs,
m_bIsWhiteSpaceInLine=rGlyphs.equals( tempWhiteSpaceStr );
}
+=======
+
+ CharGlyph aGlyph;
+
+ aGlyph.setGlyph ( rGlyphs );
+ aGlyph.setRect ( rRect );
+ aGlyph.setFontMatrix ( rFontMatrix );
+ aGlyph.setGraphicsContext ( getCurrentContext() );
+ getGCId(getCurrentContext());
+ aGlyph.setCurElement( m_pCurElement );
+
+ aGlyph.setYPrevGlyphPosition( fYPrevTextPosition );
+ aGlyph.setXPrevGlyphPosition( fXPrevTextPosition );
+ aGlyph.setPrevGlyphHeight ( fPrevTextHeight );
+ aGlyph.setPrevGlyphWidth ( fPrevTextWidth );
+
+ m_GlyphsList.push_back( aGlyph );
+
+ fYPrevTextPosition = rRect.Y1;
+ fXPrevTextPosition = rRect.X2;
+ fPrevTextHeight = rRect.Y2-rRect.Y1;
+ fPrevTextWidth = rRect.X2-rRect.X1;
+
+ if( !m_bIsWhiteSpaceInLine )
+ {
+ static rtl::OUString tempWhiteSpaceStr( 0x20 );
+ static rtl::OUString tempWhiteSpaceNonBreakingStr( 0xa0 );
+ m_bIsWhiteSpaceInLine=(rGlyphs.equals( tempWhiteSpaceStr ) || rGlyphs.equals( tempWhiteSpaceNonBreakingStr ));
+ }
+>>>>>>> .merge-right.r272944
}
GraphicsContext& PDFIProcessor::getTransformGlyphContext( CharGlyph& rGlyph )
@@ -571,22 +599,70 @@ void PDFIProcessor::setupImage(ImageId nImage)
{
const GraphicsContext& rGC( getCurrentContext() );
- // transform unit rect, to determine view box
- basegfx::B2DPoint aOrigin(0,0);
- aOrigin *= rGC.Transformation;
+ basegfx::B2DHomMatrix aTrans( rGC.Transformation );
- basegfx::B2DVector aSize(1,1);
- aSize *= rGC.Transformation;
+ // check for rotation, which is the other way around in ODF
+ basegfx::B2DTuple aScale, aTranslation;
+ double fRotate, fShearX;
+ rGC.Transformation.decompose( aScale, aTranslation, fRotate, fShearX );
+ // TODDO(F4): correcting rotation when fShearX != 0 ?
+ if( fRotate != 0.0 )
+ {
+
+ // try to create a Transformation that corrects for the wrong rotation
+ aTrans.identity();
+ aTrans.scale( aScale.getX(), aScale.getY() );
+ aTrans.rotate( -fRotate );
+
+ basegfx::B2DRange aRect( 0, 0, 1, 1 );
+ aRect.transform( aTrans );
+
+ // TODO(F3) treat translation correctly
+ // the corrections below work for multiples of 90 degree
+ // which is a common case (landscape/portrait/seascape)
+ // we need a general solution here; however this needs to
+ // work in sync with DrawXmlEmitter::fillFrameProps and WriterXmlEmitter::fillFrameProps
+ // admittedly this is a lame workaround and fails for arbitrary rotation
+ double fQuadrant = fmod( fRotate, 2.0*M_PI ) / M_PI_2;
+ int nQuadrant = (int)fQuadrant;
+ if( nQuadrant < 0 )
+ nQuadrant += 4;
+ if( nQuadrant == 1 )
+ {
+ aTranslation.setX( aTranslation.getX() + aRect.getHeight() + aRect.getWidth());
+ aTranslation.setY( aTranslation.getY() + aRect.getHeight() );
+ }
+ if( nQuadrant == 3 )
+ aTranslation.setX( aTranslation.getX() - aRect.getHeight() );
+
+ aTrans.translate( aTranslation.getX(),
+ aTranslation.getY() );
+ }
+
+ bool bMirrorVertical = aScale.getY() > 0;
+
+ // transform unit rect to determine view box
+ basegfx::B2DRange aRect( 0, 0, 1, 1 );
+ aRect.transform( aTrans );
// TODO(F3): Handle clip
const sal_Int32 nGCId = getGCId(rGC);
FrameElement* pFrame = m_pElFactory->createFrameElement( m_pCurElement, nGCId );
ImageElement* pImageElement = m_pElFactory->createImageElement( pFrame, nGCId, nImage );
- pFrame->x = pImageElement->x = aOrigin.getX();
- pFrame->y = pImageElement->y = aOrigin.getY();
- pFrame->w = pImageElement->w = aSize.getX();
- pFrame->h = pImageElement->h = aSize.getY();
+ pFrame->x = pImageElement->x = aRect.getMinX();
+ pFrame->y = pImageElement->y = aRect.getMinY();
+ pFrame->w = pImageElement->w = aRect.getWidth();
+ pFrame->h = pImageElement->h = aRect.getHeight();
pFrame->ZOrder = m_nNextZOrder++;
+
+ if( bMirrorVertical )
+ {
+ pFrame->MirrorVertical = pImageElement->MirrorVertical = true;
+ pFrame->x += aRect.getWidth();
+ pImageElement->x += aRect.getWidth();
+ pFrame->y += aRect.getHeight();
+ pImageElement->y += aRect.getHeight();
+ }
}
void PDFIProcessor::drawMask(const uno::Sequence<beans::PropertyValue>& xBitmap,
diff --git a/sdext/source/pdfimport/wrapper/wrapper.cxx b/sdext/source/pdfimport/wrapper/wrapper.cxx
index 6ec897891677..9e23a061b760 100755
--- a/sdext/source/pdfimport/wrapper/wrapper.cxx
+++ b/sdext/source/pdfimport/wrapper/wrapper.cxx
@@ -33,36 +33,39 @@
#include "precompiled_sdext.hxx"
#include "contentsink.hxx"
-
-#include <osl/file.h>
-#include <osl/thread.h>
-#include <osl/process.h>
-#include <osl/diagnose.h>
-#include <rtl/ustring.hxx>
-#include <rtl/ustrbuf.hxx>
-#include <rtl/strbuf.hxx>
-#include <rtl/byteseq.hxx>
-
-#include <cppuhelper/exc_hlp.hxx>
-#include <com/sun/star/io/XInputStream.hpp>
-#include <com/sun/star/uno/XComponentContext.hpp>
-#include <com/sun/star/awt/FontDescriptor.hpp>
-#include <com/sun/star/deployment/XPackageInformationProvider.hpp>
-#include <com/sun/star/beans/XMaterialHolder.hpp>
-#include <com/sun/star/rendering/PathCapType.hpp>
-#include <com/sun/star/rendering/PathJoinType.hpp>
-#include <com/sun/star/rendering/XColorSpace.hpp>
-#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
-#include <com/sun/star/rendering/XBitmap.hpp>
-#include <com/sun/star/geometry/Matrix2D.hpp>
-#include <com/sun/star/geometry/AffineMatrix2D.hpp>
-#include <com/sun/star/geometry/RealRectangle2D.hpp>
-
-#include <basegfx/point/b2dpoint.hxx>
-#include <basegfx/polygon/b2dpolypolygon.hxx>
-#include <basegfx/polygon/b2dpolygon.hxx>
-#include <basegfx/tools/canvastools.hxx>
-#include <basegfx/tools/unopolypolygon.hxx>
+#include "pdfparse.hxx"
+#include "pdfihelper.hxx"
+
+#include "osl/file.h"
+#include "osl/thread.h"
+#include "osl/process.h"
+#include "osl/diagnose.h"
+#include "rtl/ustring.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/byteseq.hxx"
+
+#include "cppuhelper/exc_hlp.hxx"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/awt/FontDescriptor.hpp"
+#include "com/sun/star/deployment/XPackageInformationProvider.hpp"
+#include "com/sun/star/beans/XMaterialHolder.hpp"
+#include "com/sun/star/rendering/PathCapType.hpp"
+#include "com/sun/star/rendering/PathJoinType.hpp"
+#include "com/sun/star/rendering/XColorSpace.hpp"
+#include "com/sun/star/rendering/XPolyPolygon2D.hpp"
+#include "com/sun/star/rendering/XBitmap.hpp"
+#include "com/sun/star/geometry/Matrix2D.hpp"
+#include "com/sun/star/geometry/AffineMatrix2D.hpp"
+#include "com/sun/star/geometry/RealRectangle2D.hpp"
+#include "com/sun/star/task/XInteractionHandler.hpp"
+
+#include "basegfx/point/b2dpoint.hxx"
+#include "basegfx/polygon/b2dpolypolygon.hxx"
+#include "basegfx/polygon/b2dpolygon.hxx"
+#include "basegfx/tools/canvastools.hxx"
+#include "basegfx/tools/unopolypolygon.hxx"
#include <boost/bind.hpp>
#include <boost/preprocessor/stringize.hpp>
@@ -561,18 +564,23 @@ uno::Sequence<beans::PropertyValue> Parser::readImageImpl()
static const rtl::OString aJpegMarker( "JPEG" );
static const rtl::OString aPbmMarker( "PBM" );
static const rtl::OString aPpmMarker( "PPM" );
+ static const rtl::OString aPngMarker( "PNG" );
static const rtl::OUString aJpegFile(
RTL_CONSTASCII_USTRINGPARAM( "DUMMY.JPEG" ));
static const rtl::OUString aPbmFile(
RTL_CONSTASCII_USTRINGPARAM( "DUMMY.PBM" ));
static const rtl::OUString aPpmFile(
RTL_CONSTASCII_USTRINGPARAM( "DUMMY.PPM" ));
+ static const rtl::OUString aPngFile(
+ RTL_CONSTASCII_USTRINGPARAM( "DUMMY.PNG" ));
rtl::OString aToken = readNextToken();
const sal_Int32 nImageSize( readInt32() );
rtl::OUString aFileName;
- if( aToken.compareTo( aJpegMarker ) == 0 )
+ if( aToken.compareTo( aPngMarker ) == 0 )
+ aFileName = aPngFile;
+ else if( aToken.compareTo( aJpegMarker ) == 0 )
aFileName = aJpegFile;
else if( aToken.compareTo( aPbmMarker ) == 0 )
aFileName = aPbmFile;
@@ -813,9 +821,65 @@ oslFileError readLine( oslFileHandle pFile, ::rtl::OStringBuffer& line )
} // namespace
-bool xpdf_ImportFromFile( const ::rtl::OUString& rURL,
- const ContentSinkSharedPtr& rSink,
- const uno::Reference< uno::XComponentContext >& xContext )
+static bool checkEncryption( const rtl::OUString& i_rPath,
+ const uno::Reference< task::XInteractionHandler >& i_xIHdl,
+ rtl::OUString& io_rPwd,
+ bool& o_rIsEncrypted
+ )
+{
+ bool bSuccess = false;
+ rtl::OString aPDFFile;
+ aPDFFile = rtl::OUStringToOString( i_rPath, osl_getThreadTextEncoding() );
+
+ pdfparse::PDFReader aParser;
+ boost::scoped_ptr<pdfparse::PDFEntry> pEntry( aParser.read( aPDFFile.getStr() ));
+ if( pEntry )
+ {
+ pdfparse::PDFFile* pPDFFile = dynamic_cast<pdfparse::PDFFile*>(pEntry.get());
+ if( pPDFFile )
+ {
+ o_rIsEncrypted = pPDFFile->isEncrypted();
+ if( o_rIsEncrypted )
+ {
+ bool bAuthenticated = false;
+ if( io_rPwd.getLength() )
+ {
+ rtl::OString aIsoPwd = rtl::OUStringToOString( io_rPwd,
+ RTL_TEXTENCODING_ISO_8859_1 );
+ bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() );
+ }
+ if( bAuthenticated )
+ bSuccess = true;
+ else
+ {
+ if( i_xIHdl.is() )
+ {
+ bool bEntered = false;
+ do
+ {
+ bEntered = getPassword( i_xIHdl, io_rPwd, ! bEntered );
+ rtl::OString aIsoPwd = rtl::OUStringToOString( io_rPwd,
+ RTL_TEXTENCODING_ISO_8859_1 );
+ bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() );
+ } while( bEntered && ! bAuthenticated );
+ }
+
+ OSL_TRACE( "password: %s\n", bAuthenticated ? "matches" : "does not match" );
+ bSuccess = bAuthenticated;
+ }
+ }
+ else
+ bSuccess = true;
+ }
+ }
+ return bSuccess;
+}
+
+bool xpdf_ImportFromFile( const ::rtl::OUString& rURL,
+ const ContentSinkSharedPtr& rSink,
+ const uno::Reference< task::XInteractionHandler >& xIHdl,
+ const rtl::OUString& rPwd,
+ const uno::Reference< uno::XComponentContext >& xContext )
{
OSL_ASSERT(rSink);
@@ -823,6 +887,12 @@ bool xpdf_ImportFromFile( const ::rtl::OUString& rURL
if( osl_getSystemPathFromFileURL( rURL.pData, &aSysUPath.pData ) != osl_File_E_None )
return false;
+ // check for encryption, if necessary get password
+ rtl::OUString aPwd( rPwd );
+ bool bIsEncrypted = false;
+ if( checkEncryption( aSysUPath, xIHdl, aPwd, bIsEncrypted ) == false )
+ return false;
+
rtl::OUStringBuffer converterURL = rtl::OUString::createFromAscii("xpdfimport");
// retrieve package location url (xpdfimport executable is located there)
@@ -853,15 +923,17 @@ bool xpdf_ImportFromFile( const ::rtl::OUString& rURL
rtl_bootstrap_expandMacros( &aStr.pData );
rtl::OUString aSysPath;
osl_getSystemPathFromFileURL( aStr.pData, &aSysPath.pData );
- rtl::OUStringBuffer aBuf( aStr.getLength() + 20 );
- aBuf.appendAscii( "LD_LIBRARY_PATH=" );
- aBuf.append( aSysPath );
- aStr = aBuf.makeStringAndClear();
+ rtl::OUStringBuffer aEnvBuf( aStr.getLength() + 20 );
+ aEnvBuf.appendAscii( "LD_LIBRARY_PATH=" );
+ aEnvBuf.append( aSysPath );
+ aStr = aEnvBuf.makeStringAndClear();
ppEnv = &aStr.pData;
nEnv = 1;
#endif
rtl_uString* args[] = { aSysUPath.pData };
+ sal_Int32 nArgs = 1;
+
oslProcess aProcess;
oslFileHandle pIn = NULL;
oslFileHandle pOut = NULL;
@@ -869,7 +941,7 @@ bool xpdf_ImportFromFile( const ::rtl::OUString& rURL
const oslProcessError eErr =
osl_executeProcess_WithRedirectedIO(converterURL.makeStringAndClear().pData,
args,
- sizeof(args)/sizeof(*args),
+ nArgs,
osl_Process_SEARCHPATH|osl_Process_HIDDEN,
osl_getCurrentSecurity(),
0, ppEnv, nEnv,
@@ -881,6 +953,17 @@ bool xpdf_ImportFromFile( const ::rtl::OUString& rURL
if( eErr!=osl_Process_E_None )
return false;
+ if( pIn )
+ {
+ rtl::OStringBuffer aBuf(256);
+ if( bIsEncrypted )
+ aBuf.append( rtl::OUStringToOString( aPwd, RTL_TEXTENCODING_ISO_8859_1 ) );
+ aBuf.append( '\n' );
+
+ sal_uInt64 nWritten = 0;
+ osl_writeFile( pIn, aBuf.getStr(), sal_uInt64(aBuf.getLength()), &nWritten );
+ }
+
if( pOut && pErr )
{
// read results of PDF parser. One line - one call to
@@ -908,8 +991,11 @@ bool xpdf_ImportFromFile( const ::rtl::OUString& rURL
return bRet;
}
+
bool xpdf_ImportFromStream( const uno::Reference< io::XInputStream >& xInput,
const ContentSinkSharedPtr& rSink,
+ const uno::Reference<task::XInteractionHandler >& xIHdl,
+ const rtl::OUString& rPwd,
const uno::Reference< uno::XComponentContext >& xContext )
{
OSL_ASSERT(xInput.is());
@@ -952,7 +1038,7 @@ bool xpdf_ImportFromStream( const uno::Reference< io::XInputStream >& xI
osl_closeFile( aFile );
- return bSuccess && xpdf_ImportFromFile( aURL, rSink, xContext );
+ return bSuccess && xpdf_ImportFromFile( aURL, rSink, xIHdl, rPwd, xContext );
}
}
diff --git a/sdext/source/pdfimport/xpdfwrapper/makefile.mk b/sdext/source/pdfimport/xpdfwrapper/makefile.mk
index 8ce3fb718228..796bef066cde 100644
--- a/sdext/source/pdfimport/xpdfwrapper/makefile.mk
+++ b/sdext/source/pdfimport/xpdfwrapper/makefile.mk
@@ -57,8 +57,9 @@ UWINAPILIB:=
APP1TARGET=$(TARGET)
APP1LIBSALCPPRT=
APP1OBJS= \
- $(OBJ)$/wrapper_gpl.obj $(OBJ)/pdfioutdev_gpl.obj
+ $(OBJ)$/wrapper_gpl.obj $(OBJ)/pdfioutdev_gpl.obj $(OBJ)/pnghelper.obj
+APP1STDLIBS+=$(ZLIB3RDLIB)
.IF "$(SYSTEM_POPPLER)" == "YES"
APP1STDLIBS+=$(POPPLER_LIBS)
diff --git a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
index 63c62ce786de..3c72a27e6d35 100644
--- a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
+++ b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
@@ -35,6 +35,7 @@
************************************************************************/
#include "pdfioutdev_gpl.hxx"
+#include "pnghelper.hxx"
#include <stdlib.h>
#include <stdio.h>
@@ -95,8 +96,6 @@ const char* escapeLineFeed( const char* pStr )
/// for the initial std::vector capacity when copying stream from xpdf
#define WRITE_BUFFER_INITIAL_CAPACITY (1024*100)
-typedef std::vector<char> OutputBuffer;
-
void initBuf(OutputBuffer& io_rBuffer)
{
io_rBuffer.reserve(WRITE_BUFFER_INITIAL_CAPACITY);
@@ -135,7 +134,7 @@ void writeJpeg_( OutputBuffer& o_rOutputBuf, Stream* str, bool bWithLinefeed )
str->close();
}
-void writePbm_(OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, bool bWithLinefeed)
+void writePbm_(OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, bool bWithLinefeed, bool bInvert )
{
// write as PBM (char by char, to avoid stdlib lineend messing)
o_rOutputBuf.clear();
@@ -163,19 +162,142 @@ void writePbm_(OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, b
str->reset();
// copy the raw stream
- for( int i=0; i<size; ++i)
- o_rOutputBuf.push_back(static_cast<char>(str->getChar()));
+ if( bInvert )
+ {
+ for( int i=0; i<size; ++i)
+ o_rOutputBuf.push_back(static_cast<char>(str->getChar() ^ 0xff));
+ }
+ else
+ {
+ for( int i=0; i<size; ++i)
+ o_rOutputBuf.push_back(static_cast<char>(str->getChar()));
+ }
str->close();
}
+void writePpm_( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width,
+ int height,
+ GfxImageColorMap* colorMap,
+ bool bWithLinefeed )
+{
+ // write as PPM (char by char, to avoid stdlib lineend messing)
+ o_rOutputBuf.clear();
+ o_rOutputBuf.resize(WRITE_BUFFER_SIZE);
+ o_rOutputBuf[0] = 'P';
+ o_rOutputBuf[1] = '6';
+ o_rOutputBuf[2] = '\n';
+ int nOutLen = snprintf(&o_rOutputBuf[3], WRITE_BUFFER_SIZE-10, "%d %d", width, height);
+ if( nOutLen < 0 )
+ nOutLen = WRITE_BUFFER_SIZE-10;
+ o_rOutputBuf[3+nOutLen] ='\n';
+ o_rOutputBuf[3+nOutLen+1]='2';
+ o_rOutputBuf[3+nOutLen+2]='5';
+ o_rOutputBuf[3+nOutLen+3]='5';
+ o_rOutputBuf[3+nOutLen+4]='\n';
+ o_rOutputBuf[3+nOutLen+5]=0;
+
+ const int header_size = 3+nOutLen+5;
+ const int size = width*height*3 + header_size;
+
+ printf( " PPM %d", size );
+ if( bWithLinefeed )
+ printf("\n");
+
+ // trim buffer to exact header size
+ o_rOutputBuf.resize(header_size);
+
+ // initialize stream
+ Guchar *p;
+ GfxRGB rgb;
+ ImageStream* imgStr =
+ new ImageStream(str,
+ width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+
+ for( int y=0; y<height; ++y)
+ {
+ p = imgStr->getLine();
+ for( int x=0; x<width; ++x)
+ {
+ colorMap->getRGB(p, &rgb);
+ o_rOutputBuf.push_back(colToByte(rgb.r));
+ o_rOutputBuf.push_back(colToByte(rgb.g));
+ o_rOutputBuf.push_back(colToByte(rgb.b));
+
+ p +=colorMap->getNumPixelComps();
+ }
+ }
+
+ delete imgStr;
+
+}
+
+// call this only for 1 bit image streams !
+void writePng_( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width,
+ int height,
+ GfxRGB& zeroColor,
+ GfxRGB& oneColor,
+ bool bIsMask,
+ bool bWithLinefeed )
+{
+ o_rOutputBuf.clear();
+
+ // get png image
+ PngHelper::createPng( o_rOutputBuf, str, width, height, zeroColor, oneColor, bIsMask );
+
+ printf( " PNG %d", (int)o_rOutputBuf.size() );
+ if( bWithLinefeed )
+ printf("\n");
+}
+
+void writePng_( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight, GfxImageColorMap* maskColorMap,
+ bool bWithLinefeed )
+{
+ o_rOutputBuf.clear();
+
+ // get png image
+ PngHelper::createPng( o_rOutputBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap );
+
+ printf( " PNG %d", (int)o_rOutputBuf.size() );
+ if( bWithLinefeed )
+ printf("\n");
+}
+
+void writePng_( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight, bool maskInvert,
+ bool bWithLinefeed )
+{
+ o_rOutputBuf.clear();
+
+ // get png image
+ PngHelper::createPng( o_rOutputBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert );
+
+ printf( " PNG %d", (int)o_rOutputBuf.size() );
+ if( bWithLinefeed )
+ printf("\n");
+}
+
// stolen from ImageOutputDev.cc
-void writeMask_( OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, bool bWithLinefeed )
+void writeMask_( OutputBuffer& o_rOutputBuf, Stream* str, int width, int height, bool bWithLinefeed, bool bInvert )
{
if( str->getKind() == strDCT )
writeJpeg_(o_rOutputBuf, str, bWithLinefeed);
else
- writePbm_(o_rOutputBuf, str, width, height, bWithLinefeed);
+ writePbm_(o_rOutputBuf, str, width, height, bWithLinefeed, bInvert );
}
void writeImage_( OutputBuffer& o_rOutputBuf,
@@ -195,62 +317,21 @@ void writeImage_( OutputBuffer& o_rOutputBuf,
else if (colorMap->getNumPixelComps() == 1 &&
colorMap->getBits() == 1)
{
- writePbm_(o_rOutputBuf, str, width, height, bWithLinefeed);
- }
- else
- {
- // write as PPM (char by char, to avoid stdlib lineend messing)
- o_rOutputBuf.clear();
- o_rOutputBuf.resize(WRITE_BUFFER_SIZE);
- o_rOutputBuf[0] = 'P';
- o_rOutputBuf[1] = '6';
- o_rOutputBuf[2] = '\n';
- int nOutLen = snprintf(&o_rOutputBuf[3], WRITE_BUFFER_SIZE-10, "%d %d", width, height);
- if( nOutLen < 0 )
- nOutLen = WRITE_BUFFER_SIZE-10;
- o_rOutputBuf[3+nOutLen] ='\n';
- o_rOutputBuf[3+nOutLen+1]='2';
- o_rOutputBuf[3+nOutLen+2]='5';
- o_rOutputBuf[3+nOutLen+3]='5';
- o_rOutputBuf[3+nOutLen+4]='\n';
- o_rOutputBuf[3+nOutLen+5]=0;
-
- const int header_size = 3+nOutLen+5;
- const int size = width*height*3 + header_size;
-
- printf( " PPM %d", size );
- if( bWithLinefeed )
- printf("\n");
-
- // trim buffer to exact header size
- o_rOutputBuf.resize(header_size);
-
- // initialize stream
- Guchar *p;
- GfxRGB rgb;
- ImageStream* imgStr =
- new ImageStream(str,
- width,
- colorMap->getNumPixelComps(),
- colorMap->getBits());
- imgStr->reset();
-
- for( int y=0; y<height; ++y)
+ // this is a two color bitmap, write a png
+ // provide default colors
+ GfxRGB zeroColor = { 0, 0, 0 },
+ oneColor = { byteToCol( 0xff ), byteToCol( 0xff ), byteToCol( 0xff ) };
+ if( colorMap->getColorSpace()->getMode() == csIndexed || colorMap->getColorSpace()->getMode() == csDeviceGray )
{
- p = imgStr->getLine();
- for( int x=0; x<width; ++x)
- {
- colorMap->getRGB(p, &rgb);
- o_rOutputBuf.push_back(colToByte(rgb.r));
- o_rOutputBuf.push_back(colToByte(rgb.g));
- o_rOutputBuf.push_back(colToByte(rgb.b));
-
- p +=colorMap->getNumPixelComps();
- }
+ Guchar nIndex = 0;
+ colorMap->getRGB( &nIndex, &zeroColor );
+ nIndex = 1;
+ colorMap->getRGB( &nIndex, &oneColor );
}
-
- delete imgStr;
+ writePng_( o_rOutputBuf, str, width, height, zeroColor, oneColor, false, bWithLinefeed );
}
+ else
+ writePpm_( o_rOutputBuf, str, width, height, colorMap, bWithLinefeed );
}
// forwarders
@@ -269,11 +350,13 @@ inline void writeImageLF( OutputBuffer& o_rOutputBuf,
inline void writeMask( OutputBuffer& o_rOutputBuf,
Stream* str,
int width,
- int height ) { writeMask_(o_rOutputBuf,str,width,height,false); }
+ int height,
+ bool bInvert ) { writeMask_(o_rOutputBuf,str,width,height,false,bInvert); }
inline void writeMaskLF( OutputBuffer& o_rOutputBuf,
Stream* str,
int width,
- int height ) { writeMask_(o_rOutputBuf,str,width,height,true); }
+ int height,
+ bool bInvert ) { writeMask_(o_rOutputBuf,str,width,height,true,bInvert); }
// ------------------------------------------------------------------
@@ -358,7 +441,7 @@ void PDFOutDev::printPath( GfxPath* pPath ) const
PDFOutDev::PDFOutDev( PDFDoc* pDoc ) :
m_pDoc( pDoc ),
m_aFontMap(),
- m_pUtf8Map( new UnicodeMap("UTF-8", gTrue, &mapUTF8) )
+ m_pUtf8Map( new UnicodeMap((char*)"UTF-8", gTrue, &mapUTF8) )
{
}
@@ -704,14 +787,29 @@ void PDFOutDev::endTextObject(GfxState*)
printf( "endTextObject\n" );
}
-void PDFOutDev::drawImageMask(GfxState*, Object*, Stream* str,
+void PDFOutDev::drawImageMask(GfxState* pState, Object*, Stream* str,
int width, int height, GBool invert,
GBool /*inlineImg*/ )
{
OutputBuffer aBuf; initBuf(aBuf);
printf( "drawMask %d %d %d", width, height, invert );
- writeMaskLF(aBuf, str, width, height);
+
+ int bitsPerComponent = 1;
+ StreamColorSpaceMode csMode = streamCSNone;
+ str->getImageParams( &bitsPerComponent, &csMode );
+ if( bitsPerComponent == 1 && (csMode == streamCSNone || csMode == streamCSDeviceGray) )
+ {
+ GfxRGB oneColor = { dblToCol( 1.0 ), dblToCol( 1.0 ), dblToCol( 1.0 ) };
+ GfxRGB zeroColor = { dblToCol( 0.0 ), dblToCol( 0.0 ), dblToCol( 0.0 ) };
+ pState->getFillColorSpace()->getRGB( pState->getFillColor(), &zeroColor );
+ if( invert )
+ writePng_( aBuf, str, width, height, oneColor, zeroColor, true, true );
+ else
+ writePng_( aBuf, str, width, height, zeroColor, oneColor, true, true );
+ }
+ else
+ writeMaskLF(aBuf, str, width, height, invert != 0);
writeBinaryBuffer(aBuf);
}
@@ -768,13 +866,19 @@ void PDFOutDev::drawMaskedImage(GfxState*, Object*, Stream* str,
GBool maskInvert)
{
OutputBuffer aBuf; initBuf(aBuf);
+ printf( "drawImage %d %d 0", width, height );
+ writePng_( aBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskInvert, true );
+ writeBinaryBuffer( aBuf );
+ #if 0
+ OutputBuffer aBuf; initBuf(aBuf);
OutputBuffer aMaskBuf; initBuf(aMaskBuf);
- printf( "drawMaskedImage %d %d %d %d %d", width, height, maskWidth, maskHeight, maskInvert );
+ printf( "drawMaskedImage %d %d %d %d %d", width, height, maskWidth, maskHeight, 0 /*maskInvert note: currently we do inversion here*/ );
writeImage( aBuf, str, width, height, colorMap );
- writeMaskLF( aMaskBuf, maskStr, width, height );
+ writeMaskLF( aMaskBuf, maskStr, width, height, maskInvert );
writeBinaryBuffer(aBuf);
writeBinaryBuffer(aMaskBuf);
+ #endif
}
void PDFOutDev::drawSoftMaskedImage(GfxState*, Object*, Stream* str,
@@ -785,6 +889,11 @@ void PDFOutDev::drawSoftMaskedImage(GfxState*, Object*, Stream* str,
GfxImageColorMap* maskColorMap )
{
OutputBuffer aBuf; initBuf(aBuf);
+ printf( "drawImage %d %d 0", width, height );
+ writePng_( aBuf, str, width, height, colorMap, maskStr, maskWidth, maskHeight, maskColorMap, true );
+ writeBinaryBuffer( aBuf );
+ #if 0
+ OutputBuffer aBuf; initBuf(aBuf);
OutputBuffer aMaskBuf; initBuf(aMaskBuf);
printf( "drawSoftMaskedImage %d %d %d %d", width, height, maskWidth, maskHeight );
@@ -792,6 +901,7 @@ void PDFOutDev::drawSoftMaskedImage(GfxState*, Object*, Stream* str,
writeImageLF( aMaskBuf, maskStr, maskWidth, maskHeight, maskColorMap );
writeBinaryBuffer(aBuf);
writeBinaryBuffer(aMaskBuf);
+ #endif
}
void PDFOutDev::setPageNum( int nNumPages )
diff --git a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx
index eb4d130f6a79..43a1038f02d6 100644
--- a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx
+++ b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx
@@ -64,6 +64,7 @@
#endif
#include <hash_map>
+#include <vector>
class GfxPath;
class GfxFont;
@@ -286,5 +287,10 @@ namespace pdfi
extern FILE* g_binary_out;
+// note: if you ever hcange Output_t, please keep in mind that the current code
+// relies on it being of 8 bit size
+typedef char Output_t;
+typedef std::vector< Output_t > OutputBuffer;
+
#endif /* INCLUDED_PDFI_OUTDEV_HXX */
diff --git a/sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx b/sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx
new file mode 100644
index 000000000000..91b886de1689
--- /dev/null
+++ b/sdext/source/pdfimport/xpdfwrapper/pnghelper.cxx
@@ -0,0 +1,411 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU General Public License Version 2.
+ *
+ *
+ * GNU General Public License, version 2
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ ************************************************************************/
+
+#include "pnghelper.hxx"
+
+#include "zlib/zlib.h"
+
+using namespace pdfi;
+
+// checksum helpers, courtesy of libpng.org
+
+/* Table of CRCs of all 8-bit messages. */
+sal_uInt32 PngHelper::crc_table[256];
+
+/* Flag: has the table been computed? Initially false. */
+bool PngHelper::bCRCTableInit = true;
+
+/* Make the table for a fast CRC. */
+void PngHelper::initCRCTable()
+{
+ for (sal_uInt32 n = 0; n < 256; n++)
+ {
+ sal_uInt32 c = n;
+ for (int k = 0; k < 8; k++)
+ {
+ if (c & 1)
+ c = 0xedb88320L ^ (c >> 1);
+ else
+ c = c >> 1;
+ }
+ crc_table[n] = c;
+ }
+ bCRCTableInit = false;
+}
+
+/* Update a running CRC with the bytes buf[0..len-1]--the CRC
+ should be initialized to all 1's, and the transmitted value
+ is the 1's complement of the final running CRC (see the
+ crc() routine below)). */
+
+void PngHelper::updateCRC( sal_uInt32& io_rCRC, const sal_uInt8* i_pBuf, size_t i_nLen )
+{
+ if( bCRCTableInit )
+ initCRCTable();
+
+ sal_uInt32 nCRC = io_rCRC;
+ for( size_t n = 0; n < i_nLen; n++ )
+ nCRC = crc_table[(nCRC ^ i_pBuf[n]) & 0xff] ^ (nCRC >> 8);
+ io_rCRC = nCRC;
+}
+
+sal_uInt32 PngHelper::getCRC( const sal_uInt8* i_pBuf, size_t i_nLen )
+{
+ sal_uInt32 nCRC = 0xffffffff;
+ updateCRC( nCRC, i_pBuf, i_nLen );
+ return nCRC ^ 0xffffffff;
+}
+
+sal_uInt32 PngHelper::deflateBuffer( const Output_t* i_pBuf, size_t i_nLen, OutputBuffer& o_rOut )
+{
+ size_t nOrigSize = o_rOut.size();
+
+ // prepare z stream
+ z_stream aStream;
+ aStream.zalloc = Z_NULL;
+ aStream.zfree = Z_NULL;
+ aStream.opaque = Z_NULL;
+ deflateInit( &aStream, Z_BEST_COMPRESSION );
+ aStream.avail_in = uInt(i_nLen);
+ aStream.next_in = (Bytef*)i_pBuf;
+
+ sal_uInt8 aOutBuf[ 32768 ];
+ do
+ {
+ aStream.avail_out = sizeof( aOutBuf );
+ aStream.next_out = aOutBuf;
+
+ if( deflate( &aStream, Z_FINISH ) == Z_STREAM_ERROR )
+ {
+ deflateEnd( &aStream );
+ // scrao the data of this broken stream
+ o_rOut.resize( nOrigSize );
+ return 0;
+ }
+
+ // append compressed bytes
+ sal_uInt32 nCompressedBytes = sizeof( aOutBuf ) - aStream.avail_out;
+ if( nCompressedBytes )
+ o_rOut.insert( o_rOut.end(), aOutBuf, aOutBuf+nCompressedBytes );
+
+ } while( aStream.avail_out == 0 );
+
+ // cleanup
+ deflateEnd( &aStream );
+
+ return sal_uInt32( o_rOut.size() - nOrigSize );
+}
+
+void PngHelper::appendFileHeader( OutputBuffer& o_rOutputBuf )
+{
+ static const Output_t aHeader[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
+
+ o_rOutputBuf.insert( o_rOutputBuf.end(), aHeader, aHeader + sizeof(aHeader)/sizeof(aHeader[0]) );
+}
+
+size_t PngHelper::startChunk( const char* pChunkName, OutputBuffer& o_rOutputBuf )
+{
+ size_t nIndex = sal_uInt32( o_rOutputBuf.size() );
+ o_rOutputBuf.insert( o_rOutputBuf.end(), 4, 0 );
+ o_rOutputBuf.push_back( pChunkName[0] );
+ o_rOutputBuf.push_back( pChunkName[1] );
+ o_rOutputBuf.push_back( pChunkName[2] );
+ o_rOutputBuf.push_back( pChunkName[3] );
+ return nIndex;
+}
+
+void PngHelper::set( sal_uInt32 i_nValue, OutputBuffer& o_rOutputBuf, size_t i_nIndex )
+{
+ o_rOutputBuf[ i_nIndex ] = (i_nValue & 0xff000000) >> 24;
+ o_rOutputBuf[ i_nIndex+1 ] = (i_nValue & 0x00ff0000) >> 16;
+ o_rOutputBuf[ i_nIndex+2 ] = (i_nValue & 0x0000ff00) >> 8;
+ o_rOutputBuf[ i_nIndex+3 ] = (i_nValue & 0x000000ff);
+}
+
+void PngHelper::endChunk( size_t nStart, OutputBuffer& o_rOutputBuf )
+{
+ if( nStart+8 > o_rOutputBuf.size() )
+ return; // something broken is going on
+
+ // update chunk length
+ size_t nLen = o_rOutputBuf.size() - nStart;
+ sal_uInt32 nDataLen = sal_uInt32(nLen)-8;
+ set( nDataLen, o_rOutputBuf, nStart );
+
+ // append chunk crc
+ sal_uInt32 nChunkCRC = getCRC( (sal_uInt8*)&o_rOutputBuf[nStart+4], nLen-4 );
+ append( nChunkCRC, o_rOutputBuf );
+}
+
+void PngHelper::appendIHDR( OutputBuffer& o_rOutputBuf, int width, int height, int depth, int colortype )
+{
+ size_t nStart = startChunk( "IHDR", o_rOutputBuf );
+ append( width, o_rOutputBuf );
+ append( height, o_rOutputBuf );
+ o_rOutputBuf.push_back( Output_t(depth) );
+ o_rOutputBuf.push_back( Output_t(colortype) );
+ o_rOutputBuf.push_back( 0 ); // compression method deflate
+ o_rOutputBuf.push_back( 0 ); // filtering method 0 (default)
+ o_rOutputBuf.push_back( 0 ); // no interlacing
+ endChunk( nStart, o_rOutputBuf );
+}
+
+void PngHelper::appendIEND( OutputBuffer& o_rOutputBuf )
+{
+ size_t nStart = startChunk( "IEND", o_rOutputBuf );
+ endChunk( nStart, o_rOutputBuf );
+}
+
+void PngHelper::createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width,
+ int height,
+ GfxRGB& zeroColor,
+ GfxRGB& oneColor,
+ bool bIsMask
+ )
+{
+ appendFileHeader( o_rOutputBuf );
+ appendIHDR( o_rOutputBuf, width, height, 1, 3 );
+
+ // write palette
+ size_t nIdx = startChunk( "PLTE", o_rOutputBuf );
+ // write colors 0 and 1
+ o_rOutputBuf.push_back(colToByte(zeroColor.r));
+ o_rOutputBuf.push_back(colToByte(zeroColor.g));
+ o_rOutputBuf.push_back(colToByte(zeroColor.b));
+ o_rOutputBuf.push_back(colToByte(oneColor.r));
+ o_rOutputBuf.push_back(colToByte(oneColor.g));
+ o_rOutputBuf.push_back(colToByte(oneColor.b));
+ // end PLTE chunk
+ endChunk( nIdx, o_rOutputBuf );
+
+ if( bIsMask )
+ {
+ // write tRNS chunk
+ nIdx = startChunk( "tRNS", o_rOutputBuf );
+ o_rOutputBuf.push_back( 0xff );
+ o_rOutputBuf.push_back( 0 );
+ // end tRNS chunk
+ endChunk( nIdx, o_rOutputBuf );
+ }
+
+ // create scan line data buffer
+ OutputBuffer aScanlines;
+ int nLineSize = (width + 7)/8;
+ aScanlines.reserve( nLineSize * height + height );
+
+ str->reset();
+ for( int y = 0; y < height; y++ )
+ {
+ // determine filter type (none) for this scanline
+ aScanlines.push_back( 0 );
+ for( int x = 0; x < nLineSize; x++ )
+ aScanlines.push_back( str->getChar() );
+ }
+
+ // begin IDAT chunk for scanline data
+ nIdx = startChunk( "IDAT", o_rOutputBuf );
+ // compress scanlines
+ deflateBuffer( &aScanlines[0], aScanlines.size(), o_rOutputBuf );
+ // end IDAT chunk
+ endChunk( nIdx, o_rOutputBuf );
+
+ // output IEND
+ appendIEND( o_rOutputBuf );
+}
+
+void PngHelper::createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight, GfxImageColorMap* maskColorMap )
+{
+ appendFileHeader( o_rOutputBuf );
+ appendIHDR( o_rOutputBuf, width, height, 8, 6 ); // RGBA image
+
+ // initialize stream
+ Guchar *p, *pm;
+ GfxRGB rgb;
+ GfxGray alpha;
+ ImageStream* imgStr =
+ new ImageStream(str,
+ width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+
+ // create scan line data buffer
+ OutputBuffer aScanlines;
+ aScanlines.reserve( width*height*4 + height );
+
+ for( int y=0; y<height; ++y)
+ {
+ aScanlines.push_back( 0 );
+ p = imgStr->getLine();
+ for( int x=0; x<width; ++x)
+ {
+ colorMap->getRGB(p, &rgb);
+ aScanlines.push_back(colToByte(rgb.r));
+ aScanlines.push_back(colToByte(rgb.g));
+ aScanlines.push_back(colToByte(rgb.b));
+ aScanlines.push_back( 0xff );
+
+ p +=colorMap->getNumPixelComps();
+ }
+ }
+
+
+ // now fill in the mask data
+
+ // CAUTION: originally this was done in one single loop
+ // it caused merry chaos; the reason is that maskStr and str are
+ // not independent streams, it happens that reading one advances
+ // the other, too. Hence the two passes are imperative !
+
+ // initialize mask stream
+ ImageStream* imgStrMask =
+ new ImageStream(maskStr,
+ maskWidth,
+ maskColorMap->getNumPixelComps(),
+ maskColorMap->getBits());
+
+ imgStrMask->reset();
+ for( int y = 0; y < maskHeight; ++y )
+ {
+ pm = imgStrMask->getLine();
+ for( int x = 0; x < maskWidth; ++x )
+ {
+ maskColorMap->getGray(pm,&alpha);
+ pm += maskColorMap->getNumPixelComps();
+ int nIndex = (y*height/maskHeight) * (width*4+1) + // mapped line
+ (x*width/maskWidth)*4 + 1 + 3 // mapped column
+ ;
+ aScanlines[ nIndex ] = colToByte(alpha);
+ }
+ }
+
+ delete imgStr;
+ delete imgStrMask;
+
+ // begind IDAT chunk for scanline data
+ size_t nIdx = startChunk( "IDAT", o_rOutputBuf );
+ // compress scanlines
+ deflateBuffer( &aScanlines[0], aScanlines.size(), o_rOutputBuf );
+ // end IDAT chunk
+ endChunk( nIdx, o_rOutputBuf );
+ // output IEND
+ appendIEND( o_rOutputBuf );
+}
+
+// one bit mask; 0 bits opaque
+void PngHelper::createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight,
+ bool maskInvert
+ )
+{
+ appendFileHeader( o_rOutputBuf );
+ appendIHDR( o_rOutputBuf, width, height, 8, 6 ); // RGBA image
+
+ // initialize stream
+ Guchar *p;
+ GfxRGB rgb;
+ ImageStream* imgStr =
+ new ImageStream(str,
+ width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+
+ // create scan line data buffer
+ OutputBuffer aScanlines;
+ aScanlines.reserve( width*height*4 + height );
+
+ for( int y=0; y<height; ++y)
+ {
+ aScanlines.push_back( 0 );
+ p = imgStr->getLine();
+ for( int x=0; x<width; ++x)
+ {
+ colorMap->getRGB(p, &rgb);
+ aScanlines.push_back(colToByte(rgb.r));
+ aScanlines.push_back(colToByte(rgb.g));
+ aScanlines.push_back(colToByte(rgb.b));
+ aScanlines.push_back( 0xff );
+
+ p +=colorMap->getNumPixelComps();
+ }
+ }
+
+
+ // now fill in the mask data
+
+ // CAUTION: originally this was done in one single loop
+ // it caused merry chaos; the reason is that maskStr and str are
+ // not independent streams, it happens that reading one advances
+ // the other, too. Hence the two passes are imperative !
+
+ // initialize mask stream
+ ImageStream* imgStrMask =
+ new ImageStream(maskStr, maskWidth, 1, 1);
+
+ imgStrMask->reset();
+ for( int y = 0; y < maskHeight; ++y )
+ {
+ for( int x = 0; x < maskWidth; ++x )
+ {
+ Guchar aPixel = 0;
+ imgStrMask->getPixel( &aPixel );
+ int nIndex = (y*height/maskHeight) * (width*4+1) + // mapped line
+ (x*width/maskWidth)*4 + 1 + 3 // mapped column
+ ;
+ if( maskInvert )
+ aScanlines[ nIndex ] = aPixel ? 0xff : 0x00;
+ else
+ aScanlines[ nIndex ] = aPixel ? 0x00 : 0xff;
+ }
+ }
+
+ delete imgStr;
+ delete imgStrMask;
+
+ // begind IDAT chunk for scanline data
+ size_t nIdx = startChunk( "IDAT", o_rOutputBuf );
+ // compress scanlines
+ deflateBuffer( &aScanlines[0], aScanlines.size(), o_rOutputBuf );
+ // end IDAT chunk
+ endChunk( nIdx, o_rOutputBuf );
+ // output IEND
+ appendIEND( o_rOutputBuf );
+}
+
diff --git a/sdext/source/pdfimport/xpdfwrapper/pnghelper.hxx b/sdext/source/pdfimport/xpdfwrapper/pnghelper.hxx
new file mode 100644
index 000000000000..34fe4757f382
--- /dev/null
+++ b/sdext/source/pdfimport/xpdfwrapper/pnghelper.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU General Public License Version 2.
+ *
+ *
+ * GNU General Public License, version 2
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ ************************************************************************/
+#ifndef _IPDF_PNGHELPER_HXX
+#define _IPDF_PNGHELPER_HXX
+
+#include "sal/types.h"
+#include "pdfioutdev_gpl.hxx"
+
+
+namespace pdfi
+{
+ class PngHelper
+ {
+ static sal_uInt32 crc_table[ 256 ];
+ static bool bCRCTableInit;
+
+ static void initCRCTable();
+ static void appendFileHeader( OutputBuffer& o_rOutputBuf );
+ static size_t startChunk( const char* pChunkName, OutputBuffer& o_rOut );
+ static void endChunk( size_t nStart, OutputBuffer& o_rOut );
+
+ static void set( sal_uInt32 i_nValue, OutputBuffer& o_rOutputBuf, size_t i_nIndex );
+ static void append( sal_uInt32 i_nValue, OutputBuffer& o_rOutputBuf )
+ {
+ size_t nCur = o_rOutputBuf.size();
+ o_rOutputBuf.insert( o_rOutputBuf.end(), 4, 0 );
+ set( i_nValue, o_rOutputBuf, nCur );
+ }
+
+ static void appendIHDR( OutputBuffer& o_rOutputBuf, int width, int height, int depth, int colortype );
+ static void appendIEND( OutputBuffer& o_rOutputBuf );
+
+ public:
+ static void updateCRC( sal_uInt32& io_rCRC, const sal_uInt8* i_pBuf, size_t i_nLen );
+ static sal_uInt32 getCRC( const sal_uInt8* i_pBuf, size_t i_nLen );
+
+ // deflates the passed buff i_pBuf and appends it to the output vector
+ // returns the number of bytes added to the output
+ static sal_uInt32 deflateBuffer( const Output_t* i_pBuf, size_t i_nLen, OutputBuffer& o_rOut );
+
+ static void createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width,
+ int height,
+ GfxRGB& zeroColor,
+ GfxRGB& oneColor,
+ bool bIsMask
+ );
+ static void createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight, GfxImageColorMap* maskColorMap );
+
+ // for one bit masks
+ static void createPng( OutputBuffer& o_rOutputBuf,
+ Stream* str,
+ int width, int height, GfxImageColorMap* colorMap,
+ Stream* maskStr,
+ int maskWidth, int maskHeight, bool maskInvert );
+
+ };
+}
+
+#endif
diff --git a/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx b/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx
index 687f905e8355..fadf71e2c20e 100644
--- a/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx
+++ b/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx
@@ -49,12 +49,12 @@ static char userPassword[33] = "\001";
static char outputFile[256] = "\001";
static ArgDesc argDesc[] = {
- {"-f", argString, outputFile, sizeof(outputFile),
- "output file for binary streams"},
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
+ {(char*)"-f", argString, outputFile, sizeof(outputFile),
+ (char*)"output file for binary streams"},
+ {(char*)"-opw", argString, ownerPassword, sizeof(ownerPassword),
+ (char*)"owner password (for encrypted files)"},
+ {(char*)"-upw", argString, userPassword, sizeof(userPassword),
+ (char*)"user password (for encrypted files)"},
{NULL, argString, NULL, 0, NULL }
};
#else
@@ -104,7 +104,7 @@ int main(int argc, char **argv)
// read config file
globalParams = new GlobalParams(
#ifndef SYSTEM_POPPLER
- ""
+ (char*)""
#endif
);
globalParams->setErrQuiet(gTrue);
@@ -112,6 +112,23 @@ int main(int argc, char **argv)
globalParams->setupBaseFonts(NULL);
#endif
+ // try to read a possible open password form stdin
+ char aPwBuf[34];
+ aPwBuf[33] = 0;
+ if( ! fgets( aPwBuf, sizeof(aPwBuf)-1, stdin ) )
+ aPwBuf[0] = 0; // mark as empty
+ else
+ {
+ for( unsigned int i = 0; i < sizeof(aPwBuf); i++ )
+ {
+ if( aPwBuf[i] == '\n' )
+ {
+ aPwBuf[i] = 0;
+ break;
+ }
+ }
+ }
+
// PDFDoc takes over ownership for all strings below
GooString* pFileName = new GooString(argv[1]);
GooString* pTempErrFileName = new GooString("_err.pdf");
@@ -121,12 +138,14 @@ int main(int argc, char **argv)
// check for password string(s)
- GooString* pOwnerPasswordStr(
- ownerPassword[0] != '\001' ? new GooString(ownerPassword)
- : (GooString *)NULL );
- GooString* pUserPasswordStr(
- userPassword[0] != '\001' ? new GooString(userPassword)
- : (GooString *)NULL );
+ GooString* pOwnerPasswordStr( ownerPassword[0] != '\001'
+ ? new GooString(ownerPassword)
+ : (GooString *)NULL );
+ GooString* pUserPasswordStr( aPwBuf[0] != 0
+ ? new GooString( aPwBuf )
+ : ( userPassword[0] != '\001'
+ ? new GooString(userPassword)
+ : (GooString *)NULL ) );
if( outputFile[0] != '\001' )
g_binary_out = fopen(outputFile,"wb");
@@ -150,10 +169,7 @@ int main(int argc, char **argv)
!aDoc.okToPrint() ||
!aDoc.okToChange()||
!aDoc.okToCopy()||
- !aDoc.okToAddNotes()||
- (userPassword[0] != '\001')||
- (ownerPassword[0] != '\001')
- )
+ !aDoc.okToAddNotes() )
{
pdfi::PDFOutDev* pOutDev( new pdfi::PDFOutDev(&aErrDoc) );