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