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 27cdf0e10cSrcweir #ifdef SYSTEM_ZLIB 28cdf0e10cSrcweir #include "zlib.h" 29cdf0e10cSrcweir #else 30cdf0e10cSrcweir #include <zlib/zlib.h> 31cdf0e10cSrcweir #endif 32cdf0e10cSrcweir 33cdf0e10cSrcweir #include "outputwrap.hxx" 34cdf0e10cSrcweir #include "contentsink.hxx" 35cdf0e10cSrcweir #include "pdfihelper.hxx" 36cdf0e10cSrcweir #include "wrapper.hxx" 37cdf0e10cSrcweir #include "pdfparse.hxx" 38cdf0e10cSrcweir #include "../pdfiadaptor.hxx" 39cdf0e10cSrcweir 40cdf0e10cSrcweir #include <rtl/math.hxx> 41cdf0e10cSrcweir #include <osl/file.hxx> 42cdf0e10cSrcweir #include <osl/process.h> 43*74e62aedSDamjan Jovanovic #include <gtest/gtest.h> 44cdf0e10cSrcweir #include <cppuhelper/compbase1.hxx> 45cdf0e10cSrcweir #include <cppuhelper/bootstrap.hxx> 46cdf0e10cSrcweir #include <cppuhelper/basemutex.hxx> 47cdf0e10cSrcweir #include <comphelper/sequence.hxx> 48cdf0e10cSrcweir 49cdf0e10cSrcweir 50cdf0e10cSrcweir #include <com/sun/star/rendering/XCanvas.hpp> 51cdf0e10cSrcweir #include <com/sun/star/rendering/XColorSpace.hpp> 52cdf0e10cSrcweir #include <com/sun/star/rendering/PathJoinType.hpp> 53cdf0e10cSrcweir #include <com/sun/star/rendering/PathCapType.hpp> 54cdf0e10cSrcweir #include <com/sun/star/rendering/BlendMode.hpp> 55cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp> 56cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp> 57cdf0e10cSrcweir #include <com/sun/star/registry/XSimpleRegistry.hpp> 58cdf0e10cSrcweir 59cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx> 60cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx> 61cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx> 62cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx> 63cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx> 64cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygonclipper.hxx> 65cdf0e10cSrcweir 66cdf0e10cSrcweir #include <vector> 67cdf0e10cSrcweir #include <hash_map> 68cdf0e10cSrcweir 69cdf0e10cSrcweir 70cdf0e10cSrcweir using namespace ::pdfparse; 71cdf0e10cSrcweir using namespace ::pdfi; 72cdf0e10cSrcweir using namespace ::com::sun::star; 73cdf0e10cSrcweir 74cdf0e10cSrcweir namespace 75cdf0e10cSrcweir { 76cdf0e10cSrcweir class TestSink : public ContentSink 77cdf0e10cSrcweir { 78cdf0e10cSrcweir public: 79cdf0e10cSrcweir TestSink() : 80cdf0e10cSrcweir m_nNextFontId( 1 ), 81cdf0e10cSrcweir m_aIdToFont(), 82cdf0e10cSrcweir m_aFontToId(), 83cdf0e10cSrcweir m_aGCStack(1), 84cdf0e10cSrcweir m_aPageSize(), 85cdf0e10cSrcweir m_aHyperlinkBounds(), 86cdf0e10cSrcweir m_aURI(), 87cdf0e10cSrcweir m_aTextOut(), 88cdf0e10cSrcweir m_nNumPages(0), 89cdf0e10cSrcweir m_bPageEnded(false), 90cdf0e10cSrcweir m_bRedCircleSeen(false), 91cdf0e10cSrcweir m_bGreenStrokeSeen(false), 92cdf0e10cSrcweir m_bDashedLineSeen(false) 93cdf0e10cSrcweir {} 94cdf0e10cSrcweir 95cdf0e10cSrcweir ~TestSink() 96cdf0e10cSrcweir { 97*74e62aedSDamjan Jovanovic ASSERT_TRUE(m_aPageSize.Width == 79400 && m_aPageSize.Height == 59500) << "A4 page size (in 100th of points)"; 98*74e62aedSDamjan Jovanovic ASSERT_TRUE(m_bPageEnded) << "endPage() called"; 99*74e62aedSDamjan Jovanovic ASSERT_TRUE(m_nNumPages == 1) << "Num pages equal one"; 100*74e62aedSDamjan Jovanovic ASSERT_TRUE(rtl::math::approxEqual(m_aHyperlinkBounds.X1,34.7 ) && 101cdf0e10cSrcweir rtl::math::approxEqual(m_aHyperlinkBounds.Y1,386.0) && 102cdf0e10cSrcweir rtl::math::approxEqual(m_aHyperlinkBounds.X2,166.7) && 103*74e62aedSDamjan Jovanovic rtl::math::approxEqual(m_aHyperlinkBounds.Y2,406.2)) << "Correct hyperlink bounding box"; 104*74e62aedSDamjan Jovanovic ASSERT_TRUE(m_aURI == ::rtl::OUString::createFromAscii( "http://download.openoffice.org/" )) << "Correct hyperlink URI"; 105cdf0e10cSrcweir 106cdf0e10cSrcweir const char* sText = " \n \nThis is a testtext\nNew paragraph,\nnew line\n" 107cdf0e10cSrcweir "Hyperlink, this is\n?\nThis is more text\noutline mode\n?\nNew paragraph\n"; 108cdf0e10cSrcweir ::rtl::OString aTmp; 109cdf0e10cSrcweir m_aTextOut.makeStringAndClear().convertToString( &aTmp, 110cdf0e10cSrcweir RTL_TEXTENCODING_ASCII_US, 111cdf0e10cSrcweir OUSTRING_TO_OSTRING_CVTFLAGS ); 112*74e62aedSDamjan Jovanovic ASSERT_TRUE( sText == aTmp ) << "Imported text is \"This is a testtext New paragraph, new line" 113*74e62aedSDamjan Jovanovic " Hyperlink, this is * This is more text outline mode * New paragraph\""; 114cdf0e10cSrcweir 115*74e62aedSDamjan Jovanovic ASSERT_TRUE(m_bRedCircleSeen) << "red circle seen in input"; 116*74e62aedSDamjan Jovanovic ASSERT_TRUE(m_bGreenStrokeSeen) << "green stroke seen in input"; 117*74e62aedSDamjan Jovanovic ASSERT_TRUE(m_bDashedLineSeen) << "dashed line seen in input"; 118cdf0e10cSrcweir } 119cdf0e10cSrcweir 120cdf0e10cSrcweir private: 121cdf0e10cSrcweir GraphicsContext& getCurrentContext() { return m_aGCStack.back(); } 122cdf0e10cSrcweir 123cdf0e10cSrcweir // ContentSink interface implementation 124cdf0e10cSrcweir virtual void setPageNum( sal_Int32 nNumPages ) 125cdf0e10cSrcweir { 126cdf0e10cSrcweir m_nNumPages = nNumPages; 127cdf0e10cSrcweir } 128cdf0e10cSrcweir 129cdf0e10cSrcweir virtual void startPage( const geometry::RealSize2D& rSize ) 130cdf0e10cSrcweir { 131cdf0e10cSrcweir m_aPageSize = rSize; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir virtual void endPage() 135cdf0e10cSrcweir { 136cdf0e10cSrcweir m_bPageEnded = true; 137cdf0e10cSrcweir } 138cdf0e10cSrcweir 139cdf0e10cSrcweir virtual void hyperLink( const geometry::RealRectangle2D& rBounds, 140cdf0e10cSrcweir const ::rtl::OUString& rURI ) 141cdf0e10cSrcweir { 142cdf0e10cSrcweir m_aHyperlinkBounds = rBounds; 143cdf0e10cSrcweir m_aURI = rURI; 144cdf0e10cSrcweir } 145cdf0e10cSrcweir 146cdf0e10cSrcweir virtual void pushState() 147cdf0e10cSrcweir { 148cdf0e10cSrcweir m_aGCStack.push_back( m_aGCStack.back() ); 149cdf0e10cSrcweir } 150cdf0e10cSrcweir 151cdf0e10cSrcweir virtual void popState() 152cdf0e10cSrcweir { 153cdf0e10cSrcweir m_aGCStack.pop_back(); 154cdf0e10cSrcweir } 155cdf0e10cSrcweir 156cdf0e10cSrcweir virtual void setTransformation( const geometry::AffineMatrix2D& rMatrix ) 157cdf0e10cSrcweir { 158cdf0e10cSrcweir basegfx::unotools::homMatrixFromAffineMatrix( 159cdf0e10cSrcweir getCurrentContext().Transformation, 160cdf0e10cSrcweir rMatrix ); 161cdf0e10cSrcweir } 162cdf0e10cSrcweir 163cdf0e10cSrcweir virtual void setLineDash( const uno::Sequence<double>& dashes, 164cdf0e10cSrcweir double start ) 165cdf0e10cSrcweir { 166cdf0e10cSrcweir GraphicsContext& rContext( getCurrentContext() ); 167cdf0e10cSrcweir if( dashes.getLength() ) 168cdf0e10cSrcweir comphelper::sequenceToContainer(rContext.DashArray,dashes); 169*74e62aedSDamjan Jovanovic ASSERT_TRUE(start == 0.0) << "line dashing start offset"; 170cdf0e10cSrcweir } 171cdf0e10cSrcweir 172cdf0e10cSrcweir virtual void setFlatness( double nFlatness ) 173cdf0e10cSrcweir { 174cdf0e10cSrcweir getCurrentContext().Flatness = nFlatness; 175cdf0e10cSrcweir } 176cdf0e10cSrcweir 177cdf0e10cSrcweir virtual void setLineJoin(sal_Int8 nJoin) 178cdf0e10cSrcweir { 179cdf0e10cSrcweir getCurrentContext().LineJoin = nJoin; 180cdf0e10cSrcweir } 181cdf0e10cSrcweir 182cdf0e10cSrcweir virtual void setLineCap(sal_Int8 nCap) 183cdf0e10cSrcweir { 184cdf0e10cSrcweir getCurrentContext().LineCap = nCap; 185cdf0e10cSrcweir } 186cdf0e10cSrcweir 187cdf0e10cSrcweir virtual void setMiterLimit(double nVal) 188cdf0e10cSrcweir { 189cdf0e10cSrcweir getCurrentContext().MiterLimit = nVal; 190cdf0e10cSrcweir } 191cdf0e10cSrcweir 192cdf0e10cSrcweir virtual void setLineWidth(double nVal) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir getCurrentContext().LineWidth = nVal; 195cdf0e10cSrcweir } 196cdf0e10cSrcweir 197cdf0e10cSrcweir virtual void setFillColor( const rendering::ARGBColor& rColor ) 198cdf0e10cSrcweir { 199cdf0e10cSrcweir getCurrentContext().FillColor = rColor; 200cdf0e10cSrcweir } 201cdf0e10cSrcweir 202cdf0e10cSrcweir virtual void setStrokeColor( const rendering::ARGBColor& rColor ) 203cdf0e10cSrcweir { 204cdf0e10cSrcweir getCurrentContext().LineColor = rColor; 205cdf0e10cSrcweir } 206cdf0e10cSrcweir 207cdf0e10cSrcweir virtual void setBlendMode(sal_Int8 nMode) 208cdf0e10cSrcweir { 209cdf0e10cSrcweir getCurrentContext().BlendMode = nMode; 210cdf0e10cSrcweir } 211cdf0e10cSrcweir 212cdf0e10cSrcweir virtual void setFont( const FontAttributes& rFont ) 213cdf0e10cSrcweir { 214cdf0e10cSrcweir FontToIdMap::const_iterator it = m_aFontToId.find( rFont ); 215cdf0e10cSrcweir if( it != m_aFontToId.end() ) 216cdf0e10cSrcweir getCurrentContext().FontId = it->second; 217cdf0e10cSrcweir else 218cdf0e10cSrcweir { 219cdf0e10cSrcweir m_aFontToId[ rFont ] = m_nNextFontId; 220cdf0e10cSrcweir m_aIdToFont[ m_nNextFontId ] = rFont; 221cdf0e10cSrcweir getCurrentContext().FontId = m_nNextFontId; 222cdf0e10cSrcweir m_nNextFontId++; 223cdf0e10cSrcweir } 224cdf0e10cSrcweir } 225cdf0e10cSrcweir 226cdf0e10cSrcweir virtual void strokePath( const uno::Reference<rendering::XPolyPolygon2D>& rPath ) 227cdf0e10cSrcweir { 228cdf0e10cSrcweir GraphicsContext& rContext( getCurrentContext() ); 229cdf0e10cSrcweir basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); 230cdf0e10cSrcweir aPath.transform( rContext.Transformation ); 231cdf0e10cSrcweir 232cdf0e10cSrcweir if( rContext.DashArray.empty() ) 233cdf0e10cSrcweir { 234*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.LineColor.Alpha == 1.0 && 235cdf0e10cSrcweir rContext.LineColor.Red == 0.0 && 236cdf0e10cSrcweir rContext.LineColor.Green == 1.0 && 237*74e62aedSDamjan Jovanovic rContext.LineColor.Blue == 0.0) << "Line color is green"; 238cdf0e10cSrcweir 239*74e62aedSDamjan Jovanovic ASSERT_TRUE(rtl::math::approxEqual(rContext.LineWidth, 28.3)) << "Line width is 0"; 240cdf0e10cSrcweir 241cdf0e10cSrcweir const char* sExportString = "m53570 7650-35430 24100"; 242*74e62aedSDamjan Jovanovic ASSERT_TRUE(basegfx::tools::exportToSvgD( aPath, true, true, false ).compareToAscii(sExportString) == 0) << "Stroke is m535.7 518.5-354.3-241"; 243cdf0e10cSrcweir 244cdf0e10cSrcweir m_bGreenStrokeSeen = true; 245cdf0e10cSrcweir } 246cdf0e10cSrcweir else 247cdf0e10cSrcweir { 248*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.DashArray.size() == 4 && 249cdf0e10cSrcweir rtl::math::approxEqual(rContext.DashArray[0],14.3764) && 250cdf0e10cSrcweir rContext.DashArray[0] == rContext.DashArray[1] && 251cdf0e10cSrcweir rContext.DashArray[1] == rContext.DashArray[2] && 252*74e62aedSDamjan Jovanovic rContext.DashArray[2] == rContext.DashArray[3]) << "Dash array cons ists of four entries"; 253cdf0e10cSrcweir 254*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.LineColor.Alpha == 1.0 && 255cdf0e10cSrcweir rContext.LineColor.Red == 0.0 && 256cdf0e10cSrcweir rContext.LineColor.Green == 0.0 && 257*74e62aedSDamjan Jovanovic rContext.LineColor.Blue == 0.0) << "Line color is black"; 258cdf0e10cSrcweir 259*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.LineWidth == 0) << "Line width is 0"; 260cdf0e10cSrcweir 261cdf0e10cSrcweir const char* sExportString = "m49890 5670.00000000001-35430 24090"; 262*74e62aedSDamjan Jovanovic ASSERT_TRUE(basegfx::tools::exportToSvgD( aPath, true, true, false ).compareToAscii(sExportString) == 0) << "Stroke is m49890 5670.00000000001-35430 24090"; 263cdf0e10cSrcweir 264cdf0e10cSrcweir m_bDashedLineSeen = true; 265cdf0e10cSrcweir } 266*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.BlendMode == rendering::BlendMode::NORMAL) << "Blend mode is normal"; 267*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.LineJoin == rendering::PathJoinType::ROUND) << "Join type is round"; 268*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.LineCap == rendering::PathCapType::BUTT) << "Cap type is butt"; 269*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.MiterLimit == 10) << "Line miter limit is 10"; 270*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.Flatness == 1) << "Flatness is 0"; 271*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.FontId == 0) << "Font id is 0"; 272cdf0e10cSrcweir } 273cdf0e10cSrcweir 274cdf0e10cSrcweir virtual void fillPath( const uno::Reference<rendering::XPolyPolygon2D>& rPath ) 275cdf0e10cSrcweir { 276cdf0e10cSrcweir GraphicsContext& rContext( getCurrentContext() ); 277cdf0e10cSrcweir basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); 278cdf0e10cSrcweir aPath.transform( rContext.Transformation ); 279cdf0e10cSrcweir 280*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.FillColor.Alpha == 1.0 && 281cdf0e10cSrcweir rContext.FillColor.Red == 0.0 && 282cdf0e10cSrcweir rContext.FillColor.Green == 0.0 && 283*74e62aedSDamjan Jovanovic rContext.FillColor.Blue == 0.0) << "Fill color is black"; 284*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.BlendMode == rendering::BlendMode::NORMAL) << "Blend mode is normal"; 285*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.Flatness == 10) << "Flatness is 10"; 286*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.FontId == 0) << "Font id is 0"; 287cdf0e10cSrcweir } 288cdf0e10cSrcweir 289cdf0e10cSrcweir virtual void eoFillPath( const uno::Reference<rendering::XPolyPolygon2D>& rPath ) 290cdf0e10cSrcweir { 291cdf0e10cSrcweir GraphicsContext& rContext( getCurrentContext() ); 292cdf0e10cSrcweir basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); 293cdf0e10cSrcweir aPath.transform( rContext.Transformation ); 294cdf0e10cSrcweir 295*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.FillColor.Alpha == 1.0 && 296cdf0e10cSrcweir rContext.FillColor.Red == 1.0 && 297cdf0e10cSrcweir rContext.FillColor.Green == 0.0 && 298*74e62aedSDamjan Jovanovic rContext.FillColor.Blue == 0.0) << "Fill color is black"; 299*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.BlendMode == rendering::BlendMode::NORMAL) << "Blend mode is normal"; 300*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.Flatness == 1) << "Flatness is 0"; 301*74e62aedSDamjan Jovanovic ASSERT_TRUE(rContext.FontId == 0) << "Font id is 0"; 302cdf0e10cSrcweir 303cdf0e10cSrcweir const char* sExportString = "m12050 49610c-4310 0-7800-3490-7800-7800 0-4300 " 304cdf0e10cSrcweir "3490-7790 7800-7790 4300 0 7790 3490 7790 7790 0 4310-3490 7800-7790 7800z"; 305*74e62aedSDamjan Jovanovic ASSERT_TRUE(basegfx::tools::exportToSvgD( aPath, true, true, false ).compareToAscii(sExportString) == 0) << "Stroke is a 4-bezier circle"; 306cdf0e10cSrcweir 307cdf0e10cSrcweir m_bRedCircleSeen = true; 308cdf0e10cSrcweir } 309cdf0e10cSrcweir 310cdf0e10cSrcweir virtual void intersectClip(const uno::Reference<rendering::XPolyPolygon2D>& rPath) 311cdf0e10cSrcweir { 312cdf0e10cSrcweir basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); 313cdf0e10cSrcweir basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip; 314cdf0e10cSrcweir 315cdf0e10cSrcweir if( aCurClip.count() ) // #i92985# adapted API from (..., false, false) to (..., true, false) 316cdf0e10cSrcweir aNewClip = basegfx::tools::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false ); 317cdf0e10cSrcweir 318cdf0e10cSrcweir getCurrentContext().Clip = aNewClip; 319cdf0e10cSrcweir } 320cdf0e10cSrcweir 321cdf0e10cSrcweir virtual void intersectEoClip(const uno::Reference<rendering::XPolyPolygon2D>& rPath) 322cdf0e10cSrcweir { 323cdf0e10cSrcweir basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); 324cdf0e10cSrcweir basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip; 325cdf0e10cSrcweir 326cdf0e10cSrcweir if( aCurClip.count() ) // #i92985# adapted API from (..., false, false) to (..., true, false) 327cdf0e10cSrcweir aNewClip = basegfx::tools::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false ); 328cdf0e10cSrcweir 329cdf0e10cSrcweir getCurrentContext().Clip = aNewClip; 330cdf0e10cSrcweir } 331cdf0e10cSrcweir 332cdf0e10cSrcweir virtual void drawGlyphs( const rtl::OUString& rGlyphs, 333cdf0e10cSrcweir const geometry::RealRectangle2D& /*rRect*/, 334cdf0e10cSrcweir const geometry::Matrix2D& /*rFontMatrix*/ ) 335cdf0e10cSrcweir { 336cdf0e10cSrcweir m_aTextOut.append(rGlyphs); 337cdf0e10cSrcweir } 338cdf0e10cSrcweir 339cdf0e10cSrcweir virtual void endText() 340cdf0e10cSrcweir { 341cdf0e10cSrcweir m_aTextOut.append( ::rtl::OUString::createFromAscii("\n") ); 342cdf0e10cSrcweir } 343cdf0e10cSrcweir 344cdf0e10cSrcweir virtual void drawMask(const uno::Sequence<beans::PropertyValue>& xBitmap, 345cdf0e10cSrcweir bool /*bInvert*/ ) 346cdf0e10cSrcweir { 347*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap.getLength()==3) << "drawMask received two properties"; 348*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap[0].Name.compareToAscii( "URL" ) == 0) << "drawMask got URL param"; 349*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap[1].Name.compareToAscii( "InputStream" ) == 0) << "drawMask got InputStream param"; 350cdf0e10cSrcweir } 351cdf0e10cSrcweir 352cdf0e10cSrcweir virtual void drawImage(const uno::Sequence<beans::PropertyValue>& xBitmap ) 353cdf0e10cSrcweir { 354*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap.getLength()==3) << "drawImage received two properties"; 355*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap[0].Name.compareToAscii( "URL" ) == 0) << "drawImage got URL param"; 356*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap[1].Name.compareToAscii( "InputStream" ) == 0) << "drawImage got InputStream param"; 357cdf0e10cSrcweir } 358cdf0e10cSrcweir 359cdf0e10cSrcweir virtual void drawColorMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap, 360cdf0e10cSrcweir const uno::Sequence<uno::Any>& /*xMaskColors*/ ) 361cdf0e10cSrcweir { 362*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap.getLength()==3) << "drawColorMaskedImage received two properties"; 363*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap[0].Name.compareToAscii( "URL" ) == 0) << "drawColorMaskedImage got URL param"; 364*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap[1].Name.compareToAscii( "InputStream" ) == 0) << "drawColorMaskedImage got InputStream param"; 365cdf0e10cSrcweir } 366cdf0e10cSrcweir 367cdf0e10cSrcweir virtual void drawMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap, 368cdf0e10cSrcweir const uno::Sequence<beans::PropertyValue>& xMask, 369cdf0e10cSrcweir bool /*bInvertMask*/) 370cdf0e10cSrcweir { 371*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap.getLength()==3) << "drawMaskedImage received two properties #1"; 372*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap[0].Name.compareToAscii( "URL" ) == 0) << "drawMaskedImage got URL param #1"; 373*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap[1].Name.compareToAscii( "InputStream" ) == 0) << "drawMaskedImage got InputStream param #1"; 374cdf0e10cSrcweir 375*74e62aedSDamjan Jovanovic ASSERT_TRUE(xMask.getLength()==3) << "drawMaskedImage received two properties #2"; 376*74e62aedSDamjan Jovanovic ASSERT_TRUE(xMask[0].Name.compareToAscii( "URL" ) == 0) << "drawMaskedImage got URL param #2"; 377*74e62aedSDamjan Jovanovic ASSERT_TRUE(xMask[1].Name.compareToAscii( "InputStream" ) == 0) << "drawMaskedImage got InputStream param #2"; 378cdf0e10cSrcweir } 379cdf0e10cSrcweir 380cdf0e10cSrcweir virtual void drawAlphaMaskedImage(const uno::Sequence<beans::PropertyValue>& xBitmap, 381cdf0e10cSrcweir const uno::Sequence<beans::PropertyValue>& xMask) 382cdf0e10cSrcweir { 383*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap.getLength()==3) << "drawAlphaMaskedImage received two properties #1"; 384*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap[0].Name.compareToAscii( "URL" ) == 0) << "drawAlphaMaskedImage got URL param #1"; 385*74e62aedSDamjan Jovanovic ASSERT_TRUE(xBitmap[1].Name.compareToAscii( "InputStream" ) == 0) << "drawAlphaMaskedImage got InputStream param #1"; 386cdf0e10cSrcweir 387*74e62aedSDamjan Jovanovic ASSERT_TRUE(xMask.getLength()==3) << "drawAlphaMaskedImage received two properties #2"; 388*74e62aedSDamjan Jovanovic ASSERT_TRUE(xMask[0].Name.compareToAscii( "URL" ) == 0) << "drawAlphaMaskedImage got URL param #2"; 389*74e62aedSDamjan Jovanovic ASSERT_TRUE(xMask[1].Name.compareToAscii( "InputStream" ) == 0) << "drawAlphaMaskedImage got InputStream param #2"; 390cdf0e10cSrcweir } 391cdf0e10cSrcweir 392cdf0e10cSrcweir virtual void setTextRenderMode( sal_Int32 ) 393cdf0e10cSrcweir { 394cdf0e10cSrcweir } 395cdf0e10cSrcweir 396cdf0e10cSrcweir typedef std::hash_map<sal_Int32,FontAttributes> IdToFontMap; 397cdf0e10cSrcweir typedef std::hash_map<FontAttributes,sal_Int32,FontAttrHash> FontToIdMap; 398cdf0e10cSrcweir 399cdf0e10cSrcweir typedef std::hash_map<sal_Int32,GraphicsContext> IdToGCMap; 400cdf0e10cSrcweir typedef std::hash_map<GraphicsContext,sal_Int32,GraphicsContextHash> GCToIdMap; 401cdf0e10cSrcweir 402cdf0e10cSrcweir typedef std::vector<GraphicsContext> GraphicsContextStack; 403cdf0e10cSrcweir 404cdf0e10cSrcweir sal_Int32 m_nNextFontId; 405cdf0e10cSrcweir IdToFontMap m_aIdToFont; 406cdf0e10cSrcweir FontToIdMap m_aFontToId; 407cdf0e10cSrcweir 408cdf0e10cSrcweir GraphicsContextStack m_aGCStack; 409cdf0e10cSrcweir geometry::RealSize2D m_aPageSize; 410cdf0e10cSrcweir geometry::RealRectangle2D m_aHyperlinkBounds; 411cdf0e10cSrcweir ::rtl::OUString m_aURI; 412cdf0e10cSrcweir ::rtl::OUStringBuffer m_aTextOut; 413cdf0e10cSrcweir sal_Int32 m_nNumPages; 414cdf0e10cSrcweir bool m_bPageEnded; 415cdf0e10cSrcweir bool m_bRedCircleSeen; 416cdf0e10cSrcweir bool m_bGreenStrokeSeen; 417cdf0e10cSrcweir bool m_bDashedLineSeen; 418cdf0e10cSrcweir }; 419cdf0e10cSrcweir 420*74e62aedSDamjan Jovanovic class PDFITest : public ::testing::Test 421cdf0e10cSrcweir { 422*74e62aedSDamjan Jovanovic protected: 423cdf0e10cSrcweir uno::Reference<uno::XComponentContext> mxCtx; 424cdf0e10cSrcweir rtl::OUString msBaseDir; 425cdf0e10cSrcweir bool mbUnoInitialized; 426cdf0e10cSrcweir 427cdf0e10cSrcweir public: 428cdf0e10cSrcweir PDFITest() : mxCtx(),msBaseDir(),mbUnoInitialized(false) 429cdf0e10cSrcweir {} 430cdf0e10cSrcweir 431*74e62aedSDamjan Jovanovic void SetUp() 432cdf0e10cSrcweir { 433cdf0e10cSrcweir if( !mbUnoInitialized ) 434cdf0e10cSrcweir { 435*74e62aedSDamjan Jovanovic const char* pArgs( getenv("TESTS_FORWARD_STRING") ); 436*74e62aedSDamjan Jovanovic ASSERT_TRUE(pArgs) << "Test file parameter"; 437cdf0e10cSrcweir 438cdf0e10cSrcweir msBaseDir = rtl::OUString::createFromAscii(pArgs); 439cdf0e10cSrcweir 440cdf0e10cSrcweir // bootstrap UNO 441cdf0e10cSrcweir try 442cdf0e10cSrcweir { 443cdf0e10cSrcweir ::rtl::OUString aIniUrl; 444*74e62aedSDamjan Jovanovic ASSERT_TRUE( 445cdf0e10cSrcweir osl_getFileURLFromSystemPath( 446cdf0e10cSrcweir (msBaseDir+rtl::OUString::createFromAscii("pdfi_unittest_test.ini")).pData, 447*74e62aedSDamjan Jovanovic &aIniUrl.pData ) == osl_File_E_None ) 448*74e62aedSDamjan Jovanovic << "Converting ini file to URL"; 449cdf0e10cSrcweir 450cdf0e10cSrcweir mxCtx = ::cppu::defaultBootstrap_InitialComponentContext(aIniUrl); 451*74e62aedSDamjan Jovanovic ASSERT_TRUE(mxCtx.is()) << "Getting component context"; 452cdf0e10cSrcweir } 453cdf0e10cSrcweir catch( uno::Exception& ) 454cdf0e10cSrcweir { 455*74e62aedSDamjan Jovanovic FAIL() << "Bootstrapping UNO"; 456cdf0e10cSrcweir } 457cdf0e10cSrcweir 458cdf0e10cSrcweir mbUnoInitialized = true; 459cdf0e10cSrcweir } 460cdf0e10cSrcweir } 461*74e62aedSDamjan Jovanovic void TearDown() 462cdf0e10cSrcweir { 463cdf0e10cSrcweir } 464cdf0e10cSrcweir }; 465cdf0e10cSrcweir 466*74e62aedSDamjan Jovanovic TEST_F(PDFITest, testXPDFParser) 467*74e62aedSDamjan Jovanovic { 468*74e62aedSDamjan Jovanovic pdfi::ContentSinkSharedPtr pSink( new TestSink() ); 469*74e62aedSDamjan Jovanovic pdfi::xpdf_ImportFromFile( msBaseDir + rtl::OUString::createFromAscii("pdfi_unittest_test.pdf"), 470*74e62aedSDamjan Jovanovic pSink, 471*74e62aedSDamjan Jovanovic uno::Reference< task::XInteractionHandler >(), 472*74e62aedSDamjan Jovanovic rtl::OUString(), 473*74e62aedSDamjan Jovanovic mxCtx ); 474*74e62aedSDamjan Jovanovic 475*74e62aedSDamjan Jovanovic // make destruction explicit, a bunch of things are 476*74e62aedSDamjan Jovanovic // checked in the destructor 477*74e62aedSDamjan Jovanovic pSink.reset(); 478*74e62aedSDamjan Jovanovic } 479*74e62aedSDamjan Jovanovic 480*74e62aedSDamjan Jovanovic TEST_F(PDFITest, testOdfDrawExport) 481*74e62aedSDamjan Jovanovic { 482*74e62aedSDamjan Jovanovic pdfi::PDFIRawAdaptor aAdaptor( mxCtx ); 483*74e62aedSDamjan Jovanovic aAdaptor.setTreeVisitorFactory( createDrawTreeVisitorFactory() ); 484*74e62aedSDamjan Jovanovic 485*74e62aedSDamjan Jovanovic ::rtl::OUString aURL, aAbsURL, aBaseURL; 486*74e62aedSDamjan Jovanovic osl_getFileURLFromSystemPath( (msBaseDir + rtl::OUString::createFromAscii("pdfi_unittest_draw.xml")).pData, 487*74e62aedSDamjan Jovanovic &aURL.pData ); 488*74e62aedSDamjan Jovanovic osl_getProcessWorkingDir(&aBaseURL.pData); 489*74e62aedSDamjan Jovanovic osl_getAbsoluteFileURL(aBaseURL.pData,aURL.pData,&aAbsURL.pData); 490*74e62aedSDamjan Jovanovic ASSERT_TRUE(aAdaptor.odfConvert( msBaseDir + rtl::OUString::createFromAscii("pdfi_unittest_test.pdf"), 491*74e62aedSDamjan Jovanovic new OutputWrap(aAbsURL), 492*74e62aedSDamjan Jovanovic NULL )) << "Exporting to ODF"; 493*74e62aedSDamjan Jovanovic } 494*74e62aedSDamjan Jovanovic 495*74e62aedSDamjan Jovanovic TEST_F(PDFITest, testOdfWriterExport) 496*74e62aedSDamjan Jovanovic { 497*74e62aedSDamjan Jovanovic pdfi::PDFIRawAdaptor aAdaptor( mxCtx ); 498*74e62aedSDamjan Jovanovic aAdaptor.setTreeVisitorFactory( createWriterTreeVisitorFactory() ); 499*74e62aedSDamjan Jovanovic 500*74e62aedSDamjan Jovanovic ::rtl::OUString aURL, aAbsURL, aBaseURL; 501*74e62aedSDamjan Jovanovic osl_getFileURLFromSystemPath( (msBaseDir + rtl::OUString::createFromAscii("pdfi_unittest_writer.xml")).pData, 502*74e62aedSDamjan Jovanovic &aURL.pData ); 503*74e62aedSDamjan Jovanovic osl_getProcessWorkingDir(&aBaseURL.pData); 504*74e62aedSDamjan Jovanovic osl_getAbsoluteFileURL(aBaseURL.pData,aURL.pData,&aAbsURL.pData); 505*74e62aedSDamjan Jovanovic ASSERT_TRUE(aAdaptor.odfConvert( msBaseDir + rtl::OUString::createFromAscii("pdfi_unittest_test.pdf"), 506*74e62aedSDamjan Jovanovic new OutputWrap(aAbsURL), 507*74e62aedSDamjan Jovanovic NULL )) << "Exporting to ODF"; 508*74e62aedSDamjan Jovanovic } 509cdf0e10cSrcweir 510*74e62aedSDamjan Jovanovic } 511cdf0e10cSrcweir 512*74e62aedSDamjan Jovanovic int main(int argc, char **argv) 513*74e62aedSDamjan Jovanovic { 514*74e62aedSDamjan Jovanovic ::testing::InitGoogleTest(&argc, argv); 515*74e62aedSDamjan Jovanovic return RUN_ALL_TESTS(); 516*74e62aedSDamjan Jovanovic } 517