1c142477cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3c142477cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4c142477cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5c142477cSAndrew Rist  * distributed with this work for additional information
6c142477cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7c142477cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8c142477cSAndrew Rist  * "License"); you may not use this file except in compliance
9c142477cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10c142477cSAndrew Rist  *
11c142477cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12c142477cSAndrew Rist  *
13c142477cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14c142477cSAndrew Rist  * software distributed under the License is distributed on an
15c142477cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16c142477cSAndrew Rist  * KIND, either express or implied.  See the License for the
17c142477cSAndrew Rist  * specific language governing permissions and limitations
18c142477cSAndrew Rist  * under the License.
19c142477cSAndrew Rist  *
20c142477cSAndrew Rist  *************************************************************/
21c142477cSAndrew Rist 
22c142477cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sdext.hxx"
26cdf0e10cSrcweir 
27*b63233d8Sdamjan #define BASEGFX_STATICLIBRARY
28*b63233d8Sdamjan 
29cdf0e10cSrcweir #ifdef SYSTEM_ZLIB
30cdf0e10cSrcweir #include "zlib.h"
31cdf0e10cSrcweir #else
32cdf0e10cSrcweir #include <zlib/zlib.h>
33cdf0e10cSrcweir #endif
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include "outputwrap.hxx"
36cdf0e10cSrcweir #include "contentsink.hxx"
37cdf0e10cSrcweir #include "pdfihelper.hxx"
38cdf0e10cSrcweir #include "wrapper.hxx"
39cdf0e10cSrcweir #include "pdfparse.hxx"
40cdf0e10cSrcweir #include "../pdfiadaptor.hxx"
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <rtl/math.hxx>
43cdf0e10cSrcweir #include <osl/file.hxx>
44cdf0e10cSrcweir #include <osl/process.h>
4574e62aedSDamjan Jovanovic #include <gtest/gtest.h>
46cdf0e10cSrcweir #include <cppuhelper/compbase1.hxx>
47cdf0e10cSrcweir #include <cppuhelper/bootstrap.hxx>
48cdf0e10cSrcweir #include <cppuhelper/basemutex.hxx>
49cdf0e10cSrcweir #include <comphelper/sequence.hxx>
50cdf0e10cSrcweir 
51cdf0e10cSrcweir 
52cdf0e10cSrcweir #include <com/sun/star/rendering/XCanvas.hpp>
53cdf0e10cSrcweir #include <com/sun/star/rendering/XColorSpace.hpp>
54cdf0e10cSrcweir #include <com/sun/star/rendering/PathJoinType.hpp>
55cdf0e10cSrcweir #include <com/sun/star/rendering/PathCapType.hpp>
56cdf0e10cSrcweir #include <com/sun/star/rendering/BlendMode.hpp>
57cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
58cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
59cdf0e10cSrcweir #include <com/sun/star/registry/XSimpleRegistry.hpp>
60cdf0e10cSrcweir 
61cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
62cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx>
63cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
64cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx>
65cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx>
66cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygonclipper.hxx>
67cdf0e10cSrcweir 
68cdf0e10cSrcweir #include <vector>
69cdf0e10cSrcweir #include <hash_map>
70cdf0e10cSrcweir 
71cdf0e10cSrcweir 
72cdf0e10cSrcweir using namespace ::pdfparse;
73cdf0e10cSrcweir using namespace ::pdfi;
74cdf0e10cSrcweir using namespace ::com::sun::star;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir namespace
77cdf0e10cSrcweir {
78cdf0e10cSrcweir     class TestSink : public ContentSink
79cdf0e10cSrcweir     {
80cdf0e10cSrcweir     public:
TestSink()81cdf0e10cSrcweir         TestSink() :
82cdf0e10cSrcweir             m_nNextFontId( 1 ),
83cdf0e10cSrcweir             m_aIdToFont(),
84cdf0e10cSrcweir             m_aFontToId(),
85cdf0e10cSrcweir             m_aGCStack(1),
86cdf0e10cSrcweir             m_aPageSize(),
87cdf0e10cSrcweir             m_aHyperlinkBounds(),
88cdf0e10cSrcweir             m_aURI(),
89cdf0e10cSrcweir             m_aTextOut(),
90cdf0e10cSrcweir             m_nNumPages(0),
91cdf0e10cSrcweir             m_bPageEnded(false),
92cdf0e10cSrcweir             m_bRedCircleSeen(false),
93cdf0e10cSrcweir             m_bGreenStrokeSeen(false),
94cdf0e10cSrcweir             m_bDashedLineSeen(false)
95cdf0e10cSrcweir         {}
96cdf0e10cSrcweir 
~TestSink()97cdf0e10cSrcweir         ~TestSink()
98cdf0e10cSrcweir         {
9974e62aedSDamjan Jovanovic             ASSERT_TRUE(m_aPageSize.Width == 79400 && m_aPageSize.Height == 59500) << "A4 page size (in 100th of points)";
10074e62aedSDamjan Jovanovic             ASSERT_TRUE(m_bPageEnded) << "endPage() called";
10174e62aedSDamjan Jovanovic             ASSERT_TRUE(m_nNumPages == 1) << "Num pages equal one";
10274e62aedSDamjan Jovanovic             ASSERT_TRUE(rtl::math::approxEqual(m_aHyperlinkBounds.X1,34.7 ) &&
103cdf0e10cSrcweir                                     rtl::math::approxEqual(m_aHyperlinkBounds.Y1,386.0) &&
104cdf0e10cSrcweir                                     rtl::math::approxEqual(m_aHyperlinkBounds.X2,166.7) &&
10574e62aedSDamjan Jovanovic                                     rtl::math::approxEqual(m_aHyperlinkBounds.Y2,406.2)) << "Correct hyperlink bounding box";
10674e62aedSDamjan Jovanovic             ASSERT_TRUE(m_aURI == ::rtl::OUString::createFromAscii( "http://download.openoffice.org/" )) << "Correct hyperlink URI";
107cdf0e10cSrcweir 
108cdf0e10cSrcweir             const char* sText = " \n \nThis is a testtext\nNew paragraph,\nnew line\n"
109cdf0e10cSrcweir                 "Hyperlink, this is\n?\nThis is more text\noutline mode\n?\nNew paragraph\n";
110cdf0e10cSrcweir             ::rtl::OString aTmp;
111cdf0e10cSrcweir             m_aTextOut.makeStringAndClear().convertToString( &aTmp,
112cdf0e10cSrcweir                                                              RTL_TEXTENCODING_ASCII_US,
113cdf0e10cSrcweir                                                              OUSTRING_TO_OSTRING_CVTFLAGS );
11474e62aedSDamjan Jovanovic             ASSERT_TRUE( sText == aTmp ) << "Imported text is \"This is a testtext New paragraph, new line"
11574e62aedSDamjan Jovanovic                                     " Hyperlink, this is * This is more text outline mode * New paragraph\"";
116cdf0e10cSrcweir 
11774e62aedSDamjan Jovanovic             ASSERT_TRUE(m_bRedCircleSeen) << "red circle seen in input";
11874e62aedSDamjan Jovanovic             ASSERT_TRUE(m_bGreenStrokeSeen) << "green stroke seen in input";
11974e62aedSDamjan Jovanovic             ASSERT_TRUE(m_bDashedLineSeen) << "dashed line seen in input";
120cdf0e10cSrcweir         }
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     private:
getCurrentContext()123cdf0e10cSrcweir         GraphicsContext& getCurrentContext() { return m_aGCStack.back(); }
124cdf0e10cSrcweir 
125cdf0e10cSrcweir         // ContentSink interface implementation
setPageNum(sal_Int32 nNumPages)126cdf0e10cSrcweir         virtual void setPageNum( sal_Int32 nNumPages )
127cdf0e10cSrcweir         {
128cdf0e10cSrcweir             m_nNumPages = nNumPages;
129cdf0e10cSrcweir         }
130cdf0e10cSrcweir 
startPage(const geometry::RealSize2D & rSize)131cdf0e10cSrcweir         virtual void startPage( const geometry::RealSize2D& rSize )
132cdf0e10cSrcweir         {
133cdf0e10cSrcweir             m_aPageSize = rSize;
134cdf0e10cSrcweir         }
135cdf0e10cSrcweir 
endPage()136cdf0e10cSrcweir         virtual void endPage()
137cdf0e10cSrcweir         {
138cdf0e10cSrcweir             m_bPageEnded = true;
139cdf0e10cSrcweir         }
140cdf0e10cSrcweir 
hyperLink(const geometry::RealRectangle2D & rBounds,const::rtl::OUString & rURI)141cdf0e10cSrcweir         virtual void hyperLink( const geometry::RealRectangle2D& rBounds,
142cdf0e10cSrcweir                                 const ::rtl::OUString&             rURI )
143cdf0e10cSrcweir         {
144cdf0e10cSrcweir             m_aHyperlinkBounds = rBounds;
145cdf0e10cSrcweir             m_aURI = rURI;
146cdf0e10cSrcweir         }
147cdf0e10cSrcweir 
pushState()148cdf0e10cSrcweir         virtual void pushState()
149cdf0e10cSrcweir         {
150cdf0e10cSrcweir             m_aGCStack.push_back( m_aGCStack.back() );
151cdf0e10cSrcweir         }
152cdf0e10cSrcweir 
popState()153cdf0e10cSrcweir         virtual void popState()
154cdf0e10cSrcweir         {
155cdf0e10cSrcweir             m_aGCStack.pop_back();
156cdf0e10cSrcweir         }
157cdf0e10cSrcweir 
setTransformation(const geometry::AffineMatrix2D & rMatrix)158cdf0e10cSrcweir         virtual void setTransformation( const geometry::AffineMatrix2D& rMatrix )
159cdf0e10cSrcweir         {
160cdf0e10cSrcweir             basegfx::unotools::homMatrixFromAffineMatrix(
161cdf0e10cSrcweir                 getCurrentContext().Transformation,
162cdf0e10cSrcweir                 rMatrix );
163cdf0e10cSrcweir         }
164cdf0e10cSrcweir 
setLineDash(const uno::Sequence<double> & dashes,double start)165cdf0e10cSrcweir         virtual void setLineDash( const uno::Sequence<double>& dashes,
166cdf0e10cSrcweir                                   double                       start )
167cdf0e10cSrcweir         {
168cdf0e10cSrcweir             GraphicsContext& rContext( getCurrentContext() );
169cdf0e10cSrcweir             if( dashes.getLength() )
170cdf0e10cSrcweir                 comphelper::sequenceToContainer(rContext.DashArray,dashes);
17174e62aedSDamjan Jovanovic             ASSERT_TRUE(start == 0.0) << "line dashing start offset";
172cdf0e10cSrcweir         }
173cdf0e10cSrcweir 
setFlatness(double nFlatness)174cdf0e10cSrcweir         virtual void setFlatness( double nFlatness )
175cdf0e10cSrcweir         {
176cdf0e10cSrcweir             getCurrentContext().Flatness = nFlatness;
177cdf0e10cSrcweir         }
178cdf0e10cSrcweir 
setLineJoin(sal_Int8 nJoin)179cdf0e10cSrcweir         virtual void setLineJoin(sal_Int8 nJoin)
180cdf0e10cSrcweir         {
181cdf0e10cSrcweir             getCurrentContext().LineJoin = nJoin;
182cdf0e10cSrcweir         }
183cdf0e10cSrcweir 
setLineCap(sal_Int8 nCap)184cdf0e10cSrcweir         virtual void setLineCap(sal_Int8 nCap)
185cdf0e10cSrcweir         {
186cdf0e10cSrcweir             getCurrentContext().LineCap = nCap;
187cdf0e10cSrcweir         }
188cdf0e10cSrcweir 
setMiterLimit(double nVal)189cdf0e10cSrcweir         virtual void setMiterLimit(double nVal)
190cdf0e10cSrcweir         {
191cdf0e10cSrcweir             getCurrentContext().MiterLimit = nVal;
192cdf0e10cSrcweir         }
193cdf0e10cSrcweir 
setLineWidth(double nVal)194cdf0e10cSrcweir         virtual void setLineWidth(double nVal)
195cdf0e10cSrcweir         {
196cdf0e10cSrcweir             getCurrentContext().LineWidth = nVal;
197cdf0e10cSrcweir         }
198cdf0e10cSrcweir 
setFillColor(const rendering::ARGBColor & rColor)199cdf0e10cSrcweir         virtual void setFillColor( const rendering::ARGBColor& rColor )
200cdf0e10cSrcweir         {
201cdf0e10cSrcweir             getCurrentContext().FillColor = rColor;
202cdf0e10cSrcweir         }
203cdf0e10cSrcweir 
setStrokeColor(const rendering::ARGBColor & rColor)204cdf0e10cSrcweir         virtual void setStrokeColor( const rendering::ARGBColor& rColor )
205cdf0e10cSrcweir         {
206cdf0e10cSrcweir             getCurrentContext().LineColor = rColor;
207cdf0e10cSrcweir         }
208cdf0e10cSrcweir 
setBlendMode(sal_Int8 nMode)209cdf0e10cSrcweir         virtual void setBlendMode(sal_Int8 nMode)
210cdf0e10cSrcweir         {
211cdf0e10cSrcweir             getCurrentContext().BlendMode = nMode;
212cdf0e10cSrcweir         }
213cdf0e10cSrcweir 
setFont(const FontAttributes & rFont)214cdf0e10cSrcweir         virtual void setFont( const FontAttributes& rFont )
215cdf0e10cSrcweir         {
216cdf0e10cSrcweir             FontToIdMap::const_iterator it = m_aFontToId.find( rFont );
217cdf0e10cSrcweir             if( it != m_aFontToId.end() )
218cdf0e10cSrcweir                 getCurrentContext().FontId = it->second;
219cdf0e10cSrcweir             else
220cdf0e10cSrcweir             {
221cdf0e10cSrcweir                 m_aFontToId[ rFont ] = m_nNextFontId;
222cdf0e10cSrcweir                 m_aIdToFont[ m_nNextFontId ] = rFont;
223cdf0e10cSrcweir                 getCurrentContext().FontId = m_nNextFontId;
224cdf0e10cSrcweir                 m_nNextFontId++;
225cdf0e10cSrcweir             }
226cdf0e10cSrcweir         }
227cdf0e10cSrcweir 
strokePath(const uno::Reference<rendering::XPolyPolygon2D> & rPath)228cdf0e10cSrcweir         virtual void strokePath( const uno::Reference<rendering::XPolyPolygon2D>& rPath )
229cdf0e10cSrcweir         {
230cdf0e10cSrcweir             GraphicsContext& rContext( getCurrentContext() );
231cdf0e10cSrcweir             basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath);
232cdf0e10cSrcweir             aPath.transform( rContext.Transformation );
233cdf0e10cSrcweir 
234cdf0e10cSrcweir             if( rContext.DashArray.empty() )
235cdf0e10cSrcweir             {
23674e62aedSDamjan Jovanovic                 ASSERT_TRUE(rContext.LineColor.Alpha == 1.0 &&
237cdf0e10cSrcweir                                         rContext.LineColor.Red == 0.0 &&
238cdf0e10cSrcweir                                         rContext.LineColor.Green == 1.0 &&
23974e62aedSDamjan Jovanovic                                         rContext.LineColor.Blue == 0.0) << "Line color is green";
240cdf0e10cSrcweir 
24174e62aedSDamjan Jovanovic                 ASSERT_TRUE(rtl::math::approxEqual(rContext.LineWidth, 28.3)) << "Line width is 0";
242cdf0e10cSrcweir 
243cdf0e10cSrcweir                 const char* sExportString = "m53570 7650-35430 24100";
24474e62aedSDamjan Jovanovic                 ASSERT_TRUE(basegfx::tools::exportToSvgD( aPath, true, true, false ).compareToAscii(sExportString) == 0) << "Stroke is m535.7 518.5-354.3-241";
245cdf0e10cSrcweir 
246cdf0e10cSrcweir                 m_bGreenStrokeSeen = true;
247cdf0e10cSrcweir             }
248cdf0e10cSrcweir             else
249cdf0e10cSrcweir             {
25074e62aedSDamjan Jovanovic                 ASSERT_TRUE(rContext.DashArray.size() == 4 &&
251cdf0e10cSrcweir                                         rtl::math::approxEqual(rContext.DashArray[0],14.3764) &&
252cdf0e10cSrcweir                                         rContext.DashArray[0] == rContext.DashArray[1] &&
253cdf0e10cSrcweir                                         rContext.DashArray[1] == rContext.DashArray[2] &&
25474e62aedSDamjan Jovanovic                                         rContext.DashArray[2] == rContext.DashArray[3]) << "Dash array cons  ists of four entries";
255cdf0e10cSrcweir 
25674e62aedSDamjan Jovanovic                 ASSERT_TRUE(rContext.LineColor.Alpha == 1.0 &&
257cdf0e10cSrcweir                                         rContext.LineColor.Red == 0.0 &&
258cdf0e10cSrcweir                                         rContext.LineColor.Green == 0.0 &&
25974e62aedSDamjan Jovanovic                                         rContext.LineColor.Blue == 0.0) << "Line color is black";
260cdf0e10cSrcweir 
26174e62aedSDamjan Jovanovic                 ASSERT_TRUE(rContext.LineWidth == 0) << "Line width is 0";
262cdf0e10cSrcweir 
263cdf0e10cSrcweir                 const char* sExportString = "m49890 5670.00000000001-35430 24090";
26474e62aedSDamjan Jovanovic                 ASSERT_TRUE(basegfx::tools::exportToSvgD( aPath, true, true, false ).compareToAscii(sExportString) == 0) << "Stroke is m49890 5670.00000000001-35430 24090";
265cdf0e10cSrcweir 
266cdf0e10cSrcweir                 m_bDashedLineSeen = true;
267cdf0e10cSrcweir             }
26874e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.BlendMode == rendering::BlendMode::NORMAL) << "Blend mode is normal";
26974e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.LineJoin == rendering::PathJoinType::ROUND) << "Join type is round";
27074e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.LineCap == rendering::PathCapType::BUTT) << "Cap type is butt";
27174e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.MiterLimit == 10) << "Line miter limit is 10";
27274e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.Flatness == 1) << "Flatness is 0";
27374e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.FontId == 0) << "Font id is 0";
274cdf0e10cSrcweir         }
275cdf0e10cSrcweir 
fillPath(const uno::Reference<rendering::XPolyPolygon2D> & rPath)276cdf0e10cSrcweir         virtual void fillPath( const uno::Reference<rendering::XPolyPolygon2D>& rPath )
277cdf0e10cSrcweir         {
278cdf0e10cSrcweir             GraphicsContext& rContext( getCurrentContext() );
279cdf0e10cSrcweir             basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath);
280cdf0e10cSrcweir             aPath.transform( rContext.Transformation );
281cdf0e10cSrcweir 
28274e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.FillColor.Alpha == 1.0 &&
283cdf0e10cSrcweir                                     rContext.FillColor.Red == 0.0 &&
284cdf0e10cSrcweir                                     rContext.FillColor.Green == 0.0 &&
28574e62aedSDamjan Jovanovic                                     rContext.FillColor.Blue == 0.0) << "Fill color is black";
28674e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.BlendMode == rendering::BlendMode::NORMAL) << "Blend mode is normal";
28774e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.Flatness == 10) << "Flatness is 10";
28874e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.FontId == 0) << "Font id is 0";
289cdf0e10cSrcweir         }
290cdf0e10cSrcweir 
eoFillPath(const uno::Reference<rendering::XPolyPolygon2D> & rPath)291cdf0e10cSrcweir         virtual void eoFillPath( const uno::Reference<rendering::XPolyPolygon2D>& rPath )
292cdf0e10cSrcweir         {
293cdf0e10cSrcweir             GraphicsContext& rContext( getCurrentContext() );
294cdf0e10cSrcweir             basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath);
295cdf0e10cSrcweir             aPath.transform( rContext.Transformation );
296cdf0e10cSrcweir 
29774e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.FillColor.Alpha == 1.0 &&
298cdf0e10cSrcweir                                     rContext.FillColor.Red == 1.0 &&
299cdf0e10cSrcweir                                     rContext.FillColor.Green == 0.0 &&
30074e62aedSDamjan Jovanovic                                     rContext.FillColor.Blue == 0.0) << "Fill color is black";
30174e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.BlendMode == rendering::BlendMode::NORMAL) << "Blend mode is normal";
30274e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.Flatness == 1) << "Flatness is 0";
30374e62aedSDamjan Jovanovic             ASSERT_TRUE(rContext.FontId == 0) << "Font id is 0";
304cdf0e10cSrcweir 
305cdf0e10cSrcweir             const char* sExportString = "m12050 49610c-4310 0-7800-3490-7800-7800 0-4300 "
306cdf0e10cSrcweir                 "3490-7790 7800-7790 4300 0 7790 3490 7790 7790 0 4310-3490 7800-7790 7800z";
30774e62aedSDamjan Jovanovic             ASSERT_TRUE(basegfx::tools::exportToSvgD( aPath, true, true, false ).compareToAscii(sExportString) == 0) << "Stroke is a 4-bezier circle";
308cdf0e10cSrcweir 
309cdf0e10cSrcweir             m_bRedCircleSeen = true;
310cdf0e10cSrcweir         }
311cdf0e10cSrcweir 
intersectClip(const uno::Reference<rendering::XPolyPolygon2D> & rPath)312cdf0e10cSrcweir         virtual void intersectClip(const uno::Reference<rendering::XPolyPolygon2D>& rPath)
313cdf0e10cSrcweir         {
314cdf0e10cSrcweir             basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath);
315cdf0e10cSrcweir             basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip;
316cdf0e10cSrcweir 
317cdf0e10cSrcweir             if( aCurClip.count() )  // #i92985# adapted API from (..., false, false) to (..., true, false)
318cdf0e10cSrcweir                 aNewClip = basegfx::tools::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false );
319cdf0e10cSrcweir 
320cdf0e10cSrcweir             getCurrentContext().Clip = aNewClip;
321cdf0e10cSrcweir         }
322cdf0e10cSrcweir 
intersectEoClip(const uno::Reference<rendering::XPolyPolygon2D> & rPath)323cdf0e10cSrcweir         virtual void intersectEoClip(const uno::Reference<rendering::XPolyPolygon2D>& rPath)
324cdf0e10cSrcweir         {
325cdf0e10cSrcweir             basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath);
326cdf0e10cSrcweir             basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip;
327cdf0e10cSrcweir 
328cdf0e10cSrcweir             if( aCurClip.count() )  // #i92985# adapted API from (..., false, false) to (..., true, false)
329cdf0e10cSrcweir                 aNewClip = basegfx::tools::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false );
330cdf0e10cSrcweir 
331cdf0e10cSrcweir             getCurrentContext().Clip = aNewClip;
332cdf0e10cSrcweir         }
333cdf0e10cSrcweir 
drawGlyphs(const rtl::OUString & rGlyphs,const geometry::RealRectangle2D &,const geometry::Matrix2D &)334cdf0e10cSrcweir         virtual void drawGlyphs( const rtl::OUString&             rGlyphs,
335cdf0e10cSrcweir                                  const geometry::RealRectangle2D& /*rRect*/,
336cdf0e10cSrcweir                                  const geometry::Matrix2D&        /*rFontMatrix*/ )
337cdf0e10cSrcweir         {
338cdf0e10cSrcweir             m_aTextOut.append(rGlyphs);
339cdf0e10cSrcweir         }
340cdf0e10cSrcweir 
endText()341cdf0e10cSrcweir         virtual void endText()
342cdf0e10cSrcweir         {
343cdf0e10cSrcweir             m_aTextOut.append( ::rtl::OUString::createFromAscii("\n") );
344cdf0e10cSrcweir         }
345cdf0e10cSrcweir 
drawMask(const uno::Sequence<beans::PropertyValue> & xBitmap,bool)346cdf0e10cSrcweir         virtual void drawMask(const uno::Sequence<beans::PropertyValue>& xBitmap,
347cdf0e10cSrcweir                               bool                                       /*bInvert*/ )
348cdf0e10cSrcweir         {
34974e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap.getLength()==3) << "drawMask received two properties";
35074e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap[0].Name.compareToAscii( "URL" ) == 0) << "drawMask got URL param";
35174e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap[1].Name.compareToAscii( "InputStream" ) == 0) << "drawMask got InputStream param";
352cdf0e10cSrcweir         }
353cdf0e10cSrcweir 
drawImage(const uno::Sequence<beans::PropertyValue> & xBitmap)354cdf0e10cSrcweir         virtual void drawImage(const uno::Sequence<beans::PropertyValue>& xBitmap )
355cdf0e10cSrcweir         {
35674e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap.getLength()==3) << "drawImage received two properties";
35774e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap[0].Name.compareToAscii( "URL" ) == 0) << "drawImage got URL param";
35874e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap[1].Name.compareToAscii( "InputStream" ) == 0) << "drawImage got InputStream param";
359cdf0e10cSrcweir         }
360cdf0e10cSrcweir 
drawColorMaskedImage(const uno::Sequence<beans::PropertyValue> & xBitmap,const uno::Sequence<uno::Any> &)361cdf0e10cSrcweir         virtual void drawColorMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap,
362cdf0e10cSrcweir                                           const uno::Sequence<uno::Any>&             /*xMaskColors*/ )
363cdf0e10cSrcweir         {
36474e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap.getLength()==3) << "drawColorMaskedImage received two properties";
36574e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap[0].Name.compareToAscii( "URL" ) == 0) << "drawColorMaskedImage got URL param";
36674e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap[1].Name.compareToAscii( "InputStream" ) == 0) << "drawColorMaskedImage got InputStream param";
367cdf0e10cSrcweir         }
368cdf0e10cSrcweir 
drawMaskedImage(const uno::Sequence<beans::PropertyValue> & xBitmap,const uno::Sequence<beans::PropertyValue> & xMask,bool)369cdf0e10cSrcweir         virtual void drawMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap,
370cdf0e10cSrcweir                                      const uno::Sequence<beans::PropertyValue>& xMask,
371cdf0e10cSrcweir                                      bool                                       /*bInvertMask*/)
372cdf0e10cSrcweir         {
37374e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap.getLength()==3) << "drawMaskedImage received two properties #1";
37474e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap[0].Name.compareToAscii( "URL" ) == 0) << "drawMaskedImage got URL param #1";
37574e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap[1].Name.compareToAscii( "InputStream" ) == 0) << "drawMaskedImage got InputStream param #1";
376cdf0e10cSrcweir 
37774e62aedSDamjan Jovanovic             ASSERT_TRUE(xMask.getLength()==3) << "drawMaskedImage received two properties #2";
37874e62aedSDamjan Jovanovic             ASSERT_TRUE(xMask[0].Name.compareToAscii( "URL" ) == 0) << "drawMaskedImage got URL param #2";
37974e62aedSDamjan Jovanovic             ASSERT_TRUE(xMask[1].Name.compareToAscii( "InputStream" ) == 0) << "drawMaskedImage got InputStream param #2";
380cdf0e10cSrcweir         }
381cdf0e10cSrcweir 
drawAlphaMaskedImage(const uno::Sequence<beans::PropertyValue> & xBitmap,const uno::Sequence<beans::PropertyValue> & xMask)382cdf0e10cSrcweir         virtual void drawAlphaMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap,
383cdf0e10cSrcweir                                           const uno::Sequence<beans::PropertyValue>& xMask)
384cdf0e10cSrcweir         {
38574e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap.getLength()==3) << "drawAlphaMaskedImage received two properties #1";
38674e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap[0].Name.compareToAscii( "URL" ) == 0) << "drawAlphaMaskedImage got URL param #1";
38774e62aedSDamjan Jovanovic             ASSERT_TRUE(xBitmap[1].Name.compareToAscii( "InputStream" ) == 0) << "drawAlphaMaskedImage got InputStream param #1";
388cdf0e10cSrcweir 
38974e62aedSDamjan Jovanovic             ASSERT_TRUE(xMask.getLength()==3) << "drawAlphaMaskedImage received two properties #2";
39074e62aedSDamjan Jovanovic             ASSERT_TRUE(xMask[0].Name.compareToAscii( "URL" ) == 0) << "drawAlphaMaskedImage got URL param #2";
39174e62aedSDamjan Jovanovic             ASSERT_TRUE(xMask[1].Name.compareToAscii( "InputStream" ) == 0) << "drawAlphaMaskedImage got InputStream param #2";
392cdf0e10cSrcweir         }
393cdf0e10cSrcweir 
setTextRenderMode(sal_Int32)394cdf0e10cSrcweir         virtual void setTextRenderMode( sal_Int32 )
395cdf0e10cSrcweir         {
396cdf0e10cSrcweir         }
397cdf0e10cSrcweir 
398cdf0e10cSrcweir         typedef std::hash_map<sal_Int32,FontAttributes> IdToFontMap;
399cdf0e10cSrcweir         typedef std::hash_map<FontAttributes,sal_Int32,FontAttrHash> FontToIdMap;
400cdf0e10cSrcweir 
401cdf0e10cSrcweir         typedef std::hash_map<sal_Int32,GraphicsContext> IdToGCMap;
402cdf0e10cSrcweir         typedef std::hash_map<GraphicsContext,sal_Int32,GraphicsContextHash> GCToIdMap;
403cdf0e10cSrcweir 
404cdf0e10cSrcweir         typedef std::vector<GraphicsContext> GraphicsContextStack;
405cdf0e10cSrcweir 
406cdf0e10cSrcweir         sal_Int32                 m_nNextFontId;
407cdf0e10cSrcweir         IdToFontMap               m_aIdToFont;
408cdf0e10cSrcweir         FontToIdMap               m_aFontToId;
409cdf0e10cSrcweir 
410cdf0e10cSrcweir         GraphicsContextStack      m_aGCStack;
411cdf0e10cSrcweir         geometry::RealSize2D      m_aPageSize;
412cdf0e10cSrcweir         geometry::RealRectangle2D m_aHyperlinkBounds;
413cdf0e10cSrcweir         ::rtl::OUString           m_aURI;
414cdf0e10cSrcweir         ::rtl::OUStringBuffer     m_aTextOut;
415cdf0e10cSrcweir         sal_Int32                 m_nNumPages;
416cdf0e10cSrcweir         bool                      m_bPageEnded;
417cdf0e10cSrcweir         bool                      m_bRedCircleSeen;
418cdf0e10cSrcweir         bool                      m_bGreenStrokeSeen;
419cdf0e10cSrcweir         bool                      m_bDashedLineSeen;
420cdf0e10cSrcweir     };
421cdf0e10cSrcweir 
42274e62aedSDamjan Jovanovic     class PDFITest : public ::testing::Test
423cdf0e10cSrcweir     {
42474e62aedSDamjan Jovanovic     protected:
425cdf0e10cSrcweir         uno::Reference<uno::XComponentContext> mxCtx;
426cdf0e10cSrcweir         rtl::OUString                          msBaseDir;
427cdf0e10cSrcweir         bool                                   mbUnoInitialized;
428cdf0e10cSrcweir 
429cdf0e10cSrcweir     public:
PDFITest()430cdf0e10cSrcweir         PDFITest() : mxCtx(),msBaseDir(),mbUnoInitialized(false)
431cdf0e10cSrcweir         {}
432cdf0e10cSrcweir 
SetUp()43374e62aedSDamjan Jovanovic         void SetUp()
434cdf0e10cSrcweir         {
435cdf0e10cSrcweir             if( !mbUnoInitialized )
436cdf0e10cSrcweir             {
43774e62aedSDamjan Jovanovic                 const char* pArgs( getenv("TESTS_FORWARD_STRING") );
43874e62aedSDamjan Jovanovic                 ASSERT_TRUE(pArgs) << "Test file parameter";
439cdf0e10cSrcweir 
440cdf0e10cSrcweir                 msBaseDir = rtl::OUString::createFromAscii(pArgs);
441cdf0e10cSrcweir 
442cdf0e10cSrcweir                 // bootstrap UNO
443cdf0e10cSrcweir                 try
444cdf0e10cSrcweir                 {
445cdf0e10cSrcweir                     ::rtl::OUString aIniUrl;
44674e62aedSDamjan Jovanovic                     ASSERT_TRUE(
447cdf0e10cSrcweir                         osl_getFileURLFromSystemPath(
448cdf0e10cSrcweir                             (msBaseDir+rtl::OUString::createFromAscii("pdfi_unittest_test.ini")).pData,
44974e62aedSDamjan Jovanovic                             &aIniUrl.pData ) == osl_File_E_None )
45074e62aedSDamjan Jovanovic                         << "Converting ini file to URL";
451cdf0e10cSrcweir 
452cdf0e10cSrcweir                     mxCtx = ::cppu::defaultBootstrap_InitialComponentContext(aIniUrl);
45374e62aedSDamjan Jovanovic                     ASSERT_TRUE(mxCtx.is()) << "Getting component context";
454cdf0e10cSrcweir                 }
455cdf0e10cSrcweir                 catch( uno::Exception& )
456cdf0e10cSrcweir                 {
45774e62aedSDamjan Jovanovic                     FAIL() << "Bootstrapping UNO";
458cdf0e10cSrcweir                 }
459cdf0e10cSrcweir 
460cdf0e10cSrcweir                 mbUnoInitialized = true;
461cdf0e10cSrcweir             }
462cdf0e10cSrcweir         }
TearDown()46374e62aedSDamjan Jovanovic         void TearDown()
464cdf0e10cSrcweir         {
465cdf0e10cSrcweir         }
466cdf0e10cSrcweir     };
467cdf0e10cSrcweir 
TEST_F(PDFITest,testXPDFParser)46874e62aedSDamjan Jovanovic     TEST_F(PDFITest, testXPDFParser)
46974e62aedSDamjan Jovanovic     {
47074e62aedSDamjan Jovanovic         pdfi::ContentSinkSharedPtr pSink( new TestSink() );
47174e62aedSDamjan Jovanovic         pdfi::xpdf_ImportFromFile( msBaseDir + rtl::OUString::createFromAscii("pdfi_unittest_test.pdf"),
47274e62aedSDamjan Jovanovic                                    pSink,
47374e62aedSDamjan Jovanovic                                    uno::Reference< task::XInteractionHandler >(),
47474e62aedSDamjan Jovanovic                                    rtl::OUString(),
47574e62aedSDamjan Jovanovic                                    mxCtx );
47674e62aedSDamjan Jovanovic 
47774e62aedSDamjan Jovanovic         // make destruction explicit, a bunch of things are
47874e62aedSDamjan Jovanovic         // checked in the destructor
47974e62aedSDamjan Jovanovic         pSink.reset();
48074e62aedSDamjan Jovanovic     }
48174e62aedSDamjan Jovanovic 
TEST_F(PDFITest,testOdfDrawExport)48274e62aedSDamjan Jovanovic     TEST_F(PDFITest, testOdfDrawExport)
48374e62aedSDamjan Jovanovic     {
48474e62aedSDamjan Jovanovic         pdfi::PDFIRawAdaptor aAdaptor( mxCtx );
48574e62aedSDamjan Jovanovic         aAdaptor.setTreeVisitorFactory( createDrawTreeVisitorFactory() );
48674e62aedSDamjan Jovanovic 
48774e62aedSDamjan Jovanovic         ::rtl::OUString aURL, aAbsURL, aBaseURL;
48874e62aedSDamjan Jovanovic         osl_getFileURLFromSystemPath( (msBaseDir + rtl::OUString::createFromAscii("pdfi_unittest_draw.xml")).pData,
48974e62aedSDamjan Jovanovic                                       &aURL.pData );
49074e62aedSDamjan Jovanovic         osl_getProcessWorkingDir(&aBaseURL.pData);
49174e62aedSDamjan Jovanovic         osl_getAbsoluteFileURL(aBaseURL.pData,aURL.pData,&aAbsURL.pData);
49274e62aedSDamjan Jovanovic         ASSERT_TRUE(aAdaptor.odfConvert( msBaseDir + rtl::OUString::createFromAscii("pdfi_unittest_test.pdf"),
49374e62aedSDamjan Jovanovic                                          new OutputWrap(aAbsURL),
49474e62aedSDamjan Jovanovic                                          NULL )) << "Exporting to ODF";
49574e62aedSDamjan Jovanovic     }
49674e62aedSDamjan Jovanovic 
TEST_F(PDFITest,testOdfWriterExport)49774e62aedSDamjan Jovanovic     TEST_F(PDFITest, testOdfWriterExport)
49874e62aedSDamjan Jovanovic     {
49974e62aedSDamjan Jovanovic         pdfi::PDFIRawAdaptor aAdaptor( mxCtx );
50074e62aedSDamjan Jovanovic         aAdaptor.setTreeVisitorFactory( createWriterTreeVisitorFactory() );
50174e62aedSDamjan Jovanovic 
50274e62aedSDamjan Jovanovic         ::rtl::OUString aURL, aAbsURL, aBaseURL;
50374e62aedSDamjan Jovanovic         osl_getFileURLFromSystemPath( (msBaseDir + rtl::OUString::createFromAscii("pdfi_unittest_writer.xml")).pData,
50474e62aedSDamjan Jovanovic                                       &aURL.pData );
50574e62aedSDamjan Jovanovic         osl_getProcessWorkingDir(&aBaseURL.pData);
50674e62aedSDamjan Jovanovic         osl_getAbsoluteFileURL(aBaseURL.pData,aURL.pData,&aAbsURL.pData);
50774e62aedSDamjan Jovanovic         ASSERT_TRUE(aAdaptor.odfConvert( msBaseDir + rtl::OUString::createFromAscii("pdfi_unittest_test.pdf"),
50874e62aedSDamjan Jovanovic                                          new OutputWrap(aAbsURL),
50974e62aedSDamjan Jovanovic                                          NULL )) << "Exporting to ODF";
51074e62aedSDamjan Jovanovic     }
511cdf0e10cSrcweir 
51274e62aedSDamjan Jovanovic }
513cdf0e10cSrcweir 
main(int argc,char ** argv)51474e62aedSDamjan Jovanovic int main(int argc, char **argv)
51574e62aedSDamjan Jovanovic {
51674e62aedSDamjan Jovanovic     ::testing::InitGoogleTest(&argc, argv);
51774e62aedSDamjan Jovanovic     return RUN_ALL_TESTS();
51874e62aedSDamjan Jovanovic }
519