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