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