fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / sd / source / filter / eppt / epptso.cxx
blob41a82388dfc5816f425d32ce750d5038e4a00515
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <osl/endian.h>
21 #include <eppt.hxx>
22 #include "text.hxx"
23 #include "epptdef.hxx"
24 #include "escherex.hxx"
25 #include <tools/poly.hxx>
26 #include <vcl/bmpacc.hxx>
27 #include <vcl/gradient.hxx>
28 #include <vcl/gfxlink.hxx>
29 #include <tools/stream.hxx>
30 #include <sot/storage.hxx>
31 #include <vcl/outdev.hxx>
32 #include <vcl/virdev.hxx>
33 #include <sfx2/app.hxx>
34 #include <svl/languageoptions.hxx>
35 #include <editeng/svxenum.hxx>
36 #include <svx/unoapi.hxx>
37 #include <svx/svdoashp.hxx>
38 #include <com/sun/star/style/VerticalAlignment.hpp>
39 #include <com/sun/star/container/XIndexReplace.hpp>
40 #include <com/sun/star/presentation/XPresentationPage.hpp>
41 #include <com/sun/star/awt/XFont.hpp>
42 #include <com/sun/star/awt/FontWeight.hpp>
43 #include <com/sun/star/awt/FontUnderline.hpp>
44 #include <com/sun/star/style/ParagraphAdjust.hpp>
45 #include <com/sun/star/style/LineSpacing.hpp>
46 #include <com/sun/star/style/LineSpacingMode.hpp>
47 #ifndef _COM_SUN_STAR_STYLE_XSTYLEFAMILIESSUPPLIER_PP_
48 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
49 #endif
50 #include <com/sun/star/style/XStyle.hpp>
51 #include <com/sun/star/drawing/PointSequence.hpp>
52 #include <com/sun/star/drawing/FlagSequence.hpp>
53 #include <com/sun/star/drawing/PolygonFlags.hpp>
54 #include <com/sun/star/beans/PropertyValue.hpp>
55 #include <com/sun/star/drawing/XControlShape.hpp>
56 #include <comphelper/processfactory.hxx>
57 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
58 #include <com/sun/star/i18n/XBreakIterator.hpp>
59 #include <com/sun/star/i18n/XScriptTypeDetector.hpp>
60 #include <com/sun/star/i18n/ScriptType.hpp>
61 #include <com/sun/star/i18n/ScriptDirection.hpp>
62 #include <com/sun/star/embed/Aspects.hpp>
63 #include <vcl/cvtgrf.hxx>
64 #include <tools/urlobj.hxx>
65 #include <comphelper/extract.hxx>
66 #include <cppuhelper/proptypehlp.hxx>
67 #include <toolkit/unohlp.hxx>
68 #include <rtl/crc.h>
69 #include <comphelper/classids.hxx>
70 #include <unotools/ucbstreamhelper.hxx>
71 #include <com/sun/star/text/FontRelief.hpp>
72 #include <editeng/frmdiritem.hxx>
73 #include <vcl/fltcall.hxx>
74 #include <com/sun/star/table/XTable.hpp>
75 #include <com/sun/star/table/XMergeableCell.hpp>
76 #include <com/sun/star/table/BorderLine.hpp>
77 #include <set>
78 #include <oox/ole/olehelper.hxx>
79 #include "i18nlangtag/languagetag.hxx"
81 using namespace ::com::sun::star;
83 ////////////////////////////////////////////////////////////////////////////////////////////////////
85 #define ANSI_CHARSET 0
86 #define SYMBOL_CHARSET 2
88 ////////////////////////////////////////////////////////////////////////////////////////////////////
90 /* Font Families */
91 #define FF_ROMAN 0x10
92 #define FF_SWISS 0x20
93 #define FF_MODERN 0x30
94 #define FF_SCRIPT 0x40
95 #define FF_DECORATIVE 0x50
97 ////////////////////////////////////////////////////////////////////////////////////////////////////
99 #define DEFAULT_PITCH 0x00
100 #define FIXED_PITCH 0x01
102 // ---------------------------------------------------------------------------------------------
104 PPTExBulletProvider::PPTExBulletProvider()
106 pGraphicProv = new EscherGraphicProvider( _E_GRAPH_PROV_USE_INSTANCES | _E_GRAPH_PROV_DO_NOT_ROTATE_METAFILES );
109 PPTExBulletProvider::~PPTExBulletProvider()
111 delete pGraphicProv;
114 sal_uInt16 PPTExBulletProvider::GetId( const OString& rUniqueId, Size& rGraphicSize )
116 sal_uInt16 nRetValue = 0xffff;
118 if ( !rUniqueId.isEmpty() )
120 Rectangle aRect;
121 GraphicObject aGraphicObject( rUniqueId );
122 Graphic aMappedGraphic, aGraphic( aGraphicObject.GetGraphic() );
123 Size aPrefSize( aGraphic.GetPrefSize() );
124 BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
126 if ( rGraphicSize.Width() && rGraphicSize.Height() )
128 double fQ1 = ( (double)aPrefSize.Width() / (double)aPrefSize.Height() );
129 double fQ2 = ( (double)rGraphicSize.Width() / (double)rGraphicSize.Height() );
130 double fXScale = 1;
131 double fYScale = 1;
133 if ( fQ1 > fQ2 )
134 fYScale = fQ1 / fQ2;
135 else if ( fQ1 < fQ2 )
136 fXScale = fQ2 / fQ1;
138 if ( ( fXScale != 1.0 ) || ( fYScale != 1.0 ) )
140 aBmpEx.Scale( fXScale, fYScale );
141 Size aNewSize( (sal_Int32)((double)rGraphicSize.Width() / fXScale + 0.5 ),
142 (sal_Int32)((double)rGraphicSize.Height() / fYScale + 0.5 ) );
144 rGraphicSize = aNewSize;
146 aMappedGraphic = Graphic( aBmpEx );
147 aGraphicObject = GraphicObject( aMappedGraphic );
150 sal_uInt32 nId = pGraphicProv->GetBlibID( aBuExPictureStream, aGraphicObject.GetUniqueID(), aRect, NULL, NULL );
152 if ( nId && ( nId < 0x10000 ) )
153 nRetValue = (sal_uInt16)nId - 1;
155 return nRetValue;
158 // ---------------------------------------------------------------------------------------------
160 sal_uInt32 PPTWriter::ImplVBAInfoContainer( SvStream* pStrm )
162 sal_uInt32 nSize = 28;
163 if ( pStrm )
165 *pStrm << (sal_uInt32)( 0x1f | ( EPP_VBAInfo << 16 ) )
166 << (sal_uInt32)( nSize - 8 )
167 << (sal_uInt32)( 2 | ( EPP_VBAInfoAtom << 16 ) )
168 << (sal_uInt32)12;
169 mpPptEscherEx->InsertPersistOffset( EPP_Persist_VBAInfoAtom, pStrm->Tell() );
170 *pStrm << (sal_uInt32)0
171 << (sal_uInt32)0
172 << (sal_uInt32)1;
174 return nSize;
177 // ---------------------------------------------------------------------------------------------
179 sal_uInt32 PPTWriter::ImplSlideViewInfoContainer( sal_uInt32 nInstance, SvStream* pStrm )
181 sal_uInt32 nSize = 111;
182 if ( pStrm )
184 sal_uInt8 bShowGuides = 0;
185 sal_uInt8 bSnapToGrid = 1;
186 sal_uInt8 bSnapToShape = 0;
188 sal_Int32 nScaling = 85;
189 sal_Int32 nMasterCoordinate = 0xdda;
190 sal_Int32 nXOrigin = -780;
191 sal_Int32 nYOrigin = -84;
193 sal_Int32 nPosition1 = 0x870;
194 sal_Int32 nPosition2 = 0xb40;
196 if ( nInstance )
198 bShowGuides = 1;
199 nScaling = 0x3b;
200 nMasterCoordinate = 0xf0c;
201 nXOrigin = -1752;
202 nYOrigin = -72;
203 nPosition1 = 0xb40;
204 nPosition2 = 0x870;
206 *pStrm << (sal_uInt32)( 0xf | ( EPP_SlideViewInfo << 16 ) | ( nInstance << 4 ) )
207 << (sal_uInt32)( nSize - 8 )
208 << (sal_uInt32)( EPP_SlideViewInfoAtom << 16 ) << (sal_uInt32)3
209 << bShowGuides << bSnapToGrid << bSnapToShape
210 << (sal_uInt32)( EPP_ViewInfoAtom << 16 ) << (sal_uInt32)52
211 << nScaling << (sal_Int32)100 << nScaling << (sal_Int32)100 // scaling atom - Keeps the current scale
212 << nScaling << (sal_Int32)100 << nScaling << (sal_Int32)100 // scaling atom - Keeps the previous scale
213 << (sal_Int32)0x17ac << nMasterCoordinate// Origin - Keeps the origin in master coordinates
214 << nXOrigin << nYOrigin // Origin
215 << (sal_uInt8)1 // Bool1 varScale - Set if zoom to fit is set
216 << (sal_uInt8)0 // bool1 draftMode - Not used
217 << (sal_uInt16)0 // padword
218 << (sal_uInt32)( ( 7 << 4 ) | ( EPP_GuideAtom << 16 ) ) << (sal_uInt32)8
219 << (sal_uInt32)0 // Type of the guide. If the guide is horizontal this value is zero. If it's vertical, it's one.
220 << nPosition1 // Position of the guide in master coordinates. X coordinate if it's vertical, and Y coordinate if it's horizontal.
221 << (sal_uInt32)( ( 7 << 4 ) | ( EPP_GuideAtom << 16 ) ) << (sal_uInt32)8
222 << (sal_Int32)1 // Type of the guide. If the guide is horizontal this value is zero. If it's vertical, it's one.
223 << nPosition2; // Position of the guide in master coordinates. X coordinate if it's vertical, and Y coordinate if it's horizontal.
225 return nSize;
228 // ---------------------------------------------------------------------------------------------
230 sal_uInt32 PPTWriter::ImplOutlineViewInfoContainer( SvStream* pStrm )
232 sal_uInt32 nSize = 68;
233 if ( pStrm )
235 *pStrm << (sal_uInt32)( 0xf | ( EPP_OutlineViewInfo << 16 ) ) << (sal_uInt32)( nSize - 8 )
236 << (sal_uInt32)( EPP_ViewInfoAtom << 16 ) << (sal_uInt32)52
237 << (sal_Int32)170 << (sal_Int32)200 << (sal_Int32)170 << (sal_Int32)200 // scaling atom - Keeps the current scale
238 << (sal_Int32)170 << (sal_Int32)200 << (sal_Int32)170 << (sal_Int32)200 // scaling atom - Keeps the previous scale
239 << (sal_Int32)0x17ac << (sal_Int32)0xdda // Origin - Keeps the origin in master coordinates
240 << (sal_Int32)-780 << (sal_Int32)-84 // Origin
241 << (sal_uInt8)1 // bool1 varScale - Set if zoom to fit is set
242 << (sal_uInt8)0 // bool1 draftMode - Not used
243 << (sal_uInt16)0; // padword
245 return nSize;
248 // ---------------------------------------------------------------------------------------------
250 sal_uInt32 PPTWriter::ImplProgBinaryTag( SvStream* pStrm )
252 sal_uInt32 nPictureStreamSize, nOutlineStreamSize, nSize = 8;
254 nPictureStreamSize = aBuExPictureStream.Tell();
255 if ( nPictureStreamSize )
256 nSize += nPictureStreamSize + 8;
258 nOutlineStreamSize = aBuExOutlineStream.Tell();
259 if ( nOutlineStreamSize )
260 nSize += nOutlineStreamSize + 8;
262 if ( pStrm )
264 *pStrm << (sal_uInt32)( EPP_BinaryTagData << 16 ) << (sal_uInt32)( nSize - 8 );
265 if ( nPictureStreamSize )
267 *pStrm << (sal_uInt32)( 0xf | ( EPP_PST_ExtendedBuGraContainer << 16 ) ) << nPictureStreamSize;
268 pStrm->Write( aBuExPictureStream.GetData(), nPictureStreamSize );
270 if ( nOutlineStreamSize )
272 *pStrm << (sal_uInt32)( 0xf | ( EPP_PST_ExtendedPresRuleContainer << 16 ) ) << nOutlineStreamSize;
273 pStrm->Write( aBuExOutlineStream.GetData(), nOutlineStreamSize );
276 return nSize;
279 // ---------------------------------------------------------------------------------------------
281 sal_uInt32 PPTWriter::ImplProgBinaryTagContainer( SvStream* pStrm, SvMemoryStream* pBinTagStrm )
283 sal_uInt32 nSize = 8 + 8 + 14;
284 if ( pStrm )
286 *pStrm << (sal_uInt32)( 0xf | ( EPP_ProgBinaryTag << 16 ) ) << (sal_uInt32)0
287 << (sal_uInt32)( EPP_CString << 16 ) << (sal_uInt32)14
288 << (sal_uInt32)0x5f005f << (sal_uInt32)0x50005f
289 << (sal_uInt32)0x540050 << (sal_uInt16)0x39;
291 if ( pBinTagStrm )
293 sal_uInt32 nLen = pBinTagStrm->Tell();
294 nSize += nLen + 8;
295 *pStrm << (sal_uInt32)( EPP_BinaryTagData << 16 ) << nLen;
296 pStrm->Write( pBinTagStrm->GetData(), nLen );
298 else
299 nSize += ImplProgBinaryTag( pStrm );
301 if ( pStrm )
303 pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) );
304 *pStrm << (sal_uInt32)( nSize - 8 );
305 pStrm->SeekRel( nSize - 8 );
307 return nSize;
310 // ---------------------------------------------------------------------------------------------
312 sal_uInt32 PPTWriter::ImplProgTagContainer( SvStream* pStrm, SvMemoryStream* pBinTagStrm )
314 sal_uInt32 nSize = 0;
315 if ( aBuExPictureStream.Tell() || aBuExOutlineStream.Tell() || pBinTagStrm )
317 nSize = 8;
318 if ( pStrm )
320 *pStrm << (sal_uInt32)( 0xf | ( EPP_ProgTags << 16 ) ) << (sal_uInt32)0;
322 nSize += ImplProgBinaryTagContainer( pStrm, pBinTagStrm );
323 if ( pStrm )
325 pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) );
326 *pStrm << (sal_uInt32)( nSize - 8 );
327 pStrm->SeekRel( nSize - 8 );
330 return nSize;
333 // ---------------------------------------------------------------------------------------------
335 sal_uInt32 PPTWriter::ImplDocumentListContainer( SvStream* pStrm )
337 sal_uInt32 nSize = 8;
338 if ( pStrm )
340 *pStrm << (sal_uInt32)( ( EPP_List << 16 ) | 0xf ) << (sal_uInt32)0;
343 nSize += ImplVBAInfoContainer( pStrm );
344 nSize += ImplSlideViewInfoContainer( 0, pStrm );
345 nSize += ImplOutlineViewInfoContainer( pStrm );
346 nSize += ImplSlideViewInfoContainer( 1, pStrm );
347 nSize += ImplProgTagContainer( pStrm );
349 if ( pStrm )
351 pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) );
352 *pStrm << (sal_uInt32)( nSize - 8 );
353 pStrm->SeekRel( nSize - 8 );
355 return nSize;
358 // ---------------------------------------------------------------------------------------------
360 sal_uInt32 PPTWriter::ImplMasterSlideListContainer( SvStream* pStrm )
362 sal_uInt32 i, nSize = 28 * mnMasterPages + 8;
363 if ( pStrm )
365 *pStrm << (sal_uInt32)( 0x1f | ( EPP_SlideListWithText << 16 ) ) << (sal_uInt32)( nSize - 8 );
367 for ( i = 0; i < mnMasterPages; i++ )
369 *pStrm << (sal_uInt32)( EPP_SlidePersistAtom << 16 ) << (sal_uInt32)20;
370 mpPptEscherEx->InsertPersistOffset( EPP_MAINMASTER_PERSIST_KEY | i, pStrm->Tell() );
371 *pStrm << (sal_uInt32)0 // psrReference - logical reference to the slide persist object ( EPP_MAINMASTER_PERSIST_KEY )
372 << (sal_uInt32)0 // flags - only bit 3 used, if set then slide contains shapes other than placeholders
373 << (sal_Int32)0 // numberTexts - number of placeholder texts stored with the persist object. Allows to display outline view without loading the slide persist objects
374 << (sal_Int32)( 0x80000000 | i ) // slideId - Unique slide identifier, used for OLE link monikers for example
375 << (sal_uInt32)0; // reserved, usualy 0
378 return nSize;
381 // ---------------------------------------------------------------------------------------------
383 sal_uInt32 PPTWriter::ImplInsertBookmarkURL( const String& rBookmarkURL, const sal_uInt32 nType,
384 const String& rStringVer0, const String& rStringVer1, const String& rStringVer2, const String& rStringVer3 )
386 sal_uInt32 nHyperId = ++mnExEmbed;
388 OUString sBookmarkURL( rBookmarkURL );
389 INetURLObject aBaseURI( maBaseURI );
390 INetURLObject aBookmarkURI( rBookmarkURL );
391 if( aBaseURI.GetProtocol() == aBookmarkURI.GetProtocol() )
393 OUString aRelUrl( INetURLObject::GetRelURL( maBaseURI, rBookmarkURL,
394 INetURLObject::WAS_ENCODED, INetURLObject::DECODE_TO_IURI, RTL_TEXTENCODING_UTF8, INetURLObject::FSYS_DETECT ) );
395 if ( !aRelUrl.isEmpty() )
396 sBookmarkURL = aRelUrl;
398 maHyperlink.push_back( EPPTHyperlink( sBookmarkURL, nType ) );
400 *mpExEmbed << (sal_uInt16)0xf
401 << (sal_uInt16)EPP_ExHyperlink
402 << (sal_uInt32)0;
403 sal_uInt32 nHyperSize, nHyperStart = mpExEmbed->Tell();
404 *mpExEmbed << (sal_uInt16)0
405 << (sal_uInt16)EPP_ExHyperlinkAtom
406 << (sal_uInt32)4
407 << nHyperId;
409 sal_uInt16 i, nStringLen;
410 nStringLen = rStringVer0.Len();
411 if ( nStringLen )
413 *mpExEmbed << (sal_uInt32)( EPP_CString << 16 ) << (sal_uInt32)( nStringLen * 2 );
414 for ( i = 0; i < nStringLen; i++ )
416 *mpExEmbed << rStringVer0.GetChar( i );
419 nStringLen = rStringVer1.Len();
420 if ( nStringLen )
422 *mpExEmbed << (sal_uInt32)( ( EPP_CString << 16 ) | 0x10 ) << (sal_uInt32)( nStringLen * 2 );
423 for ( i = 0; i < nStringLen; i++ )
425 *mpExEmbed << rStringVer1.GetChar( i );
428 nStringLen = rStringVer2.Len();
429 if ( nStringLen )
431 *mpExEmbed << (sal_uInt32)( ( EPP_CString << 16 ) | 0x20 ) << (sal_uInt32)( nStringLen * 2 );
432 for ( i = 0; i < nStringLen; i++ )
434 *mpExEmbed << rStringVer2.GetChar( i );
437 nStringLen = rStringVer3.Len();
438 if ( nStringLen )
440 *mpExEmbed << (sal_uInt32)( ( EPP_CString << 16 ) | 0x30 ) << (sal_uInt32)( nStringLen * 2 );
441 for ( i = 0; i < nStringLen; i++ )
443 *mpExEmbed << rStringVer3.GetChar( i );
446 nHyperSize = mpExEmbed->Tell() - nHyperStart;
447 mpExEmbed->SeekRel( - ( (sal_Int32)nHyperSize + 4 ) );
448 *mpExEmbed << nHyperSize;
449 mpExEmbed->SeekRel( nHyperSize );
450 return nHyperId;
453 // ---------------------------------------------------------------------------------------------
455 sal_Bool PPTWriter::ImplCloseDocument()
457 sal_uInt32 nOfs = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_Document );
458 if ( nOfs )
460 mpPptEscherEx->PtReplaceOrInsert( EPP_Persist_CurrentPos, mpStrm->Tell() );
461 mpStrm->Seek( nOfs );
463 // creating the TxMasterStyleAtom
464 SvMemoryStream aTxMasterStyleAtomStrm( 0x200, 0x200 );
466 EscherExAtom aTxMasterStyleAtom( aTxMasterStyleAtomStrm, EPP_TxMasterStyleAtom, EPP_TEXTTYPE_Other );
467 aTxMasterStyleAtomStrm << (sal_uInt16)5; // paragraph count
468 sal_uInt16 nLev;
469 sal_Bool bFirst = sal_True;
470 for ( nLev = 0; nLev < 5; nLev++ )
472 mpStyleSheet->mpParaSheet[ EPP_TEXTTYPE_Other ]->Write( aTxMasterStyleAtomStrm, mpPptEscherEx, nLev, bFirst, sal_False, mXPagePropSet );
473 mpStyleSheet->mpCharSheet[ EPP_TEXTTYPE_Other ]->Write( aTxMasterStyleAtomStrm, mpPptEscherEx, nLev, bFirst, sal_False, mXPagePropSet );
474 bFirst = sal_False;
478 mpExEmbed->Seek( STREAM_SEEK_TO_END );
479 sal_uInt32 nExEmbedSize = mpExEmbed->Tell();
481 // nEnviroment : whole size of the environment container
482 sal_uInt32 nEnvironment = maFontCollection.GetCount() * 76 // 68 bytes per Fontenityatom and 8 Bytes per header
483 + 8 // 1 FontCollection container
484 + 20 // SrKinsoku container
485 + 18 // 1 TxSiStyleAtom
486 + aTxMasterStyleAtomStrm.Tell() // 1 TxMasterStyleAtom;
487 + mpStyleSheet->SizeOfTxCFStyleAtom();
489 sal_uInt32 nBytesToInsert = nEnvironment + 8;
491 if ( nExEmbedSize )
492 nBytesToInsert += nExEmbedSize + 8 + 12;
494 nBytesToInsert += maSoundCollection.GetSize();
495 nBytesToInsert += mpPptEscherEx->DrawingGroupContainerSize();
496 nBytesToInsert += ImplMasterSlideListContainer( NULL );
497 nBytesToInsert += ImplDocumentListContainer( NULL );
499 // insert nBytes into stream and adjust depending container
500 mpPptEscherEx->InsertAtCurrentPos( nBytesToInsert, false );
502 // CREATE HYPERLINK CONTAINER
503 if ( nExEmbedSize )
505 *mpStrm << (sal_uInt16)0xf
506 << (sal_uInt16)EPP_ExObjList
507 << (sal_uInt32)( nExEmbedSize + 12 )
508 << (sal_uInt16)0
509 << (sal_uInt16)EPP_ExObjListAtom
510 << (sal_uInt32)4
511 << (sal_uInt32)mnExEmbed;
512 mpPptEscherEx->InsertPersistOffset( EPP_Persist_ExObj, mpStrm->Tell() );
513 mpStrm->Write( mpExEmbed->GetData(), nExEmbedSize );
516 // CREATE ENVIRONMENT
517 *mpStrm << (sal_uInt16)0xf << (sal_uInt16)EPP_Environment << (sal_uInt32)nEnvironment;
519 // Open Container ( EPP_SrKinsoku )
520 *mpStrm << (sal_uInt16)0x2f << (sal_uInt16)EPP_SrKinsoku << (sal_uInt32)12;
521 mpPptEscherEx->AddAtom( 4, EPP_SrKinsokuAtom, 0, 3 );
522 *mpStrm << (sal_Int32)0; // SrKinsoku Level 0
524 // Open Container ( EPP_FontCollection )
525 *mpStrm << (sal_uInt16)0xf << (sal_uInt16)EPP_FontCollection << (sal_uInt32)maFontCollection.GetCount() * 76;
527 for ( sal_uInt32 i = 0; i < maFontCollection.GetCount(); i++ )
529 mpPptEscherEx->AddAtom( 68, EPP_FontEnityAtom, 0, i );
530 const FontCollectionEntry* pDesc = maFontCollection.GetById( i );
531 sal_uInt32 nFontLen = pDesc->Name.Len();
532 if ( nFontLen > 31 )
533 nFontLen = 31;
534 for ( sal_uInt16 n = 0; n < 32; n++ )
536 sal_Unicode nUniCode = 0;
537 if ( n < nFontLen )
538 nUniCode = pDesc->Name.GetChar( n );
539 *mpStrm << nUniCode;
541 sal_uInt8 lfCharSet = ANSI_CHARSET;
542 sal_uInt8 lfClipPrecision = 0;
543 sal_uInt8 lfQuality = 6;
544 sal_uInt8 lfPitchAndFamily = 0;
546 if ( pDesc->CharSet == RTL_TEXTENCODING_SYMBOL )
547 lfCharSet = SYMBOL_CHARSET;
549 switch( pDesc->Family )
551 case ::com::sun::star::awt::FontFamily::ROMAN :
552 lfPitchAndFamily |= FF_ROMAN;
553 break;
555 case ::com::sun::star::awt::FontFamily::SWISS :
556 lfPitchAndFamily |= FF_SWISS;
557 break;
559 case ::com::sun::star::awt::FontFamily::MODERN :
560 lfPitchAndFamily |= FF_MODERN;
561 break;
563 case ::com::sun::star::awt::FontFamily::SCRIPT:
564 lfPitchAndFamily |= FF_SCRIPT;
565 break;
567 case ::com::sun::star::awt::FontFamily::DECORATIVE:
568 lfPitchAndFamily |= FF_DECORATIVE;
569 break;
571 default:
572 lfPitchAndFamily |= FAMILY_DONTKNOW;
573 break;
575 switch( pDesc->Pitch )
577 case ::com::sun::star::awt::FontPitch::FIXED:
578 lfPitchAndFamily |= FIXED_PITCH;
579 break;
581 default:
582 lfPitchAndFamily |= DEFAULT_PITCH;
583 break;
585 *mpStrm << lfCharSet
586 << lfClipPrecision
587 << lfQuality
588 << lfPitchAndFamily;
590 mpStyleSheet->WriteTxCFStyleAtom( *mpStrm ); // create style that is used for new standard objects
591 mpPptEscherEx->AddAtom( 10, EPP_TxSIStyleAtom );
592 *mpStrm << (sal_uInt32)7 // ?
593 << (sal_Int16)2 // ?
594 << (sal_uInt8)9 // ?
595 << (sal_uInt8)8 // ?
596 << (sal_Int16)0; // ?
598 mpStrm->Write( aTxMasterStyleAtomStrm.GetData(), aTxMasterStyleAtomStrm.Tell() );
599 maSoundCollection.Write( *mpStrm );
600 mpPptEscherEx->WriteDrawingGroupContainer( *mpStrm );
601 ImplMasterSlideListContainer( mpStrm );
602 ImplDocumentListContainer( mpStrm );
604 sal_uInt32 nOldPos = mpPptEscherEx->PtGetOffsetByID( EPP_Persist_CurrentPos );
605 if ( nOldPos )
607 mpStrm->Seek( nOldPos );
608 return sal_True;
611 return sal_False;
614 // ---------------------------------------------------------------------------------------------
616 sal_Bool PropValue::GetPropertyValue(
617 ::com::sun::star::uno::Any& rAny,
618 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
619 const String& rString,
620 sal_Bool bTestPropertyAvailability )
622 sal_Bool bRetValue = sal_True;
623 if ( bTestPropertyAvailability )
625 bRetValue = sal_False;
628 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
629 aXPropSetInfo( rXPropSet->getPropertySetInfo() );
630 if ( aXPropSetInfo.is() )
631 bRetValue = aXPropSetInfo->hasPropertyByName( rString );
633 catch( ::com::sun::star::uno::Exception& )
635 bRetValue = sal_False;
638 if ( bRetValue )
642 rAny = rXPropSet->getPropertyValue( rString );
643 if ( !rAny.hasValue() )
644 bRetValue = sal_False;
646 catch( ::com::sun::star::uno::Exception& )
648 bRetValue = sal_False;
651 return bRetValue;
654 // ---------------------------------------------------------------------------------------------
656 ::com::sun::star::beans::PropertyState PropValue::GetPropertyState(
657 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
658 const String& rPropertyName )
660 ::com::sun::star::beans::PropertyState eRetValue = ::com::sun::star::beans::PropertyState_AMBIGUOUS_VALUE;
663 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState > aXPropState
664 ( rXPropSet, ::com::sun::star::uno::UNO_QUERY );
665 if ( aXPropState.is() )
666 eRetValue = aXPropState->getPropertyState( rPropertyName );
668 catch( ::com::sun::star::uno::Exception& )
670 //...
672 return eRetValue;
675 // ---------------------------------------------------------------------------------------------
677 sal_Bool PropValue::ImplGetPropertyValue( const OUString& rString )
679 return GetPropertyValue( mAny, mXPropSet, rString );
682 // ---------------------------------------------------------------------------------------------
684 sal_Bool PropValue::ImplGetPropertyValue( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & aXPropSet, const OUString& rString )
686 return GetPropertyValue( mAny, aXPropSet, rString );
689 // ---------------------------------------------------------------------------------------------
691 sal_Bool PropStateValue::ImplGetPropertyValue( const OUString& rString, sal_Bool bGetPropertyState )
693 ePropState = ::com::sun::star::beans::PropertyState_AMBIGUOUS_VALUE;
694 sal_Bool bRetValue = sal_True;
695 #ifdef UNX
696 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
697 aXPropSetInfo( mXPropSet->getPropertySetInfo() );
698 if ( !aXPropSetInfo.is() )
699 return sal_False;
700 #endif
703 mAny = mXPropSet->getPropertyValue( rString );
704 if ( !mAny.hasValue() )
705 bRetValue = sal_False;
706 else if ( bGetPropertyState )
707 ePropState = mXPropState->getPropertyState( rString );
708 else
709 ePropState = ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
711 catch( ::com::sun::star::uno::Exception& )
713 bRetValue = sal_False;
715 return bRetValue;
718 // ---------------------------------------------------------------------------------------------
720 void PPTWriter::ImplWriteParagraphs( SvStream& rOut, TextObj& rTextObj )
722 sal_Bool bFirstParagraph = sal_True;
723 sal_uInt32 nCharCount;
724 sal_uInt32 nPropertyFlags = 0;
725 sal_uInt16 nDepth = 0;
726 sal_Int16 nLineSpacing;
727 int nInstance = rTextObj.GetInstance();
729 for ( sal_uInt32 i = 0; i < rTextObj.ParagraphCount(); ++i, bFirstParagraph = sal_False )
731 ParagraphObj* pPara = rTextObj.GetParagraph(i);
732 PortionObj* pPortion = pPara->front();
733 nCharCount = pPara->CharacterCount();
735 nDepth = pPara->nDepth;
736 if ( nDepth > 4)
737 nDepth = 4;
739 if ( ( pPara->meTextAdjust == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
740 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_Adjust, pPara->mnTextAdjust ) ) )
741 nPropertyFlags |= 0x00000800;
742 nLineSpacing = pPara->mnLineSpacing;
744 const FontCollectionEntry* pDesc = maFontCollection.GetById( pPortion->mnFont );
745 sal_Int16 nNormalSpacing = 100;
746 if ( !mbFontIndependentLineSpacing && pDesc )
748 double fN = 100.0;
749 fN *= pDesc->Scaling;
750 nNormalSpacing = (sal_Int16)( fN + 0.5 );
752 if ( !mbFontIndependentLineSpacing && bFirstParagraph && ( nLineSpacing > nNormalSpacing ) ) // sj: i28747, no replacement for fixed linespacing
754 nLineSpacing = nNormalSpacing;
755 nPropertyFlags |= 0x00001000;
757 else
759 if ( nLineSpacing > 0 )
761 if ( !mbFontIndependentLineSpacing && pDesc )
762 nLineSpacing = (sal_Int16)( (double)nLineSpacing * pDesc->Scaling + 0.5 );
764 else
766 if ( !pPara->mbFixedLineSpacing && pPortion && pPortion->mnCharHeight > (sal_uInt16)( ((double)-nLineSpacing) * 0.001 * 72.0 / 2.54 ) ) // 1/100mm to point
767 nLineSpacing = nNormalSpacing;
768 else
769 nLineSpacing = (sal_Int16)( (double)nLineSpacing / 4.40972 );
771 if ( ( pPara->meLineSpacing == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
772 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_LineFeed, nLineSpacing ) ) )
773 nPropertyFlags |= 0x00001000;
775 if ( ( pPara->meLineSpacingTop == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
776 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_UpperDist, pPara->mnLineSpacingTop ) ) )
777 nPropertyFlags |= 0x00002000;
778 if ( ( pPara->meLineSpacingBottom == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
779 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_LowerDist, pPara->mnLineSpacingBottom ) ) )
780 nPropertyFlags |= 0x00004000;
781 if ( ( pPara->meForbiddenRules == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
782 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_UpperDist, pPara->mbForbiddenRules ) ) )
783 nPropertyFlags |= 0x00020000;
784 if ( ( pPara->meParagraphPunctation == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
785 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, ParaAttr_UpperDist, pPara->mbParagraphPunctation ) ) )
786 nPropertyFlags |= 0x00080000;
787 if ( ( pPara->meBiDi == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
788 ( mpStyleSheet->IsHardAttribute( nInstance, nDepth, ParaAttr_BiDi, pPara->mnBiDi ) ) )
789 nPropertyFlags |= 0x00200000;
791 sal_Int32 nBuRealSize = pPara->nBulletRealSize;
792 sal_Int16 nBulletFlags = pPara->nBulletFlags;
794 if ( pPara->bExtendedParameters )
795 nPropertyFlags |= pPara->nParaFlags;
796 else
798 nPropertyFlags |= 1; // turn off bullet explicit
799 nBulletFlags = 0;
802 // Write nTextOfs and nBullets
803 if ( mpStyleSheet->IsHardAttribute( nInstance, nDepth, ParaAttr_TextOfs, pPara->nTextOfs ) )
804 nPropertyFlags |= 0x100;
805 if ( mpStyleSheet->IsHardAttribute( nInstance, nDepth, ParaAttr_BulletOfs, pPara->nBulletOfs ))
806 nPropertyFlags |= 0x400;
808 FontCollectionEntry aFontDescEntry( pPara->aFontDesc.Name, pPara->aFontDesc.Family, pPara->aFontDesc.Pitch, pPara->aFontDesc.CharSet );
809 sal_uInt16 nFontId = (sal_uInt16)maFontCollection.GetId( aFontDescEntry );
811 rOut << nCharCount
812 << nDepth // Level
813 << (sal_uInt32)nPropertyFlags; // Paragraph Attribut Set
815 if ( nPropertyFlags & 0xf )
816 rOut << nBulletFlags;
817 if ( nPropertyFlags & 0x80 )
818 rOut << (sal_uInt16)( pPara->cBulletId );
819 if ( nPropertyFlags & 0x10 )
820 rOut << nFontId;
821 if ( nPropertyFlags & 0x40 )
822 rOut << (sal_Int16)nBuRealSize;
823 if ( nPropertyFlags & 0x20 )
825 sal_uInt32 nBulletColor = pPara->nBulletColor;
826 if ( nBulletColor == COL_AUTO )
828 sal_Bool bIsDark = sal_False;
829 ::com::sun::star::uno::Any aAny;
830 if ( PropValue::GetPropertyValue( aAny, mXPagePropSet, OUString( "IsBackgroundDark" ), sal_True ) )
831 aAny >>= bIsDark;
832 nBulletColor = bIsDark ? 0xffffff : 0x000000;
834 nBulletColor &= 0xffffff;
835 nBulletColor |= 0xfe000000;
836 rOut << nBulletColor;
838 if ( nPropertyFlags & 0x00000800 )
839 rOut << (sal_uInt16)( pPara->mnTextAdjust );
840 if ( nPropertyFlags & 0x00001000 )
841 rOut << (sal_uInt16)( nLineSpacing );
842 if ( nPropertyFlags & 0x00002000 )
843 rOut << (sal_uInt16)( pPara->mnLineSpacingTop );
844 if ( nPropertyFlags & 0x00004000 )
845 rOut << (sal_uInt16)( pPara->mnLineSpacingBottom );
846 if ( nPropertyFlags & 0x100 )
847 rOut << (sal_uInt16)(pPara->nTextOfs);
848 if ( nPropertyFlags & 0x400 )
849 rOut << (sal_uInt16)(pPara->nBulletOfs);
850 if ( nPropertyFlags & 0x000e0000 )
852 sal_uInt16 nAsianSettings = 0;
853 if ( pPara->mbForbiddenRules )
854 nAsianSettings |= 1;
855 if ( pPara->mbParagraphPunctation )
856 nAsianSettings |= 4;
857 rOut << nAsianSettings;
859 if ( nPropertyFlags & 0x200000 )
860 rOut << pPara->mnBiDi;
864 // -----------------------------------------------------------------------
866 void PPTWriter::ImplWritePortions( SvStream& rOut, TextObj& rTextObj )
868 sal_uInt32 nPropertyFlags;
869 int nInstance = rTextObj.GetInstance();
871 for ( sal_uInt32 i = 0; i < rTextObj.ParagraphCount(); ++i )
873 ParagraphObj* pPara = rTextObj.GetParagraph(i);
874 for ( ParagraphObj::const_iterator it = pPara->begin(); it != pPara->end(); ++it )
876 PortionObj* pPortion = *it;
877 nPropertyFlags = 0;
878 sal_uInt32 nCharAttr = pPortion->mnCharAttr;
879 sal_uInt32 nCharColor = pPortion->mnCharColor;
881 if ( nCharColor == COL_AUTO ) // nCharColor depends to the background color
883 sal_Bool bIsDark = sal_False;
884 ::com::sun::star::uno::Any aAny;
885 if ( PropValue::GetPropertyValue( aAny, mXPagePropSet, OUString( "IsBackgroundDark" ), sal_True ) )
886 aAny >>= bIsDark;
887 nCharColor = bIsDark ? 0xffffff : 0x000000;
890 nCharColor &= 0xffffff;
892 /* the portion is using the embossed or engraved attribute, which we want to map to the relief feature of PPT.
893 Because the relief feature of PPT is dependent to the background color, such a mapping can not always be used. */
894 if ( nCharAttr & 0x200 )
896 sal_uInt32 nBackgroundColor = 0xffffff;
898 if ( !nCharColor ) // special threatment for
899 nCharColor = 0xffffff; // black fontcolor
901 ::com::sun::star::uno::Any aAny;
902 ::com::sun::star::drawing::FillStyle aFS( ::com::sun::star::drawing::FillStyle_NONE );
903 if ( PropValue::GetPropertyValue( aAny, mXPropSet, OUString( "FillStyle" ) ) )
904 aAny >>= aFS;
905 switch( aFS )
907 case ::com::sun::star::drawing::FillStyle_GRADIENT :
909 Point aEmptyPoint = Point();
910 Rectangle aRect( aEmptyPoint, Size( 28000, 21000 ) );
911 EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect );
912 aPropOpt.CreateGradientProperties( mXPropSet );
913 aPropOpt.GetOpt( ESCHER_Prop_fillColor, nBackgroundColor );
915 break;
916 case ::com::sun::star::drawing::FillStyle_SOLID :
918 if ( PropValue::GetPropertyValue( aAny, mXPropSet, OUString( "FillColor" ) ) )
919 nBackgroundColor = mpPptEscherEx->GetColor( *((sal_uInt32*)aAny.getValue()) );
921 break;
922 case ::com::sun::star::drawing::FillStyle_NONE :
924 ::com::sun::star::uno::Any aBackAny;
925 ::com::sun::star::drawing::FillStyle aBackFS( ::com::sun::star::drawing::FillStyle_NONE );
926 if ( PropValue::GetPropertyValue( aBackAny, mXBackgroundPropSet, OUString( "FillStyle" ) ) )
927 aBackAny >>= aBackFS;
928 switch( aBackFS )
930 case ::com::sun::star::drawing::FillStyle_GRADIENT :
932 Point aEmptyPoint = Point();
933 Rectangle aRect( aEmptyPoint, Size( 28000, 21000 ) );
934 EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect );
935 aPropOpt.CreateGradientProperties( mXBackgroundPropSet );
936 aPropOpt.GetOpt( ESCHER_Prop_fillColor, nBackgroundColor );
938 break;
939 case ::com::sun::star::drawing::FillStyle_SOLID :
941 if ( PropValue::GetPropertyValue( aAny, mXBackgroundPropSet, OUString( "FillColor" ) ) )
942 nBackgroundColor = mpPptEscherEx->GetColor( *((sal_uInt32*)aAny.getValue()) );
944 break;
945 default:
946 break;
949 break;
950 default:
951 break;
954 sal_Int32 nB = nBackgroundColor & 0xff;
955 nB += (sal_uInt8)( nBackgroundColor >> 8 );
956 nB += (sal_uInt8)( nBackgroundColor >> 16 );
957 // if the background color is nearly black, relief can't been used, because the text would not be visible
958 if ( nB < 0x60 || ( nBackgroundColor != nCharColor ) )
960 nCharAttr &=~ 0x200;
962 // now check if the text is part of a group, and if the previous object has the same color than the fontcolor
963 // ( and if fillcolor is not available the background color ), it is sometimes
964 // not possible to export the 'embossed' flag
965 if ( ( GetCurrentGroupLevel() > 0 ) && ( GetCurrentGroupIndex() >= 1 ) )
967 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > aGroupedShape( GetCurrentGroupAccess()->getByIndex( GetCurrentGroupIndex() - 1 ), uno::UNO_QUERY );
968 if( aGroupedShape.is() )
970 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aPropSetOfNextShape
971 ( aGroupedShape, ::com::sun::star::uno::UNO_QUERY );
972 if ( aPropSetOfNextShape.is() )
974 if ( PropValue::GetPropertyValue( aAny, aPropSetOfNextShape,
975 OUString( "FillColor" ), sal_True ) )
977 if ( nCharColor == mpPptEscherEx->GetColor( *((sal_uInt32*)aAny.getValue()) ) )
979 nCharAttr |= 0x200;
987 nCharColor |= 0xfe000000;
988 if ( nInstance == 4 ) // special handling for normal textobjects:
989 nPropertyFlags |= nCharAttr & 0x217; // not all attributes ar inherited
990 else
992 if ( /* ( pPortion->mnCharAttrHard & 1 ) || */
993 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Bold, nCharAttr ) ) )
994 nPropertyFlags |= 1;
995 if ( /* ( pPortion->mnCharAttrHard & 2 ) || */
996 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Italic, nCharAttr ) ) )
997 nPropertyFlags |= 2;
998 if ( /* ( pPortion->mnCharAttrHard & 4 ) || */
999 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Underline, nCharAttr ) ) )
1000 nPropertyFlags |= 4;
1001 if ( /* ( pPortion->mnCharAttrHard & 0x10 ) || */
1002 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Shadow, nCharAttr ) ) )
1003 nPropertyFlags |= 0x10;
1004 if ( /* ( pPortion->mnCharAttrHard & 0x200 ) || */
1005 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Embossed, nCharAttr ) ) )
1006 nPropertyFlags |= 512;
1008 if ( rTextObj.HasExtendedBullets() )
1010 nPropertyFlags |= ( i & 0x3f ) << 10 ;
1011 nCharAttr |= ( i & 0x3f ) << 10;
1013 if ( ( pPortion->meFontName == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1014 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Font, pPortion->mnFont ) ) )
1015 nPropertyFlags |= 0x00010000;
1016 if ( ( pPortion->meAsianOrComplexFont == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1017 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_AsianOrComplexFont, pPortion->mnAsianOrComplexFont ) ) )
1018 nPropertyFlags |= 0x00200000;
1019 if ( ( pPortion->meCharHeight == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1020 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_FontHeight, pPortion->mnCharHeight ) ) )
1021 nPropertyFlags |= 0x00020000;
1022 if ( ( pPortion->meCharColor == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1023 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_FontColor, nCharColor & 0xffffff ) ) )
1024 nPropertyFlags |= 0x00040000;
1025 if ( ( pPortion->meCharEscapement == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) ||
1026 ( mpStyleSheet->IsHardAttribute( nInstance, pPara->nDepth, CharAttr_Escapement, pPortion->mnCharEscapement ) ) )
1027 nPropertyFlags |= 0x00080000;
1029 sal_uInt32 nCharCount = pPortion->Count();
1031 rOut << nCharCount
1032 << nPropertyFlags; //PropertyFlags
1034 if ( nPropertyFlags & 0xffff )
1035 rOut << (sal_uInt16)( nCharAttr );
1036 if ( nPropertyFlags & 0x00010000 )
1037 rOut << pPortion->mnFont;
1038 if ( nPropertyFlags & 0x00200000 )
1039 rOut << pPortion->mnAsianOrComplexFont;
1040 if ( nPropertyFlags & 0x00020000 )
1041 rOut << (sal_uInt16)( pPortion->mnCharHeight );
1042 if ( nPropertyFlags & 0x00040000 )
1043 rOut << (sal_uInt32)nCharColor;
1044 if ( nPropertyFlags & 0x00080000 )
1045 rOut << pPortion->mnCharEscapement;
1051 * Loads and converts text from shape, value is stored in mnTextSize.
1053 sal_Bool PPTWriter::ImplGetText()
1055 mnTextSize = 0;
1056 mbFontIndependentLineSpacing = sal_False;
1057 mXText = ::com::sun::star::uno::Reference<
1058 ::com::sun::star::text::XSimpleText >
1059 ( mXShape, ::com::sun::star::uno::UNO_QUERY );
1061 if ( mXText.is() )
1063 mnTextSize = mXText->getString().getLength();
1064 ::com::sun::star::uno::Any aAny;
1065 if ( GetPropertyValue( aAny, mXPropSet, OUString( "FontIndependentLineSpacing" ) ), sal_True )
1066 aAny >>= mbFontIndependentLineSpacing;
1068 return ( mnTextSize != 0 );
1071 // -----------------------------------------------------------------------
1073 void PPTWriter::ImplFlipBoundingBox( EscherPropertyContainer& rPropOpt )
1075 if ( mnAngle < 0 )
1076 mnAngle = ( 36000 + mnAngle ) % 36000;
1077 else
1078 mnAngle = ( 36000 - ( mnAngle % 36000 ) );
1080 double fCos = cos( (double)mnAngle * F_PI18000 );
1081 double fSin = sin( (double)mnAngle * F_PI18000 );
1083 double fWidthHalf = maRect.GetWidth() / 2;
1084 double fHeightHalf = maRect.GetHeight() / 2;
1086 double fXDiff = fCos * fWidthHalf + fSin * (-fHeightHalf);
1087 double fYDiff = - ( fSin * fWidthHalf - fCos * ( -fHeightHalf ) );
1089 maRect.Move( (sal_Int32)( -( fWidthHalf - fXDiff ) ), (sal_Int32)( - ( fHeightHalf + fYDiff ) ) );
1090 mnAngle *= 655;
1091 mnAngle += 0x8000;
1092 mnAngle &=~0xffff; // round nAngle to full grads
1093 rPropOpt.AddOpt( ESCHER_Prop_Rotation, mnAngle );
1095 if ( ( mnAngle >= ( 45 << 16 ) && mnAngle < ( 135 << 16 ) ) ||
1096 ( mnAngle >= ( 225 << 16 ) && mnAngle < ( 315 << 16 ) ) )
1098 // Maddeningly, in those two areas of PPT is the BoundingBox already
1099 // vertical. Therefore, we need to put down it BEFORE THE ROTATION.
1100 ::com::sun::star::awt::Point
1101 aTopLeft( (sal_Int32)( maRect.Left() + fWidthHalf - fHeightHalf ), (sal_Int32)( maRect.Top() + fHeightHalf - fWidthHalf ) );
1102 Size aNewSize( maRect.GetHeight(), maRect.GetWidth() );
1103 maRect = Rectangle( Point( aTopLeft.X, aTopLeft.Y ), aNewSize );
1107 // -----------------------------------------------------------------------
1109 void PPTWriter::ImplAdjustFirstLineLineSpacing( TextObj& rTextObj, EscherPropertyContainer& rPropOpt )
1111 if ( !mbFontIndependentLineSpacing )
1113 if ( rTextObj.ParagraphCount() )
1115 ParagraphObj* pPara = rTextObj.GetParagraph(0);
1116 if ( !pPara->empty() )
1118 PortionObj* pPortion = pPara->front();
1119 sal_Int16 nLineSpacing = pPara->mnLineSpacing;
1120 const FontCollectionEntry* pDesc = maFontCollection.GetById( pPortion->mnFont );
1121 if ( pDesc )
1122 nLineSpacing = (sal_Int16)( (double)nLineSpacing * pDesc->Scaling + 0.5 );
1124 if ( ( nLineSpacing > 0 ) && ( nLineSpacing < 100 ) )
1126 double fCharHeight = pPortion->mnCharHeight;
1127 fCharHeight *= 2540 / 72;
1128 fCharHeight *= 100 - nLineSpacing;
1129 fCharHeight /= 100;
1131 sal_uInt32 nUpperDistance = 0;
1132 rPropOpt.GetOpt( ESCHER_Prop_dyTextTop, nUpperDistance );
1133 nUpperDistance += static_cast< sal_uInt32 >( fCharHeight * 360.0 );
1134 rPropOpt.AddOpt( ESCHER_Prop_dyTextTop, nUpperDistance );
1141 // -----------------------------------------------------------------------
1143 void PPTWriter::ImplWriteTextStyleAtom( SvStream& rOut, int nTextInstance, sal_uInt32 nAtomInstance,
1144 TextRuleEntry* pTextRule, SvStream& rExtBuStr, EscherPropertyContainer* pPropOpt )
1146 PPTExParaSheet& rParaSheet = mpStyleSheet->GetParaSheet( nTextInstance );
1148 rOut << (sal_uInt32)( ( EPP_TextHeaderAtom << 16 ) | ( nAtomInstance << 4 ) ) << (sal_uInt32)4
1149 << sal_Int32(nTextInstance);
1151 if ( mbEmptyPresObj )
1152 mnTextSize = 0;
1153 if ( !mbEmptyPresObj )
1155 ParagraphObj* pPara;
1156 TextObjBinary aTextObj( mXText, nTextInstance, maFontCollection, (PPTExBulletProvider&)*this );
1158 // leaving out EPP_TextCharsAtom w/o text - still write out
1159 // attribute info though
1160 if ( mnTextSize )
1161 aTextObj.Write( &rOut );
1163 if ( pPropOpt )
1164 ImplAdjustFirstLineLineSpacing( aTextObj, *pPropOpt );
1166 sal_uInt32 nSize, nPos = rOut.Tell();
1168 rOut << (sal_uInt32)( EPP_StyleTextPropAtom << 16 ) << (sal_uInt32)0;
1169 ImplWriteParagraphs( rOut, aTextObj );
1170 ImplWritePortions( rOut, aTextObj );
1171 nSize = rOut.Tell() - nPos;
1172 rOut.SeekRel( - ( (sal_Int32)nSize - 4 ) );
1173 rOut << (sal_uInt32)( nSize - 8 );
1174 rOut.SeekRel( nSize - 8 );
1176 for ( sal_uInt32 i = 0; i < aTextObj.ParagraphCount(); ++i )
1178 pPara = aTextObj.GetParagraph(i);
1179 for ( ParagraphObj::const_iterator it = pPara->begin(); it != pPara->end(); ++it )
1181 PortionObj* pPortion = *it;
1182 if ( pPortion->mpFieldEntry )
1184 const FieldEntry* pFieldEntry = pPortion->mpFieldEntry;
1186 switch ( pFieldEntry->nFieldType >> 28 )
1188 case 1 :
1189 case 2 :
1191 rOut << (sal_uInt32)( EPP_DateTimeMCAtom << 16 ) << (sal_uInt32)8
1192 << (sal_uInt32)( pFieldEntry->nFieldStartPos ) // TxtOffset to TxtField;
1193 << (sal_uInt8)( pFieldEntry->nFieldType & 0xff ) // Type
1194 << (sal_uInt8)0 << (sal_uInt16)0; // PadBytes
1196 break;
1197 case 3 :
1199 rOut << (sal_uInt32)( EPP_SlideNumberMCAtom << 16 ) << (sal_uInt32 ) 4
1200 << (sal_uInt32)( pFieldEntry->nFieldStartPos );
1202 break;
1203 case 4 :
1205 sal_uInt32 nPageIndex = 0;
1206 String aPageUrl;
1207 String aEmpty;
1208 String aFile( pFieldEntry->aFieldUrl );
1209 String aTarget( pFieldEntry->aFieldUrl );
1210 INetURLObject aUrl( pFieldEntry->aFieldUrl );
1211 if ( INET_PROT_FILE == aUrl.GetProtocol() )
1212 aFile = aUrl.PathToFileName();
1213 else if ( INET_PROT_SMB == aUrl.GetProtocol() )
1215 // Convert smb notation to '\\' and skip the 'smb:' part
1216 aFile = aUrl.GetMainURL(INetURLObject::NO_DECODE).copy(4);
1217 aFile.SearchAndReplaceAll( '/', '\\' );
1218 aTarget = aFile;
1220 else if ( pFieldEntry->aFieldUrl.GetChar( 0 ) == '#' )
1222 String aPage( INetURLObject::decode( pFieldEntry->aFieldUrl, '%', INetURLObject::DECODE_WITH_CHARSET ) );
1223 aPage.Erase( 0, 1 );
1225 OUString aUPage(aPage);
1226 std::vector<OUString>::const_iterator pIter = std::find(
1227 maSlideNameList.begin(),maSlideNameList.end(),aUPage);
1229 if ( pIter != maSlideNameList.end() )
1231 nPageIndex = pIter - maSlideNameList.begin();
1232 aPageUrl = OUString::valueOf(static_cast<sal_Int32>(256 + nPageIndex));
1233 aPageUrl.Append( OUString( "," ) );
1234 aPageUrl.Append( OUString::number( nPageIndex + 1 ) );
1235 aPageUrl.Append( OUString( ",Slide " ) );
1236 aPageUrl.Append( OUString::number( nPageIndex + 1 ) );
1239 sal_uInt32 nHyperId(0);
1240 if ( aPageUrl.Len() )
1241 nHyperId = ImplInsertBookmarkURL( aPageUrl, 1 | ( nPageIndex << 8 ) | ( 1 << 31 ), pFieldEntry->aRepresentation, aEmpty, aEmpty, aPageUrl );
1242 else
1243 nHyperId = ImplInsertBookmarkURL( pFieldEntry->aFieldUrl, 2 | ( nHyperId << 8 ), aFile, aTarget, aEmpty, aEmpty );
1245 rOut << (sal_uInt32)( ( EPP_InteractiveInfo << 16 ) | 0xf ) << (sal_uInt32)24
1246 << (sal_uInt32)( EPP_InteractiveInfoAtom << 16 ) << (sal_uInt32)16
1247 << (sal_uInt32)0 // soundref
1248 << nHyperId // hyperlink id
1249 << (sal_uInt8)4 // hyperlink action
1250 << (sal_uInt8)0 // ole verb
1251 << (sal_uInt8)0 // jump
1252 << (sal_uInt8)0 // flags
1253 << (sal_uInt8)8 // hyperlink type ?
1254 << (sal_uInt8)0 << (sal_uInt8)0 << (sal_uInt8)0
1255 << (sal_uInt32)( EPP_TxInteractiveInfoAtom << 16 ) << (sal_uInt32)8
1256 << (sal_uInt32)( pFieldEntry->nFieldStartPos )
1257 << (sal_uInt32)( pFieldEntry->nFieldEndPos );
1259 break;
1260 case 5 :
1262 rOut << (sal_uInt32)( EPP_GenericDateMCAtom << 16 ) << (sal_uInt32)4
1263 << (sal_uInt32)( pFieldEntry->nFieldStartPos );
1265 break;
1266 case 6 :
1268 rOut << (sal_uInt32)( EPP_HeaderMCAtom << 16 ) << (sal_uInt32 ) 4
1269 << (sal_uInt32)( pFieldEntry->nFieldStartPos );
1271 break;
1272 case 7 :
1274 rOut << (sal_uInt32)( EPP_FooterMCAtom << 16 ) << (sal_uInt32 ) 4
1275 << (sal_uInt32)( pFieldEntry->nFieldStartPos );
1277 break;
1278 default:
1279 break;
1285 aTextObj.WriteTextSpecInfo( &rOut );
1287 // write Star Office Default TabSizes (if necessary)
1288 if ( aTextObj.ParagraphCount() )
1290 pPara = aTextObj.GetParagraph(0);
1291 sal_uInt32 nParaFlags = 0x1f;
1292 sal_Int16 nDepth, nMask, nNumberingRule[ 10 ];
1293 sal_uInt32 nTextOfs = pPara->nTextOfs;
1294 sal_uInt32 nTabs = pPara->maTabStop.getLength();
1295 const ::com::sun::star::style::TabStop* pTabStop = ( const ::com::sun::star::style::TabStop* )pPara->maTabStop.getConstArray();
1297 for ( sal_uInt32 i = 0; i < aTextObj.ParagraphCount(); ++i )
1299 pPara = aTextObj.GetParagraph(i);
1300 if ( pPara->bExtendedParameters )
1302 nDepth = pPara->nDepth;
1303 if ( nDepth < 5 )
1305 nMask = 1 << nDepth;
1306 if ( nParaFlags & nMask )
1308 nParaFlags &=~ nMask;
1309 if ( ( rParaSheet.maParaLevel[ nDepth ].mnTextOfs != pPara->nTextOfs ) ||
1310 ( rParaSheet.maParaLevel[ nDepth ].mnBulletOfs != pPara->nBulletOfs ) )
1312 nParaFlags |= nMask << 16;
1313 nNumberingRule[ nDepth << 1 ] = pPara->nTextOfs;
1314 nNumberingRule[ ( nDepth << 1 ) + 1 ] = (sal_Int16)pPara->nBulletOfs;
1320 nParaFlags >>= 16;
1322 sal_Int32 nDefaultTabSizeSrc = 2011; // I've no idea where this number came from, honestly
1323 const uno::Reference< beans::XPropertySet > xPropSet( mXModel, uno::UNO_QUERY );
1324 if ( xPropSet.is() )
1326 ImplGetPropertyValue( xPropSet, OUString( "TabStop" ) );
1327 sal_Int32 nTabStop( 0 );
1328 if ( mAny >>= nTabStop )
1329 nDefaultTabSizeSrc = nTabStop;
1331 const sal_uInt32 nDefaultTabSize = MapSize( awt::Size( nDefaultTabSizeSrc, 1 ) ).Width;
1332 sal_uInt32 nDefaultTabs = abs( maRect.GetWidth() ) / nDefaultTabSize;
1333 if ( nTabs )
1334 nDefaultTabs -= (sal_Int32)( ( ( pTabStop[ nTabs - 1 ].Position / 4.40972 ) + nTextOfs ) / nDefaultTabSize );
1335 if ( (sal_Int32)nDefaultTabs < 0 )
1336 nDefaultTabs = 0;
1338 sal_uInt32 nTabCount = nTabs + nDefaultTabs;
1339 sal_uInt32 i, nTextRulerAtomFlags = 0;
1341 if ( nTabCount )
1342 nTextRulerAtomFlags |= 4;
1343 if ( nParaFlags )
1344 nTextRulerAtomFlags |= ( ( nParaFlags << 3 ) | ( nParaFlags << 8 ) );
1346 if ( nTextRulerAtomFlags )
1348 SvStream* pRuleOut = &rOut;
1349 if ( pTextRule )
1350 pRuleOut = pTextRule->pOut = new SvMemoryStream( 0x100, 0x100 );
1352 sal_uInt32 nRulePos = pRuleOut->Tell();
1353 *pRuleOut << (sal_uInt32)( EPP_TextRulerAtom << 16 ) << (sal_uInt32)0;
1354 *pRuleOut << nTextRulerAtomFlags;
1355 if ( nTextRulerAtomFlags & 4 )
1357 *pRuleOut << (sal_uInt16)nTabCount;
1358 for ( i = 0; i < nTabs; i++ )
1360 sal_uInt16 nPosition = (sal_uInt16)( ( pTabStop[ i ].Position / 4.40972 ) + nTextOfs );
1361 sal_uInt16 nType;
1362 switch ( pTabStop[ i ].Alignment )
1364 case ::com::sun::star::style::TabAlign_DECIMAL : nType = 3; break;
1365 case ::com::sun::star::style::TabAlign_RIGHT : nType = 2; break;
1366 case ::com::sun::star::style::TabAlign_CENTER : nType = 1; break;
1368 case ::com::sun::star::style::TabAlign_LEFT :
1369 default: nType = 0;
1371 *pRuleOut << nPosition
1372 << nType;
1375 sal_uInt32 nWidth = 1;
1376 if ( nTabs )
1377 nWidth += (sal_Int32)( ( ( pTabStop[ nTabs - 1 ].Position / 4.40972 + nTextOfs ) / nDefaultTabSize ) );
1378 nWidth *= nDefaultTabSize;
1379 for ( i = 0; i < nDefaultTabs; i++, nWidth += nDefaultTabSize )
1380 *pRuleOut << nWidth;
1382 for ( i = 0; i < 5; i++ )
1384 if ( nTextRulerAtomFlags & ( 8 << i ) )
1385 *pRuleOut << nNumberingRule[ i << 1 ];
1386 if ( nTextRulerAtomFlags & ( 256 << i ) )
1387 *pRuleOut << nNumberingRule[ ( i << 1 ) + 1 ];
1389 sal_uInt32 nBufSize = pRuleOut->Tell() - nRulePos;
1390 pRuleOut->SeekRel( - ( (sal_Int32)nBufSize - 4 ) );
1391 *pRuleOut << (sal_uInt32)( nBufSize - 8 );
1392 pRuleOut->SeekRel( nBufSize - 8 );
1395 if ( aTextObj.HasExtendedBullets() )
1397 if ( aTextObj.ParagraphCount() )
1399 ParagraphObj* pBulletPara = aTextObj.GetParagraph(0);
1400 sal_uInt32 nBulletFlags = 0;
1401 sal_uInt32 nNumberingType = 0, nPos2 = rExtBuStr.Tell();
1403 rExtBuStr << (sal_uInt32)( EPP_PST_ExtendedParagraphAtom << 16 ) << (sal_uInt32)0;
1405 for ( sal_uInt32 i = 0; i < aTextObj.ParagraphCount(); ++i )
1407 pBulletPara = aTextObj.GetParagraph(i);
1408 nBulletFlags = 0;
1409 sal_uInt16 nBulletId = pBulletPara->nBulletId;
1410 if ( pBulletPara->bExtendedBulletsUsed )
1412 nBulletFlags = 0x800000;
1413 if ( pBulletPara->nNumberingType != SVX_NUM_BITMAP )
1414 nBulletFlags = 0x3000000;
1416 rExtBuStr << (sal_uInt32)nBulletFlags;
1418 if ( nBulletFlags & 0x800000 )
1419 rExtBuStr << nBulletId;
1420 if ( nBulletFlags & 0x1000000 )
1422 switch( pBulletPara->nNumberingType )
1424 case SVX_NUM_NUMBER_NONE :
1425 case SVX_NUM_CHAR_SPECIAL :
1426 nNumberingType = 0;
1427 break;
1428 case SVX_NUM_CHARS_UPPER_LETTER :
1429 case SVX_NUM_CHARS_UPPER_LETTER_N :
1430 case SVX_NUM_CHARS_LOWER_LETTER :
1431 case SVX_NUM_CHARS_LOWER_LETTER_N :
1432 case SVX_NUM_ROMAN_UPPER :
1433 case SVX_NUM_ROMAN_LOWER :
1434 case SVX_NUM_ARABIC :
1435 case SVX_NUM_NUMBER_UPPER_ZH:
1436 case SVX_NUM_CIRCLE_NUMBER:
1437 case SVX_NUM_NUMBER_UPPER_ZH_TW:
1438 case SVX_NUM_NUMBER_LOWER_ZH:
1439 case SVX_NUM_FULL_WIDTH_ARABIC:
1440 nNumberingType = pBulletPara->nMappedNumType;
1441 break;
1443 case SVX_NUM_BITMAP :
1444 nNumberingType = 0;
1445 break;
1448 rExtBuStr << (sal_uInt32)nNumberingType;
1450 if ( nBulletFlags & 0x2000000 )
1451 rExtBuStr << (sal_uInt16)pBulletPara->nStartWith;
1452 rExtBuStr << (sal_uInt32)0 << (sal_uInt32)0;
1454 sal_uInt32 nBulletSize = ( rExtBuStr.Tell() - nPos2 ) - 8;
1455 rExtBuStr.SeekRel( - ( (sal_Int32)nBulletSize + 4 ) );
1456 rExtBuStr << nBulletSize;
1457 rExtBuStr.SeekRel( nBulletSize );
1463 // -----------------------------------------------------------------------
1465 void PPTWriter::ImplWriteObjectEffect( SvStream& rSt,
1466 ::com::sun::star::presentation::AnimationEffect eAe,
1467 ::com::sun::star::presentation::AnimationEffect eTe,
1468 sal_uInt16 nOrder )
1470 EscherExContainer aAnimationInfo( rSt, EPP_AnimationInfo );
1471 EscherExAtom aAnimationInfoAtom( rSt, EPP_AnimationInfoAtom, 0, 1 );
1472 sal_uInt32 nDimColor = 0x7000000; // color to use for dimming
1473 sal_uInt32 nFlags = 0x4400; // set of flags that determine type of build
1474 sal_uInt32 nSoundRef = 0; // 0 if storage is from clipboard. Otherwise index(ID) in SoundCollection list.
1475 sal_uInt32 nDelayTime = 0; // delay before playing object
1476 sal_uInt16 nSlideCount = 1; // number of slides to play object
1477 sal_uInt8 nBuildType = 1; // type of build
1478 sal_uInt8 nFlyMethod = 0; // animation effect( fly, zoom, appear, etc )
1479 sal_uInt8 nFlyDirection = 0; // Animation direction( left, right, up, down, etc )
1480 sal_uInt8 nAfterEffect = 0; // what to do after build
1481 sal_uInt8 nSubEffect = 0; // build by word or letter
1482 sal_uInt8 nOleVerb = 0; // Determines object's class (sound, video, other)
1484 if ( eAe == ::com::sun::star::presentation::AnimationEffect_NONE )
1486 nBuildType = 0;
1487 eAe = eTe;
1489 switch ( eAe )
1491 case ::com::sun::star::presentation::AnimationEffect_NONE :
1492 break;
1493 case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LEFT :
1495 nFlyDirection = 2;
1496 nFlyMethod = 10;
1498 break;
1499 case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_TOP :
1501 nFlyDirection = 3;
1502 nFlyMethod = 10;
1504 break;
1505 case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_RIGHT :
1507 nFlyDirection = 0;
1508 nFlyMethod = 10;
1510 break;
1511 case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_BOTTOM :
1513 nFlyDirection = 1;
1514 nFlyMethod = 10;
1516 break;
1517 case ::com::sun::star::presentation::AnimationEffect_FADE_TO_CENTER :
1519 nFlyDirection = 1;
1520 nFlyMethod = 11;
1522 break;
1523 case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_CENTER :
1525 nFlyDirection = 0;
1526 nFlyMethod = 11;
1528 break;
1529 case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LEFT :
1531 nFlyDirection = 0;
1532 nFlyMethod = 12;
1534 break;
1535 case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_TOP :
1537 nFlyDirection = 1;
1538 nFlyMethod = 12;
1540 break;
1541 case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_RIGHT :
1543 nFlyDirection = 2;
1544 nFlyMethod = 12;
1546 break;
1547 case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_BOTTOM :
1549 nFlyDirection = 3;
1550 nFlyMethod = 12;
1552 break;
1553 case ::com::sun::star::presentation::AnimationEffect_VERTICAL_STRIPES :
1555 nFlyDirection = 0;
1556 nFlyMethod = 2;
1558 break;
1559 case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_STRIPES :
1561 nFlyDirection = 1;
1562 nFlyMethod = 2;
1564 break;
1565 case ::com::sun::star::presentation::AnimationEffect_CLOCKWISE :
1567 nFlyDirection = 1;
1568 nFlyMethod = 3;
1570 break;
1571 case ::com::sun::star::presentation::AnimationEffect_COUNTERCLOCKWISE :
1573 nFlyDirection = 0;
1574 nFlyMethod = 3;
1576 break;
1577 case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_UPPERLEFT :
1579 nFlyDirection = 7;
1580 nFlyMethod = 9;
1582 break;
1583 case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_UPPERRIGHT :
1585 nFlyDirection = 6;
1586 nFlyMethod = 9;
1588 break;
1589 case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LOWERLEFT :
1591 nFlyDirection = 5;
1592 nFlyMethod = 9;
1594 break;
1595 case ::com::sun::star::presentation::AnimationEffect_FADE_FROM_LOWERRIGHT :
1597 nFlyDirection = 4;
1598 nFlyMethod = 9;
1600 break;
1601 case ::com::sun::star::presentation::AnimationEffect_CLOSE_VERTICAL :
1603 nFlyDirection = 1;
1604 nFlyMethod = 13;
1606 break;
1607 case ::com::sun::star::presentation::AnimationEffect_CLOSE_HORIZONTAL :
1609 nFlyDirection = 3;
1610 nFlyMethod = 13;
1612 break;
1613 case ::com::sun::star::presentation::AnimationEffect_OPEN_VERTICAL :
1615 nFlyDirection = 0;
1616 nFlyMethod = 13;
1618 break;
1619 case ::com::sun::star::presentation::AnimationEffect_OPEN_HORIZONTAL :
1621 nFlyDirection = 2;
1622 nFlyMethod = 13;
1624 break;
1625 case ::com::sun::star::presentation::AnimationEffect_PATH :
1627 nFlyDirection = 28;
1628 nFlyMethod = 12;
1630 break;
1631 case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_LEFT :
1633 nFlyDirection = 0;
1634 nFlyMethod = 1;
1636 break;
1637 case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_TOP :
1639 nFlyDirection = 0;
1640 nFlyMethod = 1;
1642 break;
1643 case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_RIGHT :
1645 nFlyDirection = 0;
1646 nFlyMethod = 1;
1648 break;
1649 case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_BOTTOM :
1651 nFlyDirection = 0;
1652 nFlyMethod = 1;
1654 break;
1655 case ::com::sun::star::presentation::AnimationEffect_SPIRALIN_LEFT :
1656 case ::com::sun::star::presentation::AnimationEffect_SPIRALIN_RIGHT :
1657 case ::com::sun::star::presentation::AnimationEffect_SPIRALOUT_LEFT :
1658 case ::com::sun::star::presentation::AnimationEffect_SPIRALOUT_RIGHT :
1660 nFlyDirection = 0x1c;
1661 nFlyMethod = 0xc;
1663 break;
1664 case ::com::sun::star::presentation::AnimationEffect_DISSOLVE :
1666 nFlyDirection = 0;
1667 nFlyMethod = 5;
1669 break;
1670 case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_LEFT :
1672 nFlyDirection = 2;
1673 nFlyMethod = 10;
1675 break;
1676 case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_TOP :
1678 nFlyDirection = 3;
1679 nFlyMethod = 10;
1681 break;
1682 case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_RIGHT :
1684 nFlyDirection = 0;
1685 nFlyMethod = 10;
1687 break;
1688 case ::com::sun::star::presentation::AnimationEffect_WAVYLINE_FROM_BOTTOM :
1690 nFlyDirection = 1;
1691 nFlyMethod = 10;
1693 break;
1694 case ::com::sun::star::presentation::AnimationEffect_RANDOM :
1696 nFlyDirection = 0;
1697 nFlyMethod = 1;
1699 break;
1700 case ::com::sun::star::presentation::AnimationEffect_VERTICAL_LINES :
1702 nFlyDirection = 1;
1703 nFlyMethod = 8;
1705 break;
1706 case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_LINES :
1708 nFlyDirection = 0;
1709 nFlyMethod = 8;
1711 break;
1712 case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_LEFT :
1714 nFlyDirection = 2;
1715 nFlyMethod = 10;
1717 break;
1718 case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_TOP :
1720 nFlyDirection = 3;
1721 nFlyMethod = 10;
1723 break;
1724 case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_RIGHT :
1726 nFlyDirection = 0;
1727 nFlyMethod = 10;
1729 break;
1730 case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_BOTTOM :
1732 nFlyDirection = 1;
1733 nFlyMethod = 10;
1735 break;
1736 case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_UPPERLEFT :
1738 nFlyDirection = 7;
1739 nFlyMethod = 9;
1741 break;
1742 case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_UPPERRIGHT :
1744 nFlyDirection = 6;
1745 nFlyMethod = 9;
1747 break;
1748 case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_LOWERLEFT :
1750 nFlyDirection = 5;
1751 nFlyMethod = 9;
1753 break;
1754 case ::com::sun::star::presentation::AnimationEffect_LASER_FROM_LOWERRIGHT :
1756 nFlyDirection = 4;
1757 nFlyMethod = 9;
1759 break;
1760 case ::com::sun::star::presentation::AnimationEffect_APPEAR :
1761 break;
1762 case ::com::sun::star::presentation::AnimationEffect_HIDE :
1764 nFlyDirection = 0;
1765 nFlyMethod = 1;
1767 break;
1768 case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_UPPERLEFT :
1770 nFlyDirection = 4;
1771 nFlyMethod = 12;
1773 break;
1774 case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_UPPERRIGHT :
1776 nFlyDirection = 5;
1777 nFlyMethod = 12;
1779 break;
1780 case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LOWERRIGHT :
1782 nFlyDirection = 7;
1783 nFlyMethod = 12;
1785 break;
1786 case ::com::sun::star::presentation::AnimationEffect_MOVE_FROM_LOWERLEFT :
1788 nFlyDirection = 6;
1789 nFlyMethod = 12;
1791 break;
1792 case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_UPPERLEFT :
1793 case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_UPPERRIGHT :
1794 case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_LOWERRIGHT :
1795 case ::com::sun::star::presentation::AnimationEffect_MOVE_TO_LOWERLEFT :
1796 nAfterEffect |= 2;
1797 break;
1798 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_LEFT :
1799 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_UPPERLEFT :
1801 nFlyDirection = 8;
1802 nFlyMethod = 12;
1804 break;
1805 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_TOP :
1806 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_UPPERRIGHT :
1808 nFlyDirection = 11;
1809 nFlyMethod = 12;
1811 break;
1812 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_RIGHT :
1813 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_LOWERRIGHT :
1815 nFlyDirection = 10;
1816 nFlyMethod = 12;
1818 break;
1819 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_BOTTOM :
1820 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_FROM_LOWERLEFT :
1822 nFlyDirection = 9;
1823 nFlyMethod = 12;
1825 break;
1826 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_LEFT :
1827 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_UPPERLEFT :
1828 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_TOP :
1829 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_UPPERRIGHT :
1830 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_RIGHT :
1831 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_LOWERRIGHT :
1832 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_BOTTOM :
1833 case ::com::sun::star::presentation::AnimationEffect_MOVE_SHORT_TO_LOWERLEFT :
1834 nAfterEffect |= 2;
1835 break;
1836 case ::com::sun::star::presentation::AnimationEffect_VERTICAL_CHECKERBOARD :
1838 nFlyDirection = 1;
1839 nFlyMethod = 3;
1841 break;
1842 case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_CHECKERBOARD :
1844 nFlyDirection = 0;
1845 nFlyMethod = 3;
1847 break;
1848 case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_ROTATE :
1849 case ::com::sun::star::presentation::AnimationEffect_VERTICAL_ROTATE :
1851 nFlyDirection = 27;
1852 nFlyMethod = 12;
1854 break;
1855 case ::com::sun::star::presentation::AnimationEffect_HORIZONTAL_STRETCH :
1856 case ::com::sun::star::presentation::AnimationEffect_VERTICAL_STRETCH :
1858 nFlyDirection = 22;
1859 nFlyMethod = 12;
1861 break;
1862 case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_LEFT :
1863 case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_UPPERLEFT :
1865 nFlyDirection = 23;
1866 nFlyMethod = 12;
1868 break;
1869 case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_TOP :
1870 case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_UPPERRIGHT :
1872 nFlyDirection = 24;
1873 nFlyMethod = 12;
1875 break;
1876 case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_RIGHT :
1877 case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_LOWERRIGHT :
1879 nFlyDirection = 25;
1880 nFlyMethod = 12;
1882 break;
1883 case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_BOTTOM :
1884 case ::com::sun::star::presentation::AnimationEffect_STRETCH_FROM_LOWERLEFT :
1886 nFlyDirection = 26;
1887 nFlyMethod = 12;
1889 break;
1890 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN :
1892 nFlyDirection = 16;
1893 nFlyMethod = 12;
1895 break;
1896 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_SMALL :
1897 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_SPIRAL :
1899 nFlyDirection = 17;
1900 nFlyMethod = 12;
1902 break;
1903 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT :
1905 nFlyDirection = 18;
1906 nFlyMethod = 12;
1908 break;
1909 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_SMALL :
1910 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_SPIRAL :
1912 nFlyDirection = 19;
1913 nFlyMethod = 12;
1915 break;
1916 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_LEFT :
1917 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_UPPERLEFT :
1918 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_TOP :
1919 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_UPPERRIGHT :
1920 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_RIGHT :
1921 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_LOWERRIGHT :
1922 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_BOTTOM :
1923 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_LOWERLEFT :
1924 case ::com::sun::star::presentation::AnimationEffect_ZOOM_IN_FROM_CENTER :
1926 nFlyDirection = 16;
1927 nFlyMethod = 12;
1929 break;
1930 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_LEFT :
1931 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_UPPERLEFT :
1932 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_TOP :
1933 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_UPPERRIGHT :
1934 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_RIGHT :
1935 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_LOWERRIGHT :
1936 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_BOTTOM :
1937 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_LOWERLEFT :
1938 case ::com::sun::star::presentation::AnimationEffect_ZOOM_OUT_FROM_CENTER :
1939 nAfterEffect |= 2;
1940 break;
1941 default:
1942 break;
1944 if ( mnDiaMode >= 1 )
1945 nFlags |= 4;
1946 if ( eTe != ::com::sun::star::presentation::AnimationEffect_NONE )
1947 nBuildType = 2;
1948 if ( ImplGetPropertyValue( OUString( "SoundOn" ) ) )
1950 sal_Bool bBool(sal_False);
1951 mAny >>= bBool;
1952 if ( bBool )
1954 if ( ImplGetPropertyValue( OUString( "Sound" ) ) )
1956 nSoundRef = maSoundCollection.GetId( *(OUString*)mAny.getValue() );
1957 if ( nSoundRef )
1958 nFlags |= 0x10;
1962 sal_Bool bDimHide = sal_False;
1963 sal_Bool bDimPrevious = sal_False;
1964 if ( ImplGetPropertyValue( OUString( "DimHide" ) ) )
1965 mAny >>= bDimHide;
1966 if ( ImplGetPropertyValue( OUString( "DimPrevious" ) ) )
1967 mAny >>= bDimPrevious;
1968 if ( bDimPrevious )
1969 nAfterEffect |= 1;
1970 if ( bDimHide )
1971 nAfterEffect |= 2;
1972 if ( ImplGetPropertyValue( OUString( "DimColor" ) ) )
1973 nDimColor = mpPptEscherEx->GetColor( *((sal_uInt32*)mAny.getValue()) ) | 0xfe000000;
1975 rSt << nDimColor << nFlags << nSoundRef << nDelayTime
1976 << nOrder // order of build ( 1.. )
1977 << nSlideCount << nBuildType << nFlyMethod << nFlyDirection
1978 << nAfterEffect << nSubEffect << nOleVerb
1979 << (sal_uInt16)0; // PadWord
1982 // -----------------------------------------------------------------------
1984 void PPTWriter::ImplWriteClickAction( SvStream& rSt, ::com::sun::star::presentation::ClickAction eCa, sal_Bool bMediaClickAction )
1986 sal_uInt32 nSoundRef = 0; // a reference to a sound in the sound collection, or NULL.
1987 sal_uInt32 nHyperLinkID = 0;// a persistent unique identifier to an external hyperlink object (only valid when action == HyperlinkAction).
1988 sal_uInt8 nAction = 0; // Action See Action Table
1989 sal_uInt8 nOleVerb = 0; // OleVerb Only valid when action == OLEAction. OLE verb to use, 0 = first verb, 1 = second verb, etc.
1990 sal_uInt8 nJump = 0; // Jump See Jump Table
1991 sal_uInt8 nFlags = 0; // Bit 1: Animated. If 1, then button is animated
1992 // Bit 2: Stop sound. If 1, then stop current sound when button is pressed.
1993 // Bit 3: CustomShowReturn. If 1, and this is a jump to custom show, then return to this slide after custom show.
1994 sal_uInt8 nHyperLinkType = 0;// HyperlinkType a value from the LinkTo enum, such as LT_URL (only valid when action == HyperlinkAction).
1996 String aFile;
1999 Action Table: Action Value
2000 NoAction 0
2001 MacroAction 1
2002 RunProgramAction 2
2003 JumpAction 3
2004 HyperlinkAction 4
2005 OLEAction 5
2006 MediaAction 6
2007 CustomShowAction 7
2009 Jump Table: Jump Value
2010 NoJump 0
2011 NextSlide, 1
2012 PreviousSlide, 2
2013 FirstSlide, 3
2014 LastSlide, 4
2015 LastSlideViewed 5
2016 EndShow 6
2019 if ( bMediaClickAction )
2020 nAction = 6;
2021 else switch( eCa )
2023 case ::com::sun::star::presentation::ClickAction_STOPPRESENTATION :
2024 nJump += 2;
2025 case ::com::sun::star::presentation::ClickAction_LASTPAGE :
2026 nJump++;
2027 case ::com::sun::star::presentation::ClickAction_FIRSTPAGE :
2028 nJump++;
2029 case ::com::sun::star::presentation::ClickAction_PREVPAGE :
2030 nJump++;
2031 case ::com::sun::star::presentation::ClickAction_NEXTPAGE :
2033 nJump++;
2034 nAction = 3;
2036 break;
2037 case ::com::sun::star::presentation::ClickAction_SOUND :
2039 if ( ImplGetPropertyValue( OUString( "Bookmark" ) ) )
2040 nSoundRef = maSoundCollection.GetId( *(OUString*)mAny.getValue() );
2042 break;
2043 case ::com::sun::star::presentation::ClickAction_PROGRAM :
2045 if ( ImplGetPropertyValue( OUString( "Bookmark" ) ) )
2047 INetURLObject aUrl( *(OUString*)mAny.getValue() );
2048 if ( INET_PROT_FILE == aUrl.GetProtocol() )
2050 aFile = aUrl.PathToFileName();
2051 nAction = 2;
2055 break;
2057 case ::com::sun::star::presentation::ClickAction_BOOKMARK :
2059 if ( ImplGetPropertyValue( OUString( "Bookmark" ) ) )
2061 OUString aBookmark( *(OUString*)mAny.getValue() );
2062 sal_uInt32 nIndex = 0;
2063 std::vector<OUString>::const_iterator pIter;
2064 for ( pIter = maSlideNameList.begin(); pIter != maSlideNameList.end(); ++pIter, nIndex++ )
2066 if ( *pIter == aBookmark )
2068 // Bookmark is a link to a document page
2069 nAction = 4;
2070 nHyperLinkType = 7;
2072 String aEmpty;
2073 String aHyperString = OUString::valueOf(static_cast<sal_Int32>(256 + nIndex));
2074 aHyperString.Append( OUString( "," ) );
2075 aHyperString.Append( OUString::number( nIndex + 1 ) );
2076 aHyperString.Append( OUString( ",Slide " ) );
2077 aHyperString.Append( OUString::number( nIndex + 1 ) );
2078 nHyperLinkID = ImplInsertBookmarkURL( aHyperString, 1 | ( nIndex << 8 ) | ( 1 << 31 ), aBookmark, aEmpty, aEmpty, aHyperString );
2083 break;
2085 case ::com::sun::star::presentation::ClickAction_DOCUMENT :
2087 if ( ImplGetPropertyValue( OUString( "Bookmark" ) ) )
2089 String aBookmark( *(OUString*)mAny.getValue() );
2090 if ( aBookmark.Len() )
2092 nAction = 4;
2093 nHyperLinkType = 8;
2095 String aEmpty;
2096 String aBookmarkFile( aBookmark );
2097 INetURLObject aUrl( aBookmark );
2098 if ( INET_PROT_FILE == aUrl.GetProtocol() )
2099 aBookmarkFile = aUrl.PathToFileName();
2100 nHyperLinkID = ImplInsertBookmarkURL( aBookmark, (sal_uInt32)(2 | ( 1 << 31 )), aBookmarkFile, aBookmark, aEmpty, aEmpty );
2104 break;
2106 case ::com::sun::star::presentation::ClickAction_INVISIBLE :
2107 case ::com::sun::star::presentation::ClickAction_VERB :
2108 case ::com::sun::star::presentation::ClickAction_VANISH :
2109 case ::com::sun::star::presentation::ClickAction_MACRO :
2110 default :
2111 break;
2114 sal_uInt32 nContainerSize = 24;
2115 if ( nAction == 2 )
2116 nContainerSize += ( aFile.Len() * 2 ) + 8;
2117 rSt << (sal_uInt32)( ( EPP_InteractiveInfo << 16 ) | 0xf ) << (sal_uInt32)nContainerSize
2118 << (sal_uInt32)( EPP_InteractiveInfoAtom << 16 ) << (sal_uInt32)16
2119 << nSoundRef
2120 << nHyperLinkID
2121 << nAction
2122 << nOleVerb
2123 << nJump
2124 << nFlags
2125 << (sal_uInt32)nHyperLinkType;
2127 if ( nAction == 2 ) // run program Action
2129 sal_uInt16 i, nLen = aFile.Len();
2130 rSt << (sal_uInt32)( ( EPP_CString << 16 ) | 0x20 ) << (sal_uInt32)( nLen * 2 );
2131 for ( i = 0; i < nLen; i++ )
2132 rSt << aFile.GetChar( i );
2135 rSt << (sal_uInt32)( ( EPP_InteractiveInfo << 16 ) | 0x1f ) << (sal_uInt32)24 // Mouse Over Action
2136 << (sal_uInt32)( EPP_InteractiveInfo << 16 ) << (sal_uInt32)16;
2137 for ( int i = 0; i < 4; i++, rSt << (sal_uInt32)0 ) ;
2140 // -----------------------------------------------------------------------
2142 sal_Bool PPTWriter::ImplGetEffect( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rPropSet,
2143 ::com::sun::star::presentation::AnimationEffect& eEffect,
2144 ::com::sun::star::presentation::AnimationEffect& eTextEffect,
2145 sal_Bool& bIsSound )
2147 ::com::sun::star::uno::Any aAny;
2148 if ( GetPropertyValue( aAny, rPropSet, OUString( "Effect" ) ) )
2149 aAny >>= eEffect;
2150 else
2151 eEffect = ::com::sun::star::presentation::AnimationEffect_NONE;
2153 if ( GetPropertyValue( aAny, rPropSet, OUString( "TextEffect" ) ) )
2154 aAny >>= eTextEffect;
2155 else
2156 eTextEffect = ::com::sun::star::presentation::AnimationEffect_NONE;
2157 if ( GetPropertyValue( aAny, rPropSet, OUString( "SoundOn" ) ) )
2158 aAny >>= bIsSound;
2159 else
2160 bIsSound = sal_False;
2162 sal_Bool bHasEffect = ( ( eEffect != ::com::sun::star::presentation::AnimationEffect_NONE )
2163 || ( eTextEffect != ::com::sun::star::presentation::AnimationEffect_NONE )
2164 || bIsSound );
2165 return bHasEffect;
2168 // -----------------------------------------------------------------------
2170 sal_Bool PPTWriter::ImplCreatePresentationPlaceholder( const sal_Bool bMasterPage, const PageType /* ePageType */,
2171 const sal_uInt32 nStyleInstance, const sal_uInt8 nPlaceHolderId )
2173 sal_Bool bRet = ImplGetText();
2174 if ( bRet && bMasterPage )
2176 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2177 sal_uInt32 nPresShapeID = mpPptEscherEx->GenerateShapeId();
2178 mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xa00, nPresShapeID );// Flags: HaveAnchor | HasSpt
2179 EscherPropertyContainer aPropOpt;
2180 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x50001 );
2181 aPropOpt.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 );
2182 aPropOpt.AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle );
2183 aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x110001 );
2184 aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x8000001 );
2185 aPropOpt.AddOpt( ESCHER_Prop_shadowColor, 0x8000002 );
2186 aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
2187 sal_uInt32 nLineFlags = 0x90001;
2188 if ( aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ) )
2189 nLineFlags |= 0x10001; // draw dashed line if no line
2190 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags );
2192 SvMemoryStream aExtBu( 0x200, 0x200 );
2193 SvMemoryStream aClientTextBox( 0x200, 0x200 );
2194 ImplWriteTextStyleAtom( aClientTextBox, nStyleInstance, 0, NULL, aExtBu, &aPropOpt );
2196 aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
2197 aPropOpt.CreateShapeProperties( mXShape );
2198 aPropOpt.Commit( *mpStrm );
2199 mpPptEscherEx->AddAtom( 8, ESCHER_ClientAnchor );
2200 *mpStrm << (sal_Int16)maRect.Top() << (sal_Int16)maRect.Left() << (sal_Int16)maRect.Right() << (sal_Int16)maRect.Bottom(); // oben, links, rechts, unten ????
2201 mpPptEscherEx->OpenContainer( ESCHER_ClientData );
2202 mpPptEscherEx->AddAtom( 8, EPP_OEPlaceholderAtom );
2203 *mpStrm << (sal_uInt32)0 // PlacementID
2204 << (sal_uInt8)nPlaceHolderId // PlaceHolderID
2205 << (sal_uInt8)0 // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER )
2206 << (sal_uInt16)0; // padword
2207 mpPptEscherEx->CloseContainer(); // ESCHER_ClientData
2209 if ( aClientTextBox.Tell() )
2211 *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf )
2212 << (sal_uInt32)aClientTextBox.Tell();
2214 mpStrm->Write( aClientTextBox.GetData(), aClientTextBox.Tell() );
2216 mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer
2218 else
2219 bRet = sal_False;
2220 return bRet;
2223 // -----------------------------------------------------------------------
2225 void PPTWriter::ImplCreateShape( sal_uInt32 nType, sal_uInt32 nFlags, EscherSolverContainer& rSolver )
2227 sal_uInt32 nId = mpPptEscherEx->GenerateShapeId();
2228 mpPptEscherEx->AddShape( nType, nFlags, nId );
2229 rSolver.AddShape( mXShape, nId );
2232 void PPTWriter::ImplCreateTextShape( EscherPropertyContainer& rPropOpt, EscherSolverContainer& rSolver, sal_Bool bFill )
2234 mnTextStyle = EPP_TEXTSTYLE_TEXT;
2235 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2236 ImplCreateShape( ESCHER_ShpInst_TextBox, 0xa00, rSolver );
2237 if ( bFill )
2238 rPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
2239 if ( ImplGetText() )
2240 rPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
2243 void PPTWriter::ImplWritePage( const PHLayout& rLayout, EscherSolverContainer& aSolverContainer, PageType ePageType, sal_Bool bMasterPage, int nPageNumber )
2245 // #i119551# PPT does not support groups of polygons and text (MS patch KB2289187)
2246 // sal_uInt32 nGroupLevel = 0;
2248 sal_uInt32 nInstance, nGroups, nShapes, nShapeCount, nPer, nLastPer, nIndices, nOlePictureId;
2249 sal_uInt16 nEffectCount;
2250 ::com::sun::star::awt::Point aTextRefPoint;
2252 ResetGroupTable( nShapes = mXShapes->getCount() );
2254 nIndices = nInstance = nLastPer = nShapeCount = nEffectCount = 0;
2256 sal_Bool bIsTitlePossible = sal_True; // powerpoint is not able to handle more than one title
2258 sal_uInt32 nOutlinerCount = 0; // the outline objects have to conform to the layout,
2259 sal_uInt32 nPrevTextStyle = 0; // there are no more than two allowed
2261 nOlePictureId = 0;
2263 sal_Bool bAdditionalText = sal_False;
2265 sal_Bool bSecOutl = sal_False;
2266 sal_uInt32 nPObjects = 0;
2268 SvMemoryStream* pClientTextBox = NULL;
2269 SvMemoryStream* pClientData = NULL;
2271 while( GetNextGroupEntry() )
2273 nShapeCount++;
2275 nPer = ( 5 * nShapeCount ) / nShapes;
2276 if ( nPer != nLastPer )
2278 nLastPer = nPer;
2279 sal_uInt32 nValue = mnPagesWritten * 5 + nPer;
2280 if ( nValue > mnStatMaxValue )
2281 nValue = mnStatMaxValue;
2282 if ( mbStatusIndicator && ( nValue > mnLatestStatValue ) )
2284 mXStatusIndicator->setValue( nValue );
2285 mnLatestStatValue = nValue;
2288 nGroups = GetGroupsClosed();
2289 for ( sal_uInt32 i = 0; i < nGroups; i++, mpPptEscherEx->LeaveGroup() ) ;
2291 if ( GetShapeByIndex( GetCurrentGroupIndex(), sal_True ) )
2293 sal_Bool bIsSound;
2294 sal_Bool bMediaClickAction = sal_False;
2295 ::com::sun::star::presentation::AnimationEffect eAe;
2296 ::com::sun::star::presentation::AnimationEffect eTe;
2298 if ( ImplGetPropertyValue( OUString( "PresentationOrder" ) ) )
2299 nEffectCount = *(sal_uInt16*)mAny.getValue();
2301 sal_Bool bEffect = ImplGetEffect( mXPropSet, eAe, eTe, bIsSound );
2302 ::com::sun::star::presentation::ClickAction eCa = ::com::sun::star::presentation::ClickAction_NONE;
2303 if ( ImplGetPropertyValue( OUString( "OnClick" ) ) )
2304 mAny >>= eCa;
2306 sal_Bool bGroup = mType == "drawing.Group";
2307 sal_Bool bOpenBezier = mType == "drawing.OpenBezier";
2308 sal_Bool bClosedBezier = mType == "drawing.ClosedBezier";
2309 sal_Bool bPolyPolygon = mType == "drawing.PolyPolygon";
2310 sal_Bool bPolyLine = mType == "drawing.PolyLine";
2312 const ::com::sun::star::awt::Size aSize100thmm( mXShape->getSize() );
2313 const ::com::sun::star::awt::Point aPoint100thmm( mXShape->getPosition() );
2314 Rectangle aRect100thmm( Point( aPoint100thmm.X, aPoint100thmm.Y ), Size( aSize100thmm.Width, aSize100thmm.Height ) );
2315 EscherPropertyContainer aPropOpt( mpPptEscherEx->GetGraphicProvider(), mpPicStrm, aRect100thmm );
2317 if ( bGroup )
2319 SvMemoryStream* pTmp = NULL;
2320 ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >
2321 aXIndexAccess( mXShape, ::com::sun::star::uno::UNO_QUERY );
2322 if ( EnterGroup( aXIndexAccess ) )
2324 if ( bEffect && !mbUseNewAnimations )
2326 pTmp = new SvMemoryStream( 0x200, 0x200 );
2327 ImplWriteObjectEffect( *pTmp, eAe, eTe, ++nEffectCount );
2329 if ( eCa != ::com::sun::star::presentation::ClickAction_NONE )
2331 if ( !pTmp )
2332 pTmp = new SvMemoryStream( 0x200, 0x200 );
2333 ImplWriteClickAction( *pTmp, eCa, bMediaClickAction );
2335 sal_uInt32 nShapeId = mpPptEscherEx->EnterGroup( &maRect, pTmp );
2336 aSolverContainer.AddShape( mXShape, nShapeId );
2337 delete pTmp;
2340 else
2342 sal_Bool bIsFontwork = sal_False;
2343 sal_Bool bIsHatching = sal_False;
2344 ::com::sun::star::uno::Any aAny;
2345 ::com::sun::star::drawing::FillStyle eFS;
2346 if ( GetPropertyValue( aAny, mXPropSet, OUString( "IsFontwork" ), sal_True ) )
2347 aAny >>= bIsFontwork;
2348 if ( GetPropertyValue( aAny, mXPropSet, OUString( "FillStyle" ), sal_True ) )
2350 aAny >>= eFS;
2351 bIsHatching = eFS == ::com::sun::star::drawing::FillStyle_HATCH;
2353 if ( bIsHatching || bIsFontwork || ( mType == "drawing.Measure" ) || ( mType == "drawing.Caption" ) )
2355 if ( ImplGetPropertyValue( OUString( "BoundRect" ) ) )
2357 ::com::sun::star::awt::Rectangle aRect( *(::com::sun::star::awt::Rectangle*)mAny.getValue() );
2358 maPosition = MapPoint( ::com::sun::star::awt::Point( aRect.X, aRect.Y ) );
2359 maSize = MapSize( ::com::sun::star::awt::Size( aRect.Width, aRect.Height ) );
2360 maRect = Rectangle( Point( maPosition.X, maPosition.Y ), Size( maSize.Width, maSize.Height ) );
2362 mType = "drawing.dontknow";
2365 sal_uInt8 nPlaceHolderAtom = EPP_PLACEHOLDER_NONE;
2367 mnTextSize = 0;
2368 mnTextStyle = EPP_TEXTSTYLE_NORMAL;
2370 if ( mType == "drawing.Custom" )
2372 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2373 sal_uInt32 nMirrorFlags;
2374 OUString sCustomShapeType;
2375 MSO_SPT eShapeType = aPropOpt.GetCustomShapeType( mXShape, nMirrorFlags, sCustomShapeType );
2376 if ( sCustomShapeType == "col-502ad400" || sCustomShapeType == "col-60da8460" )
2377 { // sj: creating metafile for customshapes that can't be saved to ms format properly
2378 ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer );
2379 if ( aPropOpt.CreateGraphicProperties( mXPropSet, OUString( "MetaFile" ), sal_False ) )
2381 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
2382 SdrObject* pObj = GetSdrObjectFromXShape( mXShape );
2383 if ( pObj )
2385 Rectangle aBound = pObj->GetCurrentBoundRect();
2386 maPosition = MapPoint( ::com::sun::star::awt::Point( aBound.Left(), aBound.Top() ) );
2387 maSize = MapSize( ::com::sun::star::awt::Size ( aBound.GetWidth(), aBound.GetHeight() ) );
2388 maRect = Rectangle( Point( maPosition.X, maPosition.Y ), Size( maSize.Width, maSize.Height ) );
2389 mnAngle = 0;
2393 else
2395 ImplCreateShape( eShapeType, nMirrorFlags | 0xa00, aSolverContainer );
2396 aPropOpt.CreateCustomShapeProperties( eShapeType, mXShape );
2397 aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape);
2398 if ( ImplGetText() )
2400 if ( !aPropOpt.IsFontWork() )
2401 aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_True, sal_True );
2405 else if ( mType == "drawing.Rectangle" )
2407 sal_Int32 nRadius = 0;
2408 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2409 if ( ImplGetPropertyValue( OUString( "CornerRadius" ) ) )
2411 mAny >>= nRadius;
2412 nRadius = MapSize( ::com::sun::star::awt::Size( nRadius, 0 ) ).Width;
2414 if ( nRadius )
2416 ImplCreateShape( ESCHER_ShpInst_RoundRectangle, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt
2417 sal_Int32 nLenght = maRect.GetWidth();
2418 if ( nLenght > maRect.GetHeight() )
2419 nLenght = maRect.GetHeight();
2420 nLenght >>= 1;
2421 if ( nRadius >= nLenght )
2422 nRadius = 0x2a30; // 0x2a30 ist PPTs maximum radius
2423 else
2424 nRadius = ( 0x2a30 * nRadius ) / nLenght;
2425 aPropOpt.AddOpt( ESCHER_Prop_adjustValue, nRadius );
2427 else
2429 ImplCreateShape( ESCHER_ShpInst_Rectangle, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt
2431 aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
2432 if ( ImplGetText() )
2433 aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False );
2435 else if ( mType == "drawing.Ellipse" )
2437 ::com::sun::star::drawing::CircleKind eCircleKind( ::com::sun::star::drawing::CircleKind_FULL );
2438 PolyStyle ePolyKind = POLY_CHORD;
2439 if ( ImplGetPropertyValue( OUString( "CircleKind" ) ) )
2441 mAny >>= eCircleKind;
2442 switch ( eCircleKind )
2444 case ::com::sun::star::drawing::CircleKind_SECTION :
2446 ePolyKind = POLY_PIE;
2448 break;
2449 case ::com::sun::star::drawing::CircleKind_ARC :
2451 ePolyKind = POLY_ARC;
2453 break;
2455 case ::com::sun::star::drawing::CircleKind_CUT :
2457 ePolyKind = POLY_CHORD;
2459 break;
2461 default:
2462 eCircleKind = ::com::sun::star::drawing::CircleKind_FULL;
2465 if ( eCircleKind == ::com::sun::star::drawing::CircleKind_FULL )
2467 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2468 ImplCreateShape( ESCHER_ShpInst_Ellipse, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt
2469 aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
2470 if ( ImplGetText() )
2471 aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False );
2473 else
2475 sal_Int32 nStartAngle, nEndAngle;
2476 if ( !ImplGetPropertyValue( OUString( "CircleStartAngle" ) ) )
2477 continue;
2478 nStartAngle = *( (sal_Int32*)mAny.getValue() );
2479 if( !ImplGetPropertyValue( OUString( "CircleEndAngle" ) ) )
2480 continue;
2481 nEndAngle = *( (sal_Int32*)mAny.getValue() );
2482 ::com::sun::star::awt::Point aPoint( mXShape->getPosition() );
2483 ::com::sun::star::awt::Size aSize( mXShape->getSize() );
2484 ::com::sun::star::awt::Point aStart, aEnd, aCenter;
2485 Rectangle aRect( Point( aPoint.X, aPoint.Y ), Size( aSize.Width, aSize.Height ) );
2486 aStart.X = (sal_Int32)( ( cos( (double)( nStartAngle * F_PI18000 ) ) * 100.0 ) );
2487 aStart.Y = - (sal_Int32)( ( sin( (double)( nStartAngle * F_PI18000 ) ) * 100.0 ) );
2488 aEnd.X = (sal_Int32)( ( cos( (double)( nEndAngle * F_PI18000 ) ) * 100.0 ) );
2489 aEnd.Y = - (sal_Int32)( ( sin( (double)( nEndAngle * F_PI18000 ) ) * 100.0 ) );
2490 aCenter.X = aPoint.X + ( aSize.Width / 2 );
2491 aCenter.Y = aPoint.Y + ( aSize.Height / 2 );
2492 aStart.X += aCenter.X;
2493 aStart.Y += aCenter.Y;
2494 aEnd.X += aCenter.X;
2495 aEnd.Y += aCenter.Y;
2496 Polygon aPolygon( aRect, Point( aStart.X, aStart.Y ), Point( aEnd.X, aEnd.Y ), ePolyKind );
2497 sal_Bool bNeedText = sal_True;
2498 if ( mnAngle )
2500 aPolygon.Rotate( aRect.TopLeft(), (sal_uInt16)( mnAngle / 10 ) );
2501 if ( ImplGetText() )
2503 // #i119551# PPT does not support groups of polygons and text (MS patch KB2289187)
2504 // mpPptEscherEx->EnterGroup( 0,0 );
2505 // nGroupLevel = mpPptEscherEx->GetGroupLevel();
2506 bNeedText = sal_False;
2507 bAdditionalText = sal_True;
2508 mnTextSize = 0;
2510 mnAngle = 0;
2512 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2513 ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt
2514 ::com::sun::star::awt::Rectangle aNewRect;
2515 switch ( ePolyKind )
2517 case POLY_PIE :
2518 case POLY_CHORD :
2520 if ( aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, &aPolygon ) )
2521 aPropOpt.CreateFillProperties( mXPropSet, sal_True , mXShape );
2523 break;
2525 case POLY_ARC :
2527 if ( aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, &aPolygon ) )
2528 aPropOpt.CreateLineProperties( mXPropSet, sal_False );
2530 break;
2532 maRect = MapRectangle( aNewRect );
2533 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
2534 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
2535 if ( bNeedText && ImplGetText() )
2536 aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False );
2539 else if ( mType == "drawing.Control" )
2541 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XControlShape >
2542 aXControlShape( mXShape, ::com::sun::star::uno::UNO_QUERY );
2543 if ( !aXControlShape.is() )
2544 continue;
2545 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >
2546 aXControlModel( aXControlShape->getControl() );
2547 if ( !aXControlModel.is() )
2548 continue;
2550 sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT;
2553 // try to get the aspect when available
2554 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
2555 xShapeProps( mXShape, ::com::sun::star::uno::UNO_QUERY_THROW );
2556 xShapeProps->getPropertyValue( OUString( "Aspect" ) ) >>= nAspect;
2558 catch( ::com::sun::star::uno::Exception& )
2561 *mpExEmbed << (sal_uInt32)( 0xf | ( EPP_ExControl << 16 ) )
2562 << (sal_uInt32)0; // Size of this container
2564 sal_uInt32 nSize, nOldPos = mpExEmbed->Tell();
2566 sal_uInt32 nPageId = nPageNumber;
2567 if ( ePageType == MASTER )
2568 nPageId |= 0x80000000;
2569 else
2570 nPageId += 0x100;
2571 *mpExEmbed << (sal_uInt32)( EPP_ExControlAtom << 16 )
2572 << (sal_uInt32)4
2573 << nPageId;
2574 PPTExOleObjEntry* pEntry = new PPTExOleObjEntry( OCX_CONTROL, mpExEmbed->Tell() );
2575 pEntry->xControlModel = aXControlModel;
2576 maExOleObj.push_back( pEntry );
2578 mnExEmbed++;
2580 *mpExEmbed << (sal_uInt32)( 1 | ( EPP_ExOleObjAtom << 16 ) )
2581 << (sal_uInt32)24
2582 << (sal_uInt32)nAspect
2583 << (sal_uInt32)2
2584 << (sal_uInt32)mnExEmbed
2585 << (sal_uInt32)0
2586 << (sal_uInt32)4 // index to the persist table
2587 << (sal_uInt32)0x0012de00;
2589 ::com::sun::star::awt::Size aSize;
2590 OUString aControlName;
2591 SvStorageRef xTemp( new SvStorage( new SvMemoryStream(), sal_True ) );
2592 if ( oox::ole::MSConvertOCXControls::WriteOCXStream( mXModel, xTemp, aXControlModel, aSize, aControlName ) )
2594 String aUserName( xTemp->GetUserName() );
2595 String aOleIdentifier;
2596 if ( aUserName.Len() )
2598 SvStorageStreamRef xCompObj = xTemp->OpenSotStream(
2599 OUString( "\1CompObj" ),
2600 STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYALL );
2601 xCompObj->Seek( STREAM_SEEK_TO_END );
2602 sal_uInt32 nStreamLen = xCompObj->Tell();
2603 xCompObj->Seek( 0 );
2604 sal_Int16 nVersion, nByteOrder;
2605 sal_Int32 nWinVersion, nVal, nStringLen;
2606 *xCompObj >> nVersion
2607 >> nByteOrder
2608 >> nWinVersion
2609 >> nVal;
2610 xCompObj->SeekRel( 16 ); // skipping clsid
2611 *xCompObj >> nStringLen;
2612 if ( ( xCompObj->Tell() + nStringLen ) < nStreamLen )
2614 xCompObj->SeekRel( nStringLen ); // now skipping the UserName;
2615 *xCompObj >> nStringLen;
2616 if ( ( xCompObj->Tell() + nStringLen ) < nStreamLen )
2618 xCompObj->SeekRel( nStringLen ); // now skipping the clipboard formatname
2619 *xCompObj >> nStringLen;
2620 if ( ( nStringLen > 1 ) && ( ( xCompObj->Tell() + nStringLen ) < nStreamLen ) )
2621 { // i think that the OleIdentifier will follow
2622 OString aTemp = read_uInt8s_ToOString(*xCompObj, nStringLen - 1);
2623 aOleIdentifier = OStringToOUString(aTemp, RTL_TEXTENCODING_MS_1252);
2629 if ( !aControlName.isEmpty() )
2630 PPTWriter::WriteCString( *mpExEmbed, aControlName, 1 );
2631 if ( aOleIdentifier.Len() )
2632 PPTWriter::WriteCString( *mpExEmbed, aOleIdentifier, 2 );
2633 if ( aUserName.Len() )
2634 PPTWriter::WriteCString( *mpExEmbed, aUserName, 3 );
2636 nSize = mpExEmbed->Tell() - nOldPos;
2637 mpExEmbed->Seek( nOldPos - 4 );
2638 *mpExEmbed << nSize;
2639 mpExEmbed->Seek( STREAM_SEEK_TO_END );
2640 nOlePictureId = mnExEmbed;
2642 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2643 sal_uInt32 nSpFlags = SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_OLESHAPE;
2644 ImplCreateShape( ESCHER_ShpInst_HostControl, nSpFlags, aSolverContainer );
2645 if ( aPropOpt.CreateGraphicProperties( mXPropSet, OUString( "MetaFile" ), sal_False ) )
2646 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
2647 aPropOpt.AddOpt( ESCHER_Prop_pictureId, mnExEmbed );
2648 aPropOpt.AddOpt( ESCHER_Prop_pictureActive, 0x10000 );
2650 if ( !aControlName.isEmpty() )
2652 sal_uInt16 i, nBufSize;
2653 nBufSize = ( aControlName.getLength() + 1 ) << 1;
2654 sal_uInt8* pBuf = new sal_uInt8[ nBufSize ];
2655 sal_uInt8* pTmp = pBuf;
2656 for ( i = 0; i < aControlName.getLength(); i++ )
2658 sal_Unicode nUnicode = *(aControlName.getStr() + i);
2659 *pTmp++ = (sal_uInt8)nUnicode;
2660 *pTmp++ = (sal_uInt8)( nUnicode >> 8 );
2662 *pTmp++ = 0;
2663 *pTmp = 0;
2664 aPropOpt.AddOpt( ESCHER_Prop_wzName, sal_True, nBufSize, pBuf, nBufSize );
2667 else if ( mType == "drawing.Connector" )
2669 sal_uInt16 nSpType, nSpFlags;
2670 ::com::sun::star::awt::Rectangle aNewRect;
2671 if ( aPropOpt.CreateConnectorProperties( mXShape, aSolverContainer, aNewRect, nSpType, nSpFlags ) == sal_False )
2672 continue;
2674 maRect = MapRectangle( aNewRect );
2675 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
2676 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
2678 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2679 ImplCreateShape( nSpType, nSpFlags, aSolverContainer );
2681 // #119459# for connector shape, the start point and end point is fixed, and should not be rotated.
2682 mnAngle = 0;
2684 else if ( mType == "drawing.Measure" )
2686 continue;
2688 else if ( mType == "drawing.Line" )
2690 ::com::sun::star::awt::Rectangle aNewRect;
2691 aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_LINE, sal_False, aNewRect, NULL );
2692 maRect = MapRectangle( aNewRect );
2693 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
2694 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
2695 if ( ImplGetText() )
2697 aTextRefPoint = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
2698 mnTextSize = 0;
2699 bAdditionalText = sal_True;
2700 // #i119551# PPT does not support groups of polygons and text (MS patch KB2289187)
2701 // mpPptEscherEx->EnterGroup( &maRect,0 );
2703 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2704 sal_uInt32 nFlags = 0xa00; // Flags: Connector | HasSpt
2705 if ( maRect.Top() > maRect.Bottom() )
2706 nFlags |= 0x80; // Flags: VertMirror
2707 if ( maRect.Left() > maRect.Right() )
2708 nFlags |= 0x40; // Flags: HorzMirror
2710 ImplCreateShape( ESCHER_ShpInst_Line, nFlags, aSolverContainer );
2711 aPropOpt.AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex );
2712 aPropOpt.CreateLineProperties( mXPropSet, sal_False );
2713 mnAngle = 0;
2715 else if ( bPolyPolygon )
2717 if ( ImplGetText() )
2719 // #i119551# PPT does not support groups of polygons and text (MS patch KB2289187)
2720 // mpPptEscherEx->EnterGroup( 0,0 );
2721 // nGroupLevel = mpPptEscherEx->GetGroupLevel();
2722 bAdditionalText = sal_True;
2723 mnTextSize = 0;
2725 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2726 ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt
2727 ::com::sun::star::awt::Rectangle aNewRect;
2728 aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, NULL );
2729 maRect = MapRectangle( aNewRect );
2730 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
2731 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
2732 aPropOpt.CreateFillProperties( mXPropSet, sal_True , mXShape );
2733 mnAngle = 0;
2735 else if ( bPolyLine )
2737 if ( ImplGetText() )
2739 // #i119551# PPT does not support groups of polygons and text (MS patch KB2289187)
2740 // mpPptEscherEx->EnterGroup( 0,0 );
2741 // nGroupLevel = mpPptEscherEx->GetGroupLevel();
2742 bAdditionalText = sal_True;
2743 mnTextSize = 0;
2745 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2746 ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt
2747 ::com::sun::star::awt::Rectangle aNewRect;
2748 aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, NULL );
2749 maRect = MapRectangle( aNewRect );
2750 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
2751 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
2752 aPropOpt.CreateLineProperties( mXPropSet, sal_False );
2753 mnAngle = 0;
2755 else if ( bOpenBezier )
2757 if ( ImplGetText() )
2759 // #i119551# PPT does not support groups of polygons and text (MS patch KB2289187)
2760 // mpPptEscherEx->EnterGroup( 0,0 );
2761 // nGroupLevel = mpPptEscherEx->GetGroupLevel();
2762 bAdditionalText = sal_True;
2763 mnTextSize = 0;
2765 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2766 ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt
2767 ::com::sun::star::awt::Rectangle aNewRect;
2768 aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_True, aNewRect, NULL );
2769 maRect = MapRectangle( aNewRect );
2770 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
2771 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
2772 aPropOpt.CreateLineProperties( mXPropSet, sal_False );
2773 mnAngle = 0;
2775 else if ( bClosedBezier )
2777 if ( ImplGetText() )
2779 // #i119551# PPT does not support groups of polygons and text (MS patch KB2289187)
2780 // mpPptEscherEx->EnterGroup( 0,0 );
2781 // nGroupLevel = mpPptEscherEx->GetGroupLevel();
2782 bAdditionalText = sal_True;
2783 mnTextSize = 0;
2785 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2786 ImplCreateShape( ESCHER_ShpInst_NotPrimitive, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt
2787 ::com::sun::star::awt::Rectangle aNewRect;
2788 aPropOpt.CreatePolygonProperties( mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_True, aNewRect, NULL );
2789 maRect = MapRectangle( aNewRect );
2790 maPosition = ::com::sun::star::awt::Point( maRect.Left(), maRect.Top() );
2791 maSize = ::com::sun::star::awt::Size( maRect.GetWidth(), maRect.GetHeight() );
2792 aPropOpt.CreateFillProperties( mXPropSet, sal_True , mXShape );
2793 mnAngle = 0;
2795 else if ( ( mType == "drawing.GraphicObject" ) || ( mType == "presentation.GraphicObject" ) )
2797 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2799 // a GraphicObject can also be a ClickMe element
2800 if ( mbEmptyPresObj && ( ePageType == NORMAL ) )
2802 nPlaceHolderAtom = rLayout.nUsedObjectPlaceHolder;
2803 ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer ); // Flags: HaveAnchor | HaveMaster
2804 aPropOpt.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 );
2805 aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 );
2806 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x10001 );
2807 aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody );
2809 else
2811 mXText = ::com::sun::star::uno::Reference<
2812 ::com::sun::star::text::XSimpleText >
2813 ( mXShape, ::com::sun::star::uno::UNO_QUERY );
2815 if ( mXText.is() )
2816 mnTextSize = mXText->getString().getLength();
2818 if ( mnTextSize ) // graphic object or area fill
2820 /* SJ #i34951#: because M. documents are not allowing GraphicObjects containing text, we
2821 have to create a simpe Rectangle with fill bitmap instead (while not allowing BitmapMode_Repeat).
2823 ImplCreateShape( ESCHER_ShpInst_Rectangle, 0xa00, aSolverContainer ); // Flags: Connector | HasSpt
2824 if ( aPropOpt.CreateGraphicProperties( mXPropSet, OUString( "GraphicURL" ), sal_True, sal_True, sal_False ) )
2826 aPropOpt.AddOpt( ESCHER_Prop_WrapText, ESCHER_WrapNone );
2827 aPropOpt.AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle );
2828 aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 );
2829 aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x8000000 );
2830 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
2831 if ( ImplGetText() )
2832 aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_False );
2835 else
2837 ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer );
2838 const Rectangle aOldRect100thmm(aRect100thmm);
2840 if ( aPropOpt.CreateGraphicProperties( mXPropSet, OUString( "GraphicURL" ), sal_False, sal_True ) )
2842 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
2844 if(aOldRect100thmm != aRect100thmm)
2846 // #119536# graphic has been adapted (rotated) so that it can be saved without angle,
2847 // adapt local values as needed
2848 maPosition = MapPoint( ::com::sun::star::awt::Point( aRect100thmm.Left(), aRect100thmm.Top() ) );
2849 maSize = MapSize( ::com::sun::star::awt::Size ( aRect100thmm.GetWidth(), aRect100thmm.GetHeight() ) );
2850 maRect = Rectangle( Point( maPosition.X, maPosition.Y ), Size( maSize.Width, maSize.Height ) );
2851 mnAngle = 0;
2857 else if ( ( mType == "drawing.Text" ) || ( mType == "presentation.Notes" ) )
2859 if ( ( ePageType == NOTICE ) && mbPresObj )
2861 if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Notes, EPP_PLACEHOLDER_MASTERNOTESBODYIMAGE ) )
2862 continue;
2863 else
2864 nPlaceHolderAtom = EPP_PLACEHOLDER_NOTESBODY;
2866 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
2868 else if ( mType == "presentation.TitleText" )
2870 if ( mbPresObj )
2872 if ( ( ePageType == NOTICE ) && mbEmptyPresObj )
2874 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2875 nPlaceHolderAtom = EPP_PLACEHOLDER_MASTERNOTESBODYIMAGE;
2876 ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x200, aSolverContainer );
2877 aPropOpt.CreateLineProperties( mXPropSet, sal_False );
2878 aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 );
2880 else if ( rLayout.bTitlePossible && bIsTitlePossible )
2882 bIsTitlePossible = sal_False;
2884 ImplGetText();
2885 TextObjBinary aTextObj( mXText, EPP_TEXTTYPE_Title, maFontCollection, (PPTExBulletProvider&)*this );
2886 if ( ePageType == MASTER )
2888 if ( mnTextSize )
2890 OUString aUString( mXText->getString() );
2891 sal_uInt16 nChar;
2893 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2894 mnShapeMasterTitle = mpPptEscherEx->GenerateShapeId();
2895 mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xa00, mnShapeMasterTitle );// Flags: HaveAnchor | HasSpt
2896 EscherPropertyContainer aPropertyOptions;
2897 aPropertyOptions.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x50001 );
2898 aPropertyOptions.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 );
2899 aPropertyOptions.AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle );
2900 aPropertyOptions.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x110001 );
2901 aPropertyOptions.AddOpt( ESCHER_Prop_lineColor, 0x8000001 );
2902 aPropertyOptions.AddOpt( ESCHER_Prop_shadowColor, 0x8000002 );
2903 aPropertyOptions.CreateFillProperties( mXPropSet, sal_True, mXShape );
2904 sal_uInt32 nLineFlags = 0x90001;
2905 if ( aPropertyOptions.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ) )
2906 nLineFlags |= 0x10001; // draw dashed line if no line
2907 aPropertyOptions.AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags );
2908 aPropertyOptions.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
2909 ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt );
2910 aPropertyOptions.Commit( *mpStrm );
2911 mpPptEscherEx->AddAtom( 8, ESCHER_ClientAnchor );
2912 *mpStrm << (sal_Int16)maRect.Top() << (sal_Int16)maRect.Left() << (sal_Int16)maRect.Right() << (sal_Int16)maRect.Bottom(); // top, left, right, bottom ????
2913 mpPptEscherEx->OpenContainer( ESCHER_ClientData );
2914 mpPptEscherEx->AddAtom( 8, EPP_OEPlaceholderAtom );
2915 *mpStrm << (sal_uInt32)0 // PlacementID
2916 << (sal_uInt8)EPP_PLACEHOLDER_MASTERTITLE // PlaceHolderID
2917 << (sal_uInt8)0 // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER )
2918 << (sal_uInt16)0; // padword
2919 mpPptEscherEx->CloseContainer(); // ESCHER_ClientData
2920 mpPptEscherEx->OpenContainer( ESCHER_ClientTextbox );
2921 mpPptEscherEx->AddAtom( 4, EPP_TextHeaderAtom );
2922 *mpStrm << (sal_uInt32)EPP_TEXTTYPE_Title;
2923 mpPptEscherEx->AddAtom( mnTextSize << 1, EPP_TextCharsAtom );
2924 const sal_Unicode* pString = aUString.getStr();
2925 for ( sal_uInt32 i = 0; i < mnTextSize; i++ )
2927 nChar = pString[ i ]; // 0xa -> 0xb soft newline
2928 if ( nChar == 0xa )
2929 nChar++; // 0xd -> 0xd hard newline
2930 *mpStrm << nChar;
2932 mpPptEscherEx->AddAtom( 6, EPP_BaseTextPropAtom );
2933 *mpStrm << (sal_uInt32)( mnTextSize + 1 ) << (sal_uInt16)0;
2934 mpPptEscherEx->AddAtom( 10, EPP_TextSpecInfoAtom );
2935 *mpStrm << (sal_uInt32)( mnTextSize + 1 ) << (sal_uInt32)1 << (sal_uInt16)0;
2936 mpPptEscherEx->CloseContainer(); // ESCHER_ClientTextBox
2937 mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer
2939 continue;
2941 else
2943 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2944 mnTextStyle = EPP_TEXTSTYLE_TITLE;
2945 nPlaceHolderAtom = rLayout.nTypeOfTitle;
2946 ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer ); // Flags: HaveAnchor | HaveMaster
2947 aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterTitle );
2948 aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
2949 aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
2950 ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt );
2951 if ( mbEmptyPresObj )
2953 sal_uInt32 nNoLineDrawDash = 0;
2954 aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash );
2955 nNoLineDrawDash |= 0x10001;
2956 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash );
2960 else
2961 mbPresObj = sal_False;
2963 if ( !mbPresObj )
2965 mType = "drawing.Text";
2966 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
2969 else if ( ( mType == "presentation.Outliner" ) || ( mType == "presentation.Subtitle" ) )
2971 if ( mbPresObj )
2973 nOutlinerCount++;
2974 if ( (rLayout.bOutlinerPossible && ( nOutlinerCount == 1 )) ||
2975 (( rLayout.bSecOutlinerPossible && ( nOutlinerCount == 2 ) ) && ( nPrevTextStyle == EPP_TEXTSTYLE_BODY ))
2978 ImplGetText();
2979 TextObjBinary aTextObj( mXText, EPP_TEXTTYPE_Body, maFontCollection, (PPTExBulletProvider&)*this );
2980 if ( ePageType == MASTER )
2982 nPrevTextStyle = EPP_TEXTSTYLE_TITLE;
2983 if ( mnTextSize )
2985 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
2986 mnShapeMasterBody = mpPptEscherEx->GenerateShapeId();
2987 mpPptEscherEx->AddShape( ESCHER_ShpInst_Rectangle, 0xa00, mnShapeMasterBody ); // Flags: HaveAnchor | HasSpt
2988 EscherPropertyContainer aPropOpt2;
2989 aPropOpt2.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x50001 );
2990 aPropOpt2.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 );
2991 aPropOpt2.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x110001 );
2992 aPropOpt2.AddOpt( ESCHER_Prop_lineColor, 0x8000001 );
2993 aPropOpt2.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90001 );
2994 aPropOpt2.AddOpt( ESCHER_Prop_shadowColor, 0x8000002 );
2995 aPropOpt2.CreateFillProperties( mXPropSet, sal_True, mXShape );
2996 sal_uInt32 nLineFlags = 0x90001;
2997 if ( aPropOpt2.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ) )
2998 nLineFlags |= 0x10001; // draw dashed line if no line
2999 aPropOpt2.AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags );
3000 aPropOpt2.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
3001 ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt2 );
3002 aPropOpt2.Commit( *mpStrm );
3003 mpPptEscherEx->AddAtom( 8, ESCHER_ClientAnchor );
3004 *mpStrm << (sal_Int16)maRect.Top() << (sal_Int16)maRect.Left() << (sal_Int16)maRect.Right() << (sal_Int16)maRect.Bottom(); // top, left, right, bottom ????
3005 mpPptEscherEx->OpenContainer( ESCHER_ClientData );
3006 mpPptEscherEx->AddAtom( 8, EPP_OEPlaceholderAtom );
3007 *mpStrm << (sal_uInt32)1 // PlacementID
3008 << (sal_uInt8)EPP_PLACEHOLDER_MASTERBODY // PlaceHolderID
3009 << (sal_uInt8)0 // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER )
3010 << (sal_uInt16)0; // padword
3011 mpPptEscherEx->CloseContainer(); // ESCHER_ClientData
3012 mpPptEscherEx->OpenContainer( ESCHER_ClientTextbox ); // printf
3013 mpPptEscherEx->AddAtom( 4, EPP_TextHeaderAtom );
3014 *mpStrm << (sal_uInt32)EPP_TEXTTYPE_Body;
3015 mnTextSize = aTextObj.Count();
3016 aTextObj.Write( mpStrm );
3017 mpPptEscherEx->BeginAtom();
3018 for ( sal_uInt32 i = 0; i < aTextObj.ParagraphCount() ; ++i )
3020 ParagraphObj* pPara = aTextObj.GetParagraph(i);
3021 sal_uInt32 nCharCount = pPara->CharacterCount();
3022 sal_uInt16 nDepth = pPara->nDepth;
3023 if ( nDepth > 4)
3024 nDepth = 4;
3026 *mpStrm << nCharCount
3027 << nDepth;
3029 mpPptEscherEx->EndAtom( EPP_BaseTextPropAtom );
3030 mpPptEscherEx->AddAtom( 10, EPP_TextSpecInfoAtom );
3031 *mpStrm << (sal_uInt32)( mnTextSize ) << (sal_uInt32)1 << (sal_uInt16)0;
3033 mpPptEscherEx->CloseContainer(); // ESCHER_ClientTextBox
3034 mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer
3036 continue;
3038 else
3040 mnTextStyle = EPP_TEXTSTYLE_BODY;
3041 nPlaceHolderAtom = rLayout.nTypeOfOutliner;
3042 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
3043 ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer ); // Flags: HaveAnchor | HaveMaster
3044 aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody );
3045 aPropOpt.CreateFillProperties( mXPropSet, sal_True, mXShape );
3046 aPropOpt.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
3047 ImplAdjustFirstLineLineSpacing( aTextObj, aPropOpt );
3048 if ( mbEmptyPresObj )
3050 sal_uInt32 nNoLineDrawDash = 0;
3051 aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash );
3052 nNoLineDrawDash |= 0x10001;
3053 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, nNoLineDrawDash );
3057 else
3058 mbPresObj = sal_False;
3060 if ( !mbPresObj )
3062 mType = "drawing.Text";
3063 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
3066 else if ( ( mType == "drawing.Page" ) || ( mType == "presentation.Page" ) )
3068 if ( ( ePageType == NOTICE ) && mbPresObj )
3070 if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Notes, EPP_PLACEHOLDER_MASTERNOTESSLIDEIMAGE ) )
3071 continue;
3072 else
3073 nPlaceHolderAtom = EPP_PLACEHOLDER_NOTESSLIDEIMAGE;
3075 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
3077 else if ( mType == "drawing.Frame" )
3079 continue;
3081 else if ( ( mType == "drawing.OLE2" ) || ( mType == "presentation.OLE2" )
3082 || ( mType == "presentation.Chart" ) || ( mType == "presentation.Calc" )
3083 || ( mType == "presentation.OrgChart" ) )
3085 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
3086 if ( mbEmptyPresObj && ( ePageType == NORMAL ) )
3088 nPlaceHolderAtom = rLayout.nUsedObjectPlaceHolder;
3089 ImplCreateShape( ESCHER_ShpInst_Rectangle, 0x220, aSolverContainer ); // Flags: HaveAnchor | HaveMaster
3090 aPropOpt.AddOpt( ESCHER_Prop_lTxid, mnTxId += 0x60 );
3091 aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 );
3092 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x10001 );
3093 aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody );
3095 else
3097 *mpExEmbed << (sal_uInt32)( 0xf | ( EPP_ExEmbed << 16 ) )
3098 << (sal_uInt32)0; // Size of this container
3100 sal_uInt32 nSize, nOldPos = mpExEmbed->Tell();
3102 *mpExEmbed << (sal_uInt32)( EPP_ExEmbedAtom << 16 )
3103 << (sal_uInt32)8
3104 << (sal_uInt32)0 // follow colorscheme : 0->do not follow
3105 // 1->follow collorscheme
3106 // 2->follow text and background scheme
3107 << (sal_uInt8)1 // (bool)set if embedded server can not be locked
3108 << (sal_uInt8)0 // (bool)do not need to send dimension
3109 << (sal_uInt8)0 // (bool)is object a world table
3110 << (sal_uInt8)0; // pad byte
3112 PPTExOleObjEntry* pE = new PPTExOleObjEntry( NORMAL_OLE_OBJECT, mpExEmbed->Tell() );
3113 pE->xShape = mXShape;
3114 maExOleObj.push_back( pE );
3116 mnExEmbed++;
3118 sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT;
3121 // try to get the aspect when available
3122 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
3123 xShapeProps( mXShape, ::com::sun::star::uno::UNO_QUERY_THROW );
3124 xShapeProps->getPropertyValue( OUString( "Aspect" ) ) >>= nAspect;
3126 catch( ::com::sun::star::uno::Exception& )
3129 *mpExEmbed << (sal_uInt32)( 1 | ( EPP_ExOleObjAtom << 16 ) )
3130 << (sal_uInt32)24
3131 << (sal_uInt32)nAspect // Aspect
3132 << (sal_uInt32)0
3133 << (sal_uInt32)mnExEmbed // index to the persist table
3134 << (sal_uInt32)0 // subtype
3135 << (sal_uInt32)0
3136 << (sal_uInt32)0x0012b600;
3138 nSize = mpExEmbed->Tell() - nOldPos;
3139 mpExEmbed->Seek( nOldPos - 4 );
3140 *mpExEmbed << nSize;
3141 mpExEmbed->Seek( STREAM_SEEK_TO_END );
3142 nOlePictureId = mnExEmbed;
3144 sal_uInt32 nSpFlags = 0xa00;
3145 if ( nOlePictureId )
3146 nSpFlags |= 0x10;
3147 ImplCreateShape( ESCHER_ShpInst_PictureFrame, nSpFlags, aSolverContainer );
3148 if ( aPropOpt.CreateOLEGraphicProperties( mXShape ) )
3149 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
3150 if ( nOlePictureId )
3151 aPropOpt.AddOpt( ESCHER_Prop_pictureId, nOlePictureId );
3154 else if ( mType == "presentation.Header" )
3156 if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERHEADER ) )
3157 continue;
3158 else
3160 mbPresObj = sal_False;
3161 mType = "drawing.Text";
3162 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
3165 else if ( mType == "presentation.Footer" )
3167 if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERFOOTER ) )
3168 continue;
3169 else
3171 mbPresObj = sal_False;
3172 mType = "drawing.Text";
3173 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
3176 else if ( mType == "presentation.DateTime" )
3178 if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERDATE ) )
3179 continue;
3180 else
3182 mbPresObj = sal_False;
3183 mType = "drawing.Text";
3184 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
3187 else if ( mType == "presentation.SlideNumber" )
3189 if ( ImplCreatePresentationPlaceholder( bMasterPage, ePageType, EPP_TEXTTYPE_Other, EPP_PLACEHOLDER_MASTERSLIDENUMBER ) )
3190 continue;
3191 else
3193 mbPresObj = sal_False;
3194 mType = "drawing.Text";
3195 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_True );
3198 else if ( (mType.getLength() > 9) && (mType[8] == '3') && (mType[9] == 'D') ) // drawing.3D
3200 // SceneObject, CubeObject, SphereObject, LatheObject, ExtrudeObject, PolygonObject
3201 if ( !ImplGetPropertyValue( OUString( "Bitmap" ) ) )
3202 continue;
3204 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
3205 ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer );
3207 if ( aPropOpt.CreateGraphicProperties( mXPropSet, OUString( "Bitmap" ), sal_False ) )
3208 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
3210 else if ( mType == "drawing.Media" )
3212 mnAngle = 0;
3213 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
3214 ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer );
3215 if ( aPropOpt.CreateMediaGraphicProperties( mXShape ) )
3216 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
3217 ::com::sun::star::uno::Any aAny;
3218 if ( PropValue::GetPropertyValue( aAny, mXPropSet, OUString( "MediaURL" ), sal_True ) )
3220 OUString aMediaURL;
3221 if ( (aAny >>= aMediaURL ) && !aMediaURL.isEmpty() )
3223 // SJ: creating the Media RefObj
3224 sal_uInt32 nRefId = ++mnExEmbed;
3226 *mpExEmbed << (sal_uInt16)0xf
3227 << (sal_uInt16)EPP_ExMCIMovie // PPT_PST_ExAviMovie
3228 << (sal_uInt32)0;
3229 sal_uInt32 nSize, nStart = mpExEmbed->Tell();
3230 *mpExEmbed << (sal_uInt16)0
3231 << (sal_uInt16)EPP_ExObjRefAtom
3232 << (sal_uInt32)4
3233 << nRefId;
3234 *mpExEmbed << (sal_uInt16)0xf
3235 << (sal_uInt16)EPP_ExVideo
3236 << (sal_uInt32)0;
3238 *mpExEmbed << (sal_uInt16)0
3239 << (sal_uInt16)EPP_ExMediaAtom
3240 << (sal_uInt32)8
3241 << nRefId
3242 << (sal_uInt16)0
3243 << (sal_uInt16)0x435;
3245 sal_uInt16 i, nStringLen = (sal_uInt16)aMediaURL.getLength();
3246 *mpExEmbed << (sal_uInt32)( EPP_CString << 16 ) << (sal_uInt32)( nStringLen * 2 );
3247 for ( i = 0; i < nStringLen; i++ )
3249 sal_Unicode nChar = aMediaURL[ i ];
3250 *mpExEmbed << nChar;
3252 nSize = mpExEmbed->Tell() - nStart;
3253 mpExEmbed->SeekRel( - ( (sal_Int32)nSize + 4 ) );
3254 *mpExEmbed << nSize; // size of PPT_PST_ExMCIMovie
3255 mpExEmbed->SeekRel( 0x10 );
3256 nSize -= 20;
3257 *mpExEmbed << nSize; // PPT_PST_ExMediaAtom
3258 mpExEmbed->SeekRel( nSize );
3260 if ( !pClientData )
3261 pClientData = new SvMemoryStream( 0x200, 0x200 );
3262 *pClientData << (sal_uInt16)0
3263 << (sal_uInt16)EPP_ExObjRefAtom
3264 << (sal_uInt32)4
3265 << nRefId;
3266 // write EPP_InteractiveInfo container for no_action
3267 *pClientData << (sal_uInt32)( ( EPP_InteractiveInfo << 16 ) | 0xf ) << (sal_uInt32)24;
3268 *pClientData << (sal_uInt16)0
3269 << (sal_uInt16)EPP_InteractiveInfoAtom
3270 << (sal_uInt32)16
3271 << (sal_uInt32) 0
3272 << (sal_uInt32) 0
3273 << (sal_uInt8) 6
3274 << (sal_uInt8) 0
3275 << (sal_uInt8) 0
3276 << (sal_uInt8) 0
3277 << (sal_uInt32) 0;
3281 else if ( (mType == "drawing.Table") || (mType == "presentation.Table") )
3283 SvMemoryStream* pTmp = NULL;
3284 if ( bEffect && !mbUseNewAnimations )
3286 pTmp = new SvMemoryStream( 0x200, 0x200 );
3287 ImplWriteObjectEffect( *pTmp, eAe, eTe, ++nEffectCount );
3289 if ( eCa != ::com::sun::star::presentation::ClickAction_NONE )
3291 if ( !pTmp )
3292 pTmp = new SvMemoryStream( 0x200, 0x200 );
3293 ImplWriteClickAction( *pTmp, eCa, bMediaClickAction );
3295 ImplCreateTable( mXShape, aSolverContainer, aPropOpt );
3296 continue;
3298 else if ( mType == "drawing.dontknow" )
3300 mnAngle = 0;
3301 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
3302 ImplCreateShape( ESCHER_ShpInst_PictureFrame, 0xa00, aSolverContainer );
3303 if ( aPropOpt.CreateGraphicProperties( mXPropSet, OUString( "MetaFile" ), sal_False ) )
3304 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
3306 else
3308 continue;
3311 sal_Bool bClientData = ( bEffect || ( eCa != ::com::sun::star::presentation::ClickAction_NONE ) ||
3312 nPlaceHolderAtom || nOlePictureId );
3313 if ( bClientData )
3315 if ( nPlaceHolderAtom )
3317 sal_Int32 nPlacementID = -1;
3318 if ( ( mnTextStyle == EPP_TEXTSTYLE_TITLE ) || ( mnTextStyle == EPP_TEXTSTYLE_BODY ) )
3319 nPlacementID = nIndices++;
3320 else
3322 switch ( nPlaceHolderAtom )
3324 default :
3326 if ( nPlaceHolderAtom < 19 )
3327 break;
3329 case EPP_PLACEHOLDER_NOTESBODY :
3330 case EPP_PLACEHOLDER_MASTERDATE :
3331 case EPP_PLACEHOLDER_NOTESSLIDEIMAGE :
3332 case EPP_PLACEHOLDER_MASTERNOTESBODYIMAGE :
3333 nPlacementID = nIndices++;
3336 if ( !pClientData )
3337 pClientData = new SvMemoryStream( 0x200, 0x200 );
3339 *pClientData << (sal_uInt32)( EPP_OEPlaceholderAtom << 16 ) << (sal_uInt32)8
3340 << nPlacementID // PlacementID
3341 << (sal_uInt8)nPlaceHolderAtom // PlaceHolderID
3342 << (sal_uInt8)0 // Size of PlaceHolder ( 0 = FULL, 1 = HALF, 2 = QUARTER )
3343 << (sal_uInt16)0; // padword
3345 if ( nOlePictureId )
3347 if ( !pClientData )
3348 pClientData = new SvMemoryStream( 0x200, 0x200 );
3350 *pClientData << (sal_uInt32)( EPP_ExObjRefAtom << 16 ) << (sal_uInt32)4
3351 << nOlePictureId;
3352 nOlePictureId = 0;
3354 if ( bEffect )
3356 if ( !pClientData )
3357 pClientData = new SvMemoryStream( 0x200, 0x200 );
3359 // check if it is sensible to replace the object effect with text effect,
3360 // because in Impress there is the possibility to use a compound effect,
3361 // e.g. the object effect is an AnimationEffect_FADE_FROM_LEFT and the
3362 // text effect is a AnimationEffect_FADE_FROM_TOP, in PowerPoint there
3363 // can be used only one effect
3364 if ( mnTextSize && ( eTe != ::com::sun::star::presentation::AnimationEffect_NONE )
3365 && ( eAe != ::com::sun::star::presentation::AnimationEffect_NONE )
3366 && ( eTe != eAe ) )
3368 sal_uInt32 nFillStyleFlags, nLineStyleFlags;
3369 if ( aPropOpt.GetOpt( ESCHER_Prop_fNoFillHitTest, nFillStyleFlags )
3370 && aPropOpt.GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineStyleFlags ) )
3372 // there is no fillstyle and also no linestyle
3373 if ( ! ( ( nFillStyleFlags & 0x10 ) + ( nLineStyleFlags & 9 ) ) )
3374 eAe = eTe;
3377 if ( !mbUseNewAnimations )
3378 ImplWriteObjectEffect( *pClientData, eAe, eTe, ++nEffectCount );
3381 if ( eCa != ::com::sun::star::presentation::ClickAction_NONE )
3383 if ( !pClientData )
3384 pClientData = new SvMemoryStream( 0x200, 0x200 );
3385 ImplWriteClickAction( *pClientData, eCa, bMediaClickAction );
3388 if ( ( mnTextStyle == EPP_TEXTSTYLE_TITLE ) || ( mnTextStyle == EPP_TEXTSTYLE_BODY ) )
3390 if ( !pClientTextBox )
3391 pClientTextBox = new SvMemoryStream( 0x200, 0x200 );
3393 if ( mbEmptyPresObj == sal_False )
3395 if ( ( ePageType == NORMAL ) && ( bMasterPage == sal_False ) )
3397 sal_uInt32 nTextType = EPP_TEXTTYPE_Body;
3398 if ( mnTextStyle == EPP_TEXTSTYLE_BODY )
3400 if ( bSecOutl )
3401 nTextType = EPP_TEXTTYPE_HalfBody;
3402 else if ( mType == "presentation.Subtitle" )
3403 nTextType = EPP_TEXTTYPE_CenterBody;
3404 bSecOutl = sal_True;
3406 else
3407 nTextType = EPP_TEXTTYPE_Title;
3409 TextRuleEntry aTextRule( nPageNumber );
3410 SvMemoryStream aExtBu( 0x200, 0x200 );
3411 ImplGetText();
3412 ImplWriteTextStyleAtom( *pClientTextBox, nTextType, nPObjects, &aTextRule, aExtBu, NULL );
3413 ImplWriteExtParaHeader( aExtBu, nPObjects++, nTextType, nPageNumber + 0x100 );
3414 SvMemoryStream* pOut = aTextRule.pOut;
3415 if ( pOut )
3417 pClientTextBox->Write( pOut->GetData(), pOut->Tell() );
3418 delete pOut, aTextRule.pOut = NULL;
3420 if ( aExtBu.Tell() )
3422 if ( !pClientData )
3423 pClientData = new SvMemoryStream( 0x200, 0x200 );
3424 ImplProgTagContainer( pClientData, &aExtBu );
3429 else
3431 if ( !aPropOpt.IsFontWork() )
3433 if ( mnTextSize || ( nPlaceHolderAtom == EPP_PLACEHOLDER_MASTERDATE ) || ( nPlaceHolderAtom == EPP_PLACEHOLDER_NOTESBODY ) )
3435 int nInstance2;
3436 if ( ( nPlaceHolderAtom == EPP_PLACEHOLDER_MASTERDATE ) || ( nPlaceHolderAtom == EPP_PLACEHOLDER_NOTESBODY ) )
3437 nInstance2 = 2;
3438 else
3439 nInstance2 = EPP_TEXTTYPE_Other; // Text in a Shape
3441 if ( !pClientTextBox )
3442 pClientTextBox = new SvMemoryStream( 0x200, 0x200 );
3444 SvMemoryStream aExtBu( 0x200, 0x200 );
3445 ImplWriteTextStyleAtom( *pClientTextBox, nInstance2, 0, NULL, aExtBu, &aPropOpt );
3446 if ( aExtBu.Tell() )
3448 if ( !pClientData )
3449 pClientData = new SvMemoryStream( 0x200, 0x200 );
3450 ImplProgTagContainer( pClientData, &aExtBu );
3453 else if ( nPlaceHolderAtom >= 19 )
3455 if ( !pClientTextBox )
3456 pClientTextBox = new SvMemoryStream( 12 );
3458 *pClientTextBox << (sal_uInt32)( EPP_TextHeaderAtom << 16 ) << (sal_uInt32)4
3459 << (sal_uInt32)7;
3464 aPropOpt.CreateShadowProperties( mXPropSet );
3465 maRect.Justify();
3466 if ( mnAngle )
3467 ImplFlipBoundingBox( aPropOpt );
3468 aPropOpt.CreateShapeProperties( mXShape );
3469 aPropOpt.Commit( *mpStrm );
3470 if ( GetCurrentGroupLevel() > 0 )
3471 mpPptEscherEx->AddChildAnchor( maRect );
3472 else
3473 mpPptEscherEx->AddClientAnchor( maRect );
3475 if ( pClientData )
3477 *mpStrm << (sal_uInt32)( ( ESCHER_ClientData << 16 ) | 0xf )
3478 << (sal_uInt32)pClientData->Tell();
3480 mpStrm->Write( pClientData->GetData(), pClientData->Tell() );
3481 delete pClientData, pClientData = NULL;
3483 if ( pClientTextBox )
3485 *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf )
3486 << (sal_uInt32)pClientTextBox->Tell();
3488 mpStrm->Write( pClientTextBox->GetData(), pClientTextBox->Tell() );
3489 delete pClientTextBox, pClientTextBox = NULL;
3491 mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer
3493 nPrevTextStyle = mnTextStyle;
3495 if ( bAdditionalText )
3497 bAdditionalText = sal_False;
3499 ::com::sun::star::uno::Any aAny;
3500 EscherPropertyContainer aPropOpt;
3501 mnAngle = ( PropValue::GetPropertyValue( aAny,
3502 mXPropSet, OUString( "RotateAngle" ), sal_True ) )
3503 ? *((sal_Int32*)aAny.getValue() )
3504 : 0;
3506 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 );
3507 aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
3508 if ( mType == "drawing.Line" )
3510 double fDist = hypot( maRect.GetWidth(), maRect.GetHeight() );
3511 maRect = Rectangle( Point( aTextRefPoint.X, aTextRefPoint.Y ),
3512 Point( (sal_Int32)( aTextRefPoint.X + fDist ), aTextRefPoint.Y - 1 ) );
3513 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_False );
3514 aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x60006 ); // Size Shape To Fit Text
3515 if ( mnAngle < 0 )
3516 mnAngle = ( 36000 + mnAngle ) % 36000;
3517 if ( mnAngle )
3518 ImplFlipBoundingBox( aPropOpt );
3520 else
3522 ImplCreateTextShape( aPropOpt, aSolverContainer, sal_False );
3523 if ( mnAngle < 0 )
3524 mnAngle = ( 36000 + mnAngle ) % 36000;
3525 else
3526 mnAngle = ( 36000 - ( mnAngle % 36000 ) );
3528 mnAngle *= 655;
3529 mnAngle += 0x8000;
3530 mnAngle &=~0xffff; // round nAngle to full grad
3531 aPropOpt.AddOpt( ESCHER_Prop_Rotation, mnAngle );
3533 // #i119551# PPT does not support groups of polygons and text (MS patch KB2289187)
3534 // mpPptEscherEx->SetGroupSnapRect( nGroupLevel, maRect );
3535 // mpPptEscherEx->SetGroupLogicRect( nGroupLevel, maRect );
3537 if ( !pClientTextBox )
3538 pClientTextBox = new SvMemoryStream( 0x200, 0x200 );
3540 SvMemoryStream aExtBu( 0x200, 0x200 );
3541 ImplWriteTextStyleAtom( *pClientTextBox, EPP_TEXTTYPE_Other, 0, NULL, aExtBu, &aPropOpt );
3543 aPropOpt.CreateShapeProperties( mXShape );
3544 aPropOpt.Commit( *mpStrm );
3545 if ( GetCurrentGroupLevel() > 0 )
3546 mpPptEscherEx->AddChildAnchor( maRect );
3547 else
3548 mpPptEscherEx->AddClientAnchor( maRect );
3550 *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf )
3551 << (sal_uInt32)pClientTextBox->Tell();
3553 mpStrm->Write( pClientTextBox->GetData(), pClientTextBox->Tell() );
3554 delete pClientTextBox, pClientTextBox = NULL;
3556 mpPptEscherEx->CloseContainer(); // ESCHER_SpContainer
3558 // #i119551# PPT does not support groups of polygons and text (MS patch KB2289187)
3559 // mpPptEscherEx->LeaveGroup();
3562 ClearGroupTable(); // storing groups if any are still open, which should not be the case
3563 nGroups = GetGroupsClosed();
3564 for ( sal_uInt32 i = 0; i < nGroups; i++, mpPptEscherEx->LeaveGroup() ) ;
3565 mnPagesWritten++;
3568 // -----------------------------------------------------------------------
3570 struct CellBorder
3572 sal_Int32 mnPos; // specifies the distance to the top/left position of the table
3573 sal_Int32 mnLength;
3574 table::BorderLine maCellBorder;
3576 CellBorder() : mnPos ( 0 ), mnLength( 0 ){};
3579 void PPTWriter::ImplCreateCellBorder( const CellBorder* pCellBorder, sal_Int32 nX1, sal_Int32 nY1, sal_Int32 nX2, sal_Int32 nY2 )
3581 sal_Int32 nLineWidth = pCellBorder->maCellBorder.OuterLineWidth + pCellBorder->maCellBorder.InnerLineWidth;
3582 if ( nLineWidth )
3584 mnAngle = 0;
3585 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
3586 EscherPropertyContainer aPropOptSp;
3588 sal_uInt32 nId = mpPptEscherEx->GenerateShapeId();
3589 mpPptEscherEx->AddShape( ESCHER_ShpInst_Line, 0xa02, nId );
3590 aPropOptSp.AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex );
3591 aPropOptSp.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0xa0008 );
3592 aPropOptSp.AddOpt( ESCHER_Prop_fshadowObscured, 0x20000 );
3594 sal_uInt32 nBorderColor = pCellBorder->maCellBorder.Color & 0xff00; // green
3595 nBorderColor |= static_cast< sal_uInt8 >( pCellBorder->maCellBorder.Color ) << 16; // red
3596 nBorderColor |= static_cast< sal_uInt8 >( pCellBorder->maCellBorder.Color >> 16 ); // blue
3597 aPropOptSp.AddOpt( ESCHER_Prop_lineColor, nBorderColor );
3599 aPropOptSp.AddOpt( ESCHER_Prop_lineWidth, nLineWidth * 360 );
3600 aPropOptSp.AddOpt( ESCHER_Prop_fc3DLightFace, 0x80000 );
3601 aPropOptSp.Commit( *mpStrm );
3602 mpPptEscherEx->AddAtom( 16, ESCHER_ChildAnchor );
3603 *mpStrm << nX1
3604 << nY1
3605 << nX2
3606 << nY2;
3607 mpPptEscherEx->CloseContainer();
3611 void PPTWriter::WriteCString( SvStream& rSt, const String& rString, sal_uInt32 nInstance )
3613 sal_uInt32 i, nLen = rString.Len();
3614 if ( nLen )
3616 rSt << (sal_uInt32)( ( nInstance << 4 ) | ( EPP_CString << 16 ) )
3617 << (sal_uInt32)( nLen << 1 );
3618 for ( i = 0; i < nLen; i++ )
3619 rSt << rString.GetChar( (sal_uInt16)i );
3623 void PPTWriter::ImplCreateTable( uno::Reference< drawing::XShape >& rXShape, EscherSolverContainer& aSolverContainer,
3624 EscherPropertyContainer& aPropOpt )
3626 mpPptEscherEx->OpenContainer( ESCHER_SpgrContainer );
3627 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
3628 mpPptEscherEx->AddAtom( 16, ESCHER_Spgr, 1 );
3629 *mpStrm << (sal_Int32)maRect.Left() // Bounding box for the grouped shapes to which they are attached
3630 << (sal_Int32)maRect.Top()
3631 << (sal_Int32)maRect.Right()
3632 << (sal_Int32)maRect.Bottom();
3634 sal_uInt32 nShapeId = mpPptEscherEx->GenerateShapeId();
3635 mpPptEscherEx->AddShape( ESCHER_ShpInst_Min, 0x201, nShapeId ); // Flags: Group | Patriarch
3636 aSolverContainer.AddShape( rXShape, nShapeId );
3637 EscherPropertyContainer aPropOpt2;
3640 static const OUString sModel( "Model" );
3641 static const OUString sWidth( "Width" );
3642 static const OUString sHeight( "Height" );
3644 uno::Reference< table::XTable > xTable;
3645 if ( mXPropSet->getPropertyValue( sModel ) >>= xTable )
3647 uno::Reference< table::XColumnRowRange > xColumnRowRange( xTable, uno::UNO_QUERY_THROW );
3648 uno::Reference< container::XIndexAccess > xColumns( xColumnRowRange->getColumns(), uno::UNO_QUERY_THROW );
3649 uno::Reference< container::XIndexAccess > xRows( xColumnRowRange->getRows(), uno::UNO_QUERY_THROW );
3650 sal_uInt16 nRowCount = static_cast< sal_uInt16 >( xRows->getCount() );
3651 sal_uInt16 nColumnCount = static_cast< sal_uInt16 >( xColumns->getCount() );
3653 std::vector< std::pair< sal_Int32, sal_Int32 > > aColumns;
3654 std::vector< std::pair< sal_Int32, sal_Int32 > > aRows;
3656 awt::Point aPosition( MapPoint( rXShape->getPosition() ) );
3657 sal_uInt32 nPosition = aPosition.X;
3658 for ( sal_Int32 x = 0; x < nColumnCount; x++ )
3660 uno::Reference< beans::XPropertySet > xPropSet( xColumns->getByIndex( x ), uno::UNO_QUERY_THROW );
3661 awt::Size aS( 0, 0 );
3662 xPropSet->getPropertyValue( sWidth ) >>= aS.Width;
3663 awt::Size aM( MapSize( aS ) );
3664 aColumns.push_back( std::pair< sal_Int32, sal_Int32 >( nPosition, aM.Width ) );
3665 nPosition += aM.Width;
3668 nPosition = aPosition.Y;
3669 for ( sal_Int32 y = 0; y < nRowCount; y++ )
3671 uno::Reference< beans::XPropertySet > xPropSet( xRows->getByIndex( y ), uno::UNO_QUERY_THROW );
3672 awt::Size aS( 0, 0 );
3673 xPropSet->getPropertyValue( sHeight ) >>= aS.Height;
3674 awt::Size aM( MapSize( aS ) );
3675 aRows.push_back( std::pair< sal_Int32, sal_Int32 >( nPosition, aM.Height ) );
3676 nPosition += aM.Height;
3679 if ( nRowCount )
3681 SvMemoryStream aMemStrm;
3682 aMemStrm.ObjectOwnsMemory( sal_False );
3683 aMemStrm << nRowCount
3684 << nRowCount
3685 << (sal_uInt16)4;
3687 std::vector< std::pair< sal_Int32, sal_Int32 > >::const_iterator aIter( aRows.begin() );
3688 while( aIter != aRows.end() )
3689 aMemStrm << (*aIter++).second;
3691 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x1000100 );
3692 aPropOpt2.AddOpt( ESCHER_Prop_tableProperties, 1 );
3693 aPropOpt2.AddOpt( ESCHER_Prop_tableRowProperties, sal_True, aMemStrm.Tell(), static_cast< sal_uInt8* >( const_cast< void* >( aMemStrm.GetData() ) ), aMemStrm.Tell() );
3694 aPropOpt.CreateShapeProperties( rXShape );
3695 aPropOpt.Commit( *mpStrm );
3696 aPropOpt2.Commit( *mpStrm, 3, ESCHER_UDefProp );
3697 if ( GetCurrentGroupLevel() > 0 )
3698 mpPptEscherEx->AddChildAnchor( maRect );
3699 else
3700 mpPptEscherEx->AddClientAnchor( maRect );
3701 mpPptEscherEx->CloseContainer();
3703 uno::Reference< table::XCellRange > xCellRange( xTable, uno::UNO_QUERY_THROW );
3704 for( sal_Int32 nRow = 0; nRow < xRows->getCount(); nRow++ )
3706 for( sal_Int32 nColumn = 0; nColumn < xColumns->getCount(); nColumn++ )
3708 uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nColumn, nRow ), uno::UNO_QUERY_THROW );
3709 if ( !xCell->isMerged() )
3711 sal_Int32 nLeft = aColumns[ nColumn ].first;
3712 sal_Int32 nTop = aRows[ nRow ].first;
3713 sal_Int32 nRight = nLeft + aColumns[ nColumn ].second;
3714 sal_Int32 nBottom = nTop + aRows[ nRow ].second;
3716 for ( sal_Int32 nColumnSpan = 1; nColumnSpan < xCell->getColumnSpan(); nColumnSpan++ )
3718 sal_uInt32 nC = nColumnSpan + nColumn;
3719 if ( nC < aColumns.size() )
3720 nRight += aColumns[ nC ].second;
3721 else
3722 nRight = maRect.Right();
3724 for ( sal_Int32 nRowSpan = 1; nRowSpan < xCell->getRowSpan(); nRowSpan++ )
3726 sal_uInt32 nR = nRowSpan + nRow;
3727 if ( nR < aRows.size() )
3728 nBottom += aRows[ nR ].second;
3729 else
3730 nBottom = maRect.Bottom();
3733 mbFontIndependentLineSpacing = sal_False;
3734 mXPropSet = uno::Reference< beans::XPropertySet >( xCell, uno::UNO_QUERY_THROW );
3735 mXText = uno::Reference< text::XSimpleText >( xCell, uno::UNO_QUERY_THROW );
3736 mnTextSize = mXText->getString().getLength();
3738 ::com::sun::star::uno::Any aAny;
3739 if ( GetPropertyValue( aAny, mXPropSet, OUString( "FontIndependentLineSpacing" ) ), sal_True )
3740 aAny >>= mbFontIndependentLineSpacing;
3742 EscherPropertyContainer aPropOptSp;
3743 mpPptEscherEx->OpenContainer( ESCHER_SpContainer );
3744 ImplCreateShape( ESCHER_ShpInst_Rectangle, 0xa02, aSolverContainer ); // Flags: Connector | HasSpt | Child
3745 aPropOptSp.CreateFillProperties( mXPropSet, sal_True );
3746 aPropOptSp.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 );
3747 aPropOptSp.CreateTextProperties( mXPropSet, mnTxId += 0x60, sal_False, sal_True );
3748 aPropOptSp.AddOpt( ESCHER_Prop_WrapText, ESCHER_WrapSquare );
3750 SvMemoryStream aClientTextBox( 0x200, 0x200 );
3751 SvMemoryStream aExtBu( 0x200, 0x200 );
3753 ImplWriteTextStyleAtom( aClientTextBox, EPP_TEXTTYPE_Other, 0, NULL, aExtBu, &aPropOptSp );
3755 // need write client data for extend bullet
3756 if ( aExtBu.Tell() )
3758 SvMemoryStream* pClientData = new SvMemoryStream( 0x200, 0x200 );
3759 ImplProgTagContainer( pClientData, &aExtBu );
3760 *mpStrm << (sal_uInt32)( ( ESCHER_ClientData << 16 ) | 0xf )
3761 << (sal_uInt32)pClientData->Tell();
3763 mpStrm->Write( pClientData->GetData(), pClientData->Tell() );
3764 delete pClientData, pClientData = NULL;
3767 aPropOptSp.Commit( *mpStrm );
3768 mpPptEscherEx->AddAtom( 16, ESCHER_ChildAnchor );
3769 *mpStrm << nLeft
3770 << nTop
3771 << nRight
3772 << nBottom;
3774 *mpStrm << (sal_uInt32)( ( ESCHER_ClientTextbox << 16 ) | 0xf )
3775 << (sal_uInt32)aClientTextBox.Tell();
3777 mpStrm->Write( aClientTextBox.GetData(), aClientTextBox.Tell() );
3778 mpPptEscherEx->CloseContainer();
3783 static const OUString sTopBorder( "TopBorder" );
3784 static const OUString sBottomBorder( "BottomBorder" );
3785 static const OUString sLeftBorder( "LeftBorder" );
3786 static const OUString sRightBorder( "RightBorder" );
3788 // creating horz lines
3789 sal_Int32 nYPos = MapPoint( rXShape->getPosition() ).Y;
3790 for( sal_Int32 nLine = 0; nLine < ( xRows->getCount() + 1 ); nLine++ )
3792 sal_Int32 nXPos = MapPoint( rXShape->getPosition() ).X;
3793 std::vector< CellBorder > vCellBorders;
3794 for( sal_Int32 nColumn = 0; nColumn < xColumns->getCount(); nColumn++ )
3796 uno::Reference< beans::XPropertySet > xPropSet( xColumns->getByIndex( nColumn ), uno::UNO_QUERY_THROW );
3797 awt::Size aS( 0, 0 );
3798 xPropSet->getPropertyValue( sWidth ) >>= aS.Width;
3799 awt::Size aM( MapSize( aS ) );
3801 CellBorder aCellBorder;
3802 aCellBorder.mnPos = nXPos;
3803 aCellBorder.mnLength = aM.Width;
3804 if ( nLine < xRows->getCount() )
3805 { // top border
3806 uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nColumn, nLine ), uno::UNO_QUERY_THROW );
3807 uno::Reference< beans::XPropertySet > xPropSet2( xCell, uno::UNO_QUERY_THROW );
3808 table::BorderLine aBorderLine;
3809 if ( xPropSet2->getPropertyValue( sTopBorder ) >>= aBorderLine )
3810 aCellBorder.maCellBorder = aBorderLine;
3812 if ( nLine )
3813 { // bottom border
3814 uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nColumn, nLine - 1 ), uno::UNO_QUERY_THROW );
3815 uno::Reference< beans::XPropertySet > xPropSet2( xCell, uno::UNO_QUERY_THROW );
3816 table::BorderLine aBorderLine;
3817 if ( xPropSet2->getPropertyValue( sBottomBorder ) >>= aBorderLine )
3818 aCellBorder.maCellBorder = aBorderLine;
3820 vCellBorders.push_back( aCellBorder );
3821 nXPos += aM.Width;
3823 std::vector< CellBorder >::const_iterator aCellBorderIter( vCellBorders.begin() );
3824 while( aCellBorderIter != vCellBorders.end() )
3826 ImplCreateCellBorder( &*aCellBorderIter, aCellBorderIter->mnPos, nYPos,
3827 static_cast< sal_Int32 >( aCellBorderIter->mnPos + aCellBorderIter->mnLength ), nYPos );
3828 ++aCellBorderIter;
3830 if ( nLine < xRows->getCount() )
3832 uno::Reference< beans::XPropertySet > xPropSet( xRows->getByIndex( nLine ), uno::UNO_QUERY_THROW );
3833 awt::Size aS( 0, 0 );
3834 xPropSet->getPropertyValue( sHeight ) >>= aS.Height;
3835 awt::Size aM( MapSize( aS ) );
3836 nYPos += aM.Height;
3840 // creating vertical lines
3841 sal_Int32 nXPos = MapPoint( rXShape->getPosition() ).X;
3842 for( sal_Int32 nLine = 0; nLine < ( xColumns->getCount() + 1 ); nLine++ )
3844 nYPos = MapPoint( rXShape->getPosition() ).Y;
3845 std::vector< CellBorder > vCellBorders;
3846 for( sal_Int32 nRow = 0; nRow < xRows->getCount(); nRow++ )
3848 uno::Reference< beans::XPropertySet > xPropSet( xRows->getByIndex( nRow ), uno::UNO_QUERY_THROW );
3849 awt::Size aS( 0, 0 );
3850 xPropSet->getPropertyValue( sHeight ) >>= aS.Height;
3851 awt::Size aM( MapSize( aS ) );
3853 CellBorder aCellBorder;
3854 aCellBorder.mnPos = nYPos;
3855 aCellBorder.mnLength = aM.Height;
3856 if ( nLine < xColumns->getCount() )
3857 { // left border
3858 uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nLine, nRow ), uno::UNO_QUERY_THROW );
3859 uno::Reference< beans::XPropertySet > xCellSet( xCell, uno::UNO_QUERY_THROW );
3860 table::BorderLine aBorderLine;
3861 if ( xCellSet->getPropertyValue( sLeftBorder ) >>= aBorderLine )
3862 aCellBorder.maCellBorder = aBorderLine;
3864 if ( nLine )
3865 { // right border
3866 uno::Reference< table::XMergeableCell > xCell( xCellRange->getCellByPosition( nLine - 1, nRow ), uno::UNO_QUERY_THROW );
3867 uno::Reference< beans::XPropertySet > xCellSet( xCell, uno::UNO_QUERY_THROW );
3868 table::BorderLine aBorderLine;
3869 if ( xCellSet->getPropertyValue( sRightBorder ) >>= aBorderLine )
3870 aCellBorder.maCellBorder = aBorderLine;
3872 vCellBorders.push_back( aCellBorder );
3873 nYPos += aM.Height;
3875 std::vector< CellBorder >::const_iterator aCellBorderIter( vCellBorders.begin() );
3876 while( aCellBorderIter != vCellBorders.end() )
3878 ImplCreateCellBorder( &*aCellBorderIter, nXPos, aCellBorderIter->mnPos,
3879 nXPos, static_cast< sal_Int32 >( aCellBorderIter->mnPos + aCellBorderIter->mnLength ) );
3880 ++aCellBorderIter;
3882 if ( nLine < xColumns->getCount() )
3884 uno::Reference< beans::XPropertySet > xPropSet( xColumns->getByIndex( nLine ), uno::UNO_QUERY_THROW );
3885 awt::Size aS( 0, 0 );
3886 xPropSet->getPropertyValue( sWidth ) >>= aS.Width;
3887 awt::Size aM( MapSize( aS ) );
3888 nXPos += aM.Width;
3894 catch( uno::Exception& )
3897 mpPptEscherEx->CloseContainer();
3900 //----------------------------------------------------------------------------------------------------------
3902 void TextObjBinary::Write( SvStream* pStrm )
3904 sal_uInt32 nSize, nPos = pStrm->Tell();
3905 *pStrm << (sal_uInt32)( EPP_TextCharsAtom << 16 ) << (sal_uInt32)0;
3906 for ( sal_uInt32 i = 0; i < ParagraphCount(); ++i )
3907 GetParagraph(i)->Write( pStrm );
3908 nSize = pStrm->Tell() - nPos;
3909 pStrm->SeekRel( - ( (sal_Int32)nSize - 4 ) );
3910 *pStrm << (sal_uInt32)( nSize - 8 );
3911 pStrm->SeekRel( nSize - 8 );
3914 void TextObjBinary::WriteTextSpecInfo( SvStream* pStrm )
3916 sal_uInt32 nCharactersLeft( Count() );
3917 if ( nCharactersLeft >= 1 )
3919 EscherExAtom aAnimationInfoAtom( *pStrm, EPP_TextSpecInfoAtom, 0, 0 );
3920 for ( sal_uInt32 i = 0; nCharactersLeft && i < ParagraphCount(); ++i )
3922 ParagraphObj* pPtr = GetParagraph(i);
3923 for ( ParagraphObj::const_iterator it = pPtr->begin(); nCharactersLeft && it != pPtr->end(); ++it )
3925 PortionObj* pPortion = *it;
3926 sal_Int32 nPortionSize = pPortion->mnTextSize >= nCharactersLeft ? nCharactersLeft : pPortion->mnTextSize;
3927 sal_Int32 nFlags = 7;
3928 nCharactersLeft -= nPortionSize;
3929 *pStrm << static_cast< sal_uInt32 >( nPortionSize )
3930 << nFlags
3931 << static_cast< sal_Int16 >( 1 ) // spellinfo -> needs rechecking
3932 << static_cast< sal_Int16 >( LanguageTag( pPortion->meCharLocale ).makeFallback().getLanguageType() )
3933 << static_cast< sal_Int16 >( 0 ); // alt language
3936 if ( nCharactersLeft )
3937 *pStrm << nCharactersLeft << static_cast< sal_Int32 >( 1 ) << static_cast< sal_Int16 >( 1 );
3942 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */