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