xref: /AOO41X/main/svx/source/unodraw/UnoGraphicExporter.cxx (revision 1193d70da336d3c29892d6465fc19e1bdd59f51e)
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 
229             if(pSize)
230             {
231                 // use 100th mm for primitive bitmap converter tool, input is pixel
232                 // use a real OutDev to get the correct DPI, the static LogicToLogic assumes 72dpi which is wrong (!)
233                 const Size aSize100th(Application::GetDefaultDevice()->PixelToLogic(*pSize, MapMode(MAP_100TH_MM)));
234 
235                 aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height()));
236             }
237             else
238             {
239                 // use 100th mm for primitive bitmap converter tool
240                 const Size aSize100th(Application::GetDefaultDevice()->LogicToLogic(rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MapMode(MAP_100TH_MM)));
241 
242                 aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height()));
243             }
244 
245             aBmpEx = convertMetafileToBitmapEx(rMtf, aRange);
246         }
247         else
248         {
249             const SvtOptionsDrawinglayer aDrawinglayerOpt;
250             const GraphicConversionParameters aParameters(
251                 pSize ? *pSize : Size(0, 0),
252                 true, // allow unlimited size
253                 aDrawinglayerOpt.IsAntiAliasing(),
254                 aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete());
255             const Graphic aGraphic(rMtf);
256 
257             aBmpEx = BitmapEx(aGraphic.GetBitmap(aParameters));
258             aBmpEx.SetPrefMapMode( rMtf.GetPrefMapMode() );
259             aBmpEx.SetPrefSize( rMtf.GetPrefSize() );
260         }
261 
262         return aBmpEx;
263     }
264 
265     Size* CalcSize( sal_Int32 nWidth, sal_Int32 nHeight, const Size& aBoundSize, Size& aOutSize )
266     {
267         if( (nWidth == 0) && (nHeight == 0) )
268             return NULL;
269 
270         if( (nWidth == 0) && (nHeight != 0) && (aBoundSize.Height() != 0) )
271         {
272             nWidth = ( nHeight * aBoundSize.Width() ) / aBoundSize.Height();
273         }
274         else if( (nWidth != 0) && (nHeight == 0) && (aBoundSize.Width() != 0) )
275         {
276             nHeight = ( nWidth * aBoundSize.Height() ) / aBoundSize.Width();
277         }
278 
279         aOutSize.Width() = nWidth;
280         aOutSize.Height() = nHeight;
281 
282         return &aOutSize;
283     }
284 }
285 
286 class ImplExportCheckVisisbilityRedirector : public ::sdr::contact::ViewObjectContactRedirector
287 {
288 public:
289     ImplExportCheckVisisbilityRedirector( SdrPage* pCurrentPage );
290     virtual ~ImplExportCheckVisisbilityRedirector();
291 
292     virtual drawinglayer::primitive2d::Primitive2DSequence createRedirectedPrimitive2DSequence(
293         const sdr::contact::ViewObjectContact& rOriginal,
294         const sdr::contact::DisplayInfo& rDisplayInfo);
295 
296 private:
297     SdrPage*    mpCurrentPage;
298 };
299 
300 ImplExportCheckVisisbilityRedirector::ImplExportCheckVisisbilityRedirector( SdrPage* pCurrentPage )
301 :   ViewObjectContactRedirector(), mpCurrentPage( pCurrentPage )
302 {
303 }
304 
305 ImplExportCheckVisisbilityRedirector::~ImplExportCheckVisisbilityRedirector()
306 {
307 }
308 
309 drawinglayer::primitive2d::Primitive2DSequence ImplExportCheckVisisbilityRedirector::createRedirectedPrimitive2DSequence(
310     const sdr::contact::ViewObjectContact& rOriginal,
311     const sdr::contact::DisplayInfo& rDisplayInfo)
312 {
313     SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
314 
315     if(pObject)
316     {
317         SdrPage* pPage = mpCurrentPage;
318         if( pPage == 0 )
319             pPage = pObject->GetPage();
320 
321         if( (pPage == 0) || pPage->checkVisibility(rOriginal, rDisplayInfo, false) )
322         {
323             return ::sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
324         }
325 
326         return drawinglayer::primitive2d::Primitive2DSequence();
327     }
328     else
329     {
330         // not an object, maybe a page
331         return ::sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
332     }
333 }
334 
335 using namespace ::svx;
336 
337 GraphicExporter::GraphicExporter()
338 : mpUnoPage( NULL ), mnPageNumber(-1), mpCurrentPage(0), mpDoc( NULL )
339 {
340 }
341 
342 GraphicExporter::~GraphicExporter()
343 {
344 }
345 
346 IMPL_LINK(GraphicExporter, CalcFieldValueHdl, EditFieldInfo*, pInfo)
347 {
348     if( pInfo )
349     {
350         if( mpCurrentPage )
351         {
352             pInfo->SetSdrPage( mpCurrentPage );
353         }
354         else if( mnPageNumber != -1 )
355         {
356             const SvxFieldData* pField = pInfo->GetField().GetField();
357             if( pField && pField->ISA( SvxPageField ) )
358             {
359                 String aPageNumValue;
360                 sal_Bool bUpper = sal_False;
361 
362                 switch(mpDoc->GetPageNumType())
363                 {
364                     case SVX_CHARS_UPPER_LETTER:
365                         aPageNumValue += (sal_Unicode)(char)((mnPageNumber - 1) % 26 + 'A');
366                         break;
367                     case SVX_CHARS_LOWER_LETTER:
368                         aPageNumValue += (sal_Unicode)(char)((mnPageNumber - 1) % 26 + 'a');
369                         break;
370                     case SVX_ROMAN_UPPER:
371                         bUpper = sal_True;
372                     case SVX_ROMAN_LOWER:
373                         aPageNumValue += SvxNumberFormat::CreateRomanString(mnPageNumber, bUpper);
374                         break;
375                     case SVX_NUMBER_NONE:
376                         aPageNumValue.Erase();
377                         aPageNumValue += sal_Unicode(' ');
378                         break;
379                     default:
380                         aPageNumValue += String::CreateFromInt32( (sal_Int32)mnPageNumber );
381                 }
382 
383                 pInfo->SetRepresentation( aPageNumValue );
384 
385                 return(0);
386             }
387         }
388     }
389 
390     long nRet = maOldCalcFieldValueHdl.Call( pInfo );
391 
392     if( pInfo && mpCurrentPage )
393         pInfo->SetSdrPage( 0 );
394 
395     return nRet;
396 }
397 
398 /** creates an virtual device for the given page
399 
400     @return the returned VirtualDevice is owned by the caller
401 */
402 VirtualDevice* GraphicExporter::CreatePageVDev( SdrPage* pPage, sal_uIntPtr nWidthPixel, sal_uIntPtr nHeightPixel ) const
403 {
404     VirtualDevice*  pVDev = new VirtualDevice();
405     MapMode         aMM( MAP_100TH_MM );
406 
407     Point aPoint( 0, 0 );
408     Size aPageSize(pPage->GetSize());
409 
410     // use scaling?
411     if( nWidthPixel )
412     {
413         const Fraction aFrac( (long) nWidthPixel, pVDev->LogicToPixel( aPageSize, aMM ).Width() );
414 
415         aMM.SetScaleX( aFrac );
416 
417         if( nHeightPixel == 0 )
418             aMM.SetScaleY( aFrac );
419     }
420 
421     if( nHeightPixel )
422     {
423         const Fraction aFrac( (long) nHeightPixel, pVDev->LogicToPixel( aPageSize, aMM ).Height() );
424 
425         if( nWidthPixel == 0 )
426             aMM.SetScaleX( aFrac );
427 
428         aMM.SetScaleY( aFrac );
429     }
430 
431     pVDev->SetMapMode( aMM );
432 #ifdef DBG_UTIL
433     sal_Bool bAbort = !
434 #endif
435         pVDev->SetOutputSize(aPageSize);
436     DBG_ASSERT(!bAbort, "virt. Device nicht korrekt erzeugt");
437 
438     SdrView* pView = new SdrView(mpDoc, pVDev);
439     pView->SetPageVisible( sal_False );
440     pView->SetBordVisible( sal_False );
441     pView->SetGridVisible( sal_False );
442     pView->SetHlplVisible( sal_False );
443     pView->SetGlueVisible( sal_False );
444     pView->ShowSdrPage(pPage);
445     Region aRegion (Rectangle( aPoint, aPageSize ) );
446 
447     ImplExportCheckVisisbilityRedirector aRedirector( mpCurrentPage );
448 
449     pView->CompleteRedraw(pVDev, aRegion, &aRedirector);
450 
451     delete pView;
452     return pVDev;
453 }
454 
455 void GraphicExporter::ParseSettings( const Sequence< PropertyValue >& aDescriptor, ExportSettings& rSettings )
456 {
457     sal_Int32 nArgs = aDescriptor.getLength();
458     const PropertyValue* pValues = aDescriptor.getConstArray();
459     while( nArgs-- )
460     {
461         if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FilterName" ) ) )
462         {
463             pValues->Value >>= rSettings.maFilterName;
464         }
465         else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
466         {
467             pValues->Value >>= rSettings.maMediaType;
468         }
469         else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "URL" ) ) )
470         {
471             if( !( pValues->Value >>= rSettings.maURL ) )
472             {
473                 pValues->Value >>= rSettings.maURL.Complete;
474             }
475         }
476         else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OutputStream" ) ) )
477         {
478             pValues->Value >>= rSettings.mxOutputStream;
479         }
480         else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicRenderer" ) ) )
481         {
482             pValues->Value >>= rSettings.mxGraphicRenderer;
483         }
484         else if ( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StatusIndicator" ) ) )
485         {
486             pValues->Value >>= rSettings.mxStatusIndicator;
487         }
488         else if ( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "InteractionHandler" ) ) )
489         {
490             pValues->Value >>= rSettings.mxInteractionHandler;
491         }
492         else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Width" ) ) )  // for compatibility reasons, deprecated
493         {
494             pValues->Value >>= rSettings.mnWidth;
495         }
496         else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Height" ) ) ) // for compatibility reasons, deprecated
497         {
498             pValues->Value >>= rSettings.mnHeight;
499         }
500         else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ExportOnlyBackground" ) ) )   // for compatibility reasons, deprecated
501         {
502             pValues->Value >>= rSettings.mbExportOnlyBackground;
503         }
504         else if ( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FilterData" ) ) )
505         {
506             pValues->Value >>= rSettings.maFilterData;
507 
508             sal_Int32 nFilterArgs = rSettings.maFilterData.getLength();
509             PropertyValue* pDataValues = rSettings.maFilterData.getArray();
510             while( nFilterArgs-- )
511             {
512                 if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Translucent" ) ) )
513                 {
514                     if ( !( pDataValues->Value >>= rSettings.mbTranslucent ) )  // SJ: TODO: The GIF Transparency is stored as int32 in
515                     {                                               // configuration files, this has to be changed to boolean
516                         sal_Int32 nTranslucent = 0;
517                         if ( pDataValues->Value >>= nTranslucent )
518                             rSettings.mbTranslucent = nTranslucent != 0;
519                     }
520                 }
521                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PixelWidth" ) ) )
522                 {
523                     pDataValues->Value >>= rSettings.mnWidth;
524                 }
525                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PixelHeight" ) ) )
526                 {
527                     pDataValues->Value >>= rSettings.mnHeight;
528                 }
529                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Width" ) ) )  // for compatibility reasons, deprecated
530                 {
531                     pDataValues->Value >>= rSettings.mnWidth;
532                     pDataValues->Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PixelWidth" ) );
533                 }
534                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Height" ) ) ) // for compatibility reasons, deprecated
535                 {
536                     pDataValues->Value >>= rSettings.mnHeight;
537                     pDataValues->Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PixelHeight" ) );
538                 }
539                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ExportOnlyBackground" ) ) )
540                 {
541                     pDataValues->Value >>= rSettings.mbExportOnlyBackground;
542                 }
543                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HighContrast" ) ) )
544                 {
545                     pDataValues->Value >>= rSettings.mbUseHighContrast;
546                 }
547                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PageNumber" ) ) )
548                 {
549                     pDataValues->Value >>= mnPageNumber;
550                 }
551                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "VerboseComments" ) ) )
552                 {
553                     // #110496# Read flag for verbose metafile comments
554                     pDataValues->Value >>= rSettings.mbVerboseComments;
555                 }
556                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScrollText" ) ) )
557                 {
558                     // #110496# Read flag solitary scroll text metafile
559                     pDataValues->Value >>= rSettings.mbScrollText;
560                 }
561                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CurrentPage" ) ) )
562                 {
563                     Reference< XDrawPage >  xPage;
564                     pDataValues->Value >>= xPage;
565                     if( xPage.is() )
566                     {
567                         SvxDrawPage* pUnoPage = SvxDrawPage::getImplementation( xPage );
568                         if( pUnoPage && pUnoPage->GetSdrPage() )
569                             mpCurrentPage = pUnoPage->GetSdrPage();
570                     }
571                 }
572                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleXNumerator" ) ) )
573                 {
574                     sal_Int32 nVal = 1;
575                     if( pDataValues->Value >>= nVal )
576                         rSettings.maScaleX = Fraction( nVal, rSettings.maScaleX.GetDenominator() );
577                 }
578                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleXDenominator" ) ) )
579                 {
580                     sal_Int32 nVal = 1;
581                     if( pDataValues->Value >>= nVal )
582                         rSettings.maScaleX = Fraction( rSettings.maScaleX.GetNumerator(), nVal );
583                 }
584                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleYNumerator" ) ) )
585                 {
586                     sal_Int32 nVal = 1;
587                     if( pDataValues->Value >>= nVal )
588                         rSettings.maScaleY = Fraction( nVal, rSettings.maScaleY.GetDenominator() );
589                 }
590                 else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleYDenominator" ) ) )
591                 {
592                     sal_Int32 nVal = 1;
593                     if( pDataValues->Value >>= nVal )
594                         rSettings.maScaleY = Fraction( rSettings.maScaleY.GetNumerator(), nVal );
595                 }
596 
597                 pDataValues++;
598             }
599         }
600 
601         pValues++;
602     }
603 
604     // putting the StatusIndicator that we got from the MediaDescriptor into our local FilterData copy
605     if ( rSettings.mxStatusIndicator.is() )
606     {
607         rtl::OUString sStatusIndicator( RTL_CONSTASCII_USTRINGPARAM( "StatusIndicator" ) );
608         int i = rSettings.maFilterData.getLength();
609         rSettings.maFilterData.realloc( i + 1 );
610         rSettings.maFilterData[ i ].Name = sStatusIndicator;
611         rSettings.maFilterData[ i ].Value <<= rSettings.mxStatusIndicator;
612     }
613 }
614 
615 bool GraphicExporter::GetGraphic( ExportSettings& rSettings, Graphic& aGraphic, sal_Bool bVectorType )
616 {
617     if( !mpDoc || !mpUnoPage )
618         return false;
619 
620     SdrPage* pPage = mpUnoPage->GetSdrPage();
621     if( !pPage )
622         return false;
623 
624     VirtualDevice       aVDev;
625     const MapMode       aMap( mpDoc->GetScaleUnit(), Point(), rSettings.maScaleX, rSettings.maScaleY );
626 
627     SdrOutliner& rOutl=mpDoc->GetDrawOutliner(NULL);
628     maOldCalcFieldValueHdl = rOutl.GetCalcFieldValueHdl();
629     rOutl.SetCalcFieldValueHdl( LINK(this, GraphicExporter, CalcFieldValueHdl) );
630     rOutl.SetBackgroundColor( pPage->GetPageBackgroundColor() );
631 
632     // #i102251#
633     const sal_uInt32 nOldCntrl(rOutl.GetControlWord());
634     sal_uInt32 nCntrl = nOldCntrl & ~EE_CNTRL_ONLINESPELLING;
635     rOutl.SetControlWord(nCntrl);
636 
637     SdrObject* pTempBackgroundShape = 0;
638     std::vector< SdrObject* > aShapes;
639     bool bRet = true;
640 
641     // export complete page?
642     if ( !mxShape.is() )
643     {
644         if( rSettings.mbExportOnlyBackground )
645         {
646             const SdrPageProperties* pCorrectProperties = pPage->getCorrectSdrPageProperties();
647 
648             if(pCorrectProperties)
649             {
650                 pTempBackgroundShape = new SdrRectObj(Rectangle(Point(0,0), pPage->GetSize()));
651                 pTempBackgroundShape->SetMergedItemSet(pCorrectProperties->GetItemSet());
652                 pTempBackgroundShape->SetMergedItem(XLineStyleItem(XLINE_NONE));
653                 pTempBackgroundShape->NbcSetStyleSheet(pCorrectProperties->GetStyleSheet(), true);
654                 aShapes.push_back(pTempBackgroundShape);
655             }
656         }
657         else
658         {
659             const Size aSize( pPage->GetSize() );
660 
661             // generate a bitmap to convert it to a pixel format.
662             // For gif pictures there can also be a vector format used (bTranslucent)
663             if ( !bVectorType && !rSettings.mbTranslucent )
664             {
665                 long nWidthPix = 0;
666                 long nHeightPix = 0;
667                 if ( rSettings.mnWidth > 0 && rSettings.mnHeight > 0 )
668                 {
669                     nWidthPix = rSettings.mnWidth;
670                     nHeightPix = rSettings.mnHeight;
671                 }
672                 else
673                 {
674                     const Size aSizePix( Application::GetDefaultDevice()->LogicToPixel( aSize, aMap ) );
675                     if (aSizePix.Width() > MAX_EXT_PIX || aSizePix.Height() > MAX_EXT_PIX)
676                     {
677                         if (aSizePix.Width() > MAX_EXT_PIX)
678                             nWidthPix = MAX_EXT_PIX;
679                         else
680                             nWidthPix = aSizePix.Width();
681                         if (aSizePix.Height() > MAX_EXT_PIX)
682                             nHeightPix = MAX_EXT_PIX;
683                         else
684                             nHeightPix = aSizePix.Height();
685 
686                         double fWidthDif = aSizePix.Width() / nWidthPix;
687                         double fHeightDif = aSizePix.Height() / nHeightPix;
688 
689                         if (fWidthDif > fHeightDif)
690                             nHeightPix = static_cast<long>(aSizePix.Height() / fWidthDif);
691                         else
692                             nWidthPix = static_cast<long>(aSizePix.Width() / fHeightDif);
693                     }
694                     else
695                     {
696                         nWidthPix = aSizePix.Width();
697                         nHeightPix = aSizePix.Height();
698                     }
699                 }
700 
701                 boost::scoped_ptr< SdrView > pLocalView;
702                 if( PTR_CAST( FmFormModel, mpDoc ) )
703                 {
704                     pLocalView.reset( new FmFormView( PTR_CAST( FmFormModel, mpDoc ), &aVDev ) );
705                 }
706                 else
707                 {
708                     pLocalView.reset( new SdrView( mpDoc, &aVDev ) );
709                 }
710 
711 
712                 VirtualDevice*  pVDev = CreatePageVDev( pPage, nWidthPix, nHeightPix );
713 
714                 if( pVDev )
715                 {
716                     aGraphic = pVDev->GetBitmap( Point(), pVDev->GetOutputSize() );
717                     aGraphic.SetPrefMapMode( aMap );
718                     aGraphic.SetPrefSize( aSize );
719                     delete pVDev;
720                 }
721             }
722             // create a metafile to export a vector format
723             else
724             {
725                 GDIMetaFile aMtf;
726 
727                 aVDev.SetMapMode( aMap );
728                 if( rSettings.mbUseHighContrast )
729                     aVDev.SetDrawMode( aVDev.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
730                 aVDev.EnableOutput( sal_False );
731                 aMtf.Record( &aVDev );
732                 Size aNewSize;
733 
734                 // create a view
735                 SdrView*        pView;
736 
737                 if( PTR_CAST( FmFormModel, mpDoc ) )
738                 {
739                     pView = new FmFormView( PTR_CAST( FmFormModel, mpDoc ), &aVDev );
740                 }
741                 else
742                 {
743                     pView = new SdrView( mpDoc, &aVDev );
744                 }
745 
746                 pView->SetBordVisible( sal_False );
747                 pView->SetPageVisible( sal_False );
748                 pView->ShowSdrPage( pPage );
749 
750                 if ( pView && pPage )
751                 {
752                     pView->SetBordVisible( sal_False );
753                     pView->SetPageVisible( sal_False );
754                     pView->ShowSdrPage( pPage );
755 
756                     const Point aNewOrg( pPage->GetLftBorder(), pPage->GetUppBorder() );
757                     aNewSize = Size( aSize.Width() - pPage->GetLftBorder() - pPage->GetRgtBorder(),
758                                           aSize.Height() - pPage->GetUppBorder() - pPage->GetLwrBorder() );
759                     const Rectangle aClipRect( aNewOrg, aNewSize );
760                     MapMode         aVMap( aMap );
761 
762                     aVDev.Push();
763                     aVMap.SetOrigin( Point( -aNewOrg.X(), -aNewOrg.Y() ) );
764                     aVDev.SetRelativeMapMode( aVMap );
765                     aVDev.IntersectClipRegion( aClipRect );
766 
767                     // Use new StandardCheckVisisbilityRedirector
768                     ImplExportCheckVisisbilityRedirector aRedirector( mpCurrentPage );
769 
770                     pView->CompleteRedraw(&aVDev, Region(Rectangle(Point(), aNewSize)), &aRedirector);
771 
772                     aVDev.Pop();
773 
774                     aMtf.Stop();
775                     aMtf.WindStart();
776                     aMtf.SetPrefMapMode( aMap );
777                     aMtf.SetPrefSize( aNewSize );
778 
779                     // AW: Here the current version was filtering out the META_CLIPREGION_ACTIONs
780                     // from the metafile. I asked some other developers why this was done, but no
781                     // one knew a direct reason. Since it's in for long time, it may be an old
782                     // piece of code. MetaFiles save and load ClipRegions with polygons with preserving
783                     // the polygons, so a resolution-indepent roundtrip is supported. Removed this
784                     // code since it destroys some MetaFiles where ClipRegions are used. Anyways,
785                     // just filtering them out is a hack, at least the encapsulated content would need
786                     // to be clipped geometrically.
787                     aGraphic = Graphic(aMtf);
788                 }
789 
790                 if ( pView )
791                 {
792                     pView->HideSdrPage();
793                     delete pView;
794                 }
795 
796                 if( rSettings.mbTranslucent )
797                 {
798                     Size aOutSize;
799                     aGraphic = GetBitmapFromMetaFile( aGraphic.GetGDIMetaFile(), sal_True, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aNewSize, aOutSize ) );
800                 }
801             }
802         }
803     }
804 
805     // export only single shape or shape collection
806     else
807     {
808         // build list of SdrObject
809         if( mxShapes.is() )
810         {
811             Reference< XShape > xShape;
812             const sal_Int32 nCount = mxShapes->getCount();
813 
814             for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
815             {
816                 mxShapes->getByIndex( nIndex ) >>= xShape;
817                 SdrObject* pObj = GetSdrObjectFromXShape( xShape );
818                 if( pObj )
819                     aShapes.push_back( pObj );
820             }
821         }
822         else
823         {
824             // only one shape
825             SdrObject* pObj = GetSdrObjectFromXShape( mxShape );
826             if( pObj )
827                 aShapes.push_back( pObj );
828         }
829 
830         if( aShapes.empty() )
831             bRet = false;
832     }
833 
834     if( bRet && !aShapes.empty() )
835     {
836         // special treatment for only one SdrGrafObj that has text
837         sal_Bool bSingleGraphic = sal_False;
838 
839         if( 1 == aShapes.size() )
840         {
841             if( !bVectorType )
842             {
843                 SdrObject* pObj = aShapes.front();
844                 if( pObj && pObj->ISA( SdrGrafObj ) && !( (SdrGrafObj*) pObj )->HasText() )
845                 {
846                     aGraphic = ( (SdrGrafObj*) pObj )->GetTransformedGraphic();
847                     if ( aGraphic.GetType() == GRAPHIC_BITMAP )
848                     {
849                         Size aSizePixel( aGraphic.GetSizePixel() );
850                         if( rSettings.mnWidth && rSettings.mnHeight &&
851                             ( ( rSettings.mnWidth != aSizePixel.Width() ) ||
852                               ( rSettings.mnHeight != aSizePixel.Height() ) ) )
853                         {
854                             BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
855                             // export: use highest quality
856                             aBmpEx.Scale( Size( rSettings.mnWidth, rSettings.mnHeight ), BMP_SCALE_LANCZOS );
857                             aGraphic = aBmpEx;
858                         }
859 
860                         // #118804# only accept for bitmap graphics, else the
861                         // conversion to bitmap will happen anywhere without size control
862                         // as evtl. defined in rSettings.mnWidth/mnHeight
863                         bSingleGraphic = sal_True;
864                     }
865                 }
866             }
867             else if( rSettings.mbScrollText )
868             {
869                 SdrObject* pObj = aShapes.front();
870                 if( pObj && pObj->ISA( SdrTextObj )
871                     && ( (SdrTextObj*) pObj )->HasText() )
872                 {
873                     Rectangle aScrollRectangle;
874                     Rectangle aPaintRectangle;
875 
876                     const boost::scoped_ptr< GDIMetaFile > pMtf(
877                         ( (SdrTextObj*) pObj )->GetTextScrollMetaFileAndRectangle(
878                         aScrollRectangle, aPaintRectangle ) );
879 
880                     // take the larger one of the two rectangles (that
881                     // should be the bound rect of the retrieved
882                     // metafile)
883                     Rectangle aTextRect;
884 
885                     if( aScrollRectangle.IsInside( aPaintRectangle ) )
886                         aTextRect = aScrollRectangle;
887                     else
888                         aTextRect = aPaintRectangle;
889 
890                     // setup pref size and mapmode
891                     pMtf->SetPrefSize( aTextRect.GetSize() );
892 
893                     // set actual origin (mtf is at actual shape
894                     // output position)
895                     MapMode aLocalMapMode( aMap );
896                     aLocalMapMode.SetOrigin(
897                         Point( -aPaintRectangle.Left(),
898                                -aPaintRectangle.Top() ) );
899                     pMtf->SetPrefMapMode( aLocalMapMode );
900 
901                     pMtf->AddAction( new MetaCommentAction(
902                                          "XTEXT_SCROLLRECT", 0,
903                                          reinterpret_cast<sal_uInt8 const*>(&aScrollRectangle),
904                                          sizeof( Rectangle ) ) );
905                     pMtf->AddAction( new MetaCommentAction(
906                                          "XTEXT_PAINTRECT", 0,
907                                          reinterpret_cast<sal_uInt8 const*>(&aPaintRectangle),
908                                          sizeof( Rectangle ) ) );
909 
910                     aGraphic = Graphic( *pMtf );
911 
912                     bSingleGraphic = sal_True;
913                 }
914             }
915         }
916 
917         if( !bSingleGraphic )
918         {
919             // create a metafile for all shapes
920             VirtualDevice   aOut;
921 
922             // calculate bound rect for all shapes
923             Rectangle aBound;
924 
925             {
926                 std::vector< SdrObject* >::iterator aIter = aShapes.begin();
927                 const std::vector< SdrObject* >::iterator aEnd = aShapes.end();
928 
929                 while( aIter != aEnd )
930                 {
931                     SdrObject* pObj = (*aIter++);
932                     Rectangle aR1(pObj->GetCurrentBoundRect());
933                     if (aBound.IsEmpty())
934                         aBound=aR1;
935                     else
936                         aBound.Union(aR1);
937                 }
938             }
939 
940             aOut.EnableOutput( sal_False );
941             aOut.SetMapMode( aMap );
942             if( rSettings.mbUseHighContrast )
943                 aOut.SetDrawMode( aVDev.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
944 
945             GDIMetaFile aMtf;
946             aMtf.Clear();
947             aMtf.Record( &aOut );
948 
949             MapMode aOutMap( aMap );
950             aOutMap.SetOrigin( Point( -aBound.TopLeft().X(), -aBound.TopLeft().Y() ) );
951             aOut.SetRelativeMapMode( aOutMap );
952 
953             sdr::contact::DisplayInfo aDisplayInfo;
954 
955             if(mpCurrentPage)
956             {
957                 if(mpCurrentPage->TRG_HasMasterPage() && pPage->IsMasterPage())
958                 {
959                     // MasterPage is processed as another page's SubContent
960                     aDisplayInfo.SetProcessLayers(mpCurrentPage->TRG_GetMasterPageVisibleLayers());
961                     aDisplayInfo.SetSubContentActive(true);
962                 }
963             }
964 
965             if(!aShapes.empty())
966             {
967                 // more effective way to paint a vector of SdrObjects. Hand over the processed page
968                 // to have it in the
969                 sdr::contact::ObjectContactOfObjListPainter aMultiObjectPainter(aOut, aShapes, mpCurrentPage);
970                 ImplExportCheckVisisbilityRedirector aCheckVisibilityRedirector(mpCurrentPage);
971                 aMultiObjectPainter.SetViewObjectContactRedirector(&aCheckVisibilityRedirector);
972 
973                 aMultiObjectPainter.ProcessDisplay(aDisplayInfo);
974             }
975 
976             aMtf.Stop();
977             aMtf.WindStart();
978 
979             const Size  aExtSize( aOut.PixelToLogic( Size( 0, 0  ) ) );
980             Size        aBoundSize( aBound.GetWidth() + ( aExtSize.Width() ),
981                                     aBound.GetHeight() + ( aExtSize.Height() ) );
982 
983             aMtf.SetPrefMapMode( aMap );
984             aMtf.SetPrefSize( aBoundSize );
985 
986             if( !bVectorType )
987             {
988                 Size aOutSize;
989                 aGraphic = GetBitmapFromMetaFile( aMtf, rSettings.mbTranslucent, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aBoundSize, aOutSize ) );
990             }
991             else
992             {
993                 aGraphic = aMtf;
994             }
995         }
996     }
997 
998     if(pTempBackgroundShape)
999     {
1000         SdrObject::Free(pTempBackgroundShape);
1001     }
1002 
1003     rOutl.SetCalcFieldValueHdl( maOldCalcFieldValueHdl );
1004 
1005     // #i102251#
1006     rOutl.SetControlWord(nOldCntrl);
1007 
1008     return bRet;
1009 
1010 }
1011 
1012 // XFilter
1013 sal_Bool SAL_CALL GraphicExporter::filter( const Sequence< PropertyValue >& aDescriptor )
1014     throw(RuntimeException)
1015 {
1016     OGuard aGuard( Application::GetSolarMutex() );
1017 
1018     if( NULL == mpUnoPage )
1019         return sal_False;
1020 
1021     GraphicFilter*              pFilter = GraphicFilter::GetGraphicFilter();
1022 
1023     if( NULL == pFilter || NULL == mpUnoPage->GetSdrPage() || NULL == mpDoc )
1024         return sal_False;
1025 
1026     // get the arguments from the descriptor
1027     ExportSettings aSettings( mpDoc );
1028     ParseSettings( aDescriptor, aSettings );
1029 
1030     const sal_uInt16    nFilter = aSettings.maMediaType.getLength()
1031                             ? pFilter->GetExportFormatNumberForMediaType( aSettings.maMediaType )
1032                             : pFilter->GetExportFormatNumberForShortName( aSettings.maFilterName );
1033     sal_Bool            bVectorType = !pFilter->IsExportPixelFormat( nFilter );
1034 
1035     // create the output stuff
1036     Graphic aGraphic;
1037 
1038     sal_uInt16 nStatus = GetGraphic( aSettings, aGraphic, bVectorType ) ? GRFILTER_OK : GRFILTER_FILTERERROR;
1039 
1040     if( nStatus == GRFILTER_OK )
1041     {
1042         // export graphic only if it has a size
1043         const Size aGraphSize( aGraphic.GetPrefSize() );
1044         if ( ( aGraphSize.Width() == 0 ) || ( aGraphSize.Height() == 0 ) )
1045         {
1046             nStatus = GRFILTER_FILTERERROR;
1047         }
1048         else
1049         {
1050             // now we have a graphic, so export it
1051             if( aSettings.mxGraphicRenderer.is() )
1052             {
1053                 // render graphic directly into given renderer
1054                 aSettings.mxGraphicRenderer->render( aGraphic.GetXGraphic() );
1055             }
1056             else if( aSettings.mxOutputStream.is() )
1057             {
1058                 // TODO: Either utilize optional XSeekable functionality for the
1059                 // SvOutputStream, or adapt the graphic filter to not seek anymore.
1060                 SvMemoryStream aStream( 1024, 1024 );
1061 
1062                 nStatus = pFilter->ExportGraphic( aGraphic, String(), aStream, nFilter, &aSettings.maFilterData );
1063 
1064                 // copy temp stream to XOutputStream
1065                 SvOutputStream aOutputStream( aSettings.mxOutputStream );
1066                 aStream.Seek(0);
1067                 aOutputStream << aStream;
1068             }
1069             else
1070             {
1071                 INetURLObject aURLObject( aSettings.maURL.Complete );
1072                 DBG_ASSERT( aURLObject.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
1073 
1074                 nStatus = XOutBitmap::ExportGraphic( aGraphic, aURLObject, *pFilter, nFilter, &aSettings.maFilterData );
1075             }
1076         }
1077     }
1078 
1079     if ( aSettings.mxInteractionHandler.is() && ( nStatus != GRFILTER_OK ) )
1080     {
1081         Any aInteraction;
1082         Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > lContinuations(1);
1083         ::comphelper::OInteractionApprove* pApprove = new ::comphelper::OInteractionApprove();
1084         lContinuations[0] = Reference< XInteractionContinuation >(static_cast< XInteractionContinuation* >(pApprove), UNO_QUERY);
1085 
1086         GraphicFilterRequest aErrorCode;
1087         aErrorCode.ErrCode = nStatus;
1088         aInteraction <<= aErrorCode;
1089         aSettings.mxInteractionHandler->handle( framework::InteractionRequest::CreateRequest( aInteraction, lContinuations ) );
1090     }
1091     return nStatus == GRFILTER_OK;
1092 }
1093 
1094 void SAL_CALL GraphicExporter::cancel()
1095     throw(RuntimeException)
1096 {
1097 }
1098 
1099 // XExporter
1100 
1101 /** the source 'document' could be a XDrawPage, a XShape or a generic XShapes */
1102 void SAL_CALL GraphicExporter::setSourceDocument( const Reference< lang::XComponent >& xComponent )
1103     throw(IllegalArgumentException, RuntimeException)
1104 {
1105     OGuard aGuard( Application::GetSolarMutex() );
1106 
1107     mxShapes = NULL;
1108     mpUnoPage = NULL;
1109 
1110     try
1111     {
1112     // any break inside this one loop while will throw a IllegalArgumentException
1113     do
1114     {
1115         mxPage = Reference< XDrawPage >::query( xComponent );
1116         mxShapes = Reference< XShapes >::query( xComponent );
1117         mxShape = Reference< XShape >::query( xComponent );
1118 
1119         // Step 1: try a generic XShapes
1120         if( !mxPage.is() && !mxShape.is() && mxShapes.is() )
1121         {
1122             // we do not support empty shape collections
1123             if( 0 == mxShapes->getCount() )
1124                 break;
1125 
1126             // get first shape to detect corresponding page and model
1127             mxShapes->getByIndex(0) >>= mxShape;
1128         }
1129         else
1130         {
1131             mxShapes = NULL;
1132         }
1133 
1134         // Step 2: try a shape
1135         if( mxShape.is() )
1136         {
1137             if( NULL == GetSdrObjectFromXShape( mxShape ) )
1138                 break;
1139 
1140             // get page for this shape
1141             Reference< XChild > xChild( mxShape, UNO_QUERY );
1142             if( !xChild.is() )
1143                 break;
1144 
1145             Reference< XInterface > xInt;
1146             do
1147             {
1148                 xInt = xChild->getParent();
1149                 mxPage = Reference< XDrawPage >::query( xInt );
1150                 if( !mxPage.is() )
1151                     xChild = Reference< XChild >::query( xInt );
1152             }
1153             while( !mxPage.is() && xChild.is() );
1154 
1155             if( !mxPage.is() )
1156                 break;
1157         }
1158 
1159         // Step 3: check the page
1160         if( !mxPage.is() )
1161             break;
1162 
1163         mpUnoPage = SvxDrawPage::getImplementation( mxPage );
1164 
1165         if( NULL == mpUnoPage || NULL == mpUnoPage->GetSdrPage() )
1166             break;
1167 
1168         mpDoc = mpUnoPage->GetSdrPage()->GetModel();
1169 
1170         // Step 4:  If we got a generic XShapes test all contained shapes
1171         //          if they belong to the same XDrawPage
1172 
1173         if( mxShapes.is() )
1174         {
1175             SdrPage* pPage = mpUnoPage->GetSdrPage();
1176             SdrObject* pObj;
1177             Reference< XShape > xShape;
1178 
1179             sal_Bool bOk = sal_True;
1180 
1181             const sal_Int32 nCount = mxShapes->getCount();
1182 
1183             // test all but the first shape if they have the same page than
1184             // the first shape
1185             for( sal_Int32 nIndex = 1; bOk && ( nIndex < nCount ); nIndex++ )
1186             {
1187                 mxShapes->getByIndex( nIndex ) >>= xShape;
1188                 pObj = GetSdrObjectFromXShape( xShape );
1189                 bOk = pObj && pObj->GetPage() == pPage;
1190             }
1191 
1192             if( !bOk )
1193                 break;
1194         }
1195 
1196         // no errors so far
1197         return;
1198     }
1199     while( 0 );
1200     }
1201     catch( Exception& )
1202     {
1203     }
1204 
1205     throw IllegalArgumentException();
1206 }
1207 
1208 // XServiceInfo
1209 OUString SAL_CALL GraphicExporter::getImplementationName(  )
1210     throw(RuntimeException)
1211 {
1212     return GraphicExporter_getImplementationName();
1213 }
1214 
1215 sal_Bool SAL_CALL GraphicExporter::supportsService( const OUString& ServiceName )
1216     throw(RuntimeException)
1217 {
1218     Sequence< OUString > aSeq( GraphicExporter_getSupportedServiceNames() );
1219     sal_Int32 nArgs = aSeq.getLength();
1220     const OUString* pService = aSeq.getConstArray();
1221     while( nArgs-- )
1222         if( *pService++ == ServiceName )
1223             return sal_True;
1224 
1225     return sal_False;
1226 }
1227 
1228 Sequence< OUString > SAL_CALL GraphicExporter::getSupportedServiceNames(  )
1229     throw(RuntimeException)
1230 {
1231     return GraphicExporter_getSupportedServiceNames();
1232 }
1233 
1234 // XMimeTypeInfo
1235 sal_Bool SAL_CALL GraphicExporter::supportsMimeType( const OUString& MimeTypeName ) throw (RuntimeException)
1236 {
1237     const String aMimeTypeName( MimeTypeName );
1238 
1239     GraphicFilter*  pFilter = GraphicFilter::GetGraphicFilter();
1240     sal_uInt16 nCount = pFilter->GetExportFormatCount();
1241     sal_uInt16 nFilter;
1242     for( nFilter = 0; nFilter < nCount; nFilter++ )
1243     {
1244         if( aMimeTypeName.Equals( pFilter->GetExportFormatMediaType( nFilter ) ) )
1245         {
1246             return sal_True;
1247         }
1248     }
1249 
1250     return sal_False;
1251 }
1252 
1253 Sequence< OUString > SAL_CALL GraphicExporter::getSupportedMimeTypeNames(  ) throw (RuntimeException)
1254 {
1255     GraphicFilter*  pFilter = GraphicFilter::GetGraphicFilter();
1256     sal_uInt16 nCount = pFilter->GetExportFormatCount();
1257     sal_uInt16 nFilter;
1258     sal_uInt16 nFound = 0;
1259 
1260     Sequence< OUString > aSeq( nCount );
1261     OUString* pStr = aSeq.getArray();
1262 
1263     for( nFilter = 0; nFilter < nCount; nFilter++ )
1264     {
1265         OUString aMimeType( pFilter->GetExportFormatMediaType( nFilter ) );
1266         if( aMimeType.getLength() )
1267         {
1268             *pStr++ = aMimeType;
1269             nFound++;
1270         }
1271     }
1272 
1273     if( nFound < nCount )
1274         aSeq.realloc( nFound );
1275 
1276     return aSeq;
1277 }
1278 
1279 Graphic SvxGetGraphicForShape( SdrObject& rShape, bool bVector )
1280 {
1281     Graphic aGraphic;
1282     try
1283     {
1284         rtl::Reference< GraphicExporter > xExporter( new GraphicExporter() );
1285         Reference< XComponent > xComp( rShape.getUnoShape(), UNO_QUERY_THROW );
1286         xExporter->setSourceDocument( xComp );
1287         ExportSettings aSettings( rShape.GetModel() );
1288         xExporter->GetGraphic( aSettings, aGraphic, bVector );
1289     }
1290     catch( Exception& )
1291     {
1292         DBG_ERROR("SvxGetGraphicForShape(), exception caught!");
1293     }
1294     return aGraphic;
1295 }
1296 
1297