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 <com/sun/star/awt/Rectangle.hpp>
21 #include <com/sun/star/beans/PropertyValue.hpp>
22 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
23 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
24 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
25 #include <com/sun/star/container/XIndexAccess.hpp>
26 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
27 #include <com/sun/star/lang/XServiceInfo.hpp>
28 #include <vcl/gdimtf.hxx>
29 #include <unotools/tempfile.hxx>
30 #include <osl/diagnose.h>
31 #include <osl/file.hxx>
32 #include <vcl/metaact.hxx>
33 #include <vcl/wmf.hxx>
34 #include <vcl/graphicfilter.hxx>
35 #include <vcl/gdimetafiletools.hxx>
36 #include <memory>
37
38 #include "swfexporter.hxx"
39 #include "swfwriter.hxx"
40
41 using namespace ::com::sun::star::uno;
42 using namespace ::com::sun::star::drawing;
43 using namespace ::com::sun::star::task;
44 using namespace ::swf;
45
46 using com::sun::star::io::XOutputStream;
47 using com::sun::star::beans::PropertyValue;
48 using com::sun::star::container::XIndexAccess;
49 using com::sun::star::beans::XPropertySet;
50 using com::sun::star::lang::XComponent;
51 using com::sun::star::lang::XServiceInfo;
52
53
PageInfo()54 PageInfo::PageInfo()
55 : mnBackgroundID( 0 )
56 , mnObjectsID( 0)
57 , mnForegroundID( 0)
58 {
59 }
60
61
~PageInfo()62 PageInfo::~PageInfo()
63 {
64 }
65
66
FlashExporter(const Reference<XComponentContext> & rxContext,const Reference<XShapes> & rxSelectedShapes,const Reference<XDrawPage> & rxSelectedDrawPage,sal_Int32 nJPEGCompressMode,bool bExportOLEAsJPEG)67 FlashExporter::FlashExporter(
68 const Reference< XComponentContext > &rxContext,
69
70 // #i56084# variables for selection export
71 const Reference< XShapes >& rxSelectedShapes,
72 const Reference< XDrawPage >& rxSelectedDrawPage,
73
74 sal_Int32 nJPEGCompressMode,
75 bool bExportOLEAsJPEG)
76 : mxContext(rxContext)
77 // #i56084# variables for selection export
78 , mxSelectedShapes(rxSelectedShapes)
79 , mxSelectedDrawPage(rxSelectedDrawPage)
80 , mbExportSelection(false)
81
82 , mnDocWidth(0)
83 , mnDocHeight(0)
84 , mnJPEGcompressMode(nJPEGCompressMode)
85 , mbExportOLEAsJPEG(bExportOLEAsJPEG)
86 , mbPresentation(true)
87 , mnPageNumber(-1)
88 {
89 if(mxSelectedDrawPage.is() && mxSelectedShapes.is() && mxSelectedShapes->getCount())
90 {
91 // #i56084# determine export selection
92 mbExportSelection = true;
93 }
94 }
95
96
~FlashExporter()97 FlashExporter::~FlashExporter()
98 {
99 Flush();
100 }
101
Flush()102 void FlashExporter::Flush()
103 {
104 mpWriter.reset();
105 maPagesMap.clear();
106 }
107
108
109 const sal_uInt16 cBackgroundDepth = 2;
110 const sal_uInt16 cBackgroundObjectsDepth = 3;
111 const sal_uInt16 cPageObjectsDepth = 4;
112 const sal_uInt16 cWaitButtonDepth = 10;
113
exportAll(const Reference<XComponent> & xDoc,Reference<XOutputStream> const & xOutputStream,Reference<XStatusIndicator> const & xStatusIndicator)114 bool FlashExporter::exportAll( const Reference< XComponent >& xDoc, Reference< XOutputStream > const &xOutputStream, Reference< XStatusIndicator> const &xStatusIndicator )
115 {
116 Reference< XServiceInfo > xDocServInfo( xDoc, UNO_QUERY );
117 if( xDocServInfo.is() )
118 mbPresentation = xDocServInfo->supportsService( "com.sun.star.presentation.PresentationDocument" );
119
120 Reference< XDrawPagesSupplier > xDrawPagesSupplier(xDoc, UNO_QUERY);
121 if(!xDrawPagesSupplier.is())
122 return false;
123
124 Reference< XIndexAccess > xDrawPages = xDrawPagesSupplier->getDrawPages();
125 if(!xDrawPages.is())
126 return false;
127
128 Reference< XDrawPage > xDrawPage;
129
130 // #i56084# set xDrawPage directly when exporting selection
131 if(mbExportSelection)
132 {
133 xDrawPage = mxSelectedDrawPage;
134 }
135 else
136 {
137 xDrawPages->getByIndex(0) >>= xDrawPage;
138 }
139
140 Reference< XPropertySet > xProp( xDrawPage, UNO_QUERY );
141 try
142 {
143 xProp->getPropertyValue( "Width" ) >>= mnDocWidth;
144 xProp->getPropertyValue( "Height" ) >>= mnDocHeight;
145
146 sal_Int32 nOutputWidth = 14400;
147 sal_Int32 nOutputHeight = (nOutputWidth * mnDocHeight ) / mnDocWidth;
148 mpWriter.reset(new Writer( nOutputWidth, nOutputHeight, mnDocWidth, mnDocHeight, mnJPEGcompressMode ));
149 }
150 catch( const Exception& )
151 {
152 OSL_ASSERT( false );
153 return false; // no writer, no cookies
154 }
155
156 // #i56084# nPageCount is 1 when exporting selection
157 const sal_Int32 nPageCount = mbExportSelection ? 1 : xDrawPages->getCount();
158
159 if ( xStatusIndicator.is() )
160 {
161 xStatusIndicator->start("Macromedia Flash (SWF)", nPageCount);
162 }
163
164 for( sal_Int32 nPage = 0; nPage < nPageCount; nPage++)
165 {
166 // #i56084# keep PageNumber? We could determine the PageNumber of the single to-be-exported page
167 // when exporting the selection, but this is only used for swf internal, so no need to do so (AFAIK)
168 mnPageNumber = nPage + 1;
169
170 if ( xStatusIndicator.is() )
171 xStatusIndicator->setValue( nPage );
172
173 // #i56084# get current xDrawPage when not exporting selection; else already set above
174 if(!mbExportSelection)
175 {
176 xDrawPages->getByIndex(nPage) >>= xDrawPage;
177 }
178
179 if( !xDrawPage.is())
180 continue;
181
182 Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
183 if( mbPresentation )
184 {
185 bool bVisible = false;
186 xPropSet->getPropertyValue( "Visible" ) >>= bVisible;
187 if( !bVisible )
188 continue;
189 }
190
191 // #i56084# no background when exporting selection
192 if(!mbExportSelection)
193 {
194 exportBackgrounds( xDrawPage, nPage, false );
195 exportBackgrounds( xDrawPage, nPage, true );
196 }
197
198 maPagesMap[nPage].mnForegroundID = mpWriter->startSprite();
199
200 // #i56084# directly export selection in export selection mode
201 if(mbExportSelection)
202 {
203 exportShapes( mxSelectedShapes, false, false );
204 }
205 else
206 {
207 exportDrawPageContents( xDrawPage, false, false );
208 }
209
210 mpWriter->endSprite();
211
212 // AS: If the background is different than the previous slide,
213 // we have to remove the old one and place the new one.
214 if (nPage)
215 {
216 if (maPagesMap[nPage].mnBackgroundID != maPagesMap[nPage-1].mnBackgroundID)
217 {
218 mpWriter->removeShape(cBackgroundDepth);
219 mpWriter->placeShape( maPagesMap[nPage].mnBackgroundID, cBackgroundDepth, 0, 0 );
220 }
221
222 if (maPagesMap[nPage].mnObjectsID != maPagesMap[nPage-1].mnObjectsID)
223 {
224 mpWriter->removeShape(cBackgroundObjectsDepth);
225 mpWriter->placeShape( maPagesMap[nPage].mnObjectsID, cBackgroundObjectsDepth, 0, 0 );
226 }
227
228 // AS: Remove the Foreground of the previous slide.
229 mpWriter->removeShape(cPageObjectsDepth);
230 }
231 else
232 {
233 mpWriter->placeShape( maPagesMap[nPage].mnBackgroundID, cBackgroundDepth, 0, 0 );
234 mpWriter->placeShape( maPagesMap[nPage].mnObjectsID, cBackgroundObjectsDepth, 0, 0 );
235 }
236
237 mpWriter->placeShape( maPagesMap[nPage].mnForegroundID, cPageObjectsDepth, 0, 0 );
238
239 mpWriter->waitOnClick( cWaitButtonDepth );
240 mpWriter->showFrame();
241 }
242
243 mpWriter->removeShape( cBackgroundDepth );
244 mpWriter->removeShape( cBackgroundObjectsDepth );
245 mpWriter->removeShape( cPageObjectsDepth );
246 mpWriter->gotoFrame( 0 );
247 mpWriter->showFrame();
248
249 mpWriter->storeTo( xOutputStream );
250
251 return true;
252 }
253
254
exportSlides(const Reference<XDrawPage> & xDrawPage,Reference<XOutputStream> const & xOutputStream)255 bool FlashExporter::exportSlides( const Reference< XDrawPage >& xDrawPage, Reference< XOutputStream > const &xOutputStream )
256 {
257 Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
258 if( !xDrawPage.is() || !xPropSet.is() )
259 return false;
260
261 try
262 {
263 if( !mpWriter )
264 {
265 xPropSet->getPropertyValue( "Width" ) >>= mnDocWidth;
266 xPropSet->getPropertyValue( "Height" ) >>= mnDocHeight;
267
268 mpWriter.reset(new Writer( 14400, 10800, mnDocWidth, mnDocHeight, mnJPEGcompressMode ));
269 }
270
271 if( mbPresentation )
272 {
273 bool bVisible = false;
274 xPropSet->getPropertyValue( "Visible" ) >>= bVisible;
275 if( !bVisible )
276 return false;
277 }
278 }
279 catch( const Exception& )
280 {
281 OSL_ASSERT( false );
282 }
283
284 exportDrawPageContents(xDrawPage, true, false);
285
286 mpWriter->storeTo( xOutputStream );
287
288 return true;
289 }
290
exportBackgrounds(const Reference<XDrawPage> & xDrawPage,Reference<XOutputStream> const & xOutputStream,sal_uInt16 nPage,bool bExportObjects)291 sal_uInt16 FlashExporter::exportBackgrounds( const Reference< XDrawPage >& xDrawPage, Reference< XOutputStream > const &xOutputStream, sal_uInt16 nPage, bool bExportObjects )
292 {
293 Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
294 if( !xDrawPage.is() || !xPropSet.is() )
295 return 0;
296
297 if( !mpWriter )
298 {
299 xPropSet->getPropertyValue( "Width" ) >>= mnDocWidth;
300 xPropSet->getPropertyValue( "Height" ) >>= mnDocHeight;
301
302 mpWriter.reset(new Writer( 14400, 10800, mnDocWidth, mnDocHeight, mnJPEGcompressMode ));
303 }
304
305 sal_uInt16 ret = exportBackgrounds(xDrawPage, nPage, bExportObjects);
306
307 if (ret != nPage)
308 return ret;
309
310 if (bExportObjects)
311 mpWriter->placeShape( maPagesMap[nPage].mnObjectsID, uInt16_(1), 0, 0 );
312 else
313 mpWriter->placeShape( maPagesMap[nPage].mnBackgroundID, uInt16_(0), 0, 0 );
314
315 mpWriter->storeTo( xOutputStream );
316
317 return nPage;
318 }
319
exportBackgrounds(Reference<XDrawPage> const & xDrawPage,sal_uInt16 nPage,bool bExportObjects)320 sal_uInt16 FlashExporter::exportBackgrounds( Reference< XDrawPage > const & xDrawPage, sal_uInt16 nPage, bool bExportObjects )
321 {
322 Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY );
323 if( !xDrawPage.is() || !xPropSet.is() )
324 return 0;
325
326 bool bBackgroundVisible = true;
327 bool bBackgroundObjectsVisible = true;
328
329 if( mbPresentation )
330 {
331 xPropSet->getPropertyValue( "IsBackgroundVisible" ) >>= bBackgroundVisible;
332 xPropSet->getPropertyValue( "IsBackgroundObjectsVisible" ) >>= bBackgroundObjectsVisible;
333 }
334
335
336 if (bExportObjects)
337 {
338 if (bBackgroundObjectsVisible)
339 {
340 Reference< XMasterPageTarget > xMasterPageTarget( xDrawPage, UNO_QUERY );
341 if( !xMasterPageTarget.is() )
342 {
343 maPagesMap[nPage].mnObjectsID = 0xffff;
344 return 0xffff;
345 }
346 Reference<XDrawPage> aTemp = xMasterPageTarget->getMasterPage();
347 sal_uInt16 ret = exportMasterPageObjects(nPage, aTemp);
348 if (ret != nPage)
349 return ret;
350 }
351 else
352 {
353 maPagesMap[nPage].mnObjectsID = 0xffff;
354 return 0xffff;
355 }
356 }
357 else
358 {
359 if (bBackgroundVisible)
360 {
361 sal_uInt16 ret = exportDrawPageBackground(nPage, xDrawPage);
362
363 if (ret != nPage)
364 return ret;
365 }
366 else
367 {
368 maPagesMap[nPage].mnBackgroundID = 0xffff;
369 return 0xffff;
370 }
371 }
372
373 return nPage;
374 }
375
376
377 static sal_Int32 nPlaceDepth;
378 // AS: A Slide can have a private background or use its masterpage's background.
379 // We use the checksums on the metafiles to tell if backgrounds are the same and
380 // should be reused. The return value indicates which slide's background to use.
381 // If the return value != nPage, then there is no background (if == -1) or the
382 // background has already been exported.
exportDrawPageBackground(sal_uInt16 nPage,Reference<XDrawPage> const & xPage)383 sal_uInt16 FlashExporter::exportDrawPageBackground(sal_uInt16 nPage, Reference< XDrawPage > const & xPage)
384 {
385 sal_uInt16 rBackgroundID;
386
387 GDIMetaFile aMtfPrivate, aMtfMaster;
388 Reference< XComponent > xComponent( xPage, UNO_QUERY );
389
390 Reference< XMasterPageTarget > xMasterPageTarget( xPage, UNO_QUERY );
391 if( !xMasterPageTarget.is() )
392 return 0xffff;
393
394 Reference< XDrawPage > xMasterPage = xMasterPageTarget->getMasterPage();
395 if( !xMasterPage.is())
396 return 0xffff;
397
398 Reference< XComponent > xCompMaster( xMasterPage, UNO_QUERY );
399
400 getMetaFile( xCompMaster, aMtfMaster, true );
401 getMetaFile( xComponent, aMtfPrivate, true );
402
403 BitmapChecksum masterchecksum = aMtfMaster.GetChecksum();
404 BitmapChecksum privatechecksum = aMtfPrivate.GetChecksum();
405
406 // AS: If the slide has its own background
407 if (privatechecksum)
408 {
409 ChecksumCache::iterator it = gPrivateCache.find(privatechecksum);
410
411 // AS: and we've previously encountered this background, just return
412 // the previous index.
413 if (gPrivateCache.end() != it)
414 {
415 maPagesMap[nPage].mnBackgroundID =
416 maPagesMap[it->second].mnBackgroundID;
417 return it->second;
418 }
419 else
420 {
421 // AS: Otherwise, cache this checksum.
422 gPrivateCache[privatechecksum] = nPage;
423
424 rBackgroundID = mpWriter->defineShape( aMtfPrivate );
425
426 maPagesMap[nPage].mnBackgroundID = rBackgroundID;
427 return nPage;
428 }
429 }
430
431 // AS: Ok, no private background. Use the master page's.
432 // AS: Have we already exported this master page?
433 ChecksumCache::iterator it = gMasterCache.find(masterchecksum);
434
435 if (gMasterCache.end() != it)
436 {
437 maPagesMap[nPage].mnBackgroundID =
438 maPagesMap[it->second].mnBackgroundID;
439
440 return it->second; // AS: Yes, so don't export it again.
441 }
442
443 gMasterCache[masterchecksum] = nPage;
444
445 rBackgroundID = mpWriter->defineShape( aMtfMaster );
446
447 maPagesMap[nPage].mnBackgroundID = rBackgroundID;
448
449 return nPage;
450 }
451
exportMasterPageObjects(sal_uInt16 nPage,Reference<XDrawPage> const & xMasterPage)452 sal_uInt16 FlashExporter::exportMasterPageObjects(sal_uInt16 nPage, Reference< XDrawPage > const & xMasterPage)
453 {
454 BitmapChecksum shapesum = ActionSummer(xMasterPage);
455
456 ChecksumCache::iterator it = gObjectCache.find(shapesum);
457
458 if (gObjectCache.end() != it)
459 {
460 maPagesMap[nPage].mnObjectsID =
461 maPagesMap[it->second].mnObjectsID;
462
463 return it->second; // AS: Yes, so don't export it again.
464 }
465
466 gObjectCache[shapesum] = nPage;
467
468 sal_uInt16 rObjectsID = mpWriter->startSprite();
469 exportDrawPageContents( xMasterPage, false, true );
470 mpWriter->endSprite();
471
472 maPagesMap[nPage].mnObjectsID = rObjectsID;
473
474 return nPage;
475 }
476
477
478 /** export's the definition of the shapes inside this drawing page and adds the
479 shape infos to the current PageInfo */
exportDrawPageContents(const Reference<XDrawPage> & xPage,bool bStream,bool bMaster)480 void FlashExporter::exportDrawPageContents( const Reference< XDrawPage >& xPage, bool bStream, bool bMaster )
481 {
482 exportShapes(xPage, bStream, bMaster);
483 }
484
485
486 /** export's the definition of the shapes inside this XShapes container and adds the
487 shape infos to the current PageInfo */
exportShapes(const Reference<XShapes> & xShapes,bool bStream,bool bMaster)488 void FlashExporter::exportShapes( const Reference< XShapes >& xShapes, bool bStream, bool bMaster )
489 {
490 OSL_ENSURE( (xShapes->getCount() <= 0xffff), "overflow in FlashExporter::exportDrawPageContents()" );
491
492 sal_uInt16 nShapeCount = static_cast<sal_uInt16>(std::min( xShapes->getCount(), sal_Int32(0xffff) ));
493 sal_uInt16 nShape;
494
495 Reference< XShape > xShape;
496
497 for( nShape = 0; nShape < nShapeCount; nShape++ )
498 {
499 xShapes->getByIndex( nShape ) >>= xShape;
500
501 if( xShape.is() )
502 {
503 Reference< XShapes > xShapes2( xShape, UNO_QUERY );
504 if( xShapes2.is() && xShape->getShapeType() == "com.sun.star.drawing.GroupShape" )
505 // export the contents of group shapes, but we only ever stream at the top
506 // recursive level anyway, so pass false for streaming.
507 exportShapes( xShapes2, false, bMaster);
508 else
509 exportShape( xShape, bMaster);
510 }
511
512 if (bStream)
513 mpWriter->showFrame();
514 }
515 }
516
517
518 /** export this shape definition and adds it's info to the current PageInfo */
exportShape(const Reference<XShape> & xShape,bool bMaster)519 void FlashExporter::exportShape( const Reference< XShape >& xShape, bool bMaster )
520 {
521 Reference< XPropertySet > xPropSet( xShape, UNO_QUERY );
522 if( !xPropSet.is() )
523 return;
524
525 if( mbPresentation )
526 {
527 try
528 {
529 // skip empty presentation objects
530 bool bEmpty = false;
531 xPropSet->getPropertyValue( "IsEmptyPresentationObject" ) >>= bEmpty;
532 if( bEmpty )
533 return;
534
535 // don't export presentation placeholders on masterpage
536 // they can be non empty when user edits the default texts
537 if( bMaster )
538 {
539 OUString aShapeType( xShape->getShapeType() );
540 if( aShapeType == "com.sun.star.presentation.TitleTextShape" ||
541 aShapeType == "com.sun.star.presentation.OutlinerShape" ||
542 aShapeType == "com.sun.star.presentation.HeaderShape" ||
543 aShapeType == "com.sun.star.presentation.FooterShape" ||
544 aShapeType == "com.sun.star.presentation.SlideNumberShape" ||
545 aShapeType == "com.sun.star.presentation.DateTimeShape" )
546 return;
547 }
548 }
549 catch( const Exception& )
550 {
551 // TODO: If we are exporting a draw, this property is not available
552 }
553 }
554
555 try
556 {
557 css::awt::Rectangle aBoundRect;
558 xPropSet->getPropertyValue( "BoundRect" ) >>= aBoundRect;
559
560 std::unique_ptr<ShapeInfo> pShapeInfo(new ShapeInfo());
561 pShapeInfo->mnX = aBoundRect.X;
562 pShapeInfo->mnY = aBoundRect.Y;
563 pShapeInfo->mnWidth = aBoundRect.Width;
564 pShapeInfo->mnHeight = aBoundRect.Height;
565
566 GDIMetaFile aMtf;
567 Reference< XComponent > xComponent( xShape, UNO_QUERY );
568
569 bool bIsOleObject = xShape->getShapeType() == "com.sun.star.presentation.OLE2Shape" || xShape->getShapeType() == "com.sun.star.drawing.OLE2Shape";
570
571 getMetaFile( xComponent, aMtf );
572
573 // AS: If it's an OLE object, then export a JPEG if the user requested.
574 // In this case, we use the bounding rect info generated in the first getMetaFile
575 // call, and then clear the metafile and add a BMP action. This may be turned into
576 // a JPEG, depending on what gives the best compression.
577 if (bIsOleObject && mbExportOLEAsJPEG)
578 getMetaFile( xComponent, aMtf, false, true );
579
580 sal_uInt16 nID;
581 BitmapChecksum checksum = aMtf.GetChecksum();
582
583 ChecksumCache::iterator it = gMetafileCache.find(checksum);
584
585 if (gMetafileCache.end() != it)
586 nID = it->second;
587 else
588 {
589 nID = mpWriter->defineShape( aMtf );
590 gMetafileCache[checksum] = nID;
591 }
592
593 if (!nID)
594 return;
595
596 pShapeInfo->mnID = nID;
597
598 // pPageInfo->addShape( pShapeInfo );
599
600 mpWriter->placeShape( pShapeInfo->mnID, uInt16_(nPlaceDepth++), pShapeInfo->mnX, pShapeInfo->mnY );
601 }
602 catch( const Exception& )
603 {
604 OSL_ASSERT(false);
605 }
606 }
607
608
getMetaFile(Reference<XComponent> const & xComponent,GDIMetaFile & rMtf,bool bOnlyBackground,bool bExportAsJPEG)609 bool FlashExporter::getMetaFile( Reference< XComponent > const &xComponent, GDIMetaFile& rMtf, bool bOnlyBackground /* = false */, bool bExportAsJPEG /* = false */)
610 {
611 if( !mxGraphicExporter.is() )
612 mxGraphicExporter = GraphicExportFilter::create( mxContext );
613
614 utl::TempFile aFile;
615 aFile.EnableKillingFile();
616
617 Sequence< PropertyValue > aFilterData(bExportAsJPEG ? 3 : 2);
618 aFilterData[0].Name = "Version";
619 aFilterData[0].Value <<= sal_Int32(6000);
620 aFilterData[1].Name = "PageNumber";
621 aFilterData[1].Value <<= mnPageNumber;
622
623 if(bExportAsJPEG)
624 {
625 aFilterData[2].Name = "Translucent";
626 aFilterData[2].Value <<= true;
627 }
628
629 Sequence< PropertyValue > aDescriptor( bOnlyBackground ? 4 : 3 );
630 aDescriptor[0].Name = "FilterName";
631
632 // AS: If we've been asked to export as an image, then use the BMP filter.
633 // Otherwise, use SVM. This is useful for things that don't convert well as
634 // metafiles, like the occasional OLE object.
635 aDescriptor[0].Value <<= bExportAsJPEG ? OUString("PNG") : OUString("SVM");
636
637 aDescriptor[1].Name = "URL";
638 aDescriptor[1].Value <<= aFile.GetURL();
639 aDescriptor[2].Name = "FilterData";
640 aDescriptor[2].Value <<= aFilterData;
641 if( bOnlyBackground )
642 {
643 aDescriptor[3].Name = "ExportOnlyBackground";
644 aDescriptor[3].Value <<= bOnlyBackground;
645 }
646 mxGraphicExporter->setSourceDocument( xComponent );
647 mxGraphicExporter->filter( aDescriptor );
648
649 if (bExportAsJPEG)
650 {
651 Graphic aGraphic;
652 GraphicFilter aFilter(false);
653
654 aFilter.ImportGraphic( aGraphic, aFile.GetURL(), *aFile.GetStream( StreamMode::READ ) );
655 BitmapEx rBitmapEx( aGraphic.GetBitmapEx().GetBitmap(), Color(255,255,255) );
656
657 tools::Rectangle clipRect;
658 for( size_t i = 0, nCount = rMtf.GetActionSize(); i < nCount; i++ )
659 {
660 const MetaAction* pAction = rMtf.GetAction( i );
661 if (pAction->GetType() == MetaActionType::ISECTRECTCLIPREGION)
662 {
663 const MetaISectRectClipRegionAction* pA = static_cast<const MetaISectRectClipRegionAction*>(pAction);
664 clipRect = pA->GetRect();
665 break;
666 }
667 }
668 MetaBmpExScaleAction *pmetaAct = new MetaBmpExScaleAction(Point(clipRect.Left(), clipRect.Top()), Size(clipRect.GetWidth(), clipRect.GetHeight()), rBitmapEx);
669
670 rMtf.Clear();
671 rMtf.AddAction(pmetaAct);
672
673 }
674 else
675 {
676 rMtf.Read( *aFile.GetStream( StreamMode::READ ) );
677
678 if(usesClipActions(rMtf))
679 {
680 // #i121267# It is necessary to prepare the metafile since the export does *not* support
681 // clip regions. This tooling method clips the geometry content of the metafile internally
682 // against its own clip regions, so that the export is safe to ignore clip regions
683 clipMetafileContentAgainstOwnRegions(rMtf);
684 }
685 }
686
687 return rMtf.GetActionSize() != 0;
688 }
689
ActionSummer(Reference<XShape> const & xShape)690 BitmapChecksum FlashExporter::ActionSummer(Reference< XShape > const & xShape)
691 {
692 Reference< XShapes > xShapes( xShape, UNO_QUERY );
693
694 if( xShapes.is() )
695 {
696 return ActionSummer(xShapes);
697 }
698 else
699 {
700 Reference< XComponent > xComponentShape( xShape, UNO_QUERY );
701
702 GDIMetaFile aMtf;
703 getMetaFile( xComponentShape, aMtf);
704
705 return aMtf.GetChecksum();
706 }
707 }
708
ActionSummer(Reference<XShapes> const & xShapes)709 BitmapChecksum FlashExporter::ActionSummer(Reference< XShapes > const & xShapes)
710 {
711 sal_uInt32 nShapeCount = xShapes->getCount();
712 BitmapChecksum shapecount = 0;
713
714 Reference< XShape > xShape2;
715
716 for( sal_uInt32 nShape = 0; nShape < nShapeCount; nShape++ )
717 {
718 xShapes->getByIndex( nShape ) >>= xShape2;
719
720 shapecount += ActionSummer(xShape2);
721 }
722
723 return shapecount;
724 }
725
726 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
727