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 							aBmpEx.Scale( Size( rSettings.mnWidth, rSettings.mnHeight ) );
856 							aGraphic = aBmpEx;
857 						}
858 
859                         // #118804# only accept for bitmap graphics, else the
860                         // conversion to bitmap will happen anywhere without size control
861                         // as evtl. defined in rSettings.mnWidth/mnHeight
862                         bSingleGraphic = sal_True;
863 					}
864                 }
865             }
866             else if( rSettings.mbScrollText )
867             {
868                 SdrObject* pObj = aShapes.front();
869                 if( pObj && pObj->ISA( SdrTextObj )
870                     && ( (SdrTextObj*) pObj )->HasText() )
871                 {
872                     Rectangle aScrollRectangle;
873                     Rectangle aPaintRectangle;
874 
875                     const boost::scoped_ptr< GDIMetaFile > pMtf(
876                         ( (SdrTextObj*) pObj )->GetTextScrollMetaFileAndRectangle(
877                         aScrollRectangle, aPaintRectangle ) );
878 
879                     // take the larger one of the two rectangles (that
880                     // should be the bound rect of the retrieved
881                     // metafile)
882 					Rectangle aTextRect;
883 
884                     if( aScrollRectangle.IsInside( aPaintRectangle ) )
885                         aTextRect = aScrollRectangle;
886                     else
887                         aTextRect = aPaintRectangle;
888 
889                     // setup pref size and mapmode
890                     pMtf->SetPrefSize( aTextRect.GetSize() );
891 
892                     // set actual origin (mtf is at actual shape
893                     // output position)
894                     MapMode aLocalMapMode( aMap );
895                     aLocalMapMode.SetOrigin(
896                         Point( -aPaintRectangle.Left(),
897                                -aPaintRectangle.Top() ) );
898                     pMtf->SetPrefMapMode( aLocalMapMode );
899 
900                     pMtf->AddAction( new MetaCommentAction(
901                                          "XTEXT_SCROLLRECT", 0,
902                                          reinterpret_cast<sal_uInt8 const*>(&aScrollRectangle),
903                                          sizeof( Rectangle ) ) );
904                     pMtf->AddAction( new MetaCommentAction(
905                                          "XTEXT_PAINTRECT", 0,
906                                          reinterpret_cast<sal_uInt8 const*>(&aPaintRectangle),
907                                          sizeof( Rectangle ) ) );
908 
909                     aGraphic = Graphic( *pMtf );
910 
911                     bSingleGraphic = sal_True;
912                 }
913             }
914         }
915 
916         if( !bSingleGraphic )
917 		{
918 			// create a metafile for all shapes
919 			VirtualDevice	aOut;
920 
921 			// calculate bound rect for all shapes
922 			Rectangle aBound;
923 
924             {
925 			    std::vector< SdrObject* >::iterator aIter = aShapes.begin();
926 			    const std::vector< SdrObject* >::iterator aEnd = aShapes.end();
927 
928 			    while( aIter != aEnd )
929 			    {
930 				    SdrObject* pObj = (*aIter++);
931 				    Rectangle aR1(pObj->GetCurrentBoundRect());
932 				    if (aBound.IsEmpty())
933 					    aBound=aR1;
934 				    else
935 					    aBound.Union(aR1);
936 			    }
937             }
938 
939 			aOut.EnableOutput( sal_False );
940 			aOut.SetMapMode( aMap );
941             if( rSettings.mbUseHighContrast )
942                 aOut.SetDrawMode( aVDev.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
943 
944 			GDIMetaFile aMtf;
945 			aMtf.Clear();
946 			aMtf.Record( &aOut );
947 
948 			MapMode aOutMap( aMap );
949 			aOutMap.SetOrigin( Point( -aBound.TopLeft().X(), -aBound.TopLeft().Y() ) );
950 			aOut.SetRelativeMapMode( aOutMap );
951 
952 			sdr::contact::DisplayInfo aDisplayInfo;
953 
954             if(mpCurrentPage)
955             {
956 				if(mpCurrentPage->TRG_HasMasterPage() && pPage->IsMasterPage())
957 				{
958 					// MasterPage is processed as another page's SubContent
959 					aDisplayInfo.SetProcessLayers(mpCurrentPage->TRG_GetMasterPageVisibleLayers());
960 					aDisplayInfo.SetSubContentActive(true);
961 				}
962             }
963 
964 			if(!aShapes.empty())
965 			{
966 				// more effective way to paint a vector of SdrObjects. Hand over the processed page
967                 // to have it in the
968 				sdr::contact::ObjectContactOfObjListPainter aMultiObjectPainter(aOut, aShapes, mpCurrentPage);
969 				ImplExportCheckVisisbilityRedirector aCheckVisibilityRedirector(mpCurrentPage);
970 				aMultiObjectPainter.SetViewObjectContactRedirector(&aCheckVisibilityRedirector);
971 
972 				aMultiObjectPainter.ProcessDisplay(aDisplayInfo);
973 			}
974 
975 			aMtf.Stop();
976 			aMtf.WindStart();
977 
978 			const Size	aExtSize( aOut.PixelToLogic( Size( 0, 0  ) ) );
979 			Size		aBoundSize( aBound.GetWidth() + ( aExtSize.Width() ),
980 									aBound.GetHeight() + ( aExtSize.Height() ) );
981 
982 			aMtf.SetPrefMapMode( aMap );
983 			aMtf.SetPrefSize( aBoundSize );
984 
985 			if( !bVectorType )
986 			{
987 				Size aOutSize;
988 				aGraphic = GetBitmapFromMetaFile( aMtf, rSettings.mbTranslucent, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aBoundSize, aOutSize ) );
989 			}
990 			else
991 			{
992 				aGraphic = aMtf;
993 			}
994 		}
995 	}
996 
997     if(pTempBackgroundShape)
998     {
999         SdrObject::Free(pTempBackgroundShape);
1000     }
1001 
1002     rOutl.SetCalcFieldValueHdl( maOldCalcFieldValueHdl );
1003 
1004 	// #i102251#
1005     rOutl.SetControlWord(nOldCntrl);
1006 
1007 	return bRet;
1008 
1009 }
1010 
1011 // XFilter
1012 sal_Bool SAL_CALL GraphicExporter::filter( const Sequence< PropertyValue >& aDescriptor )
1013 	throw(RuntimeException)
1014 {
1015 	OGuard aGuard( Application::GetSolarMutex() );
1016 
1017 	if( NULL == mpUnoPage )
1018 		return sal_False;
1019 
1020 	GraphicFilter*				pFilter = GraphicFilter::GetGraphicFilter();
1021 
1022 	if( NULL == pFilter || NULL == mpUnoPage->GetSdrPage() || NULL == mpDoc )
1023 		return sal_False;
1024 
1025 	// get the arguments from the descriptor
1026 	ExportSettings aSettings( mpDoc );
1027 	ParseSettings( aDescriptor, aSettings );
1028 
1029 	const sal_uInt16	nFilter = aSettings.maMediaType.getLength()
1030 							? pFilter->GetExportFormatNumberForMediaType( aSettings.maMediaType )
1031 							: pFilter->GetExportFormatNumberForShortName( aSettings.maFilterName );
1032 	sal_Bool			bVectorType = !pFilter->IsExportPixelFormat( nFilter );
1033 
1034 	// create the output stuff
1035 	Graphic aGraphic;
1036 
1037 	sal_uInt16 nStatus = GetGraphic( aSettings, aGraphic, bVectorType ) ? GRFILTER_OK : GRFILTER_FILTERERROR;
1038 
1039 	if( nStatus == GRFILTER_OK )
1040 	{
1041 		// export graphic only if it has a size
1042 		const Size aGraphSize( aGraphic.GetPrefSize() );
1043 		if ( ( aGraphSize.Width() == 0 ) || ( aGraphSize.Height() == 0 ) )
1044 		{
1045 			nStatus = GRFILTER_FILTERERROR;
1046 		}
1047 		else
1048 		{
1049 			// now we have a graphic, so export it
1050             if( aSettings.mxGraphicRenderer.is() )
1051             {
1052                 // render graphic directly into given renderer
1053                 aSettings.mxGraphicRenderer->render( aGraphic.GetXGraphic() );
1054             }
1055 			else if( aSettings.mxOutputStream.is() )
1056 			{
1057                 // TODO: Either utilize optional XSeekable functionality for the
1058                 // SvOutputStream, or adapt the graphic filter to not seek anymore.
1059                 SvMemoryStream aStream( 1024, 1024 );
1060 
1061 				nStatus = pFilter->ExportGraphic( aGraphic, String(), aStream, nFilter, &aSettings.maFilterData );
1062 
1063                 // copy temp stream to XOutputStream
1064 				SvOutputStream aOutputStream( aSettings.mxOutputStream );
1065                 aStream.Seek(0);
1066                 aOutputStream << aStream;
1067 			}
1068 			else
1069 			{
1070                 INetURLObject aURLObject( aSettings.maURL.Complete );
1071                 DBG_ASSERT( aURLObject.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
1072 
1073 				nStatus = XOutBitmap::ExportGraphic( aGraphic, aURLObject, *pFilter, nFilter, &aSettings.maFilterData );
1074 			}
1075 		}
1076 	}
1077 
1078 	if ( aSettings.mxInteractionHandler.is() && ( nStatus != GRFILTER_OK ) )
1079 	{
1080         Any aInteraction;
1081         Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > lContinuations(1);
1082         ::comphelper::OInteractionApprove* pApprove = new ::comphelper::OInteractionApprove();
1083         lContinuations[0] = Reference< XInteractionContinuation >(static_cast< XInteractionContinuation* >(pApprove), UNO_QUERY);
1084 
1085 		GraphicFilterRequest aErrorCode;
1086 		aErrorCode.ErrCode = nStatus;
1087 		aInteraction <<= aErrorCode;
1088         aSettings.mxInteractionHandler->handle( framework::InteractionRequest::CreateRequest( aInteraction, lContinuations ) );
1089 	}
1090 	return nStatus == GRFILTER_OK;
1091 }
1092 
1093 void SAL_CALL GraphicExporter::cancel()
1094 	throw(RuntimeException)
1095 {
1096 }
1097 
1098 // XExporter
1099 
1100 /** the source 'document' could be a XDrawPage, a XShape or a generic XShapes */
1101 void SAL_CALL GraphicExporter::setSourceDocument( const Reference< lang::XComponent >& xComponent )
1102 	throw(IllegalArgumentException, RuntimeException)
1103 {
1104 	OGuard aGuard( Application::GetSolarMutex() );
1105 
1106 	mxShapes = NULL;
1107 	mpUnoPage = NULL;
1108 
1109 	try
1110 	{
1111 	// any break inside this one loop while will throw a IllegalArgumentException
1112 	do
1113 	{
1114 		mxPage = Reference< XDrawPage >::query( xComponent );
1115 		mxShapes = Reference< XShapes >::query( xComponent );
1116 		mxShape = Reference< XShape >::query( xComponent );
1117 
1118 		// Step 1: try a generic XShapes
1119 		if( !mxPage.is() && !mxShape.is() && mxShapes.is() )
1120 		{
1121 			// we do not support empty shape collections
1122 			if( 0 == mxShapes->getCount() )
1123 				break;
1124 
1125 			// get first shape to detect corresponding page and model
1126 			mxShapes->getByIndex(0) >>= mxShape;
1127 		}
1128 		else
1129 		{
1130 			mxShapes = NULL;
1131 		}
1132 
1133 		// Step 2: try a shape
1134 		if( mxShape.is() )
1135 		{
1136 			if( NULL == GetSdrObjectFromXShape( mxShape ) )
1137 				break;
1138 
1139 			// get page for this shape
1140 			Reference< XChild > xChild( mxShape, UNO_QUERY );
1141 			if( !xChild.is() )
1142 				break;
1143 
1144 			Reference< XInterface > xInt;
1145 			do
1146 			{
1147 				xInt = xChild->getParent();
1148 				mxPage = Reference< XDrawPage >::query( xInt );
1149 				if( !mxPage.is() )
1150 					xChild = Reference< XChild >::query( xInt );
1151 			}
1152 			while( !mxPage.is() && xChild.is() );
1153 
1154 			if( !mxPage.is() )
1155 				break;
1156 		}
1157 
1158 		// Step 3: check the page
1159 		if( !mxPage.is() )
1160 			break;
1161 
1162 		mpUnoPage = SvxDrawPage::getImplementation( mxPage );
1163 
1164 		if( NULL == mpUnoPage || NULL == mpUnoPage->GetSdrPage() )
1165 			break;
1166 
1167 		mpDoc = mpUnoPage->GetSdrPage()->GetModel();
1168 
1169 		// Step 4:  If we got a generic XShapes test all contained shapes
1170 		//			if they belong to the same XDrawPage
1171 
1172 		if( mxShapes.is() )
1173 		{
1174 			SdrPage* pPage = mpUnoPage->GetSdrPage();
1175 			SdrObject* pObj;
1176 			Reference< XShape > xShape;
1177 
1178 			sal_Bool bOk = sal_True;
1179 
1180 			const sal_Int32 nCount = mxShapes->getCount();
1181 
1182 			// test all but the first shape if they have the same page than
1183 			// the first shape
1184 			for( sal_Int32 nIndex = 1; bOk && ( nIndex < nCount ); nIndex++ )
1185 			{
1186 				mxShapes->getByIndex( nIndex ) >>= xShape;
1187 				pObj = GetSdrObjectFromXShape( xShape );
1188 				bOk = pObj && pObj->GetPage() == pPage;
1189 			}
1190 
1191 			if( !bOk )
1192 				break;
1193 		}
1194 
1195 		// no errors so far
1196 		return;
1197 	}
1198 	while( 0 );
1199 	}
1200 	catch( Exception& )
1201 	{
1202 	}
1203 
1204 	throw IllegalArgumentException();
1205 }
1206 
1207 // XServiceInfo
1208 OUString SAL_CALL GraphicExporter::getImplementationName(  )
1209 	throw(RuntimeException)
1210 {
1211 	return GraphicExporter_getImplementationName();
1212 }
1213 
1214 sal_Bool SAL_CALL GraphicExporter::supportsService( const OUString& ServiceName )
1215 	throw(RuntimeException)
1216 {
1217 	Sequence< OUString > aSeq( GraphicExporter_getSupportedServiceNames() );
1218 	sal_Int32 nArgs = aSeq.getLength();
1219 	const OUString* pService = aSeq.getConstArray();
1220 	while( nArgs-- )
1221 		if( *pService++ == ServiceName )
1222 			return sal_True;
1223 
1224 	return sal_False;
1225 }
1226 
1227 Sequence< OUString > SAL_CALL GraphicExporter::getSupportedServiceNames(  )
1228 	throw(RuntimeException)
1229 {
1230 	return GraphicExporter_getSupportedServiceNames();
1231 }
1232 
1233 // XMimeTypeInfo
1234 sal_Bool SAL_CALL GraphicExporter::supportsMimeType( const OUString& MimeTypeName ) throw (RuntimeException)
1235 {
1236 	const String aMimeTypeName( MimeTypeName );
1237 
1238 	GraphicFilter*	pFilter = GraphicFilter::GetGraphicFilter();
1239 	sal_uInt16 nCount = pFilter->GetExportFormatCount();
1240 	sal_uInt16 nFilter;
1241 	for( nFilter = 0; nFilter < nCount; nFilter++ )
1242 	{
1243 		if( aMimeTypeName.Equals( pFilter->GetExportFormatMediaType( nFilter ) ) )
1244 		{
1245 			return sal_True;
1246 		}
1247 	}
1248 
1249 	return sal_False;
1250 }
1251 
1252 Sequence< OUString > SAL_CALL GraphicExporter::getSupportedMimeTypeNames(  ) throw (RuntimeException)
1253 {
1254 	GraphicFilter*	pFilter = GraphicFilter::GetGraphicFilter();
1255 	sal_uInt16 nCount = pFilter->GetExportFormatCount();
1256 	sal_uInt16 nFilter;
1257 	sal_uInt16 nFound = 0;
1258 
1259 	Sequence< OUString > aSeq( nCount );
1260 	OUString* pStr = aSeq.getArray();
1261 
1262 	for( nFilter = 0; nFilter < nCount; nFilter++ )
1263 	{
1264 		OUString aMimeType( pFilter->GetExportFormatMediaType( nFilter ) );
1265 		if( aMimeType.getLength() )
1266 		{
1267 			*pStr++ = aMimeType;
1268 			nFound++;
1269 		}
1270 	}
1271 
1272 	if( nFound < nCount )
1273 		aSeq.realloc( nFound );
1274 
1275 	return aSeq;
1276 }
1277 
1278 Graphic SvxGetGraphicForShape( SdrObject& rShape, bool bVector )
1279 {
1280 	Graphic aGraphic;
1281 	try
1282 	{
1283 		rtl::Reference< GraphicExporter > xExporter( new GraphicExporter() );
1284 		Reference< XComponent > xComp( rShape.getUnoShape(), UNO_QUERY_THROW );
1285 		xExporter->setSourceDocument( xComp );
1286 		ExportSettings aSettings( rShape.GetModel() );
1287 		xExporter->GetGraphic( aSettings, aGraphic, bVector );
1288 	}
1289 	catch( Exception& )
1290 	{
1291 		DBG_ERROR("SvxGetGraphicForShape(), exception caught!");
1292 	}
1293 	return aGraphic;
1294 }
1295 
1296