1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_sdext.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "contentsink.hxx" 32*cdf0e10cSrcweir #include "pdfparse.hxx" 33*cdf0e10cSrcweir #include "pdfihelper.hxx" 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include "osl/file.h" 36*cdf0e10cSrcweir #include "osl/thread.h" 37*cdf0e10cSrcweir #include "osl/process.h" 38*cdf0e10cSrcweir #include "osl/diagnose.h" 39*cdf0e10cSrcweir #include "rtl/ustring.hxx" 40*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 41*cdf0e10cSrcweir #include "rtl/strbuf.hxx" 42*cdf0e10cSrcweir #include "rtl/byteseq.hxx" 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx" 45*cdf0e10cSrcweir #include "com/sun/star/io/XInputStream.hpp" 46*cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp" 47*cdf0e10cSrcweir #include "com/sun/star/awt/FontDescriptor.hpp" 48*cdf0e10cSrcweir #include "com/sun/star/deployment/XPackageInformationProvider.hpp" 49*cdf0e10cSrcweir #include "com/sun/star/beans/XMaterialHolder.hpp" 50*cdf0e10cSrcweir #include "com/sun/star/rendering/PathCapType.hpp" 51*cdf0e10cSrcweir #include "com/sun/star/rendering/PathJoinType.hpp" 52*cdf0e10cSrcweir #include "com/sun/star/rendering/XColorSpace.hpp" 53*cdf0e10cSrcweir #include "com/sun/star/rendering/XPolyPolygon2D.hpp" 54*cdf0e10cSrcweir #include "com/sun/star/rendering/XBitmap.hpp" 55*cdf0e10cSrcweir #include "com/sun/star/geometry/Matrix2D.hpp" 56*cdf0e10cSrcweir #include "com/sun/star/geometry/AffineMatrix2D.hpp" 57*cdf0e10cSrcweir #include "com/sun/star/geometry/RealRectangle2D.hpp" 58*cdf0e10cSrcweir #include "com/sun/star/task/XInteractionHandler.hpp" 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir #include "basegfx/point/b2dpoint.hxx" 61*cdf0e10cSrcweir #include "basegfx/polygon/b2dpolypolygon.hxx" 62*cdf0e10cSrcweir #include "basegfx/polygon/b2dpolygon.hxx" 63*cdf0e10cSrcweir #include "basegfx/tools/canvastools.hxx" 64*cdf0e10cSrcweir #include "basegfx/tools/unopolypolygon.hxx" 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir #include <boost/bind.hpp> 67*cdf0e10cSrcweir #include <boost/preprocessor/stringize.hpp> 68*cdf0e10cSrcweir #include <boost/scoped_ptr.hpp> 69*cdf0e10cSrcweir #include <boost/scoped_array.hpp> 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir #include <hash_map> 72*cdf0e10cSrcweir #include <string.h> 73*cdf0e10cSrcweir #ifdef WNT 74*cdf0e10cSrcweir #include <stdlib.h> 75*cdf0e10cSrcweir #include <ctype.h> 76*cdf0e10cSrcweir #endif 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir #include "rtl/bootstrap.h" 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir #include <string.h> // memcmp 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir #ifndef PDFI_IMPL_IDENTIFIER 83*cdf0e10cSrcweir # error define implementation name for pdfi extension, please! 84*cdf0e10cSrcweir #endif 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir using namespace com::sun::star; 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir namespace pdfi 89*cdf0e10cSrcweir { 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir namespace 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir // identifier of the strings coming from the out-of-process xpdf 95*cdf0e10cSrcweir // converter 96*cdf0e10cSrcweir enum parseKey { 97*cdf0e10cSrcweir CLIPPATH, 98*cdf0e10cSrcweir DRAWCHAR, 99*cdf0e10cSrcweir DRAWIMAGE, 100*cdf0e10cSrcweir DRAWLINK, 101*cdf0e10cSrcweir DRAWMASK, 102*cdf0e10cSrcweir DRAWMASKEDIMAGE, 103*cdf0e10cSrcweir DRAWSOFTMASKEDIMAGE, 104*cdf0e10cSrcweir ENDPAGE, 105*cdf0e10cSrcweir ENDTEXTOBJECT, 106*cdf0e10cSrcweir EOCLIPPATH, 107*cdf0e10cSrcweir EOFILLPATH, 108*cdf0e10cSrcweir FILLPATH, 109*cdf0e10cSrcweir HYPERLINK, 110*cdf0e10cSrcweir INTERSECTCLIP, 111*cdf0e10cSrcweir INTERSECTEOCLIP, 112*cdf0e10cSrcweir POPSTATE, 113*cdf0e10cSrcweir PUSHSTATE, 114*cdf0e10cSrcweir RESTORESTATE, 115*cdf0e10cSrcweir SAVESTATE, 116*cdf0e10cSrcweir SETBLENDMODE, 117*cdf0e10cSrcweir SETFILLCOLOR, 118*cdf0e10cSrcweir SETFONT, 119*cdf0e10cSrcweir SETLINECAP, 120*cdf0e10cSrcweir SETLINEDASH, 121*cdf0e10cSrcweir SETLINEJOIN, 122*cdf0e10cSrcweir SETLINEWIDTH, 123*cdf0e10cSrcweir SETMITERLIMIT, 124*cdf0e10cSrcweir SETPAGENUM, 125*cdf0e10cSrcweir SETSTROKECOLOR, 126*cdf0e10cSrcweir SETTEXTRENDERMODE, 127*cdf0e10cSrcweir SETTRANSFORMATION, 128*cdf0e10cSrcweir STARTPAGE, 129*cdf0e10cSrcweir STROKEPATH, 130*cdf0e10cSrcweir UPDATEBLENDMODE, 131*cdf0e10cSrcweir UPDATECTM, 132*cdf0e10cSrcweir UPDATEFILLCOLOR, 133*cdf0e10cSrcweir UPDATEFILLOPACITY, 134*cdf0e10cSrcweir UPDATEFLATNESS, 135*cdf0e10cSrcweir UPDATEFONT, 136*cdf0e10cSrcweir UPDATELINECAP, 137*cdf0e10cSrcweir UPDATELINEDASH, 138*cdf0e10cSrcweir UPDATELINEJOIN, 139*cdf0e10cSrcweir UPDATELINEWIDTH, 140*cdf0e10cSrcweir UPDATEMITERLIMIT, 141*cdf0e10cSrcweir UPDATESTROKECOLOR, 142*cdf0e10cSrcweir UPDATESTROKEOPACITY, 143*cdf0e10cSrcweir NONE 144*cdf0e10cSrcweir }; 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir #include "hash.cxx" 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir class Parser 149*cdf0e10cSrcweir { 150*cdf0e10cSrcweir typedef std::hash_map< sal_Int64, 151*cdf0e10cSrcweir FontAttributes > FontMapType; 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext> m_xContext; 154*cdf0e10cSrcweir const ContentSinkSharedPtr m_pSink; 155*cdf0e10cSrcweir const oslFileHandle m_pErr; 156*cdf0e10cSrcweir ::rtl::OString m_aLine; 157*cdf0e10cSrcweir FontMapType m_aFontMap; 158*cdf0e10cSrcweir sal_Int32 m_nNextToken; 159*cdf0e10cSrcweir sal_Int32 m_nCharIndex; 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir const double minAreaThreshold; 162*cdf0e10cSrcweir const double minLineWidth; 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir ::rtl::OString readNextToken(); 165*cdf0e10cSrcweir void readInt32( sal_Int32& o_Value ); 166*cdf0e10cSrcweir sal_Int32 readInt32(); 167*cdf0e10cSrcweir void readInt64( sal_Int64& o_Value ); 168*cdf0e10cSrcweir void readDouble( double& o_Value ); 169*cdf0e10cSrcweir double readDouble(); 170*cdf0e10cSrcweir void readBinaryData( uno::Sequence<sal_Int8>& rBuf ); 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir uno::Reference<rendering::XPolyPolygon2D> readPath( double* ); 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir void readChar(); 175*cdf0e10cSrcweir void readLineCap(); 176*cdf0e10cSrcweir void readLineDash(); 177*cdf0e10cSrcweir void readLineJoin(); 178*cdf0e10cSrcweir void readTransformation(); 179*cdf0e10cSrcweir rendering::ARGBColor readColor(); 180*cdf0e10cSrcweir void parseFontFamilyName( FontAttributes& aResult ); 181*cdf0e10cSrcweir void readFont(); 182*cdf0e10cSrcweir uno::Sequence<beans::PropertyValue> readImageImpl(); 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir void readImage(); 185*cdf0e10cSrcweir void readMask(); 186*cdf0e10cSrcweir void readLink(); 187*cdf0e10cSrcweir void readMaskedImage(); 188*cdf0e10cSrcweir void readSoftMaskedImage(); 189*cdf0e10cSrcweir int parseFontCheckForString( const sal_Unicode* pCopy, const char* str, sal_Int32& nLen, 190*cdf0e10cSrcweir FontAttributes& aResult, bool bItalic, bool bBold); 191*cdf0e10cSrcweir int parseFontRemoveSuffix( const sal_Unicode* pCopy, const char* s, sal_Int32& nLen); 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir public: 195*cdf0e10cSrcweir Parser( const ContentSinkSharedPtr& rSink, 196*cdf0e10cSrcweir oslFileHandle pErr, 197*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext>& xContext ) : 198*cdf0e10cSrcweir m_xContext(xContext), 199*cdf0e10cSrcweir m_pSink(rSink), 200*cdf0e10cSrcweir m_pErr(pErr), 201*cdf0e10cSrcweir m_aLine(), 202*cdf0e10cSrcweir m_aFontMap(101), 203*cdf0e10cSrcweir m_nNextToken(-1), 204*cdf0e10cSrcweir m_nCharIndex(-1), 205*cdf0e10cSrcweir minAreaThreshold( 300.0 ), 206*cdf0e10cSrcweir minLineWidth( 12 ) 207*cdf0e10cSrcweir {} 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir void parseLine( const ::rtl::OString& rLine ); 210*cdf0e10cSrcweir }; 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir namespace 214*cdf0e10cSrcweir { 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir /** Unescapes line-ending characters in input string. These 217*cdf0e10cSrcweir characters are encoded as pairs of characters: '\\' 'n', resp. 218*cdf0e10cSrcweir '\\' 'r'. This function converts them back to '\n', resp. '\r'. 219*cdf0e10cSrcweir */ 220*cdf0e10cSrcweir rtl::OString lcl_unescapeLineFeeds(const rtl::OString& i_rStr) 221*cdf0e10cSrcweir { 222*cdf0e10cSrcweir const size_t nOrigLen(sal::static_int_cast<size_t>(i_rStr.getLength())); 223*cdf0e10cSrcweir const sal_Char* const pOrig(i_rStr.getStr()); 224*cdf0e10cSrcweir sal_Char* const pBuffer(new sal_Char[nOrigLen + 1]); 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir const sal_Char* pRead(pOrig); 227*cdf0e10cSrcweir sal_Char* pWrite(pBuffer); 228*cdf0e10cSrcweir const sal_Char* pCur(pOrig); 229*cdf0e10cSrcweir while ((pCur = strchr(pCur, '\\')) != 0) 230*cdf0e10cSrcweir { 231*cdf0e10cSrcweir const sal_Char cNext(pCur[1]); 232*cdf0e10cSrcweir if (cNext == 'n' || cNext == 'r' || cNext == '\\') 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir const size_t nLen(pCur - pRead); 235*cdf0e10cSrcweir strncpy(pWrite, pRead, nLen); 236*cdf0e10cSrcweir pWrite += nLen; 237*cdf0e10cSrcweir *pWrite = cNext == 'n' ? '\n' : (cNext == 'r' ? '\r' : '\\'); 238*cdf0e10cSrcweir ++pWrite; 239*cdf0e10cSrcweir pCur = pRead = pCur + 2; 240*cdf0e10cSrcweir } 241*cdf0e10cSrcweir else 242*cdf0e10cSrcweir { 243*cdf0e10cSrcweir // Just continue on the next character. The current 244*cdf0e10cSrcweir // block will be copied the next time it goes through the 245*cdf0e10cSrcweir // 'if' branch. 246*cdf0e10cSrcweir ++pCur; 247*cdf0e10cSrcweir } 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir // maybe there are some data to copy yet 250*cdf0e10cSrcweir if (sal::static_int_cast<size_t>(pRead - pOrig) < nOrigLen) 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir const size_t nLen(nOrigLen - (pRead - pOrig)); 253*cdf0e10cSrcweir strncpy(pWrite, pRead, nLen); 254*cdf0e10cSrcweir pWrite += nLen; 255*cdf0e10cSrcweir } 256*cdf0e10cSrcweir *pWrite = '\0'; 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir rtl::OString aResult(pBuffer); 259*cdf0e10cSrcweir delete[] pBuffer; 260*cdf0e10cSrcweir return aResult; 261*cdf0e10cSrcweir } 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir } 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir ::rtl::OString Parser::readNextToken() 267*cdf0e10cSrcweir { 268*cdf0e10cSrcweir OSL_PRECOND(m_nCharIndex!=-1,"insufficient input"); 269*cdf0e10cSrcweir return m_aLine.getToken(m_nNextToken,' ',m_nCharIndex); 270*cdf0e10cSrcweir } 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir void Parser::readInt32( sal_Int32& o_Value ) 273*cdf0e10cSrcweir { 274*cdf0e10cSrcweir o_Value = readNextToken().toInt32(); 275*cdf0e10cSrcweir } 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir sal_Int32 Parser::readInt32() 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir return readNextToken().toInt32(); 280*cdf0e10cSrcweir } 281*cdf0e10cSrcweir 282*cdf0e10cSrcweir void Parser::readInt64( sal_Int64& o_Value ) 283*cdf0e10cSrcweir { 284*cdf0e10cSrcweir o_Value = readNextToken().toInt64(); 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir void Parser::readDouble( double& o_Value ) 288*cdf0e10cSrcweir { 289*cdf0e10cSrcweir o_Value = readNextToken().toDouble(); 290*cdf0e10cSrcweir } 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir double Parser::readDouble() 293*cdf0e10cSrcweir { 294*cdf0e10cSrcweir return readNextToken().toDouble(); 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir void Parser::readBinaryData( uno::Sequence<sal_Int8>& rBuf ) 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir sal_Int32 nFileLen( rBuf.getLength() ); 300*cdf0e10cSrcweir sal_Int8* pBuf( rBuf.getArray() ); 301*cdf0e10cSrcweir sal_uInt64 nBytesRead(0); 302*cdf0e10cSrcweir oslFileError nRes=osl_File_E_None; 303*cdf0e10cSrcweir while( nFileLen && 304*cdf0e10cSrcweir osl_File_E_None == (nRes=osl_readFile( m_pErr, pBuf, nFileLen, &nBytesRead )) ) 305*cdf0e10cSrcweir { 306*cdf0e10cSrcweir pBuf += nBytesRead; 307*cdf0e10cSrcweir nFileLen -= sal::static_int_cast<sal_Int32>(nBytesRead); 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir OSL_PRECOND(nRes==osl_File_E_None, "inconsistent data"); 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir 313*cdf0e10cSrcweir uno::Reference<rendering::XPolyPolygon2D> Parser::readPath( double* pArea = NULL ) 314*cdf0e10cSrcweir { 315*cdf0e10cSrcweir const rtl::OString aSubPathMarker( "subpath" ); 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir if( 0 != readNextToken().compareTo( aSubPathMarker ) ) 318*cdf0e10cSrcweir OSL_PRECOND(false, "broken path"); 319*cdf0e10cSrcweir 320*cdf0e10cSrcweir basegfx::B2DPolyPolygon aResult; 321*cdf0e10cSrcweir while( m_nCharIndex != -1 ) 322*cdf0e10cSrcweir { 323*cdf0e10cSrcweir basegfx::B2DPolygon aSubPath; 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir sal_Int32 nClosedFlag; 326*cdf0e10cSrcweir readInt32( nClosedFlag ); 327*cdf0e10cSrcweir aSubPath.setClosed( nClosedFlag != 0 ); 328*cdf0e10cSrcweir 329*cdf0e10cSrcweir sal_Int32 nContiguousControlPoints(0); 330*cdf0e10cSrcweir sal_Int32 nDummy=m_nCharIndex; 331*cdf0e10cSrcweir rtl::OString aCurrToken( m_aLine.getToken(m_nNextToken,' ',nDummy) ); 332*cdf0e10cSrcweir 333*cdf0e10cSrcweir while( m_nCharIndex != -1 && 0 != aCurrToken.compareTo(aSubPathMarker) ) 334*cdf0e10cSrcweir { 335*cdf0e10cSrcweir sal_Int32 nCurveFlag; 336*cdf0e10cSrcweir double nX, nY; 337*cdf0e10cSrcweir readDouble( nX ); 338*cdf0e10cSrcweir readDouble( nY ); 339*cdf0e10cSrcweir readInt32( nCurveFlag ); 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir aSubPath.append(basegfx::B2DPoint(nX,nY)); 342*cdf0e10cSrcweir if( nCurveFlag ) 343*cdf0e10cSrcweir { 344*cdf0e10cSrcweir ++nContiguousControlPoints; 345*cdf0e10cSrcweir } 346*cdf0e10cSrcweir else if( nContiguousControlPoints ) 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir OSL_PRECOND(nContiguousControlPoints==2,"broken bezier path"); 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir // have two control points before us. the current one 351*cdf0e10cSrcweir // is a normal point - thus, convert previous points 352*cdf0e10cSrcweir // into bezier segment 353*cdf0e10cSrcweir const sal_uInt32 nPoints( aSubPath.count() ); 354*cdf0e10cSrcweir const basegfx::B2DPoint aCtrlA( aSubPath.getB2DPoint(nPoints-3) ); 355*cdf0e10cSrcweir const basegfx::B2DPoint aCtrlB( aSubPath.getB2DPoint(nPoints-2) ); 356*cdf0e10cSrcweir const basegfx::B2DPoint aEnd( aSubPath.getB2DPoint(nPoints-1) ); 357*cdf0e10cSrcweir aSubPath.remove(nPoints-3, 3); 358*cdf0e10cSrcweir aSubPath.appendBezierSegment(aCtrlA, aCtrlB, aEnd); 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir nContiguousControlPoints=0; 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir 363*cdf0e10cSrcweir // one token look-ahead (new subpath or more points? 364*cdf0e10cSrcweir nDummy=m_nCharIndex; 365*cdf0e10cSrcweir aCurrToken = m_aLine.getToken(m_nNextToken,' ',nDummy); 366*cdf0e10cSrcweir } 367*cdf0e10cSrcweir 368*cdf0e10cSrcweir aResult.append( aSubPath ); 369*cdf0e10cSrcweir if( m_nCharIndex != -1 ) 370*cdf0e10cSrcweir readNextToken(); 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir if( pArea ) 374*cdf0e10cSrcweir { 375*cdf0e10cSrcweir basegfx::B2DRange aRange( aResult.getB2DRange() ); 376*cdf0e10cSrcweir if( aRange.getWidth() <= minLineWidth || aRange.getHeight() <= minLineWidth) 377*cdf0e10cSrcweir *pArea = 0.0; 378*cdf0e10cSrcweir else 379*cdf0e10cSrcweir *pArea = aRange.getWidth() * aRange.getHeight(); 380*cdf0e10cSrcweir } 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir return static_cast<rendering::XLinePolyPolygon2D*>( 383*cdf0e10cSrcweir new basegfx::unotools::UnoPolyPolygon(aResult)); 384*cdf0e10cSrcweir } 385*cdf0e10cSrcweir 386*cdf0e10cSrcweir void Parser::readChar() 387*cdf0e10cSrcweir { 388*cdf0e10cSrcweir geometry::Matrix2D aUnoMatrix; 389*cdf0e10cSrcweir geometry::RealRectangle2D aRect; 390*cdf0e10cSrcweir 391*cdf0e10cSrcweir readDouble(aRect.X1); 392*cdf0e10cSrcweir readDouble(aRect.Y1); 393*cdf0e10cSrcweir readDouble(aRect.X2); 394*cdf0e10cSrcweir readDouble(aRect.Y2); 395*cdf0e10cSrcweir readDouble(aUnoMatrix.m00); 396*cdf0e10cSrcweir readDouble(aUnoMatrix.m01); 397*cdf0e10cSrcweir readDouble(aUnoMatrix.m10); 398*cdf0e10cSrcweir readDouble(aUnoMatrix.m11); 399*cdf0e10cSrcweir 400*cdf0e10cSrcweir rtl::OString aChars = lcl_unescapeLineFeeds( m_aLine.copy( m_nCharIndex ) ); 401*cdf0e10cSrcweir 402*cdf0e10cSrcweir // chars gobble up rest of line 403*cdf0e10cSrcweir m_nCharIndex = -1; 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir m_pSink->drawGlyphs( rtl::OStringToOUString( aChars, 406*cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ), 407*cdf0e10cSrcweir aRect, aUnoMatrix ); 408*cdf0e10cSrcweir } 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir void Parser::readLineCap() 411*cdf0e10cSrcweir { 412*cdf0e10cSrcweir sal_Int8 nCap(rendering::PathCapType::BUTT); 413*cdf0e10cSrcweir switch( readInt32() ) 414*cdf0e10cSrcweir { 415*cdf0e10cSrcweir default: 416*cdf0e10cSrcweir // FALLTHROUGH intended 417*cdf0e10cSrcweir case 0: nCap = rendering::PathCapType::BUTT; break; 418*cdf0e10cSrcweir case 1: nCap = rendering::PathCapType::ROUND; break; 419*cdf0e10cSrcweir case 2: nCap = rendering::PathCapType::SQUARE; break; 420*cdf0e10cSrcweir } 421*cdf0e10cSrcweir m_pSink->setLineCap(nCap); 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir void Parser::readLineDash() 425*cdf0e10cSrcweir { 426*cdf0e10cSrcweir if( m_nCharIndex == -1 ) 427*cdf0e10cSrcweir { 428*cdf0e10cSrcweir m_pSink->setLineDash( uno::Sequence<double>(), 0.0 ); 429*cdf0e10cSrcweir return; 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir const double nOffset(readDouble()); 433*cdf0e10cSrcweir const sal_Int32 nLen(readInt32()); 434*cdf0e10cSrcweir 435*cdf0e10cSrcweir uno::Sequence<double> aDashArray(nLen); 436*cdf0e10cSrcweir double* pArray=aDashArray.getArray(); 437*cdf0e10cSrcweir for( sal_Int32 i=0; i<nLen; ++i ) 438*cdf0e10cSrcweir *pArray++ = readDouble(); 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir m_pSink->setLineDash( aDashArray, nOffset ); 441*cdf0e10cSrcweir } 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir void Parser::readLineJoin() 444*cdf0e10cSrcweir { 445*cdf0e10cSrcweir sal_Int8 nJoin(rendering::PathJoinType::MITER); 446*cdf0e10cSrcweir switch( readInt32() ) 447*cdf0e10cSrcweir { 448*cdf0e10cSrcweir default: 449*cdf0e10cSrcweir // FALLTHROUGH intended 450*cdf0e10cSrcweir case 0: nJoin = rendering::PathJoinType::MITER; break; 451*cdf0e10cSrcweir case 1: nJoin = rendering::PathJoinType::ROUND; break; 452*cdf0e10cSrcweir case 2: nJoin = rendering::PathJoinType::BEVEL; break; 453*cdf0e10cSrcweir } 454*cdf0e10cSrcweir m_pSink->setLineJoin(nJoin); 455*cdf0e10cSrcweir } 456*cdf0e10cSrcweir 457*cdf0e10cSrcweir void Parser::readTransformation() 458*cdf0e10cSrcweir { 459*cdf0e10cSrcweir geometry::AffineMatrix2D aMat; 460*cdf0e10cSrcweir readDouble(aMat.m00); 461*cdf0e10cSrcweir readDouble(aMat.m10); 462*cdf0e10cSrcweir readDouble(aMat.m01); 463*cdf0e10cSrcweir readDouble(aMat.m11); 464*cdf0e10cSrcweir readDouble(aMat.m02); 465*cdf0e10cSrcweir readDouble(aMat.m12); 466*cdf0e10cSrcweir m_pSink->setTransformation( aMat ); 467*cdf0e10cSrcweir } 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir rendering::ARGBColor Parser::readColor() 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir rendering::ARGBColor aRes; 472*cdf0e10cSrcweir readDouble(aRes.Red); 473*cdf0e10cSrcweir readDouble(aRes.Green); 474*cdf0e10cSrcweir readDouble(aRes.Blue); 475*cdf0e10cSrcweir readDouble(aRes.Alpha); 476*cdf0e10cSrcweir return aRes; 477*cdf0e10cSrcweir } 478*cdf0e10cSrcweir 479*cdf0e10cSrcweir int Parser::parseFontCheckForString( const sal_Unicode* pCopy, const char* s, sal_Int32& nLen, 480*cdf0e10cSrcweir FontAttributes& aResult, bool bItalic, bool bBold) 481*cdf0e10cSrcweir { 482*cdf0e10cSrcweir int l = strlen(s); 483*cdf0e10cSrcweir if (nLen < l) 484*cdf0e10cSrcweir return 0; 485*cdf0e10cSrcweir for (int i = 0; i < l; i++) 486*cdf0e10cSrcweir if (tolower(pCopy[i]) != s[i] 487*cdf0e10cSrcweir && toupper(pCopy[i]) != s[i]) 488*cdf0e10cSrcweir return 0; 489*cdf0e10cSrcweir aResult.isItalic = bItalic; 490*cdf0e10cSrcweir aResult.isBold = bBold; 491*cdf0e10cSrcweir nLen -= l; 492*cdf0e10cSrcweir pCopy += l; 493*cdf0e10cSrcweir return l; 494*cdf0e10cSrcweir } 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir int Parser::parseFontRemoveSuffix( const sal_Unicode* pCopy, const char* s, sal_Int32& nLen) 497*cdf0e10cSrcweir { 498*cdf0e10cSrcweir int l = strlen(s); 499*cdf0e10cSrcweir if (nLen < l) 500*cdf0e10cSrcweir return 0; 501*cdf0e10cSrcweir for (int i = 0; i < l; i++) 502*cdf0e10cSrcweir if ( pCopy[nLen - l + i] != s[i] ) 503*cdf0e10cSrcweir return 0; 504*cdf0e10cSrcweir nLen -= l; 505*cdf0e10cSrcweir return l; 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir 508*cdf0e10cSrcweir void Parser::parseFontFamilyName( FontAttributes& aResult ) 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir rtl::OUStringBuffer aNewFamilyName( aResult.familyName.getLength() ); 511*cdf0e10cSrcweir 512*cdf0e10cSrcweir const sal_Unicode* pCopy = aResult.familyName.getStr(); 513*cdf0e10cSrcweir sal_Int32 nLen = aResult.familyName.getLength(); 514*cdf0e10cSrcweir // parse out truetype subsets (e.g. BAAAAA+Thorndale) 515*cdf0e10cSrcweir if( nLen > 8 && pCopy[6] == sal_Unicode('+') ) 516*cdf0e10cSrcweir { 517*cdf0e10cSrcweir pCopy += 7; 518*cdf0e10cSrcweir nLen -= 7; 519*cdf0e10cSrcweir } 520*cdf0e10cSrcweir 521*cdf0e10cSrcweir while( nLen ) 522*cdf0e10cSrcweir { 523*cdf0e10cSrcweir if (parseFontRemoveSuffix( pCopy, "PSMT", nLen)) {} 524*cdf0e10cSrcweir else if (parseFontRemoveSuffix( pCopy, "MT", nLen)) {} 525*cdf0e10cSrcweir 526*cdf0e10cSrcweir if (parseFontCheckForString( pCopy, "Italic", nLen, aResult, true, false)) {} 527*cdf0e10cSrcweir else if (parseFontCheckForString( pCopy, "-Bold", nLen, aResult, false, true)) {} 528*cdf0e10cSrcweir else if (parseFontCheckForString( pCopy, "Bold", nLen, aResult, false, true)) {} 529*cdf0e10cSrcweir else if (parseFontCheckForString( pCopy, "-Roman", nLen, aResult, false, false)) {} 530*cdf0e10cSrcweir else if (parseFontCheckForString( pCopy, "-LightOblique", nLen, aResult, true, false)) {} 531*cdf0e10cSrcweir else if (parseFontCheckForString( pCopy, "-BoldOblique", nLen, aResult, true, true)) {} 532*cdf0e10cSrcweir else if (parseFontCheckForString( pCopy, "-Light", nLen, aResult, false, false)) {} 533*cdf0e10cSrcweir else if (parseFontCheckForString( pCopy, "-Reg", nLen, aResult, false, false)) {} 534*cdf0e10cSrcweir else 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir if( *pCopy != '-' ) 537*cdf0e10cSrcweir aNewFamilyName.append( *pCopy ); 538*cdf0e10cSrcweir pCopy++; 539*cdf0e10cSrcweir nLen--; 540*cdf0e10cSrcweir } 541*cdf0e10cSrcweir } 542*cdf0e10cSrcweir aResult.familyName = aNewFamilyName.makeStringAndClear(); 543*cdf0e10cSrcweir } 544*cdf0e10cSrcweir 545*cdf0e10cSrcweir void Parser::readFont() 546*cdf0e10cSrcweir { 547*cdf0e10cSrcweir ::rtl::OString aFontName; 548*cdf0e10cSrcweir sal_Int64 nFontID; 549*cdf0e10cSrcweir sal_Int32 nIsEmbedded, nIsBold, nIsItalic, nIsUnderline, nFileLen; 550*cdf0e10cSrcweir double nSize; 551*cdf0e10cSrcweir 552*cdf0e10cSrcweir readInt64(nFontID); 553*cdf0e10cSrcweir readInt32(nIsEmbedded); 554*cdf0e10cSrcweir readInt32(nIsBold); 555*cdf0e10cSrcweir readInt32(nIsItalic); 556*cdf0e10cSrcweir readInt32(nIsUnderline); 557*cdf0e10cSrcweir readDouble(nSize); 558*cdf0e10cSrcweir readInt32(nFileLen); 559*cdf0e10cSrcweir 560*cdf0e10cSrcweir nSize = nSize < 0.0 ? -nSize : nSize; 561*cdf0e10cSrcweir aFontName = lcl_unescapeLineFeeds( m_aLine.copy( m_nCharIndex ) ); 562*cdf0e10cSrcweir 563*cdf0e10cSrcweir // name gobbles up rest of line 564*cdf0e10cSrcweir m_nCharIndex = -1; 565*cdf0e10cSrcweir 566*cdf0e10cSrcweir FontMapType::const_iterator pFont( m_aFontMap.find(nFontID) ); 567*cdf0e10cSrcweir if( pFont != m_aFontMap.end() ) 568*cdf0e10cSrcweir { 569*cdf0e10cSrcweir OSL_PRECOND(nFileLen==0,"font data for known font"); 570*cdf0e10cSrcweir FontAttributes aRes(pFont->second); 571*cdf0e10cSrcweir aRes.size = nSize; 572*cdf0e10cSrcweir m_pSink->setFont( aRes ); 573*cdf0e10cSrcweir 574*cdf0e10cSrcweir return; 575*cdf0e10cSrcweir } 576*cdf0e10cSrcweir 577*cdf0e10cSrcweir // yet unknown font - get info and add to map 578*cdf0e10cSrcweir FontAttributes aResult( rtl::OStringToOUString( aFontName, 579*cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ), 580*cdf0e10cSrcweir nIsBold != 0, 581*cdf0e10cSrcweir nIsItalic != 0, 582*cdf0e10cSrcweir nIsUnderline != 0, 583*cdf0e10cSrcweir false, 584*cdf0e10cSrcweir nSize ); 585*cdf0e10cSrcweir 586*cdf0e10cSrcweir // extract textual attributes (bold, italic in the name, etc.) 587*cdf0e10cSrcweir parseFontFamilyName(aResult); 588*cdf0e10cSrcweir // need to read font file? 589*cdf0e10cSrcweir if( nFileLen ) 590*cdf0e10cSrcweir { 591*cdf0e10cSrcweir uno::Sequence<sal_Int8> aFontFile(nFileLen); 592*cdf0e10cSrcweir readBinaryData( aFontFile ); 593*cdf0e10cSrcweir 594*cdf0e10cSrcweir awt::FontDescriptor aFD; 595*cdf0e10cSrcweir uno::Sequence< uno::Any > aArgs(1); 596*cdf0e10cSrcweir aArgs[0] <<= aFontFile; 597*cdf0e10cSrcweir 598*cdf0e10cSrcweir try 599*cdf0e10cSrcweir { 600*cdf0e10cSrcweir uno::Reference< beans::XMaterialHolder > xMat( 601*cdf0e10cSrcweir m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( 602*cdf0e10cSrcweir rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.FontIdentificator" ) ), 603*cdf0e10cSrcweir aArgs, 604*cdf0e10cSrcweir m_xContext ), 605*cdf0e10cSrcweir uno::UNO_QUERY ); 606*cdf0e10cSrcweir if( xMat.is() ) 607*cdf0e10cSrcweir { 608*cdf0e10cSrcweir uno::Any aRes( xMat->getMaterial() ); 609*cdf0e10cSrcweir if( aRes >>= aFD ) 610*cdf0e10cSrcweir { 611*cdf0e10cSrcweir aResult.familyName = aFD.Name; 612*cdf0e10cSrcweir parseFontFamilyName(aResult); 613*cdf0e10cSrcweir aResult.isBold = (aFD.Weight > 100.0); 614*cdf0e10cSrcweir aResult.isItalic = (aFD.Slant == awt::FontSlant_OBLIQUE || 615*cdf0e10cSrcweir aFD.Slant == awt::FontSlant_ITALIC ); 616*cdf0e10cSrcweir aResult.isUnderline = false; 617*cdf0e10cSrcweir aResult.size = 0; 618*cdf0e10cSrcweir } 619*cdf0e10cSrcweir } 620*cdf0e10cSrcweir } 621*cdf0e10cSrcweir catch( uno::Exception& ) 622*cdf0e10cSrcweir { 623*cdf0e10cSrcweir } 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir if( !aResult.familyName.getLength() ) 626*cdf0e10cSrcweir { 627*cdf0e10cSrcweir // last fallback 628*cdf0e10cSrcweir aResult.familyName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Arial" ) ); 629*cdf0e10cSrcweir aResult.isUnderline = false; 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir } 633*cdf0e10cSrcweir m_aFontMap[nFontID] = aResult; 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir aResult.size = nSize; 636*cdf0e10cSrcweir m_pSink->setFont(aResult); 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir uno::Sequence<beans::PropertyValue> Parser::readImageImpl() 640*cdf0e10cSrcweir { 641*cdf0e10cSrcweir static const rtl::OString aJpegMarker( "JPEG" ); 642*cdf0e10cSrcweir static const rtl::OString aPbmMarker( "PBM" ); 643*cdf0e10cSrcweir static const rtl::OString aPpmMarker( "PPM" ); 644*cdf0e10cSrcweir static const rtl::OString aPngMarker( "PNG" ); 645*cdf0e10cSrcweir static const rtl::OUString aJpegFile( 646*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( "DUMMY.JPEG" )); 647*cdf0e10cSrcweir static const rtl::OUString aPbmFile( 648*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( "DUMMY.PBM" )); 649*cdf0e10cSrcweir static const rtl::OUString aPpmFile( 650*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( "DUMMY.PPM" )); 651*cdf0e10cSrcweir static const rtl::OUString aPngFile( 652*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( "DUMMY.PNG" )); 653*cdf0e10cSrcweir 654*cdf0e10cSrcweir rtl::OString aToken = readNextToken(); 655*cdf0e10cSrcweir const sal_Int32 nImageSize( readInt32() ); 656*cdf0e10cSrcweir 657*cdf0e10cSrcweir rtl::OUString aFileName; 658*cdf0e10cSrcweir if( aToken.compareTo( aPngMarker ) == 0 ) 659*cdf0e10cSrcweir aFileName = aPngFile; 660*cdf0e10cSrcweir else if( aToken.compareTo( aJpegMarker ) == 0 ) 661*cdf0e10cSrcweir aFileName = aJpegFile; 662*cdf0e10cSrcweir else if( aToken.compareTo( aPbmMarker ) == 0 ) 663*cdf0e10cSrcweir aFileName = aPbmFile; 664*cdf0e10cSrcweir else 665*cdf0e10cSrcweir { 666*cdf0e10cSrcweir OSL_PRECOND( aToken.compareTo( aPpmMarker ) == 0, 667*cdf0e10cSrcweir "Invalid bitmap format" ); 668*cdf0e10cSrcweir aFileName = aPpmFile; 669*cdf0e10cSrcweir } 670*cdf0e10cSrcweir 671*cdf0e10cSrcweir uno::Sequence<sal_Int8> aDataSequence(nImageSize); 672*cdf0e10cSrcweir readBinaryData( aDataSequence ); 673*cdf0e10cSrcweir 674*cdf0e10cSrcweir uno::Sequence< uno::Any > aStreamCreationArgs(1); 675*cdf0e10cSrcweir aStreamCreationArgs[0] <<= aDataSequence; 676*cdf0e10cSrcweir 677*cdf0e10cSrcweir uno::Reference< uno::XComponentContext > xContext( m_xContext, uno::UNO_SET_THROW ); 678*cdf0e10cSrcweir uno::Reference< lang::XMultiComponentFactory > xFactory( xContext->getServiceManager(), uno::UNO_SET_THROW ); 679*cdf0e10cSrcweir uno::Reference< io::XInputStream > xDataStream( xFactory->createInstanceWithArgumentsAndContext( 680*cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.SequenceInputStream" ) ), 681*cdf0e10cSrcweir aStreamCreationArgs, m_xContext ), uno::UNO_QUERY_THROW ); 682*cdf0e10cSrcweir 683*cdf0e10cSrcweir uno::Sequence<beans::PropertyValue> aSequence(3); 684*cdf0e10cSrcweir aSequence[0] = beans::PropertyValue( ::rtl::OUString::createFromAscii("URL"), 685*cdf0e10cSrcweir 0, 686*cdf0e10cSrcweir uno::makeAny(aFileName), 687*cdf0e10cSrcweir beans::PropertyState_DIRECT_VALUE ); 688*cdf0e10cSrcweir aSequence[1] = beans::PropertyValue( ::rtl::OUString::createFromAscii("InputStream"), 689*cdf0e10cSrcweir 0, 690*cdf0e10cSrcweir uno::makeAny( xDataStream ), 691*cdf0e10cSrcweir beans::PropertyState_DIRECT_VALUE ); 692*cdf0e10cSrcweir aSequence[2] = beans::PropertyValue( ::rtl::OUString::createFromAscii("InputSequence"), 693*cdf0e10cSrcweir 0, 694*cdf0e10cSrcweir uno::makeAny(aDataSequence), 695*cdf0e10cSrcweir beans::PropertyState_DIRECT_VALUE ); 696*cdf0e10cSrcweir 697*cdf0e10cSrcweir return aSequence; 698*cdf0e10cSrcweir } 699*cdf0e10cSrcweir 700*cdf0e10cSrcweir void Parser::readImage() 701*cdf0e10cSrcweir { 702*cdf0e10cSrcweir sal_Int32 nWidth, nHeight,nMaskColors; 703*cdf0e10cSrcweir readInt32(nWidth); 704*cdf0e10cSrcweir readInt32(nHeight); 705*cdf0e10cSrcweir readInt32(nMaskColors); 706*cdf0e10cSrcweir 707*cdf0e10cSrcweir uno::Sequence<beans::PropertyValue> aImg( readImageImpl() ); 708*cdf0e10cSrcweir 709*cdf0e10cSrcweir if( nMaskColors ) 710*cdf0e10cSrcweir { 711*cdf0e10cSrcweir uno::Sequence<sal_Int8> aDataSequence(nMaskColors); 712*cdf0e10cSrcweir readBinaryData( aDataSequence ); 713*cdf0e10cSrcweir 714*cdf0e10cSrcweir uno::Sequence<uno::Any> aMaskRanges(2); 715*cdf0e10cSrcweir 716*cdf0e10cSrcweir uno::Sequence<double> aMinRange(nMaskColors/2); 717*cdf0e10cSrcweir uno::Sequence<double> aMaxRange(nMaskColors/2); 718*cdf0e10cSrcweir for( sal_Int32 i=0; i<nMaskColors/2; ++i ) 719*cdf0e10cSrcweir { 720*cdf0e10cSrcweir aMinRange[i] = aDataSequence[i] / 255.0; 721*cdf0e10cSrcweir aMaxRange[i] = aDataSequence[i+nMaskColors/2] / 255.0; 722*cdf0e10cSrcweir } 723*cdf0e10cSrcweir 724*cdf0e10cSrcweir aMaskRanges[0] = uno::makeAny(aMinRange); 725*cdf0e10cSrcweir aMaskRanges[1] = uno::makeAny(aMaxRange); 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir m_pSink->drawColorMaskedImage( aImg, aMaskRanges ); 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir else 730*cdf0e10cSrcweir m_pSink->drawImage( aImg ); 731*cdf0e10cSrcweir } 732*cdf0e10cSrcweir 733*cdf0e10cSrcweir void Parser::readMask() 734*cdf0e10cSrcweir { 735*cdf0e10cSrcweir sal_Int32 nWidth, nHeight, nInvert; 736*cdf0e10cSrcweir readInt32(nWidth); 737*cdf0e10cSrcweir readInt32(nHeight); 738*cdf0e10cSrcweir readInt32(nInvert); 739*cdf0e10cSrcweir 740*cdf0e10cSrcweir m_pSink->drawMask( readImageImpl(), nInvert ); 741*cdf0e10cSrcweir } 742*cdf0e10cSrcweir 743*cdf0e10cSrcweir void Parser::readLink() 744*cdf0e10cSrcweir { 745*cdf0e10cSrcweir geometry::RealRectangle2D aBounds; 746*cdf0e10cSrcweir readDouble(aBounds.X1); 747*cdf0e10cSrcweir readDouble(aBounds.Y1); 748*cdf0e10cSrcweir readDouble(aBounds.X2); 749*cdf0e10cSrcweir readDouble(aBounds.Y2); 750*cdf0e10cSrcweir 751*cdf0e10cSrcweir m_pSink->hyperLink( aBounds, 752*cdf0e10cSrcweir rtl::OStringToOUString( lcl_unescapeLineFeeds( 753*cdf0e10cSrcweir m_aLine.copy(m_nCharIndex) ), 754*cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ) ); 755*cdf0e10cSrcweir // name gobbles up rest of line 756*cdf0e10cSrcweir m_nCharIndex = -1; 757*cdf0e10cSrcweir } 758*cdf0e10cSrcweir 759*cdf0e10cSrcweir void Parser::readMaskedImage() 760*cdf0e10cSrcweir { 761*cdf0e10cSrcweir sal_Int32 nWidth, nHeight, nMaskWidth, nMaskHeight, nMaskInvert; 762*cdf0e10cSrcweir readInt32(nWidth); 763*cdf0e10cSrcweir readInt32(nHeight); 764*cdf0e10cSrcweir readInt32(nMaskWidth); 765*cdf0e10cSrcweir readInt32(nMaskHeight); 766*cdf0e10cSrcweir readInt32(nMaskInvert); 767*cdf0e10cSrcweir 768*cdf0e10cSrcweir const uno::Sequence<beans::PropertyValue> aImage( readImageImpl() ); 769*cdf0e10cSrcweir const uno::Sequence<beans::PropertyValue> aMask ( readImageImpl() ); 770*cdf0e10cSrcweir m_pSink->drawMaskedImage( aImage, aMask, nMaskInvert != 0 ); 771*cdf0e10cSrcweir } 772*cdf0e10cSrcweir 773*cdf0e10cSrcweir void Parser::readSoftMaskedImage() 774*cdf0e10cSrcweir { 775*cdf0e10cSrcweir sal_Int32 nWidth, nHeight, nMaskWidth, nMaskHeight; 776*cdf0e10cSrcweir readInt32(nWidth); 777*cdf0e10cSrcweir readInt32(nHeight); 778*cdf0e10cSrcweir readInt32(nMaskWidth); 779*cdf0e10cSrcweir readInt32(nMaskHeight); 780*cdf0e10cSrcweir 781*cdf0e10cSrcweir const uno::Sequence<beans::PropertyValue> aImage( readImageImpl() ); 782*cdf0e10cSrcweir const uno::Sequence<beans::PropertyValue> aMask ( readImageImpl() ); 783*cdf0e10cSrcweir m_pSink->drawAlphaMaskedImage( aImage, aMask ); 784*cdf0e10cSrcweir } 785*cdf0e10cSrcweir 786*cdf0e10cSrcweir void Parser::parseLine( const ::rtl::OString& rLine ) 787*cdf0e10cSrcweir { 788*cdf0e10cSrcweir OSL_PRECOND( m_pSink, "Invalid sink" ); 789*cdf0e10cSrcweir OSL_PRECOND( m_pErr, "Invalid filehandle" ); 790*cdf0e10cSrcweir OSL_PRECOND( m_xContext.is(), "Invalid service factory" ); 791*cdf0e10cSrcweir 792*cdf0e10cSrcweir m_nNextToken = 0; m_nCharIndex = 0; m_aLine = rLine; 793*cdf0e10cSrcweir uno::Reference<rendering::XPolyPolygon2D> xPoly; 794*cdf0e10cSrcweir const ::rtl::OString& rCmd = readNextToken(); 795*cdf0e10cSrcweir const hash_entry* pEntry = PdfKeywordHash::in_word_set( rCmd.getStr(), 796*cdf0e10cSrcweir rCmd.getLength() ); 797*cdf0e10cSrcweir OSL_ASSERT(pEntry); 798*cdf0e10cSrcweir switch( pEntry->eKey ) 799*cdf0e10cSrcweir { 800*cdf0e10cSrcweir case CLIPPATH: 801*cdf0e10cSrcweir m_pSink->intersectClip(readPath()); break; 802*cdf0e10cSrcweir case DRAWCHAR: 803*cdf0e10cSrcweir readChar(); break; 804*cdf0e10cSrcweir case DRAWIMAGE: 805*cdf0e10cSrcweir readImage(); break; 806*cdf0e10cSrcweir case DRAWLINK: 807*cdf0e10cSrcweir readLink(); break; 808*cdf0e10cSrcweir case DRAWMASK: 809*cdf0e10cSrcweir readMask(); break; 810*cdf0e10cSrcweir case DRAWMASKEDIMAGE: 811*cdf0e10cSrcweir readMaskedImage(); break; 812*cdf0e10cSrcweir case DRAWSOFTMASKEDIMAGE: 813*cdf0e10cSrcweir readSoftMaskedImage(); break; 814*cdf0e10cSrcweir case ENDPAGE: 815*cdf0e10cSrcweir m_pSink->endPage(); break; 816*cdf0e10cSrcweir case ENDTEXTOBJECT: 817*cdf0e10cSrcweir m_pSink->endText(); break; 818*cdf0e10cSrcweir case EOCLIPPATH: 819*cdf0e10cSrcweir m_pSink->intersectEoClip(readPath()); break; 820*cdf0e10cSrcweir case EOFILLPATH: 821*cdf0e10cSrcweir { 822*cdf0e10cSrcweir double area = 0.0; 823*cdf0e10cSrcweir uno::Reference<rendering::XPolyPolygon2D> path = readPath( &area ); 824*cdf0e10cSrcweir m_pSink->eoFillPath(path); 825*cdf0e10cSrcweir // if area is smaller than required, add borders. 826*cdf0e10cSrcweir if(area < minAreaThreshold) 827*cdf0e10cSrcweir m_pSink->strokePath(path); 828*cdf0e10cSrcweir } 829*cdf0e10cSrcweir break; 830*cdf0e10cSrcweir case FILLPATH: 831*cdf0e10cSrcweir { 832*cdf0e10cSrcweir double area = 0.0; 833*cdf0e10cSrcweir uno::Reference<rendering::XPolyPolygon2D> path = readPath( &area ); 834*cdf0e10cSrcweir m_pSink->fillPath(path); 835*cdf0e10cSrcweir // if area is smaller than required, add borders. 836*cdf0e10cSrcweir if(area < minAreaThreshold) 837*cdf0e10cSrcweir m_pSink->strokePath(path); 838*cdf0e10cSrcweir } 839*cdf0e10cSrcweir break; 840*cdf0e10cSrcweir case RESTORESTATE: 841*cdf0e10cSrcweir m_pSink->popState(); break; 842*cdf0e10cSrcweir case SAVESTATE: 843*cdf0e10cSrcweir m_pSink->pushState(); break; 844*cdf0e10cSrcweir case SETPAGENUM: 845*cdf0e10cSrcweir m_pSink->setPageNum( readInt32() ); break; 846*cdf0e10cSrcweir case STARTPAGE: 847*cdf0e10cSrcweir { 848*cdf0e10cSrcweir const double nWidth ( readDouble() ); 849*cdf0e10cSrcweir const double nHeight( readDouble() ); 850*cdf0e10cSrcweir m_pSink->startPage( geometry::RealSize2D( nWidth, nHeight ) ); 851*cdf0e10cSrcweir break; 852*cdf0e10cSrcweir } 853*cdf0e10cSrcweir case STROKEPATH: 854*cdf0e10cSrcweir m_pSink->strokePath(readPath()); break; 855*cdf0e10cSrcweir case UPDATECTM: 856*cdf0e10cSrcweir readTransformation(); break; 857*cdf0e10cSrcweir case UPDATEFILLCOLOR: 858*cdf0e10cSrcweir m_pSink->setFillColor( readColor() ); break; 859*cdf0e10cSrcweir case UPDATEFLATNESS: 860*cdf0e10cSrcweir m_pSink->setFlatness( readDouble( ) ); break; 861*cdf0e10cSrcweir case UPDATEFONT: 862*cdf0e10cSrcweir readFont(); break; 863*cdf0e10cSrcweir case UPDATELINECAP: 864*cdf0e10cSrcweir readLineCap(); break; 865*cdf0e10cSrcweir case UPDATELINEDASH: 866*cdf0e10cSrcweir readLineDash(); break; 867*cdf0e10cSrcweir case UPDATELINEJOIN: 868*cdf0e10cSrcweir readLineJoin(); break; 869*cdf0e10cSrcweir case UPDATELINEWIDTH: 870*cdf0e10cSrcweir m_pSink->setLineWidth( readDouble() );break; 871*cdf0e10cSrcweir case UPDATEMITERLIMIT: 872*cdf0e10cSrcweir m_pSink->setMiterLimit( readDouble() ); break; 873*cdf0e10cSrcweir case UPDATESTROKECOLOR: 874*cdf0e10cSrcweir m_pSink->setStrokeColor( readColor() ); break; 875*cdf0e10cSrcweir case UPDATESTROKEOPACITY: 876*cdf0e10cSrcweir break; 877*cdf0e10cSrcweir case SETTEXTRENDERMODE: 878*cdf0e10cSrcweir m_pSink->setTextRenderMode( readInt32() ); break; 879*cdf0e10cSrcweir 880*cdf0e10cSrcweir case NONE: 881*cdf0e10cSrcweir default: 882*cdf0e10cSrcweir OSL_PRECOND(false,"Unknown input"); 883*cdf0e10cSrcweir break; 884*cdf0e10cSrcweir } 885*cdf0e10cSrcweir 886*cdf0e10cSrcweir // all consumed? 887*cdf0e10cSrcweir OSL_POSTCOND(m_nCharIndex==-1,"leftover scanner input"); 888*cdf0e10cSrcweir } 889*cdf0e10cSrcweir 890*cdf0e10cSrcweir oslFileError readLine( oslFileHandle pFile, ::rtl::OStringBuffer& line ) 891*cdf0e10cSrcweir { 892*cdf0e10cSrcweir OSL_PRECOND( line.getLength() == 0, "line buf not empty" ); 893*cdf0e10cSrcweir 894*cdf0e10cSrcweir // TODO(P3): read larger chunks 895*cdf0e10cSrcweir sal_Char aChar('\n'); 896*cdf0e10cSrcweir sal_uInt64 nBytesRead; 897*cdf0e10cSrcweir oslFileError nRes; 898*cdf0e10cSrcweir 899*cdf0e10cSrcweir // skip garbage \r \n at start of line 900*cdf0e10cSrcweir while( osl_File_E_None == (nRes=osl_readFile(pFile, &aChar, 1, &nBytesRead)) && 901*cdf0e10cSrcweir nBytesRead == 1 && 902*cdf0e10cSrcweir (aChar == '\n' || aChar == '\r') ) ; 903*cdf0e10cSrcweir 904*cdf0e10cSrcweir if( aChar != '\n' && aChar != '\r' ) 905*cdf0e10cSrcweir line.append( aChar ); 906*cdf0e10cSrcweir 907*cdf0e10cSrcweir while( osl_File_E_None == (nRes=osl_readFile(pFile, &aChar, 1, &nBytesRead)) && 908*cdf0e10cSrcweir nBytesRead == 1 && aChar != '\n' && aChar != '\r' ) 909*cdf0e10cSrcweir { 910*cdf0e10cSrcweir line.append( aChar ); 911*cdf0e10cSrcweir } 912*cdf0e10cSrcweir 913*cdf0e10cSrcweir return nRes; 914*cdf0e10cSrcweir } 915*cdf0e10cSrcweir 916*cdf0e10cSrcweir } // namespace 917*cdf0e10cSrcweir 918*cdf0e10cSrcweir static bool checkEncryption( const rtl::OUString& i_rPath, 919*cdf0e10cSrcweir const uno::Reference< task::XInteractionHandler >& i_xIHdl, 920*cdf0e10cSrcweir rtl::OUString& io_rPwd, 921*cdf0e10cSrcweir bool& o_rIsEncrypted, 922*cdf0e10cSrcweir const rtl::OUString& i_rDocName 923*cdf0e10cSrcweir ) 924*cdf0e10cSrcweir { 925*cdf0e10cSrcweir bool bSuccess = false; 926*cdf0e10cSrcweir rtl::OString aPDFFile; 927*cdf0e10cSrcweir aPDFFile = rtl::OUStringToOString( i_rPath, osl_getThreadTextEncoding() ); 928*cdf0e10cSrcweir 929*cdf0e10cSrcweir pdfparse::PDFReader aParser; 930*cdf0e10cSrcweir boost::scoped_ptr<pdfparse::PDFEntry> pEntry( aParser.read( aPDFFile.getStr() )); 931*cdf0e10cSrcweir if( pEntry ) 932*cdf0e10cSrcweir { 933*cdf0e10cSrcweir pdfparse::PDFFile* pPDFFile = dynamic_cast<pdfparse::PDFFile*>(pEntry.get()); 934*cdf0e10cSrcweir if( pPDFFile ) 935*cdf0e10cSrcweir { 936*cdf0e10cSrcweir o_rIsEncrypted = pPDFFile->isEncrypted(); 937*cdf0e10cSrcweir if( o_rIsEncrypted ) 938*cdf0e10cSrcweir { 939*cdf0e10cSrcweir bool bAuthenticated = false; 940*cdf0e10cSrcweir if( io_rPwd.getLength() ) 941*cdf0e10cSrcweir { 942*cdf0e10cSrcweir rtl::OString aIsoPwd = rtl::OUStringToOString( io_rPwd, 943*cdf0e10cSrcweir RTL_TEXTENCODING_ISO_8859_1 ); 944*cdf0e10cSrcweir bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() ); 945*cdf0e10cSrcweir // trash password string on heap 946*cdf0e10cSrcweir rtl_zeroMemory( (void*)aIsoPwd.getStr(), aIsoPwd.getLength() ); 947*cdf0e10cSrcweir } 948*cdf0e10cSrcweir if( bAuthenticated ) 949*cdf0e10cSrcweir bSuccess = true; 950*cdf0e10cSrcweir else 951*cdf0e10cSrcweir { 952*cdf0e10cSrcweir if( i_xIHdl.is() ) 953*cdf0e10cSrcweir { 954*cdf0e10cSrcweir bool bEntered = false; 955*cdf0e10cSrcweir do 956*cdf0e10cSrcweir { 957*cdf0e10cSrcweir bEntered = getPassword( i_xIHdl, io_rPwd, ! bEntered, i_rDocName ); 958*cdf0e10cSrcweir rtl::OString aIsoPwd = rtl::OUStringToOString( io_rPwd, 959*cdf0e10cSrcweir RTL_TEXTENCODING_ISO_8859_1 ); 960*cdf0e10cSrcweir bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() ); 961*cdf0e10cSrcweir // trash password string on heap 962*cdf0e10cSrcweir rtl_zeroMemory( (void*)aIsoPwd.getStr(), aIsoPwd.getLength() ); 963*cdf0e10cSrcweir } while( bEntered && ! bAuthenticated ); 964*cdf0e10cSrcweir } 965*cdf0e10cSrcweir 966*cdf0e10cSrcweir OSL_TRACE( "password: %s\n", bAuthenticated ? "matches" : "does not match" ); 967*cdf0e10cSrcweir bSuccess = bAuthenticated; 968*cdf0e10cSrcweir } 969*cdf0e10cSrcweir // trash password string on heap 970*cdf0e10cSrcweir rtl_zeroMemory( (void*)io_rPwd.getStr(), io_rPwd.getLength()*sizeof(sal_Unicode) ); 971*cdf0e10cSrcweir if( bAuthenticated ) 972*cdf0e10cSrcweir { 973*cdf0e10cSrcweir rtl::OUStringBuffer aBuf( 128 ); 974*cdf0e10cSrcweir aBuf.appendAscii( "_OOO_pdfi_Credentials_" ); 975*cdf0e10cSrcweir aBuf.append( pPDFFile->getDecryptionKey() ); 976*cdf0e10cSrcweir io_rPwd = aBuf.makeStringAndClear(); 977*cdf0e10cSrcweir } 978*cdf0e10cSrcweir } 979*cdf0e10cSrcweir else 980*cdf0e10cSrcweir bSuccess = true; 981*cdf0e10cSrcweir } 982*cdf0e10cSrcweir } 983*cdf0e10cSrcweir return bSuccess; 984*cdf0e10cSrcweir } 985*cdf0e10cSrcweir 986*cdf0e10cSrcweir bool xpdf_ImportFromFile( const ::rtl::OUString& rURL, 987*cdf0e10cSrcweir const ContentSinkSharedPtr& rSink, 988*cdf0e10cSrcweir const uno::Reference< task::XInteractionHandler >& xIHdl, 989*cdf0e10cSrcweir const rtl::OUString& rPwd, 990*cdf0e10cSrcweir const uno::Reference< uno::XComponentContext >& xContext ) 991*cdf0e10cSrcweir { 992*cdf0e10cSrcweir OSL_ASSERT(rSink); 993*cdf0e10cSrcweir 994*cdf0e10cSrcweir ::rtl::OUString aSysUPath; 995*cdf0e10cSrcweir if( osl_getSystemPathFromFileURL( rURL.pData, &aSysUPath.pData ) != osl_File_E_None ) 996*cdf0e10cSrcweir return false; 997*cdf0e10cSrcweir rtl::OUString aDocName( rURL.copy( rURL.lastIndexOf( sal_Unicode('/') )+1 ) ); 998*cdf0e10cSrcweir 999*cdf0e10cSrcweir // check for encryption, if necessary get password 1000*cdf0e10cSrcweir rtl::OUString aPwd( rPwd ); 1001*cdf0e10cSrcweir bool bIsEncrypted = false; 1002*cdf0e10cSrcweir if( checkEncryption( aSysUPath, xIHdl, aPwd, bIsEncrypted, aDocName ) == false ) 1003*cdf0e10cSrcweir return false; 1004*cdf0e10cSrcweir 1005*cdf0e10cSrcweir rtl::OUStringBuffer converterURL = rtl::OUString::createFromAscii("xpdfimport"); 1006*cdf0e10cSrcweir 1007*cdf0e10cSrcweir // retrieve package location url (xpdfimport executable is located there) 1008*cdf0e10cSrcweir // --------------------------------------------------- 1009*cdf0e10cSrcweir uno::Reference<deployment::XPackageInformationProvider> xProvider( 1010*cdf0e10cSrcweir xContext->getValueByName( 1011*cdf0e10cSrcweir rtl::OUString::createFromAscii("/singletons/com.sun.star.deployment.PackageInformationProvider" )), 1012*cdf0e10cSrcweir uno::UNO_QUERY); 1013*cdf0e10cSrcweir if( xProvider.is() ) 1014*cdf0e10cSrcweir { 1015*cdf0e10cSrcweir converterURL.insert( 1016*cdf0e10cSrcweir 0, 1017*cdf0e10cSrcweir rtl::OUString::createFromAscii("/")); 1018*cdf0e10cSrcweir converterURL.insert( 1019*cdf0e10cSrcweir 0, 1020*cdf0e10cSrcweir xProvider->getPackageLocation( 1021*cdf0e10cSrcweir rtl::OUString::createFromAscii( 1022*cdf0e10cSrcweir BOOST_PP_STRINGIZE(PDFI_IMPL_IDENTIFIER)))); 1023*cdf0e10cSrcweir } 1024*cdf0e10cSrcweir 1025*cdf0e10cSrcweir // spawn separate process to keep LGPL/GPL code apart. 1026*cdf0e10cSrcweir // --------------------------------------------------- 1027*cdf0e10cSrcweir rtl_uString** ppEnv = NULL; 1028*cdf0e10cSrcweir sal_uInt32 nEnv = 0; 1029*cdf0e10cSrcweir 1030*cdf0e10cSrcweir #if defined UNX && ! defined MACOSX 1031*cdf0e10cSrcweir rtl::OUString aStr( RTL_CONSTASCII_USTRINGPARAM( "$URE_LIB_DIR" ) ); 1032*cdf0e10cSrcweir rtl_bootstrap_expandMacros( &aStr.pData ); 1033*cdf0e10cSrcweir rtl::OUString aSysPath; 1034*cdf0e10cSrcweir osl_getSystemPathFromFileURL( aStr.pData, &aSysPath.pData ); 1035*cdf0e10cSrcweir rtl::OUStringBuffer aEnvBuf( aStr.getLength() + 20 ); 1036*cdf0e10cSrcweir aEnvBuf.appendAscii( "LD_LIBRARY_PATH=" ); 1037*cdf0e10cSrcweir aEnvBuf.append( aSysPath ); 1038*cdf0e10cSrcweir aStr = aEnvBuf.makeStringAndClear(); 1039*cdf0e10cSrcweir ppEnv = &aStr.pData; 1040*cdf0e10cSrcweir nEnv = 1; 1041*cdf0e10cSrcweir #endif 1042*cdf0e10cSrcweir 1043*cdf0e10cSrcweir rtl_uString* args[] = { aSysUPath.pData }; 1044*cdf0e10cSrcweir sal_Int32 nArgs = 1; 1045*cdf0e10cSrcweir 1046*cdf0e10cSrcweir oslProcess aProcess; 1047*cdf0e10cSrcweir oslFileHandle pIn = NULL; 1048*cdf0e10cSrcweir oslFileHandle pOut = NULL; 1049*cdf0e10cSrcweir oslFileHandle pErr = NULL; 1050*cdf0e10cSrcweir const oslProcessError eErr = 1051*cdf0e10cSrcweir osl_executeProcess_WithRedirectedIO(converterURL.makeStringAndClear().pData, 1052*cdf0e10cSrcweir args, 1053*cdf0e10cSrcweir nArgs, 1054*cdf0e10cSrcweir osl_Process_SEARCHPATH|osl_Process_HIDDEN, 1055*cdf0e10cSrcweir osl_getCurrentSecurity(), 1056*cdf0e10cSrcweir 0, ppEnv, nEnv, 1057*cdf0e10cSrcweir &aProcess, &pIn, &pOut, &pErr); 1058*cdf0e10cSrcweir 1059*cdf0e10cSrcweir bool bRet=true; 1060*cdf0e10cSrcweir try 1061*cdf0e10cSrcweir { 1062*cdf0e10cSrcweir if( eErr!=osl_Process_E_None ) 1063*cdf0e10cSrcweir return false; 1064*cdf0e10cSrcweir 1065*cdf0e10cSrcweir if( pIn ) 1066*cdf0e10cSrcweir { 1067*cdf0e10cSrcweir rtl::OStringBuffer aBuf(256); 1068*cdf0e10cSrcweir if( bIsEncrypted ) 1069*cdf0e10cSrcweir aBuf.append( rtl::OUStringToOString( aPwd, RTL_TEXTENCODING_ISO_8859_1 ) ); 1070*cdf0e10cSrcweir aBuf.append( '\n' ); 1071*cdf0e10cSrcweir 1072*cdf0e10cSrcweir sal_uInt64 nWritten = 0; 1073*cdf0e10cSrcweir osl_writeFile( pIn, aBuf.getStr(), sal_uInt64(aBuf.getLength()), &nWritten ); 1074*cdf0e10cSrcweir } 1075*cdf0e10cSrcweir 1076*cdf0e10cSrcweir if( pOut && pErr ) 1077*cdf0e10cSrcweir { 1078*cdf0e10cSrcweir // read results of PDF parser. One line - one call to 1079*cdf0e10cSrcweir // OutputDev. stderr is used for alternate streams, like 1080*cdf0e10cSrcweir // embedded fonts and bitmaps 1081*cdf0e10cSrcweir Parser aParser(rSink,pErr,xContext); 1082*cdf0e10cSrcweir ::rtl::OStringBuffer line; 1083*cdf0e10cSrcweir while( osl_File_E_None == readLine(pOut, line) && line.getLength() ) 1084*cdf0e10cSrcweir aParser.parseLine(line.makeStringAndClear()); 1085*cdf0e10cSrcweir } 1086*cdf0e10cSrcweir } 1087*cdf0e10cSrcweir catch( uno::Exception& ) 1088*cdf0e10cSrcweir { 1089*cdf0e10cSrcweir // crappy C file interface. need manual resource dealloc 1090*cdf0e10cSrcweir bRet = false; 1091*cdf0e10cSrcweir } 1092*cdf0e10cSrcweir 1093*cdf0e10cSrcweir if( pIn ) 1094*cdf0e10cSrcweir osl_closeFile(pIn); 1095*cdf0e10cSrcweir if( pOut ) 1096*cdf0e10cSrcweir osl_closeFile(pOut); 1097*cdf0e10cSrcweir if( pErr ) 1098*cdf0e10cSrcweir osl_closeFile(pErr); 1099*cdf0e10cSrcweir osl_freeProcessHandle(aProcess); 1100*cdf0e10cSrcweir return bRet; 1101*cdf0e10cSrcweir } 1102*cdf0e10cSrcweir 1103*cdf0e10cSrcweir 1104*cdf0e10cSrcweir bool xpdf_ImportFromStream( const uno::Reference< io::XInputStream >& xInput, 1105*cdf0e10cSrcweir const ContentSinkSharedPtr& rSink, 1106*cdf0e10cSrcweir const uno::Reference<task::XInteractionHandler >& xIHdl, 1107*cdf0e10cSrcweir const rtl::OUString& rPwd, 1108*cdf0e10cSrcweir const uno::Reference< uno::XComponentContext >& xContext ) 1109*cdf0e10cSrcweir { 1110*cdf0e10cSrcweir OSL_ASSERT(xInput.is()); 1111*cdf0e10cSrcweir OSL_ASSERT(rSink); 1112*cdf0e10cSrcweir 1113*cdf0e10cSrcweir // convert XInputStream to local temp file 1114*cdf0e10cSrcweir oslFileHandle aFile = NULL; 1115*cdf0e10cSrcweir rtl::OUString aURL; 1116*cdf0e10cSrcweir if( osl_createTempFile( NULL, &aFile, &aURL.pData ) != osl_File_E_None ) 1117*cdf0e10cSrcweir return false; 1118*cdf0e10cSrcweir 1119*cdf0e10cSrcweir // copy content, buffered... 1120*cdf0e10cSrcweir const sal_uInt32 nBufSize = 4096; 1121*cdf0e10cSrcweir uno::Sequence<sal_Int8> aBuf( nBufSize ); 1122*cdf0e10cSrcweir sal_uInt64 nBytes = 0; 1123*cdf0e10cSrcweir sal_uInt64 nWritten = 0; 1124*cdf0e10cSrcweir bool bSuccess = true; 1125*cdf0e10cSrcweir do 1126*cdf0e10cSrcweir { 1127*cdf0e10cSrcweir try 1128*cdf0e10cSrcweir { 1129*cdf0e10cSrcweir nBytes = xInput->readBytes( aBuf, nBufSize ); 1130*cdf0e10cSrcweir } 1131*cdf0e10cSrcweir catch( com::sun::star::uno::Exception& ) 1132*cdf0e10cSrcweir { 1133*cdf0e10cSrcweir osl_closeFile( aFile ); 1134*cdf0e10cSrcweir throw; 1135*cdf0e10cSrcweir } 1136*cdf0e10cSrcweir if( nBytes > 0 ) 1137*cdf0e10cSrcweir { 1138*cdf0e10cSrcweir osl_writeFile( aFile, aBuf.getConstArray(), nBytes, &nWritten ); 1139*cdf0e10cSrcweir if( nWritten != nBytes ) 1140*cdf0e10cSrcweir { 1141*cdf0e10cSrcweir bSuccess = false; 1142*cdf0e10cSrcweir break; 1143*cdf0e10cSrcweir } 1144*cdf0e10cSrcweir } 1145*cdf0e10cSrcweir } 1146*cdf0e10cSrcweir while( nBytes == nBufSize ); 1147*cdf0e10cSrcweir 1148*cdf0e10cSrcweir osl_closeFile( aFile ); 1149*cdf0e10cSrcweir 1150*cdf0e10cSrcweir return bSuccess && xpdf_ImportFromFile( aURL, rSink, xIHdl, rPwd, xContext ); 1151*cdf0e10cSrcweir } 1152*cdf0e10cSrcweir 1153*cdf0e10cSrcweir } 1154*cdf0e10cSrcweir 1155