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