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