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