1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svx.hxx" 26 27 #include <vector> 28 #include <vos/mutex.hxx> 29 #include <com/sun/star/io/XOutputStream.hpp> 30 #include <com/sun/star/container/XChild.hpp> 31 #include <com/sun/star/frame/XModel.hpp> 32 #include <com/sun/star/document/XFilter.hpp> 33 #include <com/sun/star/document/XExporter.hpp> 34 #include <com/sun/star/document/XMimeTypeInfo.hpp> 35 #include <com/sun/star/lang/XServiceInfo.hpp> 36 #include <com/sun/star/lang/XComponent.hpp> 37 #include <com/sun/star/drawing/XShape.hpp> 38 #include <com/sun/star/drawing/XDrawPage.hpp> 39 #include <com/sun/star/graphic/XGraphic.hpp> 40 #include <com/sun/star/graphic/XGraphicRenderer.hpp> 41 #include <com/sun/star/task/XStatusIndicator.hpp> 42 #include <com/sun/star/task/XInteractionHandler.hpp> 43 #include <com/sun/star/task/XInteractionContinuation.hpp> 44 45 #include <comphelper/interaction.hxx> 46 #include <framework/interaction.hxx> 47 #include <com/sun/star/drawing/GraphicFilterRequest.hpp> 48 #include <com/sun/star/util/URL.hpp> 49 #include <cppuhelper/implbase4.hxx> 50 #include <osl/diagnose.h> 51 #include <osl/mutex.hxx> 52 #include <vcl/metaact.hxx> 53 #include <vcl/svapp.hxx> 54 #include <vcl/virdev.hxx> 55 #include <svtools/FilterConfigItem.hxx> 56 #include <svl/outstrm.hxx> 57 #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx> 58 #include <svx/sdr/contact/viewobjectcontact.hxx> 59 #include <svx/sdr/contact/viewcontact.hxx> 60 #include <svx/sdr/contact/displayinfo.hxx> 61 #include <svx/sdr/contact/viewcontactofsdrobj.hxx> 62 #include <editeng/numitem.hxx> 63 #include <svx/svdpagv.hxx> 64 #include <svx/svdograf.hxx> 65 #include "svx/xoutbmp.hxx" 66 #include "svtools/filter.hxx" 67 #include "svx/unoapi.hxx" 68 #include <svx/svdpage.hxx> 69 #include <svx/svdmodel.hxx> 70 #include <svx/fmview.hxx> 71 #include <svx/fmmodel.hxx> 72 #include <svx/unopage.hxx> 73 #include <svx/pageitem.hxx> 74 #include <editeng/eeitem.hxx> 75 #include <svx/svdoutl.hxx> 76 #include <editeng/flditem.hxx> 77 78 #include "boost/scoped_ptr.hpp" 79 80 #define MAX_EXT_PIX 2048 81 82 using namespace ::comphelper; 83 using namespace ::osl; 84 using namespace ::vos; 85 using ::rtl::OUString; 86 using namespace ::cppu; 87 using namespace ::com::sun::star; 88 using namespace ::com::sun::star::uno; 89 using namespace ::com::sun::star::util; 90 using namespace ::com::sun::star::container; 91 using namespace ::com::sun::star::drawing; 92 using namespace ::com::sun::star::lang; 93 using namespace ::com::sun::star::document; 94 using namespace ::com::sun::star::frame; 95 using namespace ::com::sun::star::beans; 96 using namespace ::com::sun::star::task; 97 #include <svx/sdr/contact/viewobjectcontactredirector.hxx> 98 #include <svx/sdr/contact/viewobjectcontact.hxx> 99 #include <svx/sdr/contact/viewcontact.hxx> 100 101 // #i102251# 102 #include <editeng/editstat.hxx> 103 104 ////////////////////////////////////////////////////////////////////////////// 105 106 namespace svx 107 { 108 struct ExportSettings 109 { 110 OUString maFilterName; 111 OUString maMediaType; 112 URL maURL; 113 com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > mxOutputStream; 114 com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicRenderer > mxGraphicRenderer; 115 com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > mxStatusIndicator; 116 com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > mxInteractionHandler; 117 118 sal_Int32 mnWidth; 119 sal_Int32 mnHeight; 120 sal_Bool mbExportOnlyBackground; 121 sal_Bool mbVerboseComments; 122 sal_Bool mbScrollText; 123 sal_Bool mbUseHighContrast; 124 sal_Bool mbTranslucent; 125 126 Sequence< PropertyValue > maFilterData; 127 128 Fraction maScaleX; 129 Fraction maScaleY; 130 131 ExportSettings( SdrModel* pDoc ); 132 }; 133 134 ExportSettings::ExportSettings( SdrModel* pDoc ) 135 : mnWidth( 0 ) 136 , mnHeight( 0 ) 137 , mbExportOnlyBackground( false ) 138 , mbVerboseComments( false ) 139 , mbScrollText( false ) 140 , mbUseHighContrast( false ) 141 , mbTranslucent( sal_False ) 142 , maScaleX( 1, 1 ) 143 , maScaleY( 1, 1 ) 144 { 145 if( pDoc ) 146 { 147 maScaleX = pDoc->GetScaleFraction(); 148 maScaleY = pDoc->GetScaleFraction(); 149 } 150 } 151 152 /** implements a component to export shapes or pages to external graphic formats. 153 154 @implements com.sun.star.drawing.GraphicExportFilter 155 */ 156 class GraphicExporter : public WeakImplHelper4< XFilter, XExporter, XServiceInfo, XMimeTypeInfo > 157 { 158 public: 159 GraphicExporter(); 160 virtual ~GraphicExporter(); 161 162 // XFilter 163 virtual sal_Bool SAL_CALL filter( const Sequence< PropertyValue >& aDescriptor ) throw(RuntimeException); 164 virtual void SAL_CALL cancel( ) throw(RuntimeException); 165 166 // XExporter 167 virtual void SAL_CALL setSourceDocument( const Reference< XComponent >& xDoc ) throw(IllegalArgumentException, RuntimeException); 168 169 // XServiceInfo 170 virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException); 171 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException); 172 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException); 173 174 // XMimeTypeInfo 175 virtual sal_Bool SAL_CALL supportsMimeType( const ::rtl::OUString& MimeTypeName ) throw (RuntimeException); 176 virtual Sequence< OUString > SAL_CALL getSupportedMimeTypeNames( ) throw (RuntimeException); 177 178 VirtualDevice* CreatePageVDev( SdrPage* pPage, sal_uIntPtr nWidthPixel, sal_uIntPtr nHeightPixel ) const; 179 180 DECL_LINK( CalcFieldValueHdl, EditFieldInfo* ); 181 182 void ParseSettings( const Sequence< PropertyValue >& aDescriptor, ExportSettings& rSettings ); 183 bool GetGraphic( ExportSettings& rSettings, Graphic& aGraphic, sal_Bool bVectorType ); 184 185 private: 186 Reference< XShape > mxShape; 187 Reference< XDrawPage > mxPage; 188 Reference< XShapes > mxShapes; 189 190 SvxDrawPage* mpUnoPage; 191 192 Link maOldCalcFieldValueHdl; 193 sal_Int32 mnPageNumber; 194 SdrPage* mpCurrentPage; 195 SdrModel* mpDoc; 196 }; 197 198 SVX_DLLPUBLIC Reference< XInterface > SAL_CALL GraphicExporter_createInstance(const Reference< XMultiServiceFactory > & ) 199 throw( Exception ) 200 { 201 return (XWeak*)new GraphicExporter(); 202 } 203 204 SVX_DLLPUBLIC Sequence< OUString > SAL_CALL GraphicExporter_getSupportedServiceNames() 205 throw() 206 { 207 Sequence< OUString > aSupportedServiceNames( 1 ); 208 aSupportedServiceNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GraphicExportFilter" ) ); 209 return aSupportedServiceNames; 210 } 211 212 SVX_DLLPUBLIC OUString SAL_CALL GraphicExporter_getImplementationName() 213 throw() 214 { 215 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Draw.GraphicExporter" ) ); 216 } 217 218 /** creates a bitmap that is optionaly transparent from a metafile 219 */ 220 BitmapEx GetBitmapFromMetaFile( const GDIMetaFile& rMtf, sal_Bool bTransparent, const Size* pSize ) 221 { 222 BitmapEx aBmpEx; 223 224 if(bTransparent) 225 { 226 // use new primitive conversion tooling 227 basegfx::B2DRange aRange(basegfx::B2DPoint(0.0, 0.0)); 228 sal_uInt32 nMaximumQuadraticPixels(500000); 229 230 if(pSize) 231 { 232 // use 100th mm for primitive bitmap converter tool, input is pixel 233 // use a real OutDev to get the correct DPI, the static LogicToLogic assumes 72dpi which is wrong (!) 234 const Size aSize100th(Application::GetDefaultDevice()->PixelToLogic(*pSize, MapMode(MAP_100TH_MM))); 235 236 aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height())); 237 238 // when explicitely pixels are requested from the GraphicExporter, use a *very* high limit 239 // of 16gb (4096x4096 pixels), else use the default for the converters 240 nMaximumQuadraticPixels = std::min(sal_uInt32(4096 * 4096), sal_uInt32(pSize->Width() * pSize->Height())); 241 } 242 else 243 { 244 // use 100th mm for primitive bitmap converter tool 245 const Size aSize100th(Application::GetDefaultDevice()->LogicToLogic(rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MapMode(MAP_100TH_MM))); 246 247 aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height())); 248 } 249 250 aBmpEx = convertMetafileToBitmapEx(rMtf, aRange, nMaximumQuadraticPixels); 251 } 252 else 253 { 254 const SvtOptionsDrawinglayer aDrawinglayerOpt; 255 Size aTargetSize(0, 0); 256 257 if(pSize) 258 { 259 // #122820# If a concrete target size in pixels is given, use it 260 aTargetSize = *pSize; 261 262 // get hairline and full bound rect to evtl. reduce given target pixel size when 263 // it is known that it will be expanded to get the right and bottom hairlines right 264 Rectangle aHairlineRect; 265 const Rectangle aRect(rMtf.GetBoundRect(*Application::GetDefaultDevice(), &aHairlineRect)); 266 267 if(!aRect.IsEmpty() && !aHairlineRect.IsEmpty()) 268 { 269 if(aRect.Right() == aHairlineRect.Right() || aRect.Bottom() == aHairlineRect.Bottom()) 270 { 271 if(aTargetSize.Width()) 272 { 273 aTargetSize.Width() -= 1; 274 } 275 276 if(aTargetSize.Height()) 277 { 278 aTargetSize.Height() -= 1; 279 } 280 } 281 } 282 } 283 284 const GraphicConversionParameters aParameters( 285 aTargetSize, 286 true, // allow unlimited size 287 aDrawinglayerOpt.IsAntiAliasing(), 288 aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete()); 289 const Graphic aGraphic(rMtf); 290 291 aBmpEx = BitmapEx(aGraphic.GetBitmap(aParameters)); 292 aBmpEx.SetPrefMapMode( rMtf.GetPrefMapMode() ); 293 aBmpEx.SetPrefSize( rMtf.GetPrefSize() ); 294 } 295 296 return aBmpEx; 297 } 298 299 Size* CalcSize( sal_Int32 nWidth, sal_Int32 nHeight, const Size& aBoundSize, Size& aOutSize ) 300 { 301 if( (nWidth == 0) && (nHeight == 0) ) 302 return NULL; 303 304 if( (nWidth == 0) && (nHeight != 0) && (aBoundSize.Height() != 0) ) 305 { 306 nWidth = ( nHeight * aBoundSize.Width() ) / aBoundSize.Height(); 307 } 308 else if( (nWidth != 0) && (nHeight == 0) && (aBoundSize.Width() != 0) ) 309 { 310 nHeight = ( nWidth * aBoundSize.Height() ) / aBoundSize.Width(); 311 } 312 313 aOutSize.Width() = nWidth; 314 aOutSize.Height() = nHeight; 315 316 return &aOutSize; 317 } 318 } 319 320 class ImplExportCheckVisisbilityRedirector : public ::sdr::contact::ViewObjectContactRedirector 321 { 322 public: 323 ImplExportCheckVisisbilityRedirector( SdrPage* pCurrentPage ); 324 virtual ~ImplExportCheckVisisbilityRedirector(); 325 326 virtual drawinglayer::primitive2d::Primitive2DSequence createRedirectedPrimitive2DSequence( 327 const sdr::contact::ViewObjectContact& rOriginal, 328 const sdr::contact::DisplayInfo& rDisplayInfo); 329 330 private: 331 SdrPage* mpCurrentPage; 332 }; 333 334 ImplExportCheckVisisbilityRedirector::ImplExportCheckVisisbilityRedirector( SdrPage* pCurrentPage ) 335 : ViewObjectContactRedirector(), mpCurrentPage( pCurrentPage ) 336 { 337 } 338 339 ImplExportCheckVisisbilityRedirector::~ImplExportCheckVisisbilityRedirector() 340 { 341 } 342 343 drawinglayer::primitive2d::Primitive2DSequence ImplExportCheckVisisbilityRedirector::createRedirectedPrimitive2DSequence( 344 const sdr::contact::ViewObjectContact& rOriginal, 345 const sdr::contact::DisplayInfo& rDisplayInfo) 346 { 347 SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject(); 348 349 if(pObject) 350 { 351 SdrPage* pPage = mpCurrentPage; 352 if( pPage == 0 ) 353 pPage = pObject->GetPage(); 354 355 if( (pPage == 0) || pPage->checkVisibility(rOriginal, rDisplayInfo, false) ) 356 { 357 return ::sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo); 358 } 359 360 return drawinglayer::primitive2d::Primitive2DSequence(); 361 } 362 else 363 { 364 // not an object, maybe a page 365 return ::sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo); 366 } 367 } 368 369 using namespace ::svx; 370 371 GraphicExporter::GraphicExporter() 372 : mpUnoPage( NULL ), mnPageNumber(-1), mpCurrentPage(0), mpDoc( NULL ) 373 { 374 } 375 376 GraphicExporter::~GraphicExporter() 377 { 378 } 379 380 IMPL_LINK(GraphicExporter, CalcFieldValueHdl, EditFieldInfo*, pInfo) 381 { 382 if( pInfo ) 383 { 384 if( mpCurrentPage ) 385 { 386 pInfo->SetSdrPage( mpCurrentPage ); 387 } 388 else if( mnPageNumber != -1 ) 389 { 390 const SvxFieldData* pField = pInfo->GetField().GetField(); 391 if( pField && pField->ISA( SvxPageField ) ) 392 { 393 String aPageNumValue; 394 sal_Bool bUpper = sal_False; 395 396 switch(mpDoc->GetPageNumType()) 397 { 398 case SVX_CHARS_UPPER_LETTER: 399 aPageNumValue += (sal_Unicode)(char)((mnPageNumber - 1) % 26 + 'A'); 400 break; 401 case SVX_CHARS_LOWER_LETTER: 402 aPageNumValue += (sal_Unicode)(char)((mnPageNumber - 1) % 26 + 'a'); 403 break; 404 case SVX_ROMAN_UPPER: 405 bUpper = sal_True; 406 case SVX_ROMAN_LOWER: 407 aPageNumValue += SvxNumberFormat::CreateRomanString(mnPageNumber, bUpper); 408 break; 409 case SVX_NUMBER_NONE: 410 aPageNumValue.Erase(); 411 aPageNumValue += sal_Unicode(' '); 412 break; 413 default: 414 aPageNumValue += String::CreateFromInt32( (sal_Int32)mnPageNumber ); 415 } 416 417 pInfo->SetRepresentation( aPageNumValue ); 418 419 return(0); 420 } 421 } 422 } 423 424 long nRet = maOldCalcFieldValueHdl.Call( pInfo ); 425 426 if( pInfo && mpCurrentPage ) 427 pInfo->SetSdrPage( 0 ); 428 429 return nRet; 430 } 431 432 /** creates an virtual device for the given page 433 434 @return the returned VirtualDevice is owned by the caller 435 */ 436 VirtualDevice* GraphicExporter::CreatePageVDev( SdrPage* pPage, sal_uIntPtr nWidthPixel, sal_uIntPtr nHeightPixel ) const 437 { 438 VirtualDevice* pVDev = new VirtualDevice(); 439 MapMode aMM( MAP_100TH_MM ); 440 441 Point aPoint( 0, 0 ); 442 Size aPageSize(pPage->GetSize()); 443 444 // use scaling? 445 if( nWidthPixel ) 446 { 447 const Fraction aFrac( (long) nWidthPixel, pVDev->LogicToPixel( aPageSize, aMM ).Width() ); 448 449 aMM.SetScaleX( aFrac ); 450 451 if( nHeightPixel == 0 ) 452 aMM.SetScaleY( aFrac ); 453 } 454 455 if( nHeightPixel ) 456 { 457 const Fraction aFrac( (long) nHeightPixel, pVDev->LogicToPixel( aPageSize, aMM ).Height() ); 458 459 if( nWidthPixel == 0 ) 460 aMM.SetScaleX( aFrac ); 461 462 aMM.SetScaleY( aFrac ); 463 } 464 465 pVDev->SetMapMode( aMM ); 466 bool bSuccess(false); 467 468 // #122820# If available, use pixel size directly 469 if(nWidthPixel && nHeightPixel) 470 { 471 bSuccess = pVDev->SetOutputSizePixel(Size(nWidthPixel, nHeightPixel)); 472 } 473 else 474 { 475 bSuccess = pVDev->SetOutputSize(aPageSize); 476 } 477 478 if(bSuccess) 479 { 480 SdrView* pView = new SdrView(mpDoc, pVDev); 481 pView->SetPageVisible( sal_False ); 482 pView->SetBordVisible( sal_False ); 483 pView->SetGridVisible( sal_False ); 484 pView->SetHlplVisible( sal_False ); 485 pView->SetGlueVisible( sal_False ); 486 pView->ShowSdrPage(pPage); 487 Region aRegion (Rectangle( aPoint, aPageSize ) ); 488 489 ImplExportCheckVisisbilityRedirector aRedirector( mpCurrentPage ); 490 491 pView->CompleteRedraw(pVDev, aRegion, &aRedirector); 492 delete pView; 493 } 494 else 495 { 496 OSL_ENSURE(false, "Could not get a VirtualDevice of requested size (!)"); 497 } 498 499 return pVDev; 500 } 501 502 void GraphicExporter::ParseSettings( const Sequence< PropertyValue >& aDescriptor, ExportSettings& rSettings ) 503 { 504 sal_Int32 nArgs = aDescriptor.getLength(); 505 const PropertyValue* pValues = aDescriptor.getConstArray(); 506 while( nArgs-- ) 507 { 508 if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FilterName" ) ) ) 509 { 510 pValues->Value >>= rSettings.maFilterName; 511 } 512 else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) 513 { 514 pValues->Value >>= rSettings.maMediaType; 515 } 516 else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "URL" ) ) ) 517 { 518 if( !( pValues->Value >>= rSettings.maURL ) ) 519 { 520 pValues->Value >>= rSettings.maURL.Complete; 521 } 522 } 523 else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OutputStream" ) ) ) 524 { 525 pValues->Value >>= rSettings.mxOutputStream; 526 } 527 else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicRenderer" ) ) ) 528 { 529 pValues->Value >>= rSettings.mxGraphicRenderer; 530 } 531 else if ( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StatusIndicator" ) ) ) 532 { 533 pValues->Value >>= rSettings.mxStatusIndicator; 534 } 535 else if ( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "InteractionHandler" ) ) ) 536 { 537 pValues->Value >>= rSettings.mxInteractionHandler; 538 } 539 else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Width" ) ) ) // for compatibility reasons, deprecated 540 { 541 pValues->Value >>= rSettings.mnWidth; 542 } 543 else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Height" ) ) ) // for compatibility reasons, deprecated 544 { 545 pValues->Value >>= rSettings.mnHeight; 546 } 547 else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ExportOnlyBackground" ) ) ) // for compatibility reasons, deprecated 548 { 549 pValues->Value >>= rSettings.mbExportOnlyBackground; 550 } 551 else if ( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FilterData" ) ) ) 552 { 553 pValues->Value >>= rSettings.maFilterData; 554 555 sal_Int32 nFilterArgs = rSettings.maFilterData.getLength(); 556 PropertyValue* pDataValues = rSettings.maFilterData.getArray(); 557 while( nFilterArgs-- ) 558 { 559 if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Translucent" ) ) ) 560 { 561 if ( !( pDataValues->Value >>= rSettings.mbTranslucent ) ) // SJ: TODO: The GIF Transparency is stored as int32 in 562 { // configuration files, this has to be changed to boolean 563 sal_Int32 nTranslucent = 0; 564 if ( pDataValues->Value >>= nTranslucent ) 565 rSettings.mbTranslucent = nTranslucent != 0; 566 } 567 } 568 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PixelWidth" ) ) ) 569 { 570 pDataValues->Value >>= rSettings.mnWidth; 571 } 572 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PixelHeight" ) ) ) 573 { 574 pDataValues->Value >>= rSettings.mnHeight; 575 } 576 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Width" ) ) ) // for compatibility reasons, deprecated 577 { 578 pDataValues->Value >>= rSettings.mnWidth; 579 pDataValues->Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PixelWidth" ) ); 580 } 581 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Height" ) ) ) // for compatibility reasons, deprecated 582 { 583 pDataValues->Value >>= rSettings.mnHeight; 584 pDataValues->Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PixelHeight" ) ); 585 } 586 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ExportOnlyBackground" ) ) ) 587 { 588 pDataValues->Value >>= rSettings.mbExportOnlyBackground; 589 } 590 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HighContrast" ) ) ) 591 { 592 pDataValues->Value >>= rSettings.mbUseHighContrast; 593 } 594 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PageNumber" ) ) ) 595 { 596 pDataValues->Value >>= mnPageNumber; 597 } 598 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "VerboseComments" ) ) ) 599 { 600 // #110496# Read flag for verbose metafile comments 601 pDataValues->Value >>= rSettings.mbVerboseComments; 602 } 603 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScrollText" ) ) ) 604 { 605 // #110496# Read flag solitary scroll text metafile 606 pDataValues->Value >>= rSettings.mbScrollText; 607 } 608 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CurrentPage" ) ) ) 609 { 610 Reference< XDrawPage > xPage; 611 pDataValues->Value >>= xPage; 612 if( xPage.is() ) 613 { 614 SvxDrawPage* pUnoPage = SvxDrawPage::getImplementation( xPage ); 615 if( pUnoPage && pUnoPage->GetSdrPage() ) 616 mpCurrentPage = pUnoPage->GetSdrPage(); 617 } 618 } 619 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleXNumerator" ) ) ) 620 { 621 sal_Int32 nVal = 1; 622 if( pDataValues->Value >>= nVal ) 623 rSettings.maScaleX = Fraction( nVal, rSettings.maScaleX.GetDenominator() ); 624 } 625 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleXDenominator" ) ) ) 626 { 627 sal_Int32 nVal = 1; 628 if( pDataValues->Value >>= nVal ) 629 rSettings.maScaleX = Fraction( rSettings.maScaleX.GetNumerator(), nVal ); 630 } 631 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleYNumerator" ) ) ) 632 { 633 sal_Int32 nVal = 1; 634 if( pDataValues->Value >>= nVal ) 635 rSettings.maScaleY = Fraction( nVal, rSettings.maScaleY.GetDenominator() ); 636 } 637 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleYDenominator" ) ) ) 638 { 639 sal_Int32 nVal = 1; 640 if( pDataValues->Value >>= nVal ) 641 rSettings.maScaleY = Fraction( rSettings.maScaleY.GetNumerator(), nVal ); 642 } 643 644 pDataValues++; 645 } 646 } 647 648 pValues++; 649 } 650 651 // putting the StatusIndicator that we got from the MediaDescriptor into our local FilterData copy 652 if ( rSettings.mxStatusIndicator.is() ) 653 { 654 rtl::OUString sStatusIndicator( RTL_CONSTASCII_USTRINGPARAM( "StatusIndicator" ) ); 655 int i = rSettings.maFilterData.getLength(); 656 rSettings.maFilterData.realloc( i + 1 ); 657 rSettings.maFilterData[ i ].Name = sStatusIndicator; 658 rSettings.maFilterData[ i ].Value <<= rSettings.mxStatusIndicator; 659 } 660 } 661 662 bool GraphicExporter::GetGraphic( ExportSettings& rSettings, Graphic& aGraphic, sal_Bool bVectorType ) 663 { 664 if( !mpDoc || !mpUnoPage ) 665 return false; 666 667 SdrPage* pPage = mpUnoPage->GetSdrPage(); 668 if( !pPage ) 669 return false; 670 671 VirtualDevice aVDev; 672 const MapMode aMap( mpDoc->GetScaleUnit(), Point(), rSettings.maScaleX, rSettings.maScaleY ); 673 674 SdrOutliner& rOutl=mpDoc->GetDrawOutliner(NULL); 675 maOldCalcFieldValueHdl = rOutl.GetCalcFieldValueHdl(); 676 rOutl.SetCalcFieldValueHdl( LINK(this, GraphicExporter, CalcFieldValueHdl) ); 677 rOutl.SetBackgroundColor( pPage->GetPageBackgroundColor() ); 678 679 // #i102251# 680 const sal_uInt32 nOldCntrl(rOutl.GetControlWord()); 681 sal_uInt32 nCntrl = nOldCntrl & ~EE_CNTRL_ONLINESPELLING; 682 rOutl.SetControlWord(nCntrl); 683 684 SdrObject* pTempBackgroundShape = 0; 685 std::vector< SdrObject* > aShapes; 686 bool bRet = true; 687 688 // export complete page? 689 if ( !mxShape.is() ) 690 { 691 if( rSettings.mbExportOnlyBackground ) 692 { 693 const SdrPageProperties* pCorrectProperties = pPage->getCorrectSdrPageProperties(); 694 695 if(pCorrectProperties) 696 { 697 pTempBackgroundShape = new SdrRectObj(Rectangle(Point(0,0), pPage->GetSize())); 698 pTempBackgroundShape->SetMergedItemSet(pCorrectProperties->GetItemSet()); 699 pTempBackgroundShape->SetMergedItem(XLineStyleItem(XLINE_NONE)); 700 pTempBackgroundShape->NbcSetStyleSheet(pCorrectProperties->GetStyleSheet(), true); 701 aShapes.push_back(pTempBackgroundShape); 702 } 703 } 704 else 705 { 706 const Size aSize( pPage->GetSize() ); 707 708 // generate a bitmap to convert it to a pixel format. 709 // For gif pictures there can also be a vector format used (bTranslucent) 710 if ( !bVectorType && !rSettings.mbTranslucent ) 711 { 712 long nWidthPix = 0; 713 long nHeightPix = 0; 714 if ( rSettings.mnWidth > 0 && rSettings.mnHeight > 0 ) 715 { 716 nWidthPix = rSettings.mnWidth; 717 nHeightPix = rSettings.mnHeight; 718 } 719 else 720 { 721 const Size aSizePix( Application::GetDefaultDevice()->LogicToPixel( aSize, aMap ) ); 722 if (aSizePix.Width() > MAX_EXT_PIX || aSizePix.Height() > MAX_EXT_PIX) 723 { 724 if (aSizePix.Width() > MAX_EXT_PIX) 725 nWidthPix = MAX_EXT_PIX; 726 else 727 nWidthPix = aSizePix.Width(); 728 if (aSizePix.Height() > MAX_EXT_PIX) 729 nHeightPix = MAX_EXT_PIX; 730 else 731 nHeightPix = aSizePix.Height(); 732 733 double fWidthDif = aSizePix.Width() / nWidthPix; 734 double fHeightDif = aSizePix.Height() / nHeightPix; 735 736 if (fWidthDif > fHeightDif) 737 nHeightPix = static_cast<long>(aSizePix.Height() / fWidthDif); 738 else 739 nWidthPix = static_cast<long>(aSizePix.Width() / fHeightDif); 740 } 741 else 742 { 743 nWidthPix = aSizePix.Width(); 744 nHeightPix = aSizePix.Height(); 745 } 746 } 747 748 boost::scoped_ptr< SdrView > pLocalView; 749 if( PTR_CAST( FmFormModel, mpDoc ) ) 750 { 751 pLocalView.reset( new FmFormView( PTR_CAST( FmFormModel, mpDoc ), &aVDev ) ); 752 } 753 else 754 { 755 pLocalView.reset( new SdrView( mpDoc, &aVDev ) ); 756 } 757 758 759 VirtualDevice* pVDev = CreatePageVDev( pPage, nWidthPix, nHeightPix ); 760 761 if( pVDev ) 762 { 763 aGraphic = pVDev->GetBitmap( Point(), pVDev->GetOutputSize() ); 764 aGraphic.SetPrefMapMode( aMap ); 765 aGraphic.SetPrefSize( aSize ); 766 delete pVDev; 767 } 768 } 769 // create a metafile to export a vector format 770 else 771 { 772 GDIMetaFile aMtf; 773 774 aVDev.SetMapMode( aMap ); 775 if( rSettings.mbUseHighContrast ) 776 aVDev.SetDrawMode( aVDev.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT ); 777 aVDev.EnableOutput( sal_False ); 778 aMtf.Record( &aVDev ); 779 Size aNewSize; 780 781 // create a view 782 SdrView* pView; 783 784 if( PTR_CAST( FmFormModel, mpDoc ) ) 785 { 786 pView = new FmFormView( PTR_CAST( FmFormModel, mpDoc ), &aVDev ); 787 } 788 else 789 { 790 pView = new SdrView( mpDoc, &aVDev ); 791 } 792 793 pView->SetBordVisible( sal_False ); 794 pView->SetPageVisible( sal_False ); 795 pView->ShowSdrPage( pPage ); 796 797 if ( pView && pPage ) 798 { 799 pView->SetBordVisible( sal_False ); 800 pView->SetPageVisible( sal_False ); 801 pView->ShowSdrPage( pPage ); 802 803 const Point aNewOrg( pPage->GetLftBorder(), pPage->GetUppBorder() ); 804 aNewSize = Size( aSize.Width() - pPage->GetLftBorder() - pPage->GetRgtBorder(), 805 aSize.Height() - pPage->GetUppBorder() - pPage->GetLwrBorder() ); 806 const Rectangle aClipRect( aNewOrg, aNewSize ); 807 MapMode aVMap( aMap ); 808 809 aVDev.Push(); 810 aVMap.SetOrigin( Point( -aNewOrg.X(), -aNewOrg.Y() ) ); 811 aVDev.SetRelativeMapMode( aVMap ); 812 aVDev.IntersectClipRegion( aClipRect ); 813 814 // Use new StandardCheckVisisbilityRedirector 815 ImplExportCheckVisisbilityRedirector aRedirector( mpCurrentPage ); 816 817 pView->CompleteRedraw(&aVDev, Region(Rectangle(Point(), aNewSize)), &aRedirector); 818 819 aVDev.Pop(); 820 821 aMtf.Stop(); 822 aMtf.WindStart(); 823 aMtf.SetPrefMapMode( aMap ); 824 aMtf.SetPrefSize( aNewSize ); 825 826 // AW: Here the current version was filtering out the META_CLIPREGION_ACTIONs 827 // from the metafile. I asked some other developers why this was done, but no 828 // one knew a direct reason. Since it's in for long time, it may be an old 829 // piece of code. MetaFiles save and load ClipRegions with polygons with preserving 830 // the polygons, so a resolution-indepent roundtrip is supported. Removed this 831 // code since it destroys some MetaFiles where ClipRegions are used. Anyways, 832 // just filtering them out is a hack, at least the encapsulated content would need 833 // to be clipped geometrically. 834 aGraphic = Graphic(aMtf); 835 } 836 837 if ( pView ) 838 { 839 pView->HideSdrPage(); 840 delete pView; 841 } 842 843 if( rSettings.mbTranslucent ) 844 { 845 Size aOutSize; 846 aGraphic = GetBitmapFromMetaFile( aGraphic.GetGDIMetaFile(), sal_True, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aNewSize, aOutSize ) ); 847 } 848 } 849 } 850 } 851 852 // export only single shape or shape collection 853 else 854 { 855 // build list of SdrObject 856 if( mxShapes.is() ) 857 { 858 Reference< XShape > xShape; 859 const sal_Int32 nCount = mxShapes->getCount(); 860 861 for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ ) 862 { 863 mxShapes->getByIndex( nIndex ) >>= xShape; 864 SdrObject* pObj = GetSdrObjectFromXShape( xShape ); 865 if( pObj ) 866 aShapes.push_back( pObj ); 867 } 868 } 869 else 870 { 871 // only one shape 872 SdrObject* pObj = GetSdrObjectFromXShape( mxShape ); 873 if( pObj ) 874 aShapes.push_back( pObj ); 875 } 876 877 if( aShapes.empty() ) 878 bRet = false; 879 } 880 881 if( bRet && !aShapes.empty() ) 882 { 883 // special treatment for only one SdrGrafObj that has text 884 sal_Bool bSingleGraphic = sal_False; 885 886 if( 1 == aShapes.size() ) 887 { 888 if( !bVectorType ) 889 { 890 SdrObject* pObj = aShapes.front(); 891 if( pObj && pObj->ISA( SdrGrafObj ) && !( (SdrGrafObj*) pObj )->HasText() ) 892 { 893 aGraphic = ( (SdrGrafObj*) pObj )->GetTransformedGraphic(); 894 if ( aGraphic.GetType() == GRAPHIC_BITMAP ) 895 { 896 Size aSizePixel( aGraphic.GetSizePixel() ); 897 if( rSettings.mnWidth && rSettings.mnHeight && 898 ( ( rSettings.mnWidth != aSizePixel.Width() ) || 899 ( rSettings.mnHeight != aSizePixel.Height() ) ) ) 900 { 901 BitmapEx aBmpEx( aGraphic.GetBitmapEx() ); 902 // export: use highest quality 903 aBmpEx.Scale( Size( rSettings.mnWidth, rSettings.mnHeight ), BMP_SCALE_LANCZOS ); 904 aGraphic = aBmpEx; 905 } 906 907 // #118804# only accept for bitmap graphics, else the 908 // conversion to bitmap will happen anywhere without size control 909 // as evtl. defined in rSettings.mnWidth/mnHeight 910 bSingleGraphic = sal_True; 911 } 912 } 913 } 914 else if( rSettings.mbScrollText ) 915 { 916 SdrObject* pObj = aShapes.front(); 917 if( pObj && pObj->ISA( SdrTextObj ) 918 && ( (SdrTextObj*) pObj )->HasText() ) 919 { 920 Rectangle aScrollRectangle; 921 Rectangle aPaintRectangle; 922 923 const boost::scoped_ptr< GDIMetaFile > pMtf( 924 ( (SdrTextObj*) pObj )->GetTextScrollMetaFileAndRectangle( 925 aScrollRectangle, aPaintRectangle ) ); 926 927 // take the larger one of the two rectangles (that 928 // should be the bound rect of the retrieved 929 // metafile) 930 Rectangle aTextRect; 931 932 if( aScrollRectangle.IsInside( aPaintRectangle ) ) 933 aTextRect = aScrollRectangle; 934 else 935 aTextRect = aPaintRectangle; 936 937 // setup pref size and mapmode 938 pMtf->SetPrefSize( aTextRect.GetSize() ); 939 940 // set actual origin (mtf is at actual shape 941 // output position) 942 MapMode aLocalMapMode( aMap ); 943 aLocalMapMode.SetOrigin( 944 Point( -aPaintRectangle.Left(), 945 -aPaintRectangle.Top() ) ); 946 pMtf->SetPrefMapMode( aLocalMapMode ); 947 948 pMtf->AddAction( new MetaCommentAction( 949 "XTEXT_SCROLLRECT", 0, 950 reinterpret_cast<sal_uInt8 const*>(&aScrollRectangle), 951 sizeof( Rectangle ) ) ); 952 pMtf->AddAction( new MetaCommentAction( 953 "XTEXT_PAINTRECT", 0, 954 reinterpret_cast<sal_uInt8 const*>(&aPaintRectangle), 955 sizeof( Rectangle ) ) ); 956 957 aGraphic = Graphic( *pMtf ); 958 959 bSingleGraphic = sal_True; 960 } 961 } 962 } 963 964 if( !bSingleGraphic ) 965 { 966 // create a metafile for all shapes 967 VirtualDevice aOut; 968 969 // calculate bound rect for all shapes 970 Rectangle aBound; 971 972 { 973 std::vector< SdrObject* >::iterator aIter = aShapes.begin(); 974 const std::vector< SdrObject* >::iterator aEnd = aShapes.end(); 975 976 while( aIter != aEnd ) 977 { 978 SdrObject* pObj = (*aIter++); 979 Rectangle aR1(pObj->GetCurrentBoundRect()); 980 if (aBound.IsEmpty()) 981 aBound=aR1; 982 else 983 aBound.Union(aR1); 984 } 985 } 986 987 aOut.EnableOutput( sal_False ); 988 aOut.SetMapMode( aMap ); 989 if( rSettings.mbUseHighContrast ) 990 aOut.SetDrawMode( aVDev.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT ); 991 992 GDIMetaFile aMtf; 993 aMtf.Clear(); 994 aMtf.Record( &aOut ); 995 996 MapMode aOutMap( aMap ); 997 aOutMap.SetOrigin( Point( -aBound.TopLeft().X(), -aBound.TopLeft().Y() ) ); 998 aOut.SetRelativeMapMode( aOutMap ); 999 1000 sdr::contact::DisplayInfo aDisplayInfo; 1001 1002 if(mpCurrentPage) 1003 { 1004 if(mpCurrentPage->TRG_HasMasterPage() && pPage->IsMasterPage()) 1005 { 1006 // MasterPage is processed as another page's SubContent 1007 aDisplayInfo.SetProcessLayers(mpCurrentPage->TRG_GetMasterPageVisibleLayers()); 1008 aDisplayInfo.SetSubContentActive(true); 1009 } 1010 } 1011 1012 if(!aShapes.empty()) 1013 { 1014 // more effective way to paint a vector of SdrObjects. Hand over the processed page 1015 // to have it in the 1016 sdr::contact::ObjectContactOfObjListPainter aMultiObjectPainter(aOut, aShapes, mpCurrentPage); 1017 ImplExportCheckVisisbilityRedirector aCheckVisibilityRedirector(mpCurrentPage); 1018 aMultiObjectPainter.SetViewObjectContactRedirector(&aCheckVisibilityRedirector); 1019 1020 aMultiObjectPainter.ProcessDisplay(aDisplayInfo); 1021 } 1022 1023 aMtf.Stop(); 1024 aMtf.WindStart(); 1025 1026 const Size aExtSize( aOut.PixelToLogic( Size( 0, 0 ) ) ); 1027 Size aBoundSize( aBound.GetWidth() + ( aExtSize.Width() ), 1028 aBound.GetHeight() + ( aExtSize.Height() ) ); 1029 1030 aMtf.SetPrefMapMode( aMap ); 1031 aMtf.SetPrefSize( aBoundSize ); 1032 1033 if( !bVectorType ) 1034 { 1035 Size aOutSize; 1036 aGraphic = GetBitmapFromMetaFile( aMtf, rSettings.mbTranslucent, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aBoundSize, aOutSize ) ); 1037 } 1038 else 1039 { 1040 aGraphic = aMtf; 1041 } 1042 } 1043 } 1044 1045 if(pTempBackgroundShape) 1046 { 1047 SdrObject::Free(pTempBackgroundShape); 1048 } 1049 1050 rOutl.SetCalcFieldValueHdl( maOldCalcFieldValueHdl ); 1051 1052 // #i102251# 1053 rOutl.SetControlWord(nOldCntrl); 1054 1055 return bRet; 1056 1057 } 1058 1059 // XFilter 1060 sal_Bool SAL_CALL GraphicExporter::filter( const Sequence< PropertyValue >& aDescriptor ) 1061 throw(RuntimeException) 1062 { 1063 OGuard aGuard( Application::GetSolarMutex() ); 1064 1065 if( NULL == mpUnoPage ) 1066 return sal_False; 1067 1068 GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter(); 1069 1070 if( NULL == pFilter || NULL == mpUnoPage->GetSdrPage() || NULL == mpDoc ) 1071 return sal_False; 1072 1073 // get the arguments from the descriptor 1074 ExportSettings aSettings( mpDoc ); 1075 ParseSettings( aDescriptor, aSettings ); 1076 1077 const sal_uInt16 nFilter = aSettings.maMediaType.getLength() 1078 ? pFilter->GetExportFormatNumberForMediaType( aSettings.maMediaType ) 1079 : pFilter->GetExportFormatNumberForShortName( aSettings.maFilterName ); 1080 sal_Bool bVectorType = !pFilter->IsExportPixelFormat( nFilter ); 1081 1082 // create the output stuff 1083 Graphic aGraphic; 1084 1085 sal_uInt16 nStatus = GetGraphic( aSettings, aGraphic, bVectorType ) ? GRFILTER_OK : GRFILTER_FILTERERROR; 1086 1087 if( nStatus == GRFILTER_OK ) 1088 { 1089 // export graphic only if it has a size 1090 const Size aGraphSize( aGraphic.GetPrefSize() ); 1091 if ( ( aGraphSize.Width() == 0 ) || ( aGraphSize.Height() == 0 ) ) 1092 { 1093 nStatus = GRFILTER_FILTERERROR; 1094 } 1095 else 1096 { 1097 // now we have a graphic, so export it 1098 if( aSettings.mxGraphicRenderer.is() ) 1099 { 1100 // render graphic directly into given renderer 1101 aSettings.mxGraphicRenderer->render( aGraphic.GetXGraphic() ); 1102 } 1103 else if( aSettings.mxOutputStream.is() ) 1104 { 1105 // TODO: Either utilize optional XSeekable functionality for the 1106 // SvOutputStream, or adapt the graphic filter to not seek anymore. 1107 SvMemoryStream aStream( 1024, 1024 ); 1108 1109 nStatus = pFilter->ExportGraphic( aGraphic, String(), aStream, nFilter, &aSettings.maFilterData ); 1110 1111 // copy temp stream to XOutputStream 1112 SvOutputStream aOutputStream( aSettings.mxOutputStream ); 1113 aStream.Seek(0); 1114 aOutputStream << aStream; 1115 } 1116 else 1117 { 1118 INetURLObject aURLObject( aSettings.maURL.Complete ); 1119 DBG_ASSERT( aURLObject.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); 1120 1121 nStatus = XOutBitmap::ExportGraphic( aGraphic, aURLObject, *pFilter, nFilter, &aSettings.maFilterData ); 1122 } 1123 } 1124 } 1125 1126 if ( aSettings.mxInteractionHandler.is() && ( nStatus != GRFILTER_OK ) ) 1127 { 1128 Any aInteraction; 1129 Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > lContinuations(1); 1130 ::comphelper::OInteractionApprove* pApprove = new ::comphelper::OInteractionApprove(); 1131 lContinuations[0] = Reference< XInteractionContinuation >(static_cast< XInteractionContinuation* >(pApprove), UNO_QUERY); 1132 1133 GraphicFilterRequest aErrorCode; 1134 aErrorCode.ErrCode = nStatus; 1135 aInteraction <<= aErrorCode; 1136 aSettings.mxInteractionHandler->handle( framework::InteractionRequest::CreateRequest( aInteraction, lContinuations ) ); 1137 } 1138 return nStatus == GRFILTER_OK; 1139 } 1140 1141 void SAL_CALL GraphicExporter::cancel() 1142 throw(RuntimeException) 1143 { 1144 } 1145 1146 // XExporter 1147 1148 /** the source 'document' could be a XDrawPage, a XShape or a generic XShapes */ 1149 void SAL_CALL GraphicExporter::setSourceDocument( const Reference< lang::XComponent >& xComponent ) 1150 throw(IllegalArgumentException, RuntimeException) 1151 { 1152 OGuard aGuard( Application::GetSolarMutex() ); 1153 1154 mxShapes = NULL; 1155 mpUnoPage = NULL; 1156 1157 try 1158 { 1159 // any break inside this one loop while will throw a IllegalArgumentException 1160 do 1161 { 1162 mxPage = Reference< XDrawPage >::query( xComponent ); 1163 mxShapes = Reference< XShapes >::query( xComponent ); 1164 mxShape = Reference< XShape >::query( xComponent ); 1165 1166 // Step 1: try a generic XShapes 1167 if( !mxPage.is() && !mxShape.is() && mxShapes.is() ) 1168 { 1169 // we do not support empty shape collections 1170 if( 0 == mxShapes->getCount() ) 1171 break; 1172 1173 // get first shape to detect corresponding page and model 1174 mxShapes->getByIndex(0) >>= mxShape; 1175 } 1176 else 1177 { 1178 mxShapes = NULL; 1179 } 1180 1181 // Step 2: try a shape 1182 if( mxShape.is() ) 1183 { 1184 if( NULL == GetSdrObjectFromXShape( mxShape ) ) 1185 break; 1186 1187 // get page for this shape 1188 Reference< XChild > xChild( mxShape, UNO_QUERY ); 1189 if( !xChild.is() ) 1190 break; 1191 1192 Reference< XInterface > xInt; 1193 do 1194 { 1195 xInt = xChild->getParent(); 1196 mxPage = Reference< XDrawPage >::query( xInt ); 1197 if( !mxPage.is() ) 1198 xChild = Reference< XChild >::query( xInt ); 1199 } 1200 while( !mxPage.is() && xChild.is() ); 1201 1202 if( !mxPage.is() ) 1203 break; 1204 } 1205 1206 // Step 3: check the page 1207 if( !mxPage.is() ) 1208 break; 1209 1210 mpUnoPage = SvxDrawPage::getImplementation( mxPage ); 1211 1212 if( NULL == mpUnoPage || NULL == mpUnoPage->GetSdrPage() ) 1213 break; 1214 1215 mpDoc = mpUnoPage->GetSdrPage()->GetModel(); 1216 1217 // Step 4: If we got a generic XShapes test all contained shapes 1218 // if they belong to the same XDrawPage 1219 1220 if( mxShapes.is() ) 1221 { 1222 SdrPage* pPage = mpUnoPage->GetSdrPage(); 1223 SdrObject* pObj; 1224 Reference< XShape > xShape; 1225 1226 sal_Bool bOk = sal_True; 1227 1228 const sal_Int32 nCount = mxShapes->getCount(); 1229 1230 // test all but the first shape if they have the same page than 1231 // the first shape 1232 for( sal_Int32 nIndex = 1; bOk && ( nIndex < nCount ); nIndex++ ) 1233 { 1234 mxShapes->getByIndex( nIndex ) >>= xShape; 1235 pObj = GetSdrObjectFromXShape( xShape ); 1236 bOk = pObj && pObj->GetPage() == pPage; 1237 } 1238 1239 if( !bOk ) 1240 break; 1241 } 1242 1243 // no errors so far 1244 return; 1245 } 1246 while( 0 ); 1247 } 1248 catch( Exception& ) 1249 { 1250 } 1251 1252 throw IllegalArgumentException(); 1253 } 1254 1255 // XServiceInfo 1256 OUString SAL_CALL GraphicExporter::getImplementationName( ) 1257 throw(RuntimeException) 1258 { 1259 return GraphicExporter_getImplementationName(); 1260 } 1261 1262 sal_Bool SAL_CALL GraphicExporter::supportsService( const OUString& ServiceName ) 1263 throw(RuntimeException) 1264 { 1265 Sequence< OUString > aSeq( GraphicExporter_getSupportedServiceNames() ); 1266 sal_Int32 nArgs = aSeq.getLength(); 1267 const OUString* pService = aSeq.getConstArray(); 1268 while( nArgs-- ) 1269 if( *pService++ == ServiceName ) 1270 return sal_True; 1271 1272 return sal_False; 1273 } 1274 1275 Sequence< OUString > SAL_CALL GraphicExporter::getSupportedServiceNames( ) 1276 throw(RuntimeException) 1277 { 1278 return GraphicExporter_getSupportedServiceNames(); 1279 } 1280 1281 // XMimeTypeInfo 1282 sal_Bool SAL_CALL GraphicExporter::supportsMimeType( const OUString& MimeTypeName ) throw (RuntimeException) 1283 { 1284 const String aMimeTypeName( MimeTypeName ); 1285 1286 GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter(); 1287 sal_uInt16 nCount = pFilter->GetExportFormatCount(); 1288 sal_uInt16 nFilter; 1289 for( nFilter = 0; nFilter < nCount; nFilter++ ) 1290 { 1291 if( aMimeTypeName.Equals( pFilter->GetExportFormatMediaType( nFilter ) ) ) 1292 { 1293 return sal_True; 1294 } 1295 } 1296 1297 return sal_False; 1298 } 1299 1300 Sequence< OUString > SAL_CALL GraphicExporter::getSupportedMimeTypeNames( ) throw (RuntimeException) 1301 { 1302 GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter(); 1303 sal_uInt16 nCount = pFilter->GetExportFormatCount(); 1304 sal_uInt16 nFilter; 1305 sal_uInt16 nFound = 0; 1306 1307 Sequence< OUString > aSeq( nCount ); 1308 OUString* pStr = aSeq.getArray(); 1309 1310 for( nFilter = 0; nFilter < nCount; nFilter++ ) 1311 { 1312 OUString aMimeType( pFilter->GetExportFormatMediaType( nFilter ) ); 1313 if( aMimeType.getLength() ) 1314 { 1315 *pStr++ = aMimeType; 1316 nFound++; 1317 } 1318 } 1319 1320 if( nFound < nCount ) 1321 aSeq.realloc( nFound ); 1322 1323 return aSeq; 1324 } 1325 1326 Graphic SvxGetGraphicForShape( SdrObject& rShape, bool bVector ) 1327 { 1328 Graphic aGraphic; 1329 try 1330 { 1331 rtl::Reference< GraphicExporter > xExporter( new GraphicExporter() ); 1332 Reference< XComponent > xComp( rShape.getUnoShape(), UNO_QUERY_THROW ); 1333 xExporter->setSourceDocument( xComp ); 1334 ExportSettings aSettings( rShape.GetModel() ); 1335 xExporter->GetGraphic( aSettings, aGraphic, bVector ); 1336 } 1337 catch( Exception& ) 1338 { 1339 DBG_ERROR("SvxGetGraphicForShape(), exception caught!"); 1340 } 1341 return aGraphic; 1342 } 1343 1344