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