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