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