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